"""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_pos: int output_pos: int @dataclass(slots=True) class TraceData: """One frequency-domain S21 trace for a specific switch combination.""" combo: ComboKey frequency_hz: np.ndarray s21: np.ndarray @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) @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 collection_payloads: list[ResultPayload] = field(default_factory=list) blocks: list[ResultBlock] = field(default_factory=list)