AsianPlayer/TriDrive / code /eval /report_k4_summary.py
AsianPlayer's picture
download
raw
26.5 kB
"""cwm3/eval/report_k4_summary.py — compact K4 summary: driver onset PR-AUC@3s (mean ± sd over seeds) of the causal-input model and the
old-input control, both on the CAUSAL targets, next to the label-free references (persistence = base rate, k0 heuristic from the causal K0),
for the all-rows and the suspect-routes-masked protocols. Source: results/paired_compare.csv tags
K4in_s<k>_causal_vs_oldin (A causal inputs, B old inputs), K4c_s<k>_causal_vs_k0 (value_b = k0; base_rate rows = persistence),
K4cm_s<k>_causalm_vs_k0 (masked). python report_k4_summary.py [--out results/tables/k4_summary.md]
--kin-version v2 (2026-09-11): the same cells from the v2 causal packs (tags K4v2in_ / K4v2c_ / K4v2cm_, runs …_kcv2[_masked] / …_oldin_ctgt_v2, stats v2),
plus a v1-vs-v2 comparison table, the paired causal-v2 − causal-v1 deltas on identical rows (tags K4v2v1_…) and the B1 / K4 verdicts
(kill_checks.beats over the paired rows) under both protocols. python report_k4_summary.py --kin-version v2 --out results/tables/k4_v2_summary.md
"""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
import numpy as np
import pandas as pd
CWM3 = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(CWM3.parent / "cwm2" / "eval"))
import kill_checks as KC # noqa: E402
EV = ("hand_leave", "hand_return", "head_turn_onset")
PREFIX = {"v1": ("K4in_", "K4c_", "K4cm_"), "v2": ("K4v2in_", "K4v2c_", "K4v2cm_")}
ALIKE = {"v1": r"_kcv1(?:_masked)?$", "v2": r"_kcv2(?:_masked)?$"}
def beats(g):
"""kill_checks.beats over the per-seed paired rows g (delta / CIs / values) -> verdict string."""
pr = pd.DataFrame({"seed": g.seed, "delta": g.delta.astype(float), "delta_ci_lo": g.delta_ci_lo.astype(float), "delta_ci_hi": g.delta_ci_hi.astype(float), "status": "secondary"})
return KC.beats(pr, pd.DataFrame({"value": g.value_a.astype(float)}), pd.DataFrame({"value": g.value_b.astype(float)}), min_seeds=3)["verdict"]
def ms(v):
v = np.asarray([x for x in v if x is not None and np.isfinite(x)], float)
return "—" if not len(v) else (f"{v.mean():.3f} ± {v.std(ddof=1):.3f}" if len(v) > 1 else f"{v[0]:.3f}")
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--out", default=str(CWM3 / "results" / "tables" / "k4_summary.md"))
ap.add_argument("--kin-version", default="v1", choices=["v1", "v2"])
a = ap.parse_args()
ver = a.kin_version
d = pd.read_csv(CWM3 / "results" / "paired_compare.csv", low_memory=False)
d = d[d.tag.str.startswith(("K4in_", "K4c_", "K4cm_", "K4_", "K4v2in_", "K4v2c_", "K4v2cm_", "K4v2v1_", "K4v2s1_", "K4v2clip_"))].copy()
d["seed"] = d.tag.str.extract(r"_s(\d+)_")[0].astype(int)
d = d.sort_values("run_stamp").groupby(["tag", "regime", "cell", "metric"], as_index=False).tail(1)
for c in ("value_a", "value_b", "delta", "delta_ci_lo", "delta_ci_hi"):
d[c] = pd.to_numeric(d[c], errors="coerce")
def vals(prefix, cell, col, metric="pr_auc", a_like=None, tag_like=None):
x = d[d.tag.str.startswith(prefix) & (d.cell == cell) & (d.metric == metric)]
if a_like is not None:
x = x[x.a.str.contains(a_like, regex=True)]
if tag_like is not None:
x = x[x.tag.str.contains(tag_like, regex=True)]
return {r: x[x.regime == r][col].tolist() for r in ("manual", "engaged")}
P_IN, P_C, P_CM = PREFIX[ver]
if ver == "v1":
lines = ["# K4 summary — driver onset PR-AUC@3s on the CAUSAL targets (mean ± sd over seeds 0–2; stats v1; paired rows in results/paired_compare.csv)", "",
"Rows: causal-ROI inputs (`U0_kin_can_noK_s<k>_kcv1`) vs OLD route-median inputs trained on the same causal targets (`…_oldin_ctgt`, input-isolation control); "
"references: persistence (constant score → PR-AUC = base rate of the population) and the k0 current-state heuristic from the causal K0. "
"The masked protocol removes the 106 driver-box-suspect routes from training (causal model) and from every evaluated population.", ""]
else:
lines = ["# K4 v2 summary — driver onset PR-AUC@3s on the v2 CAUSAL targets (mean ± sd over seeds 0–2; **stats v2** = float64 standardisation statistics; paired rows in results/paired_compare.csv)", "",
"Inputs `results/targets_kin_causal_routes_v2/` (docs/k4_handoff.md v1 → v2): the 74 co-occupant routes whose causal driver box had fallen back to the largest person were "
"re-extracted with a population driver-side prior; **v1 and v2 differ only on those 74 re-extracted routes** (45 manual-test / 26 engaged-test routes carry different kinematics; row_ok identical). "
"Rows: causal-ROI inputs (`U0_kin_can_noK_s<k>_kcv2`) vs OLD route-median inputs trained on the same v2 causal targets (`…_oldin_ctgt_v2`, input-isolation control); "
"references: persistence (constant score → PR-AUC = base rate of the population) and the k0 current-state heuristic from the v2 causal K0. "
"The masked protocol removes the **v2 suspect list (82 (regime, split, route) entries = 64 unique routes; 17.9 % of manual-test / 14.0 % of engaged-test anchors)** from training "
"(causal model) and from every evaluated population (same mask applied to the k0 / persistence references). "
"U0 `kin_can_noK` recipe (GRU, chains only), seeds 0–2, `--kin-source causal_routes --kin-version v2`, run.json records kin_version / kin_dir / stats_version 2.", ""]
verd = {}
for proto, tag_in, tag_k0 in (("all rows", P_IN, P_C), ("suspect routes masked", None, P_CM)):
lines += [f"## Protocol: {proto}", "", "| regime | event | causal inputs | old inputs (control) | k0 heuristic | persistence (base rate) | causal vs k0 (beats) |", "|---|---|---|---|---|---|---|"]
for reg in ("manual", "engaged"):
for ev in EV:
cell = f"drv_onset|{ev}|3s"
ca = vals(tag_k0, cell, "value_a", a_like=ALIKE[ver], tag_like=r"_causalm?_vs_k0$")[reg] # the causal-input model, vs-k0 rows only
k0 = vals(tag_k0, cell, "value_b", tag_like=r"_causalm?_vs_k0$")[reg]
base = vals(tag_k0, cell, "value_a", "base_rate", tag_like=r"_causalm?_vs_k0$")[reg]
old = vals(tag_in, cell, "value_b")[reg] if tag_in else []
g = d[d.tag.str.startswith(tag_k0) & d.tag.str.contains(r"_causalm?_vs_k0$") & (d.cell == cell) & (d.metric == "pr_auc") & (d.regime == reg)].sort_values("seed")
v = beats(g) if len(g) else "—"
verd[(proto, reg, ev)] = v
lines.append(f"| {reg} | {ev} | {ms(ca)} | {ms(old)} | {ms(k0)} | {ms(base)} | {v} |")
lines.append("")
# paired deltas of the input effect
x = d[d.tag.str.startswith(P_IN) & (d.metric == "pr_auc") & d.cell.str.startswith("drv_onset")]
verd_in = {}
if len(x):
lines += ["## Input effect (causal − old inputs, both on causal targets; Δ per seed [CI])", "", "| regime | event | Δ s0 | Δ s1 | Δ s2 | mean ± sd | verdict |", "|---|---|---|---|---|---|---|"]
for reg in ("manual", "engaged"):
for ev in EV:
g = x[(x.regime == reg) & (x.cell == f"drv_onset|{ev}|3s")].sort_values("seed")
cells = [f"{float(r.delta):+.3f} [{float(r.delta_ci_lo):+.3f},{float(r.delta_ci_hi):+.3f}]" for r in g.itertuples()]
dl = g.delta.astype(float).to_numpy()
verd_in[(reg, ev)] = beats(g) if len(g) else "—"
lines.append(f"| {reg} | {ev} | " + " | ".join(cells + ["—"] * (3 - len(cells))) + f" | {ms(dl)} | {verd_in[(reg, ev)]} |")
lines.append("")
if ver == "v2":
# ---- v1 vs v2: the same cells side by side (v1 tags K4in_/K4c_/K4cm_, stats v1; v2 tags, stats v2)
lines += ["## v1 vs v2 (same cells; v1 = `…_kcv1` runs on the v1 packs / 106-entry (80-route) mask, stats v1; v2 = `…_kcv2` runs on the v2 packs / 82-entry (64-route) mask, stats v2)", "",
"| protocol | regime | event | causal v1 | causal v2 | old inputs v1 | old inputs v2 | k0 v1 | k0 v2 | persistence v1 | persistence v2 |", "|---|---|---|---|---|---|---|---|---|---|---|"]
for proto, (i1, c1), (i2, c2) in (("all rows", ("K4in_", "K4c_"), ("K4v2in_", "K4v2c_")), ("masked", (None, "K4cm_"), (None, "K4v2cm_"))):
for reg in ("manual", "engaged"):
for ev in EV:
cell = f"drv_onset|{ev}|3s"
r = {}
for tagv, (i_, c_), al in (("v1", (i1, c1), ALIKE["v1"]), ("v2", (i2, c2), ALIKE["v2"])):
r["ca" + tagv] = vals(c_, cell, "value_a", a_like=al, tag_like=r"_causalm?_vs_k0$")[reg]
r["k0" + tagv] = vals(c_, cell, "value_b", tag_like=r"_causalm?_vs_k0$")[reg]
r["base" + tagv] = vals(c_, cell, "value_a", "base_rate", tag_like=r"_causalm?_vs_k0$")[reg]
r["old" + tagv] = vals(i_, cell, "value_b")[reg] if i_ else []
lines.append(f"| {proto} | {reg} | {ev} | {ms(r['cav1'])} | {ms(r['cav2'])} | {ms(r['oldv1'])} | {ms(r['oldv2'])} | {ms(r['k0v1'])} | {ms(r['k0v2'])} | {ms(r['basev1'])} | {ms(r['basev2'])} |")
lines.append("")
# ---- paired causal v2 − causal v1 on identical rows (both scored on the v2 causal targets)
for tagname, title in (("causalv2_vs_causalv1", "all rows"), ("causalv2m_vs_causalv1m", "v2 suspect routes masked (each model trained without its own version's suspects)")):
y = d[d.tag.str.startswith("K4v2v1_") & d.tag.str.endswith(tagname) & (d.metric == "pr_auc") & d.cell.str.startswith("drv_onset")]
if not len(y):
continue
lines += [f"## Paired causal v2 − causal v1 on identical rows, scored on the v2 causal targets — {title} (Δ per seed [CI])", "",
"| regime | event | v2 (A) | v1 (B) | Δ s0 | Δ s1 | Δ s2 | mean ± sd | verdict |", "|---|---|---|---|---|---|---|---|---|"]
for reg in ("manual", "engaged"):
for ev in EV:
g = y[(y.regime == reg) & (y.cell == f"drv_onset|{ev}|3s")].sort_values("seed")
if not len(g):
continue
cells = [f"{float(r.delta):+.3f} [{float(r.delta_ci_lo):+.3f},{float(r.delta_ci_hi):+.3f}]" for r in g.itertuples()]
lines.append(f"| {reg} | {ev} | {ms(g.value_a)} | {ms(g.value_b)} | " + " | ".join(cells + ["—"] * (3 - len(cells))) + f" | {ms(g.delta.to_numpy())} | {beats(g)} |")
lines.append("")
# ---- verdicts
def b1(proto):
need = [(reg, ev) for reg in ("manual", "engaged") for ev in ("hand_leave", "head_turn_onset")]
core = all(verd.get((proto, reg, ev)) == "BEATS" for reg, ev in need)
allc = [verd.get((proto, reg, ev), "—") for reg in ("manual", "engaged") for ev in EV]
n = sum(v == "BEATS" for v in allc)
insuff = any(v in ("—", "INSUFFICIENT") for v in allc)
return ("INSUFFICIENT" if insuff else "PASS" if core else "FAIL"), n, allc
# ---- stats-version disentangling arm (coordinator 2026-09-11): v2 packs with the PRE-fix float32 statistics (`…_kcv2_stats1`), all rows
s1 = d[d.tag.str.startswith("K4v2c_") & d.tag.str.endswith("_causalstats1_vs_k0") & (d.metric == "pr_auc") & d.cell.str.startswith("drv_onset")]
s12 = d[d.tag.str.startswith("K4v2s1_") & (d.metric == "pr_auc") & d.cell.str.startswith("drv_onset")]
if len(s1) or len(s12):
lines += ["## Stats-version arm — v2 packs with the PRE-fix float32 statistics (`U0_kin_can_noK_s<k>_kcv2_stats1`, `--stats-version 1`; all rows, v2 targets)", "",
"Disentangles the standardisation-statistics switch (v1 float32 → v2 float64; kinematics SDs 2–3× smaller under v2, so the ±5 clamp of "
"`batch.std_kh` truncates more) from the pack change. `stats1 − stats2` = the same v2 packs, seeds and recipe, only the statistics differ.", "",
"| regime | event | stats v1 (A) | stats v2 (B) | k0 | Δ stats1 − stats2 s0 | s1 | s2 | mean ± sd | verdict | stats v1 vs k0 |", "|---|---|---|---|---|---|---|---|---|---|---|"]
for reg in ("manual", "engaged"):
for ev in EV:
cell = f"drv_onset|{ev}|3s"
g = s12[(s12.regime == reg) & (s12.cell == cell)].sort_values("seed")
gk = s1[(s1.regime == reg) & (s1.cell == cell)].sort_values("seed")
cells = [f"{float(r.delta):+.3f} [{float(r.delta_ci_lo):+.3f},{float(r.delta_ci_hi):+.3f}]" for r in g.itertuples()]
lines.append(f"| {reg} | {ev} | {ms(gk.value_a) if len(gk) else ms(g.value_a)} | {ms(g.value_b)} | {ms(gk.value_b)} | " + " | ".join(cells + ["—"] * (3 - len(cells))) +
f" | {ms(g.delta.to_numpy()) if len(g) else '—'} | {beats(g) if len(g) else '—'} | {beats(gk) if len(gk) else '—'} |")
lines.append("")
cj = CWM3 / "results" / "tables" / "k4_v2_clip_fraction.json"
if cj.exists():
import json
J = json.loads(cj.read_text())
lines += [f"### Fraction of FINITE standardised Kh values truncated by the ±{J['clip']:.0f} clamp (`batch.std_kh`), TRAIN split both regimes (`eval/kin_clip_fraction.py`, {J['utc']})", "",
"| channel | v2 packs, stats v1 | v2 packs, stats v2 | v1 packs, stats v1 | ksd v1 (v2 packs) | ksd v2 (v2 packs) |", "|---|---|---|---|---|---|"]
p2, p1 = J["packs"]["v2"], J["packs"]["v1"]
for i, c in enumerate(J["channels"]):
lines.append(f"| {c} | {p2['stats1']['clip_frac'][i]:.5f} | {p2['stats2']['clip_frac'][i]:.5f} | {p1['stats1']['clip_frac'][i]:.5f} | {p2['stats1']['ksd'][i]:.4f} | {p2['stats2']['ksd'][i]:.4f} |")
lines.append(f"| **all channels** | **{p2['stats1']['clip_frac_all']:.5f}** | **{p2['stats2']['clip_frac_all']:.5f}** | {p1['stats1']['clip_frac_all']:.5f} | | |")
rep = p1.get("v1_reproduction", {})
lines += ["", f"compute_stats_v1 reproduces the stored v1 statistics of `U0_kin_can_noK_s0_kcv1` on the v1 packs to max|Δ| " + ", ".join(f"{k} {v:.2e}" for k, v in rep.items()) + ".", ""]
tj = CWM3 / "results" / "tables" / "k4_v2_clip_thresholds.json"
if tj.exists():
T = json.loads(tj.read_text()); chs = T["channels"]
lines += [f"Threshold sweep under stats v2 (v2 packs, TRAIN; statistics of `{T['stats_run']}`): fraction of finite Kh values with |z| > t —", "",
"| t | all channels | head_cx | largest other channel |", "|---|---|---|---|"]
import numpy as _np
nf = _np.array(p2["stats2"]["n_finite"], float)
for t, fr in T["thresholds"].items():
fr = _np.array(fr); j = 1 + int(_np.argmax(fr[1:]))
lines.append(f"| {t} | {float((fr * nf).sum() / nf.sum()):.5f} | {fr[0]:.5f} | {fr[j]:.5f} ({chs[j]}) |")
lines += ["", "The head_cx truncation under stats v2 sits almost entirely between 5 and 6 SD (1.31 % → 0.012 % at t = 6, 0 at t = 8): a sub-population of routes whose "
"head_cx lies 5–6 SD (0.45–0.54 old units) from the mean; every other channel is ≤ 0.33 % at t = 5.", ""]
# ---- recipe arm (coordinator 2026-09-11): clamp 8 (`_kcv2_clip8`) and clamp 8 + input LayerNorm(12) (`_kcv2_clip8_ln`), stats v2, all rows
rc = d[d.tag.str.startswith("K4v2clip_") & (d.metric == "pr_auc") & d.cell.str.startswith("drv_onset")]
rk = d[d.tag.str.startswith("K4v2c_") & d.tag.str.contains(r"_(?:clip8|clip8ln)_vs_k0$") & (d.metric == "pr_auc") & d.cell.str.startswith("drv_onset")]
rec_v = {}
if len(rc):
lines += ["## Recipe arm — stats v2 with clamp 8 (`U0_kin_can_noK_s<k>_kcv2_clip8`, `kclip: 8`) and clamp 8 + input LayerNorm over the 12 kinematics channels (`…_kcv2_clip8_ln`, `u_in_ln: true`); all rows, v2 packs / targets", "",
"Δ on identical rows vs the stats-v2 baseline `_kcv2` (clamp 5), vs the stats-v1 arm `_kcv2_stats1`, and LN vs clamp-only; verdict = kill_checks.beats.", "",
"| regime | event | clip8 | clip8+LN | stats v2 (clip 5) | stats v1 | k0 | clip8 − stats2 | clip8+LN − stats2 | clip8 − stats1 | clip8+LN − stats1 | LN − clip8 | clip8 vs k0 | clip8+LN vs k0 |",
"|---|---|---|---|---|---|---|---|---|---|---|---|---|---|"]
def dv(sub, reg, cell):
g = sub[(sub.regime == reg) & (sub.cell == cell)].sort_values("seed")
return (f"{ms(g.delta.to_numpy())} {beats(g)}" if len(g) else "—"), g
for reg in ("manual", "engaged"):
for ev in EV:
cell = f"drv_onset|{ev}|3s"
g8 = rc[rc.tag.str.endswith("_clip8_vs_causal")]; g8l = rc[rc.tag.str.endswith("_clip8ln_vs_causal")]
s8, gg8 = dv(g8, reg, cell); s8l, gg8l = dv(g8l, reg, cell)
s8s1, gg8s1 = dv(rc[rc.tag.str.endswith("_clip8_vs_causalstats1")], reg, cell); s8ls1, gg8ls1 = dv(rc[rc.tag.str.endswith("_clip8ln_vs_causalstats1")], reg, cell)
sln, _ = dv(rc[rc.tag.str.endswith("_clip8ln_vs_clip8")], reg, cell)
k8 = rk[rk.tag.str.endswith("_clip8_vs_k0") & (rk.regime == reg) & (rk.cell == cell)].sort_values("seed")
k8l = rk[rk.tag.str.endswith("_clip8ln_vs_k0") & (rk.regime == reg) & (rk.cell == cell)].sort_values("seed")
for arm, g_, gs1, gk in (("clip8", gg8, gg8s1, k8), ("clip8ln", gg8l, gg8ls1, k8l)):
rec_v[(arm, reg, ev)] = {"vs_stats2": beats(g_) if len(g_) else "—", "vs_stats1": beats(gs1) if len(gs1) else "—", "vs_k0": beats(gk) if len(gk) else "—"}
lines.append(f"| {reg} | {ev} | {ms(gg8.value_a)} | {ms(gg8l.value_a)} | {ms(gg8.value_b)} | {ms(gg8s1.value_b)} | {ms(k8.value_b)} | {s8} | {s8l} | {s8s1} | {s8ls1} | {sln} | {beats(k8) if len(k8) else '—'} | {beats(k8l) if len(k8l) else '—'} |")
lines.append("")
# ---- survivor recipe under the MASKED protocol (E6, final assembly 2026-09-11): `U0_kin_can_noK_s<k>_kcv2_clip8_ln_masked` (clamp 8 + input LN, stats v2, trained
# without the 64 v2 suspect routes; every evaluated population censored likewise) vs k0 / persistence and vs the clamp-5 masked baseline `_kcv2_masked`
sm = d[d.tag.str.startswith("K4v2cm_") & d.tag.str.endswith("_clip8lnm_vs_k0") & (d.metric == "pr_auc") & d.cell.str.startswith("drv_onset")]
smb = d[d.tag.str.startswith("K4v2cm_") & d.tag.str.endswith("_clip8lnm_vs_k0") & (d.metric == "base_rate") & d.cell.str.startswith("drv_onset")]
smc = d[d.tag.str.startswith("K4v2clip_") & d.tag.str.endswith("_clip8lnm_vs_causalm") & (d.metric == "pr_auc") & d.cell.str.startswith("drv_onset")]
surv_v = {}
if len(sm):
lines += ["## Survivor recipe — masked protocol (E6, final assembly): `U0_kin_can_noK_s<k>_kcv2_clip8_ln_masked` (stats v2, clamp 8 + input LN; the 64 v2 suspect routes removed from TRAIN and from every evaluated population)", "",
"The all-rows cells of the same recipe are in the recipe arm above (`_kcv2_clip8_ln`); this section completes the two-protocol K4 table for the frozen U recipe of the final joint model.", "",
"| regime | event | clip8+LN masked | k0 (masked pops) | persistence | Δ vs k0 s0 / s1 / s2 [CI] | verdict vs k0 | clamp-5 masked baseline | Δ vs baseline s0 / s1 / s2 [CI] | verdict vs baseline |",
"|---|---|---|---|---|---|---|---|---|---|"]
for reg in ("manual", "engaged"):
for ev in EV:
cell = f"drv_onset|{ev}|3s"
g = sm[(sm.regime == reg) & (sm.cell == cell)].sort_values("seed")
gb = smb[(smb.regime == reg) & (smb.cell == cell)]
gc = smc[(smc.regime == reg) & (smc.cell == cell)].sort_values("seed")
dk = " / ".join(f"{float(r.delta):+.3f} [{float(r.delta_ci_lo):+.3f},{float(r.delta_ci_hi):+.3f}]" for r in g.itertuples()) or "—"
dc = " / ".join(f"{float(r.delta):+.3f} [{float(r.delta_ci_lo):+.3f},{float(r.delta_ci_hi):+.3f}]" for r in gc.itertuples()) or "—"
vk = beats(g) if len(g) else "—"
surv_v[(reg, ev)] = vk
lines.append(f"| {reg} | {ev} | {ms(g.value_a)} | {ms(g.value_b)} | {ms(gb.value_a) if len(gb) else '—'} | {dk} | {vk} | {ms(gc.value_b) if len(gc) else '—'} | {dc} | {beats(gc) if len(gc) else '—'} |")
lines.append("")
lines += ["## Verdicts (kill_checks.beats: ≥ 2/3 seeds CI excl. 0, same sign, |mean Δ| > seed sd)", ""]
if surv_v:
need = [(reg, ev) for reg in ("manual", "engaged") for ev in ("hand_leave", "head_turn_onset")]
core = all(surv_v.get(k) == "BEATS" for k in need)
nb = sum(v == "BEATS" for v in surv_v.values())
ins = any(v in ("—", "INSUFFICIENT") for v in surv_v.values())
lines.append(f"- **B1 (survivor recipe clip8+LN, suspect routes masked)**: **{'INSUFFICIENT' if ins else 'PASS' if core else 'FAIL'}** — rule (report_joint): hand_leave AND head_turn_onset BEATS k0 in both regimes; "
f"{nb}/6 driver cells BEATS k0 (manual hl/hr/ht, engaged hl/hr/ht: {', '.join(surv_v.get((reg, ev), '—') for reg in ('manual', 'engaged') for ev in EV)}); strict 6/6 rule: {'PASS' if nb == 6 else 'FAIL'}.")
for proto in ("all rows", "suspect routes masked"):
st, n, allc = b1(proto)
lines.append(f"- **B1 ({proto})**: **{st}** — rule (report_joint): hand_leave AND head_turn_onset BEATS k0 in both regimes; {n}/6 driver cells BEATS k0 "
f"(manual hl/hr/ht, engaged hl/hr/ht: {', '.join(allc)}); strict 6/6 rule: {'PASS' if n == 6 else 'FAIL'}.")
if verd_in:
w = [f"{r}|{e}" for (r, e), v in verd_in.items() if v == "WORSE"]
b = [f"{r}|{e}" for (r, e), v in verd_in.items() if v == "BEATS"]
ins = any(v in ("—", "INSUFFICIENT") for v in verd_in.values())
lines.append(f"- **K4 input effect (all rows)**: **{'INSUFFICIENT' if ins else 'PASS' if (not w and b) else 'FAIL'}** — rule: no driver cell WORSE and ≥ 1 BEATS; BEATS {b or 'none'}; WORSE {w or 'none'}.")
if len(s12):
vs = {(reg, ev): beats(s12[(s12.regime == reg) & (s12.cell == f"drv_onset|{ev}|3s")].sort_values("seed")) for reg in ("manual", "engaged") for ev in EV
if len(s12[(s12.regime == reg) & (s12.cell == f"drv_onset|{ev}|3s")])}
vk = {(reg, ev): beats(s1[(s1.regime == reg) & (s1.cell == f"drv_onset|{ev}|3s")].sort_values("seed")) for reg in ("manual", "engaged") for ev in EV
if len(s1[(s1.regime == reg) & (s1.cell == f"drv_onset|{ev}|3s")])}
lines.append(f"- **Stats arm (stats v1 − stats v2 on the v2 packs)**: BEATS {[f'{r}|{e}' for (r, e), v in vs.items() if v == 'BEATS'] or 'none'}; WORSE {[f'{r}|{e}' for (r, e), v in vs.items() if v == 'WORSE'] or 'none'}; "
f"stats-v1 model vs k0 BEATS {[f'{r}|{e}' for (r, e), v in vk.items() if v == 'BEATS'] or 'none'} (INCONCLUSIVE {[f'{r}|{e}' for (r, e), v in vk.items() if v == 'INCONCLUSIVE'] or 'none'}).")
if rec_v:
need = [(reg, ev) for reg in ("manual", "engaged") for ev in ("hand_leave", "head_turn_onset")]
summ = {}
for arm in ("clip8", "clip8ln"):
v = {k[1:]: x for k, x in rec_v.items() if k[0] == arm}
b2 = [f"{r}|{e}" for (r, e), x in v.items() if x["vs_stats2"] == "BEATS"]; w2 = [f"{r}|{e}" for (r, e), x in v.items() if x["vs_stats2"] == "WORSE"]
b1 = [f"{r}|{e}" for (r, e), x in v.items() if x["vs_stats1"] == "BEATS"]; w1 = [f"{r}|{e}" for (r, e), x in v.items() if x["vs_stats1"] == "WORSE"]
bk = sum(x["vs_k0"] == "BEATS" for x in v.values()); core = all(v.get((r, e), {}).get("vs_k0") == "BEATS" for r, e in need)
summ[arm] = {"b2": b2, "w2": w2, "b1": b1, "w1": w1, "bk": bk, "core": core}
lines.append(f"- **Recipe arm `{arm}` (stats v2, clamp 8{' + input LN' if arm == 'clip8ln' else ''})**: vs stats-v2 baseline BEATS {b2 or 'none'}, WORSE {w2 or 'none'}; "
f"vs stats-v1 arm BEATS {b1 or 'none'}, WORSE {w1 or 'none'}; vs k0 {bk}/6 BEATS → all-rows B1 (report_joint rule) {'PASS' if core else 'FAIL'}, strict 6/6 {'PASS' if bk == 6 else 'FAIL'}.")
def ok(arm_):
return not summ[arm_]["w2"] and not summ[arm_]["w1"]
cands = [arm_ for arm_ in ("clip8ln", "clip8") if ok(arm_)]
cands.sort(key=lambda arm_: (len(summ[arm_]["b2"]) + len(summ[arm_]["b1"]) + summ[arm_]["bk"], arm_ == "clip8ln"), reverse=True)
if cands:
best = cands[0]
lines.append(f"- **Survivor-recipe recommendation: `{best}`** — stats v2 (canonical SD units), `kclip: 8`{', `u_in_ln: true`' if best == 'clip8ln' else ''}: no cell WORSE than either the stats-v2 baseline or the stats-v1 arm; "
f"BEATS the stats-v2 baseline on {summ[best]['b2'] or 'no cell'} and the stats-v1 arm on {summ[best]['b1'] or 'no cell'}; {summ[best]['bk']}/6 cells beat k0.")
else:
lines.append("- **Survivor-recipe recommendation: neither arm is clean** (each is WORSE than the stats-v2 baseline or the stats-v1 arm on ≥ 1 cell): keep stats v2 + `kclip: 8` and re-tune the U recipe (lr / per-channel gain) before the survivor runs.")
lines.append("")
Path(a.out).write_text("\n".join(lines) + "\n")
print("\n".join(lines))
if __name__ == "__main__":
main()

Xet Storage Details

Size:
26.5 kB
·
Xet hash:
74e290964f04c9111d5fc5dc0834cc3a31ecd5a799440071017fb3ae74211625

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.