Rework radar system
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
"""Settings reach the processor atomically and preserve the saved frequency band."""
|
||||
|
||||
from copy import deepcopy
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from PyQt6.QtWidgets import QApplication, QComboBox, QDoubleSpinBox, QStackedWidget
|
||||
|
||||
from python_app.gui.antenna_geometry_editor import AntennaGeometryEditor
|
||||
from python_app.gui.controllers.sections.processing_section import build_processing_group
|
||||
from python_app.models.gui_profile_schema import GuiStateModel
|
||||
from python_app.models.dataset_model import SweepCollection
|
||||
from python_app.models.run_config_schema import RunConfigModel
|
||||
from python_app.tests.gui_test_support import isolated_window, widget
|
||||
|
||||
|
||||
class LiveSettingsRegressionTest(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
cls.app = QApplication.instance() or QApplication([])
|
||||
|
||||
def test_initial_processing_band_uses_sweep_limits_before_profile_values(self) -> None:
|
||||
config, gui = RunConfigModel(), GuiStateModel()
|
||||
config.radar.sweep.start_hz, config.radar.sweep.stop_hz = 1e6, 9.5e9
|
||||
for settings in (gui.processing.bscan, gui.processing.gpr,
|
||||
gui.processing.legacy_gpr, gui.processing.sar3d):
|
||||
settings.start_freq_mhz, settings.stop_freq_mhz = 20, 9200
|
||||
section = build_processing_group(config, gui)
|
||||
self.addCleanup(section.group.deleteLater)
|
||||
for mode in ("bscan", "gpr", "legacy_gpr", "sar3d"):
|
||||
for bound, expected in (("start", 20), ("stop", 9200)):
|
||||
with self.subTest(mode=mode, bound=bound):
|
||||
editor = widget(section, f"_{mode}_{bound}_freq_mhz", QDoubleSpinBox)
|
||||
self.assertEqual((editor.minimum(), editor.maximum(), editor.value()), (1, 9500, expected))
|
||||
|
||||
def test_failed_live_write_restores_web_batch_and_desktop_changes(self) -> None:
|
||||
window = isolated_window(self.addCleanup)
|
||||
window._pipeline.timer.stop()
|
||||
mode = window._view.processing.mode
|
||||
gain = widget(window._view.processing, "_bscan_gain", QDoubleSpinBox)
|
||||
pages = window._view.processing.pages
|
||||
live = window._live
|
||||
before = (window._profile.build_gui_state(), window._config.geometry(),
|
||||
live.active_mode, pages.currentIndex(), window._plots.stack.currentWidget(),
|
||||
live.revision, deepcopy(live.processing_settings), window._plots.required_revision,
|
||||
live.writer.path.read_bytes())
|
||||
for source in ("web", "web_geometry", "desktop_mode", "desktop_value", "desktop_geometry"):
|
||||
with self.subTest(source=source), \
|
||||
mock.patch.object(live.writer, "write", side_effect=OSError("disk full")), \
|
||||
mock.patch.object(window._preprocess, "invalidate_object_calibration_after_geometry_change") as invalidate, \
|
||||
mock.patch.object(window._log, "show_exception") as error:
|
||||
if source == "web":
|
||||
live.apply_web({"processor_mode": "bscan", "bscan_gain": gain.value() + .1})
|
||||
elif source in {"web_geometry", "desktop_geometry"}:
|
||||
editor = window._view.processing.geometries[0]
|
||||
records = editor.records()
|
||||
records[0]["x_m"] += .125
|
||||
if source == "web_geometry":
|
||||
live.apply_web({"tx_geometry": records})
|
||||
else:
|
||||
editor.set_records(records)
|
||||
elif source == "desktop_mode":
|
||||
mode.setCurrentText("bscan")
|
||||
else:
|
||||
widget(window._view.processing, "_gpr_range_comp_power", QDoubleSpinBox).setValue(.4)
|
||||
error.assert_called_once()
|
||||
invalidate.assert_not_called()
|
||||
self.assertEqual((window._profile.build_gui_state(), window._config.geometry(),
|
||||
live.active_mode, pages.currentIndex(), window._plots.stack.currentWidget(),
|
||||
live.revision, live.processing_settings, window._plots.required_revision,
|
||||
live.writer.path.read_bytes()), before)
|
||||
with mock.patch.object(window._plots, "draw_bscan", side_effect=ValueError("invalid plot")), \
|
||||
mock.patch.object(window._log, "show_exception") as error:
|
||||
live.apply_web({"processor_mode": "bscan", "bscan_gain": gain.value() + .1})
|
||||
error.assert_called_once()
|
||||
self.assertEqual((mode.currentText(), live.active_mode, pages.currentIndex()), ("bscan", "bscan", 1))
|
||||
self.assertEqual(live.processing_settings[live.revision]["processor_mode"], "bscan")
|
||||
self.assertNotEqual(live.writer.path.read_bytes(), before[-1])
|
||||
|
||||
def test_mode_publication_selects_replay_from_new_mode_before_changing_the_plot(self) -> None:
|
||||
window = isolated_window(self.addCleanup)
|
||||
window._pipeline.timer.stop()
|
||||
window._history.preprocessed.append(SweepCollection(1, 1, [], capture_start_ns=1, capture_end_ns=2))
|
||||
with mock.patch.object(window._pipeline.supervisor, "is_processor_running", return_value=True), \
|
||||
mock.patch.object(window._pipeline, "_result_reader"), \
|
||||
mock.patch.object(window._pipeline, "drain_results", return_value=None), \
|
||||
mock.patch.object(window._pipeline, "schedule_replay"), \
|
||||
mock.patch.object(window._plots, "draw_bscan"):
|
||||
for mode, reprocess in (("bscan", False), ("pass_through", True)):
|
||||
with self.subTest(mode=mode):
|
||||
window._live.apply_web({"processor_mode": mode})
|
||||
published = window._live.processing_settings[window._live.revision]
|
||||
self.assertEqual(published["processor_mode"], mode)
|
||||
self.assertEqual(published["reprocess_current_result"], reprocess)
|
||||
Reference in New Issue
Block a user