sar3d: fixed default scene window X [-2,2], Y [-0.5,2], Z [0,8] m

The grid bounds are now explicit config (sar3d_x/y/z_min/max_m) instead of
being derived from the antenna span and the depth gate. The depth mask
still zeroes voxels outside [min_depth, max_depth], so the wider Z window
just shows the masked wedge. The bound fields are double: the parity tool
recomputes the notebook-derived bounds (notebook_grid_bounds) and passes
them through the live config, and a float roundtrip shifted the axes by
~1e-7 m, flipping depth-mask knife-edge voxels against the reference npz.
Parity on frames 0034-0036 unchanged (1.3e-6, axes bit-match).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
awe
2026-09-25 17:12:18 +03:00
co-authored by Claude Fable 5
parent 60f6c9e567
commit 7329750c0c
16 changed files with 220 additions and 81 deletions
+29 -4
View File
@@ -551,10 +551,16 @@ def gui_profile_from_dict(payload: dict[str, Any]) -> GuiProfileModel:
gui.processing.sar3d.ground_depth_m,
"gui.processing.sar3d",
),
x_margin_m=_optional_float(
x_min_m=_optional_float(
sar3d_object,
"x_margin_m",
gui.processing.sar3d.x_margin_m,
"x_min_m",
gui.processing.sar3d.x_min_m,
"gui.processing.sar3d",
),
x_max_m=_optional_float(
sar3d_object,
"x_max_m",
gui.processing.sar3d.x_max_m,
"gui.processing.sar3d",
),
y_min_m=_optional_float(
@@ -569,6 +575,18 @@ def gui_profile_from_dict(payload: dict[str, Any]) -> GuiProfileModel:
gui.processing.sar3d.y_max_m,
"gui.processing.sar3d",
),
z_min_m=_optional_float(
sar3d_object,
"z_min_m",
gui.processing.sar3d.z_min_m,
"gui.processing.sar3d",
),
z_max_m=_optional_float(
sar3d_object,
"z_max_m",
gui.processing.sar3d.z_max_m,
"gui.processing.sar3d",
),
voxel_x_m=_optional_float(
sar3d_object,
"voxel_x_m",
@@ -675,8 +693,12 @@ def gui_profile_from_dict(payload: dict[str, Any]) -> GuiProfileModel:
raise ValueError("gui.processing.sar3d.edge_frame_weight must be within [0, 1]")
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.x_max_m <= gui.processing.sar3d.x_min_m:
raise ValueError("gui.processing.sar3d.x_max_m must be > x_min_m")
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.z_max_m <= gui.processing.sar3d.z_min_m:
raise ValueError("gui.processing.sar3d.z_max_m must be > z_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:
@@ -849,9 +871,12 @@ def gui_profile_to_dict(model: GuiProfileModel) -> dict[str, Any]:
"pitch_override_enabled": gui.processing.sar3d.pitch_override_enabled,
"pitch_deg": gui.processing.sar3d.pitch_deg,
"ground_depth_m": gui.processing.sar3d.ground_depth_m,
"x_margin_m": gui.processing.sar3d.x_margin_m,
"x_min_m": gui.processing.sar3d.x_min_m,
"x_max_m": gui.processing.sar3d.x_max_m,
"y_min_m": gui.processing.sar3d.y_min_m,
"y_max_m": gui.processing.sar3d.y_max_m,
"z_min_m": gui.processing.sar3d.z_min_m,
"z_max_m": gui.processing.sar3d.z_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,
+4 -1
View File
@@ -148,9 +148,12 @@ class GuiSar3dStateModel:
pitch_override_enabled: bool = False
pitch_deg: float = 17.5
ground_depth_m: float = 1.25
x_margin_m: float = 2.0
x_min_m: float = -2.0
x_max_m: float = 2.0
y_min_m: float = -0.5
y_max_m: float = 2.0
z_min_m: float = 0.0
z_max_m: float = 8.0
voxel_x_m: float = 0.025
voxel_y_m: float = 0.02
voxel_z_m: float = 0.02