added white theme, some features to processing and saving

This commit is contained in:
Ayzen
2026-04-13 10:44:01 +03:00
parent 61685d7a4d
commit 5d2f95f959
20 changed files with 295 additions and 48 deletions
@@ -168,7 +168,8 @@ class AppWindowLiveProcessingMixin:
f"cut={self._bscan_cut_m.value():g} m, "
f"max_depth={self._bscan_max_depth_m.value():g} m, "
f"gain={self._bscan_gain.value():g}, "
f"freq={self._bscan_start_freq_mhz.value():g}..{self._bscan_stop_freq_mhz.value():g} MHz)"
f"freq={self._bscan_start_freq_mhz.value():g}..{self._bscan_stop_freq_mhz.value():g} MHz, "
f"subtract_mean_ascan={self._bscan_subtract_mean_ascan.isChecked()})"
)
elif mode == "gpr":
self._log(
@@ -169,6 +169,7 @@ class AppWindowConfigProfileIOMixin:
self._bscan_gain,
self._bscan_start_freq_mhz,
self._bscan_stop_freq_mhz,
self._bscan_subtract_mean_ascan,
self._gpr_config_mode,
self._gpr_relative_permittivity,
self._gpr_tx_geometry_input,
@@ -228,6 +229,7 @@ class AppWindowConfigProfileIOMixin:
self._bscan_gain.setValue(float(gui_state.processing.bscan.gain))
self._bscan_start_freq_mhz.setValue(float(gui_state.processing.bscan.start_freq_mhz))
self._bscan_stop_freq_mhz.setValue(float(gui_state.processing.bscan.stop_freq_mhz))
self._bscan_subtract_mean_ascan.setChecked(bool(gui_state.processing.bscan.subtract_mean_ascan))
self._set_combo_current_text(self._gpr_config_mode, str(config.gpr.mode))
self._gpr_relative_permittivity.setValue(float(config.gpr.relative_permittivity))
@@ -157,6 +157,7 @@ class AppWindowConfigStateBuildersMixin:
gain=1.0,
start_freq_mhz=100.0,
stop_freq_mhz=8800.0,
subtract_mean_ascan=False,
),
gpr=GuiGprStateModel(
input_positions=self._default_gpr_input_positions_from_config(config),
@@ -235,6 +236,7 @@ class AppWindowConfigStateBuildersMixin:
gain=float(self._bscan_gain.value()),
start_freq_mhz=float(self._bscan_start_freq_mhz.value()),
stop_freq_mhz=float(self._bscan_stop_freq_mhz.value()),
subtract_mean_ascan=bool(self._bscan_subtract_mean_ascan.isChecked()),
),
gpr=GuiGprStateModel(
input_positions=self._gpr_input_positions_input.text().strip(),
@@ -39,6 +39,8 @@ def _result_tail(
def build_bscan_signature(
live_config: ProcessingLiveConfig,
*,
subtract_mean_ascan_enabled: bool,
result_history: list[ResultCollection],
history_limit: int,
floor_collection_id: int,
@@ -57,11 +59,25 @@ def build_bscan_signature(
float(live_config.bscan_gain),
float(live_config.bscan_start_freq_mhz),
float(live_config.bscan_stop_freq_mhz),
bool(subtract_mean_ascan_enabled),
int(floor_collection_id),
tuple((int(collection.collection_id), int(collection.monotonic_ns), len(collection.blocks)) for collection in result_tail),
)
def apply_mean_ascan_subtraction(
history: deque[np.ndarray],
*,
enabled: bool,
) -> np.ndarray:
"""Subtract mean A-scan across sweeps when enabled."""
sweeps = np.vstack(history).astype(np.float32, copy=False)
if not enabled:
return sweeps
mean_trace = np.mean(sweeps, axis=0, dtype=np.float32)
return sweeps - mean_trace
def rebuild_bscan_history_from_results(
result_history: list[ResultCollection],
history_limit: int,
@@ -183,7 +199,10 @@ class AppWindowBscanPlotMixin:
if not history or depth_axis is None:
return False
sweeps = np.vstack(history).astype(np.float32, copy=False)
sweeps = apply_mean_ascan_subtraction(
history,
enabled=bool(self._bscan_subtract_mean_ascan.isChecked()),
)
if sweeps.size == 0:
return False
@@ -229,6 +248,7 @@ class AppWindowBscanPlotMixin:
result_history = list(self._result_history)
return build_bscan_signature(
live_config=live_config,
subtract_mean_ascan_enabled=bool(self._bscan_subtract_mean_ascan.isChecked()),
result_history=result_history,
history_limit=self._bscan_history_limit,
floor_collection_id=self._bscan_history_floor_collection_id,
@@ -18,9 +18,9 @@ class AppWindowSnapshotMixin:
return snapshot_dir / "config_profile.json"
@staticmethod
def _vna_json_config_profile_path(output_root: Path, output_stem: str) -> Path:
def _vna_json_config_profile_path(output_dir: Path) -> Path:
"""Return companion config-profile path for one VNA-history JSON export batch."""
return output_root / f"{output_stem}_config_profile.json"
return output_dir / "config_profile.json"
def _save_snapshot(self) -> None:
"""Save runtime snapshot in numpy-directory format."""
@@ -98,8 +98,9 @@ class AppWindowSnapshotMixin:
output_stem = str(summary.get("output_stem", "")).strip()
if not output_stem:
raise RuntimeError("VNA history JSON export did not report output_stem for config companion save")
output_dir = Path(str(summary.get("output_dir", "")).strip() or output_paths[0].parent)
config_profile_path = self._vna_json_config_profile_path(output_root, output_stem)
config_profile_path = self._vna_json_config_profile_path(output_dir)
try:
self._write_gui_profile_to_path(config_profile_path, allow_overwrite=False)
except Exception as exc: # noqa: BLE001
@@ -110,6 +111,7 @@ class AppWindowSnapshotMixin:
"VNA history JSON files were saved, but the adjacent config profile could not be written",
details=(
f"output_root={output_root}\n"
f"output_dir={output_dir}\n"
f"config_profile_path={config_profile_path}\n"
f"saved_json_files={len(output_paths)}\n"
f"{exported_preview}\n\n"
@@ -134,6 +134,9 @@ def build_processing_group(owner) -> QGroupBox:
owner._bscan_stop_freq_mhz.setSingleStep(10.0)
owner._bscan_stop_freq_mhz.setValue(float(bscan_defaults.stop_freq_mhz))
owner._bscan_subtract_mean_ascan = QCheckBox("Subtract mean A-scan")
owner._bscan_subtract_mean_ascan.setChecked(bool(bscan_defaults.subtract_mean_ascan))
bscan_page = _build_processing_mode_page(
owner._processing_mode_pages,
[
@@ -143,8 +146,9 @@ def build_processing_group(owner) -> QGroupBox:
("Gain", owner._bscan_gain),
("Start MHz", owner._bscan_start_freq_mhz),
("Stop MHz", owner._bscan_stop_freq_mhz),
owner._bscan_subtract_mean_ascan,
],
split_index=3,
split_index=4,
)
owner._processing_mode_pages.addWidget(bscan_page)
@@ -314,6 +318,7 @@ def build_processing_group(owner) -> QGroupBox:
owner._bscan_gain.valueChanged.connect(owner._on_processing_live_settings_changed)
owner._bscan_start_freq_mhz.valueChanged.connect(owner._on_processing_live_settings_changed)
owner._bscan_stop_freq_mhz.valueChanged.connect(owner._on_processing_live_settings_changed)
owner._bscan_subtract_mean_ascan.toggled.connect(owner._on_processing_live_settings_changed)
owner._gpr_input_positions_input.editingFinished.connect(owner._on_processing_live_settings_changed)
owner._gpr_output_positions_input.editingFinished.connect(owner._on_processing_live_settings_changed)
owner._gpr_min_depth_m.valueChanged.connect(owner._on_processing_live_settings_changed)