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:
awe
2026-09-25 16:42:14 +03:00
co-authored by Claude Fable 5
parent b8cb572bc4
commit e1dfbec712
9 changed files with 345 additions and 149 deletions
+80 -24
View File
@@ -533,39 +533,84 @@ def gui_profile_from_dict(payload: dict[str, Any]) -> GuiProfileModel:
gui.processing.sar3d.edge_frame_weight,
"gui.processing.sar3d",
),
pitch_override_enabled=_optional_bool(
sar3d_object,
"pitch_override_enabled",
gui.processing.sar3d.pitch_override_enabled,
"gui.processing.sar3d",
),
pitch_deg=_optional_float(
sar3d_object,
"pitch_deg",
gui.processing.sar3d.pitch_deg,
"gui.processing.sar3d",
),
center_depth_m=_optional_float(
ground_depth_m=_optional_float(
sar3d_object,
"center_depth_m",
gui.processing.sar3d.center_depth_m,
"ground_depth_m",
gui.processing.sar3d.ground_depth_m,
"gui.processing.sar3d",
),
half_width_x_m=_optional_float(
x_margin_m=_optional_float(
sar3d_object,
"half_width_x_m",
gui.processing.sar3d.half_width_x_m,
"x_margin_m",
gui.processing.sar3d.x_margin_m,
"gui.processing.sar3d",
),
half_width_y_m=_optional_float(
y_min_m=_optional_float(
sar3d_object,
"half_width_y_m",
gui.processing.sar3d.half_width_y_m,
"y_min_m",
gui.processing.sar3d.y_min_m,
"gui.processing.sar3d",
),
half_width_z_m=_optional_float(
y_max_m=_optional_float(
sar3d_object,
"half_width_z_m",
gui.processing.sar3d.half_width_z_m,
"y_max_m",
gui.processing.sar3d.y_max_m,
"gui.processing.sar3d",
),
voxel_x_m=_optional_float(
sar3d_object,
"voxel_x_m",
gui.processing.sar3d.voxel_x_m,
"gui.processing.sar3d",
),
voxel_y_m=_optional_float(
sar3d_object,
"voxel_y_m",
gui.processing.sar3d.voxel_y_m,
"gui.processing.sar3d",
),
voxel_z_m=_optional_float(
sar3d_object,
"voxel_z_m",
gui.processing.sar3d.voxel_z_m,
"gui.processing.sar3d",
),
norm_edge_margin_m=_optional_float(
sar3d_object,
"norm_edge_margin_m",
gui.processing.sar3d.norm_edge_margin_m,
"gui.processing.sar3d",
),
smooth_sigma=_optional_float(
sar3d_object,
"smooth_sigma",
gui.processing.sar3d.smooth_sigma,
"gui.processing.sar3d",
),
comp_range_power=_optional_float(
sar3d_object,
"comp_range_power",
gui.processing.sar3d.comp_range_power,
"gui.processing.sar3d",
),
tx_per_segment=_optional_int(
sar3d_object,
"tx_per_segment",
gui.processing.sar3d.tx_per_segment,
"gui.processing.sar3d",
),
grid_nx=_optional_int(sar3d_object, "grid_nx", gui.processing.sar3d.grid_nx, "gui.processing.sar3d"),
grid_ny=_optional_int(sar3d_object, "grid_ny", gui.processing.sar3d.grid_ny, "gui.processing.sar3d"),
grid_nz=_optional_int(sar3d_object, "grid_nz", gui.processing.sar3d.grid_nz, "gui.processing.sar3d"),
use_compensation=_optional_bool(
sar3d_object,
"use_compensation",
@@ -628,8 +673,14 @@ def gui_profile_from_dict(payload: dict[str, Any]) -> GuiProfileModel:
raise ValueError("gui.processing.sar3d.frame_radius must be >= 0")
if not 0.0 <= gui.processing.sar3d.edge_frame_weight <= 1.0:
raise ValueError("gui.processing.sar3d.edge_frame_weight must be within [0, 1]")
if min(gui.processing.sar3d.grid_nx, gui.processing.sar3d.grid_ny, gui.processing.sar3d.grid_nz) < 2:
raise ValueError("gui.processing.sar3d.grid_nx/ny/nz must each be >= 2")
if min(gui.processing.sar3d.voxel_x_m, gui.processing.sar3d.voxel_y_m, gui.processing.sar3d.voxel_z_m) <= 0.0:
raise ValueError("gui.processing.sar3d.voxel_x/y/z_m must each be > 0")
if gui.processing.sar3d.y_max_m <= gui.processing.sar3d.y_min_m:
raise ValueError("gui.processing.sar3d.y_max_m must be > y_min_m")
if gui.processing.sar3d.ground_depth_m < 0.0:
raise ValueError("gui.processing.sar3d.ground_depth_m must be >= 0")
if gui.processing.sar3d.tx_per_segment < 1:
raise ValueError("gui.processing.sar3d.tx_per_segment must be >= 1")
data_actions_object = _as_dict(gui_object.get("data_actions"), "gui.data_actions")
gui.data_actions = GuiDataActionsStateModel(
@@ -795,14 +846,19 @@ def gui_profile_to_dict(model: GuiProfileModel) -> dict[str, Any]:
"apply_freq_phase_correction": gui.processing.sar3d.apply_freq_phase_correction,
"frame_radius": gui.processing.sar3d.frame_radius,
"edge_frame_weight": gui.processing.sar3d.edge_frame_weight,
"pitch_override_enabled": gui.processing.sar3d.pitch_override_enabled,
"pitch_deg": gui.processing.sar3d.pitch_deg,
"center_depth_m": gui.processing.sar3d.center_depth_m,
"half_width_x_m": gui.processing.sar3d.half_width_x_m,
"half_width_y_m": gui.processing.sar3d.half_width_y_m,
"half_width_z_m": gui.processing.sar3d.half_width_z_m,
"grid_nx": gui.processing.sar3d.grid_nx,
"grid_ny": gui.processing.sar3d.grid_ny,
"grid_nz": gui.processing.sar3d.grid_nz,
"ground_depth_m": gui.processing.sar3d.ground_depth_m,
"x_margin_m": gui.processing.sar3d.x_margin_m,
"y_min_m": gui.processing.sar3d.y_min_m,
"y_max_m": gui.processing.sar3d.y_max_m,
"voxel_x_m": gui.processing.sar3d.voxel_x_m,
"voxel_y_m": gui.processing.sar3d.voxel_y_m,
"voxel_z_m": gui.processing.sar3d.voxel_z_m,
"norm_edge_margin_m": gui.processing.sar3d.norm_edge_margin_m,
"smooth_sigma": gui.processing.sar3d.smooth_sigma,
"comp_range_power": gui.processing.sar3d.comp_range_power,
"tx_per_segment": gui.processing.sar3d.tx_per_segment,
"use_compensation": gui.processing.sar3d.use_compensation,
"normalize_pairs": gui.processing.sar3d.normalize_pairs,
"bottom_view_deg": gui.processing.sar3d.bottom_view_deg,