new kamil adc
This commit is contained in:
@@ -7,6 +7,10 @@ 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_model import ComboModel, RunConfigModel
|
||||
|
||||
@@ -15,33 +19,30 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
def build_kamil_adc_neutral_s21_sets(
|
||||
config: RunConfigModel,
|
||||
point_count: int,
|
||||
) -> tuple[SweepCollection, SweepCollection]:
|
||||
"""Build neutral S21 calibration/reference collections for the Kamil ADC radar.
|
||||
|
||||
The calibration uses unit S21 (1+0j) and the reference uses zero S21 across
|
||||
every configured combo, so applying them in the preprocessing pipeline leaves
|
||||
the input S21 unchanged. Returns the ``(calibration, reference)`` collections.
|
||||
the input S21 unchanged. The frequency axis is the exact acquisition grid
|
||||
(``radar.kamil_adc.band``), so neutral sets line up sample-for-sample with
|
||||
live sweeps. Returns the ``(calibration, reference)`` collections.
|
||||
"""
|
||||
if not config.is_kamil_adc:
|
||||
raise ValueError("Neutral Kamil ADC sets require radar.model='kamil_adc'")
|
||||
|
||||
points = int(point_count)
|
||||
if points <= 0:
|
||||
raise ValueError("Kamil ADC neutral set point count must be > 0")
|
||||
|
||||
combos = list(config.combos)
|
||||
if not combos:
|
||||
combos = RunConfigModel.build_full_combos(config.input_switch.positions, config.output_switch.positions)
|
||||
combos = RunConfigModel.build_full_combos(
|
||||
config.input_switch.positions, config.output_switch.positions
|
||||
)
|
||||
if not combos:
|
||||
raise ValueError("Kamil ADC neutral sets require at least one switch combo")
|
||||
|
||||
frequency_hz = np.linspace(
|
||||
float(config.radar.sweep.start_hz),
|
||||
float(config.radar.sweep.stop_hz),
|
||||
points,
|
||||
dtype=np.float32,
|
||||
)
|
||||
# Single source of truth for the axis: the same grid the processor emits.
|
||||
processor = KamilAdcSweepProcessor(KamilAdcProcessingParams.from_kamil_model(config.radar.kamil_adc))
|
||||
frequency_hz = processor.grid_hz
|
||||
|
||||
now_ns = time.monotonic_ns()
|
||||
calibration = _neutral_collection(
|
||||
combos=combos,
|
||||
@@ -55,7 +56,9 @@ def build_kamil_adc_neutral_s21_sets(
|
||||
s21_value=np.complex64(0.0 + 0.0j),
|
||||
monotonic_ns=now_ns,
|
||||
)
|
||||
logger.info("Built neutral Kamil ADC S21 sets: combos=%d points=%d", len(combos), points)
|
||||
logger.info(
|
||||
"Built neutral Kamil ADC S21 sets: combos=%d points=%d", len(combos), int(frequency_hz.size)
|
||||
)
|
||||
return calibration, reference
|
||||
|
||||
|
||||
@@ -66,17 +69,16 @@ def _neutral_collection(
|
||||
s21_value: np.complex64,
|
||||
monotonic_ns: int,
|
||||
) -> SweepCollection:
|
||||
traces = []
|
||||
for combo in combos:
|
||||
point_count = int(frequency_hz.size)
|
||||
traces.append(
|
||||
TraceData(
|
||||
combo=ComboKey(input=int(combo.input), output=int(combo.output)),
|
||||
frequency_hz=frequency_hz.copy(),
|
||||
s11=np.zeros(point_count, dtype=np.complex64),
|
||||
s21=np.full(point_count, s21_value, dtype=np.complex64),
|
||||
)
|
||||
point_count = int(frequency_hz.size)
|
||||
traces = [
|
||||
TraceData(
|
||||
combo=ComboKey(input=int(combo.input), output=int(combo.output)),
|
||||
frequency_hz=frequency_hz.copy(),
|
||||
s11=np.zeros(point_count, dtype=np.complex64),
|
||||
s21=np.full(point_count, s21_value, dtype=np.complex64),
|
||||
)
|
||||
for combo in combos
|
||||
]
|
||||
return SweepCollection(
|
||||
collection_id=1,
|
||||
monotonic_ns=monotonic_ns,
|
||||
|
||||
@@ -115,28 +115,8 @@ class MultiRadarSequentialCaptureSession:
|
||||
self._output_switch = None
|
||||
else:
|
||||
self._radar = create_single_radar_service(base_config)
|
||||
self._input_switch = SwitchService(
|
||||
name=base_config.input_switch.name,
|
||||
positions=base_config.input_switch.positions,
|
||||
default_position=base_config.input_switch.default_position,
|
||||
mode=base_config.input_switch.driver_mode,
|
||||
driver=base_config.input_switch.driver,
|
||||
gpio_chip=base_config.input_switch.gpio_chip,
|
||||
pin_a=base_config.input_switch.pin_a,
|
||||
pin_b=base_config.input_switch.pin_b,
|
||||
invert_logic=base_config.input_switch.invert_logic,
|
||||
)
|
||||
self._output_switch = SwitchService(
|
||||
name=base_config.output_switch.name,
|
||||
positions=base_config.output_switch.positions,
|
||||
default_position=base_config.output_switch.default_position,
|
||||
mode=base_config.output_switch.driver_mode,
|
||||
driver=base_config.output_switch.driver,
|
||||
gpio_chip=base_config.output_switch.gpio_chip,
|
||||
pin_a=base_config.output_switch.pin_a,
|
||||
pin_b=base_config.output_switch.pin_b,
|
||||
invert_logic=base_config.output_switch.invert_logic,
|
||||
)
|
||||
self._input_switch = SwitchService.from_model(base_config.input_switch)
|
||||
self._output_switch = SwitchService.from_model(base_config.output_switch)
|
||||
|
||||
@property
|
||||
def kind(self) -> str:
|
||||
|
||||
@@ -91,28 +91,8 @@ class SequentialCaptureSession:
|
||||
self._output_switch = None
|
||||
else:
|
||||
self._radar = create_single_radar_service(config)
|
||||
self._input_switch = SwitchService(
|
||||
name=config.input_switch.name,
|
||||
positions=config.input_switch.positions,
|
||||
default_position=config.input_switch.default_position,
|
||||
mode=config.input_switch.driver_mode,
|
||||
driver=config.input_switch.driver,
|
||||
gpio_chip=config.input_switch.gpio_chip,
|
||||
pin_a=config.input_switch.pin_a,
|
||||
pin_b=config.input_switch.pin_b,
|
||||
invert_logic=config.input_switch.invert_logic,
|
||||
)
|
||||
self._output_switch = SwitchService(
|
||||
name=config.output_switch.name,
|
||||
positions=config.output_switch.positions,
|
||||
default_position=config.output_switch.default_position,
|
||||
mode=config.output_switch.driver_mode,
|
||||
driver=config.output_switch.driver,
|
||||
gpio_chip=config.output_switch.gpio_chip,
|
||||
pin_a=config.output_switch.pin_a,
|
||||
pin_b=config.output_switch.pin_b,
|
||||
invert_logic=config.output_switch.invert_logic,
|
||||
)
|
||||
self._input_switch = SwitchService.from_model(config.input_switch)
|
||||
self._output_switch = SwitchService.from_model(config.output_switch)
|
||||
|
||||
@property
|
||||
def kind(self) -> str:
|
||||
|
||||
Reference in New Issue
Block a user