| """Aggregate the six frozen reviewer-requested outer runs.""" | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import sys | |
| from pathlib import Path | |
| from typing import Any | |
| import pandas as pd | |
| PROJECT_ROOT = Path(__file__).resolve().parents[2] | |
| if str(PROJECT_ROOT) not in sys.path: | |
| sys.path.insert(0, str(PROJECT_ROOT)) | |
| from revision.scripts.reanalysis_core import ensure_new_output_dir | |
| from revision.scripts.reanalysis_pipeline import _write_sha256_manifest | |
| STRATEGIES = ("canonical_grouped", "scaffold_aware") | |
| SEEDS = (123456, 123457, 123458) | |
| METRIC_COLUMNS = ( | |
| "r2", | |
| "mae", | |
| "rmse", | |
| "bias", | |
| "calibration_slope", | |
| "calibration_intercept", | |
| ) | |
| def _load_json(path: Path) -> dict[str, Any]: | |
| return json.loads(path.read_text(encoding="utf-8")) | |
| def _metric_rows( | |
| strategy: str, | |
| seed: int, | |
| payload: dict[str, Any], | |
| ) -> list[dict[str, Any]]: | |
| return [ | |
| { | |
| "strategy": strategy, | |
| "seed": seed, | |
| "primary_model_predeclared": payload["primary_model_predeclared"], | |
| "model": model, | |
| **metrics, | |
| } | |
| for model, metrics in payload["metrics"].items() | |
| ] | |
| def _aggregate_metrics(frame: pd.DataFrame) -> pd.DataFrame: | |
| metric_columns = [column for column in METRIC_COLUMNS if column in frame.columns] | |
| aggregate = frame.groupby(["strategy", "model"])[metric_columns].agg(["mean", "std"]) | |
| aggregate.columns = [ | |
| f"{metric}_{'sd' if statistic == 'std' else statistic}" | |
| for metric, statistic in aggregate.columns | |
| ] | |
| return aggregate.reset_index() | |
| def _aggregate_runtime(frame: pd.DataFrame) -> pd.DataFrame: | |
| aggregate = ( | |
| frame.groupby(["strategy", "model"], sort=True) | |
| .agg( | |
| parameter_count=("parameter_count", "first"), | |
| parameter_count_min=("parameter_count", "min"), | |
| parameter_count_max=("parameter_count", "max"), | |
| training_seconds_mean=("training_seconds", "mean"), | |
| training_seconds_sd=("training_seconds", "std"), | |
| ) | |
| .reset_index() | |
| ) | |
| if not ( | |
| aggregate["parameter_count"] == aggregate["parameter_count_min"] | |
| ).all() or not ( | |
| aggregate["parameter_count"] == aggregate["parameter_count_max"] | |
| ).all(): | |
| raise ValueError("Parameter counts changed across frozen outer runs.") | |
| return aggregate.drop(columns=["parameter_count_min", "parameter_count_max"]) | |
| def main() -> int: | |
| parser = argparse.ArgumentParser( | |
| description="Aggregate all six completed frozen reviewer reanalysis runs." | |
| ) | |
| parser.add_argument( | |
| "--artifacts-root", | |
| default=str( | |
| PROJECT_ROOT | |
| / "revision" | |
| / "artifacts" | |
| / "reviewer_requested_reanalysis_v4" | |
| ), | |
| ) | |
| artifacts_root = Path(parser.parse_args().artifacts_root).resolve() | |
| summary_dir = ensure_new_output_dir(artifacts_root / "summary") | |
| classical_rows: list[dict[str, Any]] = [] | |
| neural_rows: list[dict[str, Any]] = [] | |
| paired_rows: list[dict[str, Any]] = [] | |
| domain_rows: list[dict[str, Any]] = [] | |
| per_lab_frames: list[pd.DataFrame] = [] | |
| runtime_rows: list[dict[str, Any]] = [] | |
| for strategy in STRATEGIES: | |
| for seed in SEEDS: | |
| split_dir = artifacts_root / strategy / f"seed_{seed}" | |
| neural_dir = split_dir / "neural_stack" | |
| neural_metrics_path = neural_dir / "metrics.json" | |
| if not neural_metrics_path.is_file(): | |
| raise FileNotFoundError(f"Incomplete neural matrix: {neural_metrics_path}") | |
| classical_rows.extend( | |
| _metric_rows(strategy, seed, _load_json(split_dir / "classical_metrics.json")) | |
| ) | |
| neural_rows.extend( | |
| _metric_rows(strategy, seed, _load_json(neural_metrics_path)) | |
| ) | |
| for reference_model, metric_payload in _load_json( | |
| neural_dir / "paired_group_bootstrap.json" | |
| ).items(): | |
| for metric, values in metric_payload.items(): | |
| paired_rows.append( | |
| { | |
| "strategy": strategy, | |
| "seed": seed, | |
| "candidate_model": "stack_all_plus_descriptors", | |
| "reference_model": reference_model, | |
| "metric": metric, | |
| **values, | |
| } | |
| ) | |
| domain = _load_json(neural_dir / "prospective_domain_diagnostics.json") | |
| for threshold_payload in domain["threshold_sensitivity"]: | |
| domain_rows.append( | |
| { | |
| "strategy": strategy, | |
| "seed": seed, | |
| "spearman_similarity_vs_absolute_error": domain[ | |
| "spearman_similarity_vs_absolute_error" | |
| ], | |
| "spearman_model_spread_vs_absolute_error": domain[ | |
| "spearman_model_spread_vs_absolute_error" | |
| ], | |
| **threshold_payload, | |
| } | |
| ) | |
| per_lab = pd.read_csv(neural_dir / "per_lab_metrics.csv") | |
| per_lab.insert(0, "seed", seed) | |
| per_lab.insert(0, "strategy", strategy) | |
| per_lab_frames.append(per_lab) | |
| runtime = _load_json(neural_dir / "RUN_METADATA.json") | |
| for model, training_seconds in runtime["training_seconds_by_model"].items(): | |
| runtime_rows.append( | |
| { | |
| "strategy": strategy, | |
| "seed": seed, | |
| "model": model, | |
| "parameter_count": int(runtime["parameter_counts"][model]), | |
| "training_seconds": float(training_seconds), | |
| "total_run_seconds": float(runtime["total_run_seconds"]), | |
| "device": runtime["device"], | |
| "gpu_name": runtime.get("gpu_name"), | |
| } | |
| ) | |
| classical = pd.DataFrame(classical_rows) | |
| neural = pd.DataFrame(neural_rows) | |
| classical.to_csv(summary_dir / "classical_metrics_by_run.csv", index=False) | |
| neural.to_csv(summary_dir / "neural_metrics_by_run.csv", index=False) | |
| _aggregate_metrics(classical).to_csv( | |
| summary_dir / "classical_metrics_aggregate.csv", index=False | |
| ) | |
| _aggregate_metrics(neural).to_csv( | |
| summary_dir / "neural_metrics_aggregate.csv", index=False | |
| ) | |
| pd.DataFrame(paired_rows).to_csv( | |
| summary_dir / "paired_bootstrap_by_run.csv", index=False | |
| ) | |
| pd.DataFrame(domain_rows).to_csv( | |
| summary_dir / "prospective_domain_by_run.csv", index=False | |
| ) | |
| pd.concat(per_lab_frames, ignore_index=True).to_csv( | |
| summary_dir / "neural_per_lab_by_run.csv", index=False | |
| ) | |
| runtime_frame = pd.DataFrame(runtime_rows) | |
| runtime_frame.to_csv(summary_dir / "neural_runtime_by_run.csv", index=False) | |
| _aggregate_runtime(runtime_frame).to_csv( | |
| summary_dir / "neural_runtime_aggregate.csv", index=False | |
| ) | |
| _write_sha256_manifest(artifacts_root) | |
| print(f"Wrote frozen aggregate tables to: {summary_dir}") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |