Report generation

The report generation guide describes the command-line workflow, supported history mappings, output package, profile schema, and diagnostics. The API below is intended for applications that need to select sections programmatically or add a report module.

Architecture

Report generation has three layers:

  • measurement classes acquire and evaluate technical data;

  • report modules collect evaluated results into renderer-neutral mappings;

  • writers turn those mappings into tables, HTML, figures, and PDF pages.

A report profile changes metadata and presentation only. It cannot select a different technical result or alter pass/fail assessment. This boundary keeps repeated report generation deterministic and preserves the pickle as the measurement-history authority.

History report

class mpylab.env.tem.history_report.ReportSelection(module_key: str, dataset_key: str, title: str)

Identify one reportable data set in a measurement history.

property identifier

Return the stable module:dataset selection identifier.

class mpylab.env.tem.history_report.ReportModule(*args, **kwargs)

Interface implemented by modular TEM history-report sections.

collect(tem, selection)

Collect one selected data set into a renderer-neutral mapping.

Parameters:
  • tem (TEMCell) – Measurement history containing the selected data set.

  • selection (ReportSelection) – Data set selected for reporting.

Returns:

Renderer-neutral report data.

Return type:

dict

discover(tem)

Return the module’s available report selections.

Parameters:

tem (TEMCell) – Measurement history to inspect.

Returns:

Reportable data sets owned by this module.

Return type:

list of ReportSelection

pdf_figures(report)

Return figures to append to the combined PDF.

Parameters:

report (mapping) – Renderer-neutral data returned by collect().

Returns:

Figures in report order.

Return type:

iterable of matplotlib.figure.Figure

summary(report)

Return compact fields for the report index and cover.

Parameters:

report (mapping) – Renderer-neutral data returned by collect().

Returns:

Module-specific summary fields.

Return type:

dict

write(report, output_dir, formats)

Write the module’s standalone report assets.

Parameters:
  • report (mapping) – Renderer-neutral data returned by collect().

  • output_dir (path-like) – Destination directory for this report section.

  • formats (iterable of str) – Requested output formats.

Returns:

Paths and metadata for the generated assets.

Return type:

dict

mpylab.env.tem.history_report.discover_report_sections(tem, modules=(<mpylab.env.tem.history_report.VerificationReportModule object>, <mpylab.env.tem.history_report.E0yReportModule object>, <mpylab.env.tem.history_report.EmissionReportModule object>, <mpylab.env.tem.history_report.ImmunityReportModule object>))

Return all reportable sections discovered in a TEMCell history.

Parameters:
  • tem (TEMCell) – Measurement history to inspect.

  • modules (iterable of ReportModule, optional) – Report modules participating in discovery.

Returns:

Available report sections.

Return type:

list of ReportSelection

mpylab.env.tem.history_report.select_report_sections(tem, identifiers=None, modules=(<mpylab.env.tem.history_report.VerificationReportModule object>, <mpylab.env.tem.history_report.E0yReportModule object>, <mpylab.env.tem.history_report.EmissionReportModule object>, <mpylab.env.tem.history_report.ImmunityReportModule object>))

Resolve optional module:dataset identifiers against the history.

Parameters:
  • tem (TEMCell) – Measurement history to inspect.

  • identifiers (iterable of str, optional) – Selection identifiers. All available sections are selected by default.

  • modules (iterable of ReportModule, optional) – Report modules participating in discovery.

Returns:

Selected report sections in requested order.

Return type:

list of ReportSelection

mpylab.env.tem.history_report.write_history_report(tem, output_dir='tem-history-report', formats=('pdf', 'html', 'svg'), section_identifiers=None, modules=(<mpylab.env.tem.history_report.VerificationReportModule object>, <mpylab.env.tem.history_report.E0yReportModule object>, <mpylab.env.tem.history_report.EmissionReportModule object>, <mpylab.env.tem.history_report.ImmunityReportModule object>), profile=None)

Create a modular report package from a TEMCell history object.

Parameters:
  • tem (TEMCell) – Measurement history to report.

  • output_dir (path-like, optional) – Destination directory for the report package.

  • formats (iterable of str, optional) – Any combination of "pdf", "html", "svg", and "png".

  • section_identifiers (iterable of str, optional) – module:dataset identifiers to include. All are included by default.

  • modules (iterable of ReportModule, optional) – Report modules available to the generator.

  • profile (path-like, mapping, or iterable, optional) – Report profile input accepted by resolve_report_profile().

Returns:

Generated section data, traceability information, and output paths.

Return type:

dict

class mpylab.env.tem.history_report.HistoryReportError

Raised when a modular TEM history report cannot be created.

Presentation profile

class mpylab.env.tem.report_profile.ReportProfile(report: dict, laboratory: dict, measurement: dict, environment: dict, appearance: dict, source_path: Path | None = None, source_paths: tuple[Path, ...] = (), origins: dict | None = None)

Validated report metadata and presentation settings.

report

Report title, number, language, and confidentiality marking.

Type:

dict

laboratory

Laboratory identity, address, and optional logo configuration.

Type:

dict

measurement

Measurement-specific operator, customer, location, date, and text.

Type:

dict

environment

Temperature, relative humidity, and air-pressure metadata.

Type:

dict

appearance

Primary and accent colors used by report renderers.

Type:

dict

source_path

Last profile path contributing to this resolved profile.

Type:

pathlib.Path or None

source_paths

Profile paths in merge order.

Type:

tuple of pathlib.Path

origins

Mapping from (section, key) pairs to the profile path that supplied each effective value.

Type:

dict or None

property accent_color

Return the accent presentation color.

property logo_path

Return the resolved local logo path, if configured.

property primary_color

Return the primary presentation color.

property title

Return the configured report title or the stable default title.

mpylab.env.tem.report_profile.load_report_profile(path)

Load and validate one TOML report profile.

Parameters:

path (path-like) – TOML profile to load. Relative logo paths are resolved from this file’s directory.

Returns:

Validated profile with source and value-origin information.

Return type:

ReportProfile

Raises:
  • ReportProfileError – If TOML syntax, sections, values, colors, dates, environmental values, or the configured logo are invalid.

  • OSError – If the profile file cannot be opened.

mpylab.env.tem.report_profile.resolve_report_profile(profile=None)

Resolve defaults, one profile, or an ordered profile stack.

Parameters:

profile (path-like, ReportProfile, iterable, or None, optional) – Profile input. Iterable entries may themselves be paths or resolved profiles and are merged in order, with later values overriding only identical section keys. None or an empty iterable selects the validated defaults.

Returns:

Effective profile retaining all source paths and per-value origins.

Return type:

ReportProfile

Raises:
  • ReportProfileError – If the input type or any profile value is invalid, or a configured logo cannot be found.

  • OSError – If a referenced profile file cannot be opened.

mpylab.env.tem.report_profile.report_metadata_rows(profile, created_at=None)

Convert effective report metadata to provenance-aware table rows.

Parameters:
  • profile (ReportProfile) – Resolved report profile.

  • created_at (datetime.datetime or None, optional) – UTC report-creation timestamp. None uses the current UTC time.

Returns:

Rows with section, key, value, and source fields. The source distinguishes generated values, defaults, missing values, and the profile file that supplied an explicit value.

Return type:

list of dict

mpylab.env.tem.report_profile.write_report_metadata_table(path, rows)

Write report metadata and provenance as a TSV table.

Parameters:
  • path (path-like) – Destination file. Missing parent directories are created.

  • rows (iterable of mapping) – Metadata rows using METADATA_FIELDS, normally returned by report_metadata_rows().

Returns:

Destination path after writing the table.

Return type:

pathlib.Path

class mpylab.env.tem.report_profile.ReportProfileError

Raised when a TEM report profile is invalid.

Traceability

mpylab.env.tem.history_traceability.collect_history_traceability(section_results)

Collect cross-section traceability for a modular history report.

Parameters:

section_results (iterable of mapping) – Generated report sections. Each entry must provide selection, renderer-neutral report data, and a summary mapping.

Returns:

One row per report section with status, frequency coverage, dependencies, resolved and missing sources, completeness, and compact warnings. The row fields follow TRACEABILITY_FIELDS.

Return type:

list of dict

mpylab.env.tem.history_traceability.write_traceability_table(path, rows)

Write cross-section traceability rows as a TSV table.

Parameters:
  • path (path-like) – Destination file. Missing parent directories are created.

  • rows (iterable of mapping) – Traceability rows, normally returned by collect_history_traceability().

Returns:

Destination path after writing the table.

Return type:

pathlib.Path

mpylab.env.tem.history_traceability.traceability_pdf_figure(rows)

Create a compact figure summarizing history traceability.

Parameters:

rows (iterable of mapping) – Traceability rows to render. Dependencies and warnings are included beneath each section status.

Returns:

A4-sized figure suitable for insertion into the combined PDF. The caller owns the figure and is responsible for closing it.

Return type:

matplotlib.figure.Figure

Custom module lifecycle

A custom module implements ReportModule. Its collect method converts stored evaluation results into a renderer-neutral mapping. write produces section HTML, tables, and figure assets, while pdf_figures supplies figures for the combined PDF. Domain evaluation must remain outside the report module so that generating a report cannot change the technical measurement result.

The minimal integration pattern is:

from mpylab.env.tem.history_report import (
    DEFAULT_REPORT_MODULES,
    ReportSelection,
    write_history_report,
)

class MyReportModule:
    key = "my_result"
    title = "My evaluated result"

    def discover(self, tem):
        data = getattr(tem, "processedData_MyResult", {}) or {}
        return [
            ReportSelection(self.key, str(name), self.title)
            for name in sorted(data, key=str)
        ]

    def collect(self, tem, selection):
        return {
            "description": selection.dataset_key,
            "rows": tem.processedData_MyResult[selection.dataset_key],
        }

    def write(self, report, output_dir, formats):
        # Write section tables, HTML, and requested image assets here.
        return {"output_dir": output_dir}

    def pdf_figures(self, report):
        return ()

    def summary(self, report):
        return {"result_count": len(report["rows"])}

modules = (*DEFAULT_REPORT_MODULES, MyReportModule())
result = write_history_report(
    tem,
    output_dir="report",
    formats=("html", "pdf", "svg"),
    modules=modules,
)

discover must return stable ReportSelection identifiers. collect should be independently testable without Matplotlib or file I/O. write owns only its section directory, and pdf_figures transfers figure ownership to the history writer, which closes figures after use. External modules are passed explicitly through modules; the standard CLI does not import arbitrary report plugins.