98 lines
3.0 KiB
Python
98 lines
3.0 KiB
Python
"""Data models for sweep and processing payload collections."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
import numpy as np
|
|
|
|
|
|
def _empty_f32_array() -> np.ndarray:
|
|
"""Return empty float32 array used by payload defaults."""
|
|
return np.array([], dtype=np.float32)
|
|
|
|
|
|
def _empty_c64_array() -> np.ndarray:
|
|
"""Return empty complex64 array used by payload defaults."""
|
|
return np.array([], dtype=np.complex64)
|
|
|
|
|
|
def _empty_f32_matrix() -> np.ndarray:
|
|
"""Return empty 2D float32 matrix used by payload defaults."""
|
|
return np.zeros((0, 0), dtype=np.float32)
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class ComboKey:
|
|
"""Switch combination key: input position + output position."""
|
|
|
|
input: int
|
|
output: int
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class TraceData:
|
|
"""One frequency-domain trace set for a specific switch combination.
|
|
|
|
``capture_start_ns``/``capture_end_ns`` bound the monotonic window in which
|
|
THIS trace's sweep was measured, excluding the switch drive and settling that
|
|
preceded it. In switched modes a collection is assembled combo by combo over
|
|
many milliseconds, so the collection-level window says nothing about when any
|
|
individual combo was measured — these do. Zero on both means the producer did
|
|
not report per-trace timing.
|
|
"""
|
|
|
|
combo: ComboKey
|
|
frequency_hz: np.ndarray
|
|
s11: np.ndarray
|
|
s21: np.ndarray
|
|
capture_start_ns: int = 0
|
|
capture_end_ns: int = 0
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class SweepCollection:
|
|
"""Raw or preprocessed collection containing multiple combo traces."""
|
|
|
|
collection_id: int
|
|
monotonic_ns: int
|
|
traces: list[TraceData] = field(default_factory=list)
|
|
capture_start_ns: int = 0
|
|
capture_end_ns: int = 0
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class ResultPayload:
|
|
"""Processed payload item (trace-like or scalar) produced by processor stage."""
|
|
|
|
processing_name: str
|
|
kind: int
|
|
frequency_hz: np.ndarray = field(default_factory=_empty_f32_array)
|
|
trace: np.ndarray = field(default_factory=_empty_c64_array)
|
|
scalar_value: float = 0.0
|
|
image_x_axis: np.ndarray = field(default_factory=_empty_f32_array)
|
|
image_y_axis: np.ndarray = field(default_factory=_empty_f32_array)
|
|
image: np.ndarray = field(default_factory=_empty_f32_matrix)
|
|
table: np.ndarray = field(default_factory=_empty_f32_matrix)
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class ResultBlock:
|
|
"""Result payload block grouped by one switch combination."""
|
|
|
|
combo: ComboKey
|
|
payloads: list[ResultPayload] = field(default_factory=list)
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class ResultCollection:
|
|
"""Collection of processed payload blocks for one acquisition cycle."""
|
|
|
|
collection_id: int
|
|
monotonic_ns: int
|
|
# Wall-clock nanoseconds spent by the data_processor on `process_collection`
|
|
# for this collection. Zero means the producer did not report a measurement.
|
|
processing_duration_ns: int = 0
|
|
collection_payloads: list[ResultPayload] = field(default_factory=list)
|
|
blocks: list[ResultBlock] = field(default_factory=list)
|