Files
radar_system/python_app/tests/test_vna_history_json.py
T
2026-10-06 12:32:26 +03:00

88 lines
4.6 KiB
Python

"""JSON export keeps real stage data and never guesses across repeated sweep IDs."""
from __future__ import annotations
import unittest
import numpy as np
from python_app.models.dataset_model import ComboKey, ResultCollection, SweepCollection, TraceData
from python_app.storage.npz.vna_history_json import build_vna_history_payload
def sweep(cid: int, ns: int, value: float, window: tuple[int, int] = (0, 0)) -> SweepCollection:
trace = TraceData(
ComboKey(0, 0), np.array([1e8, 2e8]), np.full(2, value, complex),
capture_start_ns=window[0], capture_end_ns=window[1],
)
return SweepCollection(cid, ns, [trace], capture_start_ns=window[0], capture_end_ns=window[1])
def payload(raw: list[SweepCollection], pre: list[SweepCollection], **kwargs):
return build_vna_history_payload(raw, pre, [], input_index=0, output_index=0, **kwargs)
class VnaHistoryJsonTest(unittest.TestCase):
def test_missing_stage_is_empty_instead_of_fabricated(self) -> None:
for stage in ("raw", "preprocessed"):
with self.subTest(stage=stage):
raw, pre = ([sweep(1, 100, 7)], []) if stage == "raw" else ([], [sweep(1, 110, 9)])
history = payload(raw, pre)["sweep_history"]
self.assertEqual(len(history), 1)
self.assertEqual(history[0]["sweep_points"], [[7., 0.], [7., 0.]] if raw else [])
self.assertEqual(history[0]["calibrated_points"], [[9., 0.], [9., 0.]] if pre else [])
def test_dropped_stages_and_reused_ids_preserve_every_trace_once(self) -> None:
raw = [sweep(1, 100, 1, (80, 90)), sweep(1, 200, 2, (180, 190)), sweep(2, 300, 3, (280, 290))]
pre = [sweep(1, 210, 20, (180, 190)), sweep(3, 410, 40, (380, 390))]
for stage in ("raw", "preprocessed"):
with self.subTest(primary=stage):
history = payload(raw, pre, primary_stage=stage)["sweep_history"]
self.assertEqual(len(history), 4)
self.assertEqual([row["sweep_points"][0][0] if row["sweep_points"] else None for row in history], [1, 2, 3, None])
self.assertEqual([row["calibrated_points"][0][0] if row["calibrated_points"] else None for row in history], [None, 20, None, 40])
def test_conflicting_windows_are_never_paired(self) -> None:
history = payload([sweep(1, 100, 1, (80, 90))], [sweep(1, 110, 10, (81, 91))])["sweep_history"]
self.assertEqual(len(history), 2)
self.assertEqual(history[0]["calibrated_points"], [])
self.assertEqual(history[1]["sweep_points"], [])
def test_export_timestamp_uses_selected_trace_in_a_switched_collection(self) -> None:
pre = sweep(1, 200, 10, (100, 150))
pre.capture_start_ns, pre.capture_end_ns = 1, 190
history = payload([], [pre])["sweep_history"]
self.assertEqual(history[0]["timestamp"], 150 / 1e9)
def test_join_uses_collection_window_and_capture_order_not_trace_or_stage_time(self) -> None:
raw = sweep(1, 900, 1, (10, 20))
pre = sweep(1, 1000, 10, (10, 20))
pre.traces[0].capture_start_ns = 11
pre.traces[0].capture_end_ns = 19
fresh = sweep(1, 100, 2, (30, 40))
history = payload([fresh, raw], [pre])["sweep_history"]
self.assertEqual(len(history), 2)
self.assertEqual(history[0]["sweep_points"], [[1., 0.], [1., 0.]])
self.assertEqual(history[0]["calibrated_points"], [[10., 0.], [10., 0.]])
self.assertEqual(history[0]["timestamp"], 19 / 1e9)
self.assertEqual(history[1]["calibrated_points"], [])
def test_reordered_results_do_not_produce_an_alignment_warning(self) -> None:
pre = [sweep(1, 110, 1, (10, 20)), sweep(2, 210, 2, (30, 40))]
result = [ResultCollection(2, 999, capture_start_ns=30, capture_end_ns=40),
ResultCollection(1, 888, capture_start_ns=10, capture_end_ns=20)]
exported = build_vna_history_payload([], pre, result, input_index=0, output_index=0)
self.assertNotIn("alignment_warning", exported)
def test_selected_combo_with_many_distinct_ids_has_no_lost_or_duplicated_records(self) -> None:
raw = [sweep(cid, cid * 100, cid, (cid * 100 - 20, cid * 100 - 10)) for cid in range(1, 2001)]
pre = [sweep(cid, cid * 100 + 10, cid * 2, (cid * 100 - 20, cid * 100 - 10)) for cid in range(1, 2001)]
history = payload(raw, pre)["sweep_history"]
self.assertEqual(len(history), 2000)
self.assertEqual(history[-1]["sweep_points"][0][0], 2000)
self.assertEqual(history[-1]["calibrated_points"][0][0], 4000)
if __name__ == "__main__":
unittest.main()