bscan added s11
This commit is contained in:
@@ -225,6 +225,7 @@ class NpzStore(StoreApi):
|
||||
*,
|
||||
input_index: int = 0,
|
||||
output_index: int = 0,
|
||||
channel: str = "s21",
|
||||
primary_stage: str = "preprocessed",
|
||||
) -> tuple[Path, dict[str, Any]]:
|
||||
"""Save runtime history as vna_system-compatible JSON file."""
|
||||
@@ -251,6 +252,7 @@ class NpzStore(StoreApi):
|
||||
selected_results,
|
||||
input_index=input_index,
|
||||
output_index=output_index,
|
||||
channel=channel,
|
||||
primary_stage=primary_stage,
|
||||
)
|
||||
output_path.write_text(
|
||||
@@ -267,6 +269,7 @@ class NpzStore(StoreApi):
|
||||
summary["sweep_count"] = len(payload.get("sweep_history", []))
|
||||
summary["input_index"] = int(input_index)
|
||||
summary["output_index"] = int(output_index)
|
||||
summary["channel"] = str(channel)
|
||||
summary["primary_stage"] = str(primary_stage)
|
||||
summary["output_path"] = str(output_path)
|
||||
return output_path, summary
|
||||
|
||||
@@ -21,7 +21,20 @@ class TraceRecord:
|
||||
monotonic_ns: int
|
||||
stage_index: int
|
||||
frequency_hz: np.ndarray
|
||||
s21: np.ndarray
|
||||
samples: np.ndarray
|
||||
|
||||
|
||||
def _normalize_channel(channel: str) -> str:
|
||||
normalized = str(channel).strip().lower()
|
||||
if normalized not in {"s21", "s11"}:
|
||||
raise ValueError("channel must be either 's21' or 's11'")
|
||||
return normalized
|
||||
|
||||
|
||||
def _select_trace_samples(trace: TraceData, channel: str) -> np.ndarray:
|
||||
if channel == "s11":
|
||||
return np.asarray(trace.s11, dtype=np.complex128).reshape(-1)
|
||||
return np.asarray(trace.s21, dtype=np.complex128).reshape(-1)
|
||||
|
||||
|
||||
def _pick_trace(collection: SweepCollection, input_index: int, output_index: int) -> TraceData | None:
|
||||
@@ -37,6 +50,7 @@ def _build_stage_records(
|
||||
*,
|
||||
input_index: int,
|
||||
output_index: int,
|
||||
channel: str,
|
||||
) -> list[TraceRecord]:
|
||||
records: list[TraceRecord] = []
|
||||
for stage_index, collection in enumerate(history):
|
||||
@@ -45,18 +59,18 @@ def _build_stage_records(
|
||||
continue
|
||||
|
||||
frequency_hz = np.asarray(trace.frequency_hz, dtype=np.float64).reshape(-1)
|
||||
s21 = np.asarray(trace.s21, dtype=np.complex128).reshape(-1)
|
||||
if frequency_hz.shape != s21.shape:
|
||||
samples = _select_trace_samples(trace, channel)
|
||||
if frequency_hz.shape != samples.shape:
|
||||
raise ValueError(
|
||||
f"Shape mismatch in {stage} stage for collection_id={collection.collection_id}: "
|
||||
f"freq{frequency_hz.shape} vs s21{s21.shape}"
|
||||
f"freq{frequency_hz.shape} vs {channel}{samples.shape}"
|
||||
)
|
||||
if frequency_hz.size == 0:
|
||||
continue
|
||||
if not (
|
||||
np.isfinite(frequency_hz).all()
|
||||
and np.isfinite(np.real(s21)).all()
|
||||
and np.isfinite(np.imag(s21)).all()
|
||||
and np.isfinite(np.real(samples)).all()
|
||||
and np.isfinite(np.imag(samples)).all()
|
||||
):
|
||||
raise ValueError(f"Non-finite values in {stage} stage for collection_id={collection.collection_id}")
|
||||
|
||||
@@ -67,7 +81,7 @@ def _build_stage_records(
|
||||
monotonic_ns=int(collection.monotonic_ns),
|
||||
stage_index=int(stage_index),
|
||||
frequency_hz=frequency_hz,
|
||||
s21=s21,
|
||||
samples=samples,
|
||||
)
|
||||
)
|
||||
return records
|
||||
@@ -94,6 +108,7 @@ def _build_sweep_history(
|
||||
raw_records: list[TraceRecord],
|
||||
preprocessed_records: list[TraceRecord],
|
||||
*,
|
||||
channel: str,
|
||||
primary_stage: str,
|
||||
) -> list[dict[str, Any]]:
|
||||
raw_map, raw_order = _index_by_collection_occurrence(raw_records)
|
||||
@@ -124,11 +139,11 @@ def _build_sweep_history(
|
||||
history.append(
|
||||
{
|
||||
"timestamp": timestamp_sec,
|
||||
"sweep_points": _complex_to_points(sweep_source.s21),
|
||||
"calibrated_points": _complex_to_points(calibrated_source.s21),
|
||||
"sweep_points": _complex_to_points(sweep_source.samples),
|
||||
"calibrated_points": _complex_to_points(calibrated_source.samples),
|
||||
"reference_points": [],
|
||||
"vna_config": {
|
||||
"mode": "s11",
|
||||
"mode": channel,
|
||||
"start_freq": start_freq_hz,
|
||||
"stop_freq": stop_freq_hz,
|
||||
"points": int(base.frequency_hz.size),
|
||||
@@ -178,9 +193,11 @@ def build_vna_history_payload(
|
||||
*,
|
||||
input_index: int,
|
||||
output_index: int,
|
||||
channel: str = "s21",
|
||||
primary_stage: str = "preprocessed",
|
||||
) -> dict[str, Any]:
|
||||
"""Build vna_system-compatible history JSON payload from runtime histories."""
|
||||
channel = _normalize_channel(channel)
|
||||
if primary_stage not in {"preprocessed", "raw"}:
|
||||
raise ValueError("primary_stage must be either 'preprocessed' or 'raw'")
|
||||
|
||||
@@ -189,12 +206,14 @@ def build_vna_history_payload(
|
||||
raw_history,
|
||||
input_index=input_index,
|
||||
output_index=output_index,
|
||||
channel=channel,
|
||||
)
|
||||
preprocessed_records = _build_stage_records(
|
||||
"preprocessed",
|
||||
preprocessed_history,
|
||||
input_index=input_index,
|
||||
output_index=output_index,
|
||||
channel=channel,
|
||||
)
|
||||
if not raw_records and not preprocessed_records:
|
||||
raise ValueError(
|
||||
@@ -205,6 +224,7 @@ def build_vna_history_payload(
|
||||
sweep_history = _build_sweep_history(
|
||||
raw_records,
|
||||
preprocessed_records,
|
||||
channel=channel,
|
||||
primary_stage=primary_stage,
|
||||
)
|
||||
if not sweep_history:
|
||||
@@ -217,6 +237,7 @@ def build_vna_history_payload(
|
||||
"source_snapshot_dir": "<runtime_history>",
|
||||
"input_index": int(input_index),
|
||||
"output_index": int(output_index),
|
||||
"channel": channel,
|
||||
"primary_stage": str(primary_stage),
|
||||
"raw_record_count": len(raw_records),
|
||||
"preprocessed_record_count": len(preprocessed_records),
|
||||
@@ -228,4 +249,3 @@ def build_vna_history_payload(
|
||||
payload["alignment_warning"] = alignment_warning
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
Reference in New Issue
Block a user