#!/usr/bin/env python3 """Compare two S2 offline summary.json runs (real artifacts only).""" from __future__ import annotations import json import sys from pathlib import Path import numpy as np from imu_lidar.geometry import rpy_deg_xyz, so3_log def dig(path: Path): data = json.loads(path.read_text(encoding="utf-8")) session = data["details"]["sessions"][0] return data, session, session.get("handeye", {}), session.get("time_offset", {}) def main() -> int: old_path = Path(sys.argv[1]) new_path = Path(sys.argv[2]) old, so, heo, too = dig(old_path) new, sn, hen, ton = dig(new_path) print("==== COMPARISON (real summary.json artifacts) ====") print(f"{'metric':28s} {'run_a':28s} {'run_b':28s}") rows = [ ("status", old.get("status"), new.get("status")), ("stage", so.get("stage"), sn.get("stage")), ("delta_t_s", f"{too.get('delta_t_s'):.6f}", f"{ton.get('delta_t_s'):.6f}"), ( "corr/mag_peak", f"{too.get('correlation_peak'):.6f}", f"{ton.get('correlation_peak'):.6f}", ), ("keyframes", so.get("keyframes"), sn.get("keyframes")), ("handeye_pairs", heo.get("pair_count"), hen.get("pair_count")), ("handeye_ok", heo.get("ok"), hen.get("ok")), ("rms_deg", f"{heo.get('residual_rms_deg'):.4f}", f"{hen.get('residual_rms_deg'):.4f}"), ( "median_deg", f"{heo.get('residual_median_deg'):.4f}", f"{hen.get('residual_median_deg'):.4f}", ), ] for key, a, b in rows: print(f"{key:28s} {str(a):28s} {str(b):28s}") print("run_a pair_notes:", so.get("pair_notes")) print("run_b pair_notes:", sn.get("pair_notes")) print("run_a time notes:", too.get("notes")) print("run_b time notes:", ton.get("notes")) print("run_a handeye notes:", heo.get("notes")) print("run_b handeye notes:", hen.get("notes")) r_old = np.asarray(heo["R_IMU_lidar"], dtype=float) r_new = np.asarray(hen["R_IMU_lidar"], dtype=float) print("R relative change deg:", float(np.degrees(np.linalg.norm(so3_log(r_old.T @ r_new))))) print("RPY run_a deg:", rpy_deg_xyz(r_old)) print("RPY run_b deg:", rpy_deg_xyz(r_new)) print("delta rms (b-a):", hen.get("residual_rms_deg") - heo.get("residual_rms_deg")) print( "delta median (b-a):", hen.get("residual_median_deg") - heo.get("residual_median_deg"), ) print("artifacts:") print(" run_a:", old_path) print(" run_b:", new_path) return 0 if __name__ == "__main__": raise SystemExit(main())