Rework radar system
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""Embedded preprocess metadata and compatibility with older NPZ sets."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
from python_app.models.dataset_model import ComboKey, SweepCollection, TraceData
|
||||
from python_app.storage.npz.store import NpzStore
|
||||
|
||||
|
||||
class SetMetadataTest(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
temporary = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(temporary.cleanup)
|
||||
self.root = Path(temporary.name)
|
||||
self.store = NpzStore(self.root)
|
||||
self.kind = "s21_object_calibration"
|
||||
self.collection = SweepCollection(7, 100, [TraceData(
|
||||
ComboKey(2, 3), np.array([1e9, 2e9], dtype=np.float32),
|
||||
np.array([1 + 2j, 3 - 4j], dtype=np.complex64),
|
||||
capture_start_ns=80, capture_end_ns=90,
|
||||
)], capture_start_ns=80, capture_end_ns=90)
|
||||
self.metadata = {"radar_key": "radar", "geometry": [{"input_pos": 2, "x": 0.1}],
|
||||
"through": {"name": "through", "hash": "abc"}, "collection_id": "user value"}
|
||||
self.store.save_set(self.kind, "radar", "object", self.collection, metadata=self.metadata)
|
||||
self.archive = self.root / self.kind / "radar/object.npz"
|
||||
self.sidecar = self.archive.with_suffix(".json")
|
||||
|
||||
|
||||
def test_metadata_and_collection_round_trip_through_generic_set_api(self) -> None:
|
||||
loaded, metadata = self.store.load_set_with_metadata(self.kind, "radar", "object")
|
||||
self.assertEqual(metadata, self.metadata)
|
||||
self.assertEqual((loaded.collection_id, loaded.monotonic_ns), (7, 100))
|
||||
self.assertEqual((loaded.capture_start_ns, loaded.capture_end_ns), (80, 90))
|
||||
self.assertEqual((loaded.traces[0].capture_start_ns, loaded.traces[0].capture_end_ns), (80, 90))
|
||||
np.testing.assert_array_equal(loaded.traces[0].s21, self.collection.traces[0].s21)
|
||||
np.testing.assert_array_equal(loaded.traces[0].frequency_hz, self.collection.traces[0].frequency_hz)
|
||||
self.assertEqual(self.store.load_set(self.kind, "radar", "object").collection_id, 7)
|
||||
self.assertEqual(self.store.list_sets(self.kind, "radar"), ["object"])
|
||||
self.assertTrue(self.store.has_combo_coverage(self.kind, "radar", "object", [ComboKey(2, 3)]))
|
||||
self.assertFalse(self.store.has_combo_coverage(self.kind, "radar", "object", [ComboKey(0, 0)]))
|
||||
|
||||
|
||||
def test_embedded_metadata_is_authoritative_when_sidecar_is_stale_or_missing(self) -> None:
|
||||
for sidecar in ('{"metadata": {"radar_key": "wrong"}}', "broken JSON", None):
|
||||
with self.subTest(sidecar=sidecar):
|
||||
if sidecar is None:
|
||||
self.sidecar.unlink()
|
||||
else:
|
||||
self.sidecar.write_text(sidecar, encoding="utf-8")
|
||||
_, metadata = self.store.load_set_with_metadata(self.kind, "radar", "object")
|
||||
self.assertEqual(metadata, self.metadata)
|
||||
|
||||
|
||||
def test_old_sets_without_user_metadata_load_with_empty_dict(self) -> None:
|
||||
with np.load(self.archive, allow_pickle=False) as stored:
|
||||
arrays = {key: stored[key] for key in stored.files if key != "metadata_json"}
|
||||
envelope = json.loads(self.sidecar.read_text(encoding="utf-8"))
|
||||
del envelope["metadata"]
|
||||
self.sidecar.write_text(json.dumps(envelope), encoding="utf-8")
|
||||
for embedded in (True, False):
|
||||
with self.subTest(embedded=embedded):
|
||||
payload = dict(arrays)
|
||||
if embedded:
|
||||
payload["metadata_json"] = np.asarray(json.dumps(envelope))
|
||||
np.savez(self.archive, **payload)
|
||||
collection, metadata = self.store.load_set_with_metadata(self.kind, "radar", "object")
|
||||
self.assertEqual(metadata, {})
|
||||
np.testing.assert_array_equal(collection.traces[0].s21, self.collection.traces[0].s21)
|
||||
|
||||
|
||||
def test_invalid_metadata_cannot_overwrite_saved_set(self) -> None:
|
||||
before = (self.archive.read_bytes(), self.sidecar.read_bytes())
|
||||
for metadata in ({"value": float("nan")}, {"value": [float("inf")]}, {"value": object()}):
|
||||
with self.subTest(metadata=metadata), self.assertRaises((TypeError, ValueError)):
|
||||
self.store.save_set(self.kind, "radar", "object", self.collection, metadata=metadata)
|
||||
self.assertEqual((self.archive.read_bytes(), self.sidecar.read_bytes()), before)
|
||||
|
||||
Reference in New Issue
Block a user