sar3d: python plumbing for the new parameters and real replay timing
- replay_raw_producer carries the RECORDED per-trace capture windows from each snapshot's meta.json (re-anchored by the same shift as the frame time) instead of one synthetic window for all traces — without this the segmented timing model degenerates in replay; - GUI/profile/orchestration swap the removed window knobs (center_depth, half_width_*, grid_n*) for the notebook parameters (ground depth, pitch override, voxel pitch, Y range, X margin, norm edge margin, smooth sigma, comp power, tx per segment). Headless replay smoke on the 20260922_mine_fast_true dataset passes: 51 sar3d result collections, transparent preprocessor. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ never see time jump backwards. ``collection_id`` increases forever.
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import re
|
||||
@@ -75,6 +76,22 @@ def _load_dataset(dataset_dir: Path, combos: list[ComboKey], expected_points: in
|
||||
timestamps_ns: list[int] = []
|
||||
for name, timestamp_ns in named:
|
||||
folder = dataset_dir / name
|
||||
# Recorded per-trace capture windows from the snapshot's meta.json: the
|
||||
# sar3d segmented timing model reconstructs the acquisition segments
|
||||
# from them. Missing/partial meta leaves the zero "unmeasured" sentinel
|
||||
# and the consumer falls back to its uniform-segment model.
|
||||
windows: dict[tuple[int, int], tuple[int, int]] = {}
|
||||
meta_path = folder / "meta.json"
|
||||
if meta_path.is_file():
|
||||
try:
|
||||
meta = json.loads(meta_path.read_text())
|
||||
for entry in meta.get("traces", []):
|
||||
windows[(int(entry["input"]), int(entry["output"]))] = (
|
||||
int(entry["capture_start_ns"]),
|
||||
int(entry["capture_end_ns"]),
|
||||
)
|
||||
except (OSError, ValueError, KeyError, TypeError):
|
||||
windows = {}
|
||||
traces: list[TraceData] = []
|
||||
for combo in combos:
|
||||
s21_path = folder / f"i{combo.input}_o{combo.output}_s21.npy"
|
||||
@@ -94,12 +111,15 @@ def _load_dataset(dataset_dir: Path, combos: list[ComboKey], expected_points: in
|
||||
f"{s21_path}: {s21.size} points, but radar.sweep.points = "
|
||||
f"{expected_points}. Align the profile's sweep with the dataset."
|
||||
)
|
||||
window = windows.get((combo.input, combo.output), (0, 0))
|
||||
traces.append(
|
||||
TraceData(
|
||||
combo=combo,
|
||||
frequency_hz=freq,
|
||||
s11=np.zeros_like(s21),
|
||||
s21=s21,
|
||||
capture_start_ns=window[0],
|
||||
capture_end_ns=window[1],
|
||||
)
|
||||
)
|
||||
snapshots.append(traces)
|
||||
@@ -114,28 +134,38 @@ def _build_collection(
|
||||
collection_id: int,
|
||||
frame_ns: int,
|
||||
) -> SweepCollection:
|
||||
"""Wrap one preloaded snapshot in a SweepCollection at the given frame time."""
|
||||
"""Wrap one preloaded snapshot in a SweepCollection at the given frame time.
|
||||
|
||||
Recorded per-trace capture windows are re-anchored by the same shift as the
|
||||
frame time, preserving the real intra-frame segment layout. Traces without
|
||||
recorded windows get a synthetic window spanning the median frame gap.
|
||||
"""
|
||||
span_ns = dataset.median_gap_ns
|
||||
start_ns = frame_ns - span_ns // 2
|
||||
end_ns = frame_ns + span_ns // 2
|
||||
shift_ns = frame_ns - dataset.timestamps_ns[index]
|
||||
traces = []
|
||||
for source in dataset.snapshots[index]:
|
||||
if source.capture_end_ns > source.capture_start_ns:
|
||||
capture = (source.capture_start_ns + shift_ns, source.capture_end_ns + shift_ns)
|
||||
else:
|
||||
capture = (start_ns, end_ns)
|
||||
traces.append(
|
||||
TraceData(
|
||||
combo=source.combo,
|
||||
frequency_hz=source.frequency_hz,
|
||||
s11=source.s11,
|
||||
s21=source.s21,
|
||||
capture_start_ns=start_ns,
|
||||
capture_end_ns=end_ns,
|
||||
capture_start_ns=capture[0],
|
||||
capture_end_ns=capture[1],
|
||||
)
|
||||
)
|
||||
return SweepCollection(
|
||||
collection_id=collection_id,
|
||||
monotonic_ns=frame_ns,
|
||||
traces=traces,
|
||||
capture_start_ns=start_ns,
|
||||
capture_end_ns=end_ns,
|
||||
capture_start_ns=min(t.capture_start_ns for t in traces),
|
||||
capture_end_ns=max(t.capture_end_ns for t in traces),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user