From 9352d0c816a79f01c485d9ab79bde69472f644af Mon Sep 17 00:00:00 2001 From: ykcheungab Date: Sun, 18 Oct 2026 20:17:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=A4=9A=E7=82=B9=E5=BD=95?= =?UTF-8?q?=E5=88=B6=E8=AF=8A=E6=96=AD=E7=9A=84=E9=87=87=E9=9B=86=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=AE=9A=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 从 repeat/capture 读取帧、力和采集来源,使诊断符合现有录制目录。既有诊断检查和多点目录案例通过,该案例在 HEAD 原实现中失败。 --- .../src/orisys_autocal/record_diagnostics.py | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/apps/autocal/src/orisys_autocal/record_diagnostics.py b/apps/autocal/src/orisys_autocal/record_diagnostics.py index 5676eb0..aaa9f24 100644 --- a/apps/autocal/src/orisys_autocal/record_diagnostics.py +++ b/apps/autocal/src/orisys_autocal/record_diagnostics.py @@ -13,16 +13,25 @@ def trial_diagnostics(root: Path, trial: dict) -> dict: path = (root / trial.get("directory", "__missing_trial__")).resolve() if not path.is_relative_to(root.resolve()): raise ValueError("trial directory is outside the calibration session") + frame_path = path + try: + manifest = json.loads((root / "session.json").read_text(encoding="utf-8")) + if manifest.get("format_version") == "autocal-multipoint-1.0": + frame_path = (path / "capture").resolve() + if not frame_path.is_relative_to(root.resolve()): + raise ValueError("frame directory is outside the calibration session") + except (OSError, json.JSONDecodeError) as exc: + result["errors"].append(str(exc)) - def rows(name): + def rows(name, directory=path): try: - with (path / name).open(encoding="utf-8-sig", newline="") as handle: + with (directory / name).open(encoding="utf-8-sig", newline="") as handle: return list(csv.DictReader(handle)) except OSError: result["errors"].append(name) return [] - frames = rows("frames.csv") + frames = rows("frames.csv", frame_path) frame_by_id = {row["frame_id"]: row for row in frames if row.get("frame_id")} result["frames"] = len(frames) result["dropped"] = sum(r.get("dropped") == "1" for r in frames) @@ -33,7 +42,7 @@ def trial_diagnostics(root: Path, trial: dict) -> dict: stamps[int(row["frame_id"])] = int(row["t_host_mono_ns"]) ordered = sorted(stamps.values()) result["max_gap_s"] = max((b - a for a, b in zip(ordered, ordered[1:])), default=0) / 1e9 - for row in rows("forces.csv"): + for row in rows("forces.csv", frame_path): stamp = stamps.get(int(row["frame_id"])) raw = float(row["FN_raw"]) if row.get("FN_raw") else math.nan if row.get("valid") != "1" or not math.isfinite(raw) or stamp is None: @@ -50,6 +59,14 @@ def trial_diagnostics(root: Path, trial: dict) -> dict: metadata = json.loads((path / "session.json").read_text(encoding="utf-8")) result["source"] = metadata.get("input_source", {}) result["time_basis"] = metadata.get("time_basis", "") + if frame_path != path: + capture = json.loads((frame_path / "session.json").read_text(encoding="utf-8")) + result["source"] = capture.get("input_source", {}) + bases = {row.get("time_basis") for row in frames if row.get("time_basis")} + result["time_basis"] = next(iter(bases)) if len(bases) == 1 else "" + if not result["source"]: + kind = {"host_camera": "camera", "host_replay": "video"}.get(result["time_basis"]) + result["source"] = {"kind": kind} if kind else {} result["reason"] = metadata.get("trial_reason") or result["reason"] except (OSError, ValueError, KeyError, TypeError) as exc: result["errors"].append(str(exc))