Update GPR and SAR3D processing

This commit is contained in:
Ayzen
2026-10-08 16:24:01 +03:00
parent 390015ec39
commit 3575ca68f5
67 changed files with 1187 additions and 2581 deletions
+14 -15
View File
@@ -10,7 +10,7 @@ import math
from pathlib import Path
from PyQt6.QtCore import QSignalBlocker
from PyQt6.QtWidgets import QCheckBox, QComboBox, QDoubleSpinBox, QFormLayout, QLabel, QSpinBox
from PyQt6.QtWidgets import QCheckBox, QComboBox, QDoubleSpinBox, QFormLayout, QLabel, QSlider, QSpinBox
from python_app.storage.npz.paths import radar_config_filename_prefix
from python_app.gui.antenna_geometry_editor import AntennaGeometryEditor
@@ -61,7 +61,6 @@ _ADC_FIELDS = (
("radar.laser_control.variation.delay_time", "_optical_delay_time_input"),
)
_GEOMETRY_FIELDS = {
"relative_permittivity": "_gpr_relative_permittivity",
"tx_geometry": "_gpr_tx_geometry_input",
"rx_geometry": "_gpr_rx_geometry_input",
}
@@ -97,15 +96,15 @@ def _set_web_widget(widget: SettingWidget, value: object) -> None:
if isinstance(widget, QCheckBox):
if not isinstance(value, bool):
raise ValueError("Checkbox value must be true or false")
elif isinstance(widget, (QSpinBox, QDoubleSpinBox)):
elif isinstance(widget, (QSpinBox, QDoubleSpinBox, QSlider)):
if isinstance(value, bool) or not isinstance(value, (int, float, str)):
raise ValueError("Numeric setting requires a number")
numeric = float(value)
if not math.isfinite(numeric) or not widget.minimum() <= numeric <= widget.maximum():
raise ValueError("Numeric setting is outside its allowed range")
if isinstance(widget, QSpinBox) and numeric != int(numeric):
if isinstance(widget, (QSpinBox, QSlider)) and numeric != int(numeric):
raise ValueError("Setting requires an integer")
value = int(numeric) if isinstance(widget, QSpinBox) else numeric
value = int(numeric) if isinstance(widget, (QSpinBox, QSlider)) else numeric
elif isinstance(widget, QComboBox):
if not isinstance(value, str) or widget.findText(value) < 0:
raise ValueError(f"Unknown setting option: {value}")
@@ -192,7 +191,7 @@ class ConfigController:
config.input_switch.positions <= 1 and config.output_switch.positions <= 1
or config.input_switch.driver_mode == config.output_switch.driver_mode == "mock"
)
if self._scalar("_processing_mode") not in {"gpr", "legacy_gpr", "sar3d"} and static:
if self._scalar("_processing_mode") not in {"gpr", "sar3d"} and static:
config.combos = [ComboModel(0, 0)]
for key in PREPROCESS_ASSET_NAMES:
asset = preprocess_asset_model(config, key)
@@ -224,7 +223,6 @@ class ConfigController:
def geometry(self) -> GprModel:
return GprModel(
relative_permittivity=float(self._scalar("_gpr_relative_permittivity")),
tx_geometry=[GprTxGeometryModel(**entry) for entry in self._geometry("tx_geometry").records()],
rx_geometry=[GprRxGeometryModel(**entry) for entry in self._geometry("rx_geometry").records()],
)
@@ -242,9 +240,10 @@ class ConfigController:
if binding.spec.live in {"gpr_input_positions", "gpr_output_positions"}:
value = parse_position_csv(str(value))
setattr(config, binding.spec.live, value)
config.relative_permittivity = float(self._scalar("_gpr_relative_permittivity"))
config.tx_geometry = self._geometry("tx_geometry").records()
config.rx_geometry = self._geometry("rx_geometry").records()
if config.sar3d_y_max_m <= config.sar3d_y_min_m:
raise ValueError("SAR_Y_RANGE_M max must be above min")
for axis in ("x", "z"):
lower_name, upper_name = f"gpr_visible_{axis}_min_m", f"gpr_visible_{axis}_max_m"
lower, upper = sorted((getattr(config, lower_name), getattr(config, upper_name)))
@@ -279,7 +278,6 @@ class ConfigController:
if binding.spec.widget:
write_setting(_scalar_widget(self.fields[binding.spec.widget]), binding.read(gui))
write_setting(_scalar_widget(self.fields["_log_level_combo"]), config.logging.level.capitalize())
write_setting(_scalar_widget(self.fields["_gpr_relative_permittivity"]), config.gpr.relative_permittivity)
for name, count, records in (
("tx_geometry", config.output_switch.positions, config.gpr.tx_geometry),
("rx_geometry", config.input_switch.positions, config.gpr.rx_geometry),
@@ -292,8 +290,8 @@ class ConfigController:
widgets = {binding.spec.web: (binding.spec.group, self.fields[binding.spec.widget])
for binding in active_web_fields(mode)}
for name, widget_id in _GEOMETRY_FIELDS.items():
if mode in ({"legacy_gpr"} if name == "relative_permittivity" else {"gpr", "legacy_gpr", "sar3d"}):
widgets[name] = ("Geometry & medium", self.fields[widget_id])
if mode in {"gpr", "sar3d"}:
widgets[name] = ("Geometry", self.fields[widget_id])
return widgets
def web_schema(self) -> list[dict[str, object]]:
@@ -315,9 +313,10 @@ class ConfigController:
entry.update(kind="select", options=[widget.itemText(i) for i in range(widget.count())])
elif isinstance(widget, QCheckBox):
entry.update(kind="bool")
elif isinstance(widget, (QSpinBox, QDoubleSpinBox)):
entry.update(kind="int" if isinstance(widget, QSpinBox) else "float",
min=widget.minimum(), max=widget.maximum(), step=widget.singleStep())
elif isinstance(widget, (QSpinBox, QDoubleSpinBox, QSlider)):
entry.update(kind="int" if isinstance(widget, (QSpinBox, QSlider)) else "float",
min=widget.minimum(), max=widget.maximum(), step=widget.singleStep(),
slider=isinstance(widget, QSlider))
if isinstance(widget, QDoubleSpinBox):
entry["decimals"] = widget.decimals()
elif isinstance(widget, AntennaGeometryEditor):
@@ -357,7 +356,7 @@ class ConfigController:
geometry_snapshots.append((widget, widget.records()))
else:
scalar_snapshots.append((widget, read_setting(widget)))
if isinstance(widget, (QSpinBox, QDoubleSpinBox)):
if isinstance(widget, (QSpinBox, QDoubleSpinBox, QSlider)):
ranges.append((widget, widget.minimum(), widget.maximum()))
try:
if "processor_mode" in fields: