Rework radar system
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
"""Neutral S21 bundles: unit through-calibration and zero reference.
|
||||
|
||||
Applying these sets leaves measurements unchanged and satisfies pipeline asset
|
||||
validation before physical calibration is available. The shortcut is enabled for
|
||||
verified frequency axes: Kamil ADC, multi-device LibreVNA and single-device mock.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
|
||||
from python_app.hardware_full.kamil_adc import (
|
||||
KamilAdcProcessingParams,
|
||||
KamilAdcSweepProcessor,
|
||||
)
|
||||
from python_app.models.dataset_model import ComboKey, SweepCollection, TraceData
|
||||
from python_app.models.run_config_schema import ComboModel, RunConfigModel
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def supports_neutral_preprocess_sets(config: RunConfigModel) -> bool:
|
||||
"""Enable the shortcut only when the emitted frequency grid is verified."""
|
||||
return bool(config.is_kamil_adc or config.is_multi_device or (
|
||||
config.radar.model == RunConfigModel.LIBREVNA_MODEL and config.radar.driver_mode == "mock"
|
||||
))
|
||||
|
||||
|
||||
def neutral_frequency_grid_hz(config: RunConfigModel) -> np.ndarray:
|
||||
"""Derive the neutral axis; the preprocessor verifies it against measured data."""
|
||||
if config.is_kamil_adc:
|
||||
# Single source of truth for the axis: the same grid the processor emits.
|
||||
processor = KamilAdcSweepProcessor(
|
||||
KamilAdcProcessingParams.from_kamil_model(config.radar.kamil_adc)
|
||||
)
|
||||
return processor.grid_hz
|
||||
|
||||
points = int(config.radar.sweep.points)
|
||||
if points < 1:
|
||||
raise ValueError("Neutral sets require radar.sweep.points >= 1")
|
||||
# The single/multi-device services and mock use this same linspace.
|
||||
return np.linspace(
|
||||
float(config.radar.sweep.start_hz),
|
||||
float(config.radar.sweep.stop_hz),
|
||||
points,
|
||||
dtype=np.float32,
|
||||
)
|
||||
|
||||
|
||||
def build_neutral_s21_sets(
|
||||
config: RunConfigModel,
|
||||
) -> tuple[SweepCollection, SweepCollection]:
|
||||
"""Build neutral S21 calibration/reference collections for the active radar.
|
||||
|
||||
Covers every combo in the effective matrix, so a matrix radar widened by real
|
||||
switches gets a neutral pair for all of its positions and the preprocessor's
|
||||
``validate_combos()`` is satisfied. Returns ``(calibration, reference)``.
|
||||
"""
|
||||
combos = list(config.combos)
|
||||
if not combos:
|
||||
combos = config.build_runtime_combos()
|
||||
if not combos:
|
||||
raise ValueError("Neutral sets require at least one switch combo")
|
||||
|
||||
frequency_hz = neutral_frequency_grid_hz(config)
|
||||
|
||||
now_ns = time.monotonic_ns()
|
||||
calibration = _neutral_collection(
|
||||
combos=combos,
|
||||
frequency_hz=frequency_hz,
|
||||
s21_value=np.complex64(1.0 + 0.0j),
|
||||
monotonic_ns=now_ns,
|
||||
)
|
||||
reference = _neutral_collection(
|
||||
combos=combos,
|
||||
frequency_hz=frequency_hz,
|
||||
s21_value=np.complex64(0.0 + 0.0j),
|
||||
monotonic_ns=now_ns,
|
||||
)
|
||||
logger.info(
|
||||
"Built neutral S21 sets: model=%s combos=%d points=%d",
|
||||
config.radar.model,
|
||||
len(combos),
|
||||
int(frequency_hz.size),
|
||||
)
|
||||
return calibration, reference
|
||||
|
||||
|
||||
def _neutral_collection(
|
||||
*,
|
||||
combos: list[ComboModel],
|
||||
frequency_hz: np.ndarray,
|
||||
s21_value: np.complex64,
|
||||
monotonic_ns: int,
|
||||
) -> SweepCollection:
|
||||
point_count = int(frequency_hz.size)
|
||||
traces = [
|
||||
TraceData(
|
||||
combo=ComboKey(input=int(combo.input), output=int(combo.output)),
|
||||
frequency_hz=frequency_hz.copy(),
|
||||
s21=np.full(point_count, s21_value, dtype=np.complex64),
|
||||
)
|
||||
for combo in combos
|
||||
]
|
||||
return SweepCollection(
|
||||
collection_id=1,
|
||||
monotonic_ns=monotonic_ns,
|
||||
traces=traces,
|
||||
capture_start_ns=monotonic_ns,
|
||||
capture_end_ns=monotonic_ns,
|
||||
)
|
||||
Reference in New Issue
Block a user