orchestrator — the run → analyze → plot → report pipeline loop

Purpose

Owns the end-to-end analysis loop: build run contexts from a spec YAML, run live or load
stored NPZ logs
, reduce metrics to tables, render figures, and assemble a LaTeX/PDF report.
The single module that calls runner / data_analyzer / plotter / star_reporter — and nowhere
else reaches across those boundaries.

Role in the system

  • Entry point: top-level run_spec.py (edit the stem) → Orchestrator(stem).run().
  • runs/loads via runner (live sim) and logger (LogStore NPZ IO).
  • reduces via data_analyzer (DataSummary / LogView), renders via plotter, reports via star_reporter.
  • loads specs via pre_run_loader (RunSpecLoader / MetricSpecLoader).
  • The hard handoff between halves is the NPZ log; the loop is one direction (logger never plots, reporter never recomputes).

Inputs / Outputs

  • In: a run-spec YAML stem (resolved through RunSpecLoader), the metric catalog, the output flags, and any stored NPZ logs.
  • Out: an OrchestrationResult — contexts, LogWork logs, reduced table frames, figure paths (+ project-relative), descriptive conclusions, and report .tex/.pdf paths.
  • On disk: the run-stamp contract logs/logs_<date>/<stem>/{figures,npz,reports}/run_PMHHMM/.

Key methods

  • run — the full pipeline (contexts → logs → analyze → plot → report) → OrchestrationResultanalysis/orchestrator.py:1018
  • build_run_contexts — one context for SINGLE, else one per validated variant — :218
  • run_or_load_one — load the context’s stored NPZ if available, else run the sim live — :331
  • analyze — per-log tables + comparison/sweep/peak tables + conclusions — :401
  • plot / plot_overall — per-variant figures / cross-variant overlay + reduction-sweep figures — :505 / :767
  • overlay_figure_spec — one overlay figure (primary keys + optional twinx secondary keys) — :727
  • sweep_rows — reduce each (window, metric) across variants into keyed rows — :905
  • report / build_reporter — flat report (SINGLE) vs sectioned-per-variant — :969 / :981
  • output_run_stamp — the run_PMHHMM stamp tying every figure/log/report to one run — :181

Footguns

The stem IS the spec name

The YAML file stem is the canonical spec.name; a differing explicit name: field triggers a
[Legacy] warn and is overwritten. Variant names/labels derive from safe_filename(value) or
{flag-leaf}_{value} — never repeat them in the YAML. (analysis/INSIGHTS.md [io])

key_variables drives all report tables

comparison.key_variables is the authoritative metric list; None falls back to the catalog
include: flag (single-log legacy). The report never auto-injects scoreboard content — the console
tool validation/run_scoreboard.py is the model. (analysis/INSIGHTS.md [config])

seconds is not in the merged figure schema

figure_log_view reads window.seconds via object_fields(...).get("seconds") (tolerant) rather
than attribute access, because a figure omitting the key has no seconds attribute after the schema
merge. Any new zoom key needs the same tolerant read. (analysis/INSIGHTS.md [footgun])

Boolean comparison auto-synthesizes its variants

ComparisonMode.BOOLEAN synthesizes [False, True] when the spec omits variants, so a two-state
sweep needs only mode: boolean and flag:. (analysis/INSIGHTS.md [config])

mask_vs_smin is the ONE allowed band hardcode

resolve_mask’s mask_vs_smin: true resolves to the singularity band SMIN_BAND (from
data_analyzer); exclude: true inverts it. Band-masked rows are tagged _band/_xband to stay a
distinct row from the plain (p99) or op-window (p99_op) reduction. (analysis/INSIGHTS.md [config], [io])

Pseudocode (one run())

contexts = build_run_contexts()          # SINGLE → 1; else 1 per validated variant
log_work = run_or_load_logs(contexts)     # per context: load stored NPZ OR run live (Runner)
analysis = analyze(log_work)              # LogView → reduced tables; comparison/sweep/peak; conclusions
variant_figures  = plot(analysis)         # per-variant configured + peak figures (Plotter)
overlay_figures  = plot_overall(analysis) # cross-variant overlay + reduction-sweep (spans ALL variants)
report           = report(...)            # SINGLE → flat report; else Intro + one section per variant
return OrchestrationResult(...)           # contexts, logs, tables, figures, conclusions, report paths

runner · logger · data_analyzer · plotter · star_reporter · pre_run_loader · terminology