Buckets:
| """cwm3/data/qc_driver_box_suspects.py — per-route agreement of the causal kinematics with the old non-causal cache and the list of | |
| wrong-occupant suspects (route-level causal box locked onto a co-occupant). For a given kin dir (+ pose dirs, v2 first): | |
| per route (>= 500 jointly valid cells): Pearson r of head_turn and min_hand_rest_dist (K, old vs new), hands_on agreement, co-occupant | |
| fraction, driver-side-prior source. Suspect = r(head_turn) < 0.3 or hands_on agreement < 0.5. Writes <kin_dir>/qc_per_route.csv and | |
| <kin_dir>/driver_box_suspect_routes.json (summary per split: routes/anchors flagged), prints the summary.""" | |
| import argparse, json, sys | |
| from pathlib import Path | |
| import numpy as np, pandas as pd | |
| ROOT = Path(__file__).resolve().parents[1]; OLD = ROOT.parent / "cwm2" / "results" / "targets_kin"; S12 = ROOT.parent / "s12_wm" / "results" | |
| def main(): | |
| ap = argparse.ArgumentParser(); ap.add_argument("--kin-dir", default=str(ROOT / "results" / "targets_kin_causal_routes")); ap.add_argument("--pose-dirs", nargs="*", default=[str(ROOT / "results" / "pose_causal_routes")]); a = ap.parse_args() | |
| KIN = Path(a.kin_dir); pdirs = [Path(d) for d in a.pose_dirs] | |
| def pose(u): | |
| for d in pdirs: | |
| if (d / f"{u}.npz").exists(): return np.load(d / f"{u}.npz"), d.name | |
| return None, None | |
| rows = [] | |
| for reg in ("manual", "engaged"): | |
| for sp in ("train", "val", "test"): | |
| o = np.load(OLD / f"kin_{reg}_{sp}.npz", allow_pickle=True); n = np.load(KIN / f"kin_causal_{reg}_{sp}.npz", allow_pickle=True) | |
| uid = n["uid"]; both = n["Kvalid"] & o["Kvalid"]; Ko = o["K"][:, :, [6, 10]].astype(np.float32); Kn = n["K_c"][:, :, [6, 10]].astype(np.float32); So, Sn = o["S"][:, :, 0], n["S_c"][:, :, 0] | |
| order = np.argsort(uid, kind="stable"); b = np.flatnonzero(np.r_[1, uid[order][1:] != uid[order][:-1], 1]) | |
| for a_, e_ in zip(b[:-1], b[1:]): | |
| rr = order[a_:e_]; u = uid[rr[0]]; m = both[rr]; n_anch = len(rr) | |
| if m.sum() < 500: continue | |
| z, src_dir = pose(u) | |
| if z is None: continue | |
| def pr(c): | |
| x, y = Ko[rr][:, :, c][m], Kn[rr][:, :, c][m]; k = np.isfinite(x) & np.isfinite(y) | |
| return float(np.corrcoef(x[k], y[k])[0, 1]) if k.sum() > 100 and x[k].std() > 0 and y[k].std() > 0 else np.nan | |
| ms = np.isfinite(So[rr]) & np.isfinite(Sn[rr]); agr = float((So[rr][ms] == Sn[rr][ms]).mean()) if ms.any() else np.nan | |
| rows.append(dict(reg=reg, sp=sp, uid=u, src=str(z["dside_source"]), pose_dir=src_dir, r_ht=pr(0), r_md=pr(1), hands_agr=agr, n_cells=int(m.sum()), n_anchors=n_anch, co_frac=float((z["n_persons"] >= 2).mean()))) | |
| df = pd.DataFrame(rows); df.to_csv(KIN / "qc_per_route.csv", index=False) | |
| sus = df[(df.r_ht < 0.3) | (df.hands_agr < 0.5)] | |
| tot = {} | |
| for reg in ("manual", "engaged"): | |
| for sp in ("train", "val", "test"): tot[(reg, sp)] = int(len(np.load(S12 / f"targets_{reg}_{sp}.npz", allow_pickle=True)["t"])) | |
| summ = {f"{r}_{s}": dict(routes_compared=int(((df.reg == r) & (df.sp == s)).sum()), routes_flagged=int(((sus.reg == r) & (sus.sp == s)).sum()), anchors_flagged=int(sus[(sus.reg == r) & (sus.sp == s)].n_anchors.sum()), anchors_total=tot[(r, s)], | |
| anchors_flagged_frac=round(float(sus[(sus.reg == r) & (sus.sp == s)].n_anchors.sum() / tot[(r, s)]), 4), median_r_head_turn=round(float(df[(df.reg == r) & (df.sp == s)].r_ht.median()), 3)) for r in ("manual", "engaged") for s in ("train", "test")} | |
| by_src = df.groupby("src").agg(routes=("uid", "count"), median_r_head_turn=("r_ht", "median"), median_hands_agr=("hands_agr", "median"), co_frac_mean=("co_frac", "mean"), flagged=("r_ht", lambda x: int((x < 0.3).sum()))).round(3).reset_index().to_dict("records") | |
| rec = dict(kin_dir=str(KIN), pose_dirs=[str(d) for d in pdirs], definition="suspect = per-route r(head_turn) < 0.3 or hands_on agreement < 0.5 on >= 500 jointly valid cells", summary=summ, n_routes_flagged=int(len(sus.uid.unique())), by_source=by_src, | |
| flagged=sus.sort_values("n_anchors", ascending=False)[["reg", "sp", "uid", "src", "pose_dir", "r_ht", "r_md", "hands_agr", "co_frac", "n_anchors"]].round(3).to_dict("records")) | |
| (KIN / "driver_box_suspect_routes.json").write_text(json.dumps(rec, indent=1)) | |
| print("SUSPECTS_DONE", json.dumps(dict(n_routes_flagged=rec["n_routes_flagged"], summary=summ, by_source=by_src), default=str)) | |
| if __name__ == "__main__": | |
| main() | |
Xet Storage Details
- Size:
- 4.57 kB
- Xet hash:
- 0cf7260e4bd47e78b567e1abd78d55aca498bef8ddab4e18d7db7a32c098caa4
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.