spb/wpai0001_uqo
Public
1#!/usr/bin/env python32"""Regenerate paper figures from registered run results (no computation, no new data).34Usage: python scripts/build_figures.py --run <run_id> [--out paper/figures]5Every figure written is listed with the run id and results hash in paper/figures/FIGURE_PROVENANCE.md.6"""7from __future__ import annotations89import argparse10import hashlib11import json12import sys13from pathlib import Path1415ROOT = Path(__file__).resolve().parents[1]16sys.path.insert(0, str(ROOT / "src"))17sys.path.insert(0, str(ROOT / "scripts"))1819from wp_ai_0001.config import PilotConfig # noqa: E40220from wp_ai_0001.instrumentation.provenance import utc_now # noqa: E402212223def main() -> None:24 ap = argparse.ArgumentParser()25 ap.add_argument("--run", required=True)26 ap.add_argument("--out", default=str(ROOT / "paper" / "figures"))27 args = ap.parse_args()28 res_path = ROOT / "experiments" / "summaries" / args.run / "results.json"29 man_path = ROOT / "experiments" / "manifests" / f"{args.run}.json"30 results = json.loads(res_path.read_text())31 manifest = json.loads(man_path.read_text())32 if manifest["status"] != "completed":33 raise SystemExit(f"run {args.run} has status {manifest['status']}; refusing to build figures")34 out = Path(args.out)35 out.mkdir(parents=True, exist_ok=True)36 if results["run_id"].startswith("pilot_tier0_opseq"):37 from run_pilot import make_figures3839 cfg = PilotConfig.model_validate(manifest["config"])40 make_figures(results, out, results["localization"]["positions"], cfg)41 elif results["run_id"].startswith("graft_tier0"):42 from wp_ai_0001.visualization.figures_graft import fig_layer_grid_dose, fig_mechanism, fig_pareto, fig_portability, fig_subspace4344 fig_pareto(results, out)45 fig_layer_grid_dose(results, out)46 fig_subspace(results, out)47 fig_portability(results, out)48 if "h5_act_procrustes_seenfit" in results.get("rule_vs_cache", {}):49 fig_mechanism(results, out)50 elif results["run_id"].startswith("tier1_taskvector"):51 from wp_ai_0001.visualization.figures_graft import fig_tier15253 fig_tier1(results, out)54 else:55 raise SystemExit("no figure recipe for this run type")56 digest = hashlib.sha256(res_path.read_bytes()).hexdigest()[:16]57 prov = out / "FIGURE_PROVENANCE.md"58 lines = [l for l in prov.read_text().splitlines() if not l.startswith(f"| {args.run} ")] if prov.exists() else ["# Figure provenance", "", "| run id | results sha256[:16] | built (UTC) | figures |", "|---|---|---|---|"]59 lines.append(f"| {args.run} | {digest} | {utc_now()} | " + ", ".join(sorted(p.name for p in out.glob('*.pdf'))) + " |")60 prov.write_text("\n".join(lines) + "\n")61 print(f"figures written to {out} (provenance updated)")626364if __name__ == "__main__":65 main()66