UI updates

This commit is contained in:
Ayzen
2026-04-01 20:21:16 +03:00
parent 4abc95c372
commit 669205d8f8
43 changed files with 2055 additions and 973 deletions
+79 -24
View File
@@ -176,30 +176,6 @@ class NpzStore(StoreApi):
save_trace_history_numpy(snapshot_dir / "preprocessed", selected_preprocessed)
save_result_history_numpy(snapshot_dir / "results", selected_results)
(snapshot_dir / "manifest.json").write_text(
json.dumps(
{
"format": "numpy-directory-v1",
"selection_mode": selection_summary["selection_mode"],
"anchor_stage": selection_summary.get("anchor_stage", "unknown"),
"selected_collection_ids": selection_summary["selected_collection_ids"],
"aligned_key_count": int(selection_summary.get("aligned_key_count", 0)),
"raw_missing_count": int(selection_summary.get("raw_missing_count", 0)),
"preprocessed_missing_count": int(selection_summary.get("preprocessed_missing_count", 0)),
"result_missing_count": int(selection_summary.get("result_missing_count", 0)),
"raw_collections": len(selected_raw),
"preprocessed_collections": len(selected_preprocessed),
"result_collections": len(selected_results),
"last_n_requested": int(last_n),
"raw_history_size": len(raw_history),
"preprocessed_history_size": len(preprocessed_history),
"result_history_size": len(result_history),
},
indent=2,
),
encoding="utf-8",
)
if selection_summary.get("anchor_stage") == "results":
expected = min(int(last_n), len(result_history))
if len(selected_results) != expected:
@@ -211,6 +187,7 @@ class NpzStore(StoreApi):
selection_summary["raw_count"] = len(selected_raw)
selection_summary["preprocessed_count"] = len(selected_preprocessed)
selection_summary["result_count"] = len(selected_results)
selection_summary["snapshot_stem"] = snapshot_stem
selection_summary["snapshot_dir"] = str(snapshot_dir)
return snapshot_dir, selection_summary
@@ -271,9 +248,87 @@ class NpzStore(StoreApi):
summary["output_index"] = int(output_index)
summary["channel"] = str(channel)
summary["primary_stage"] = str(primary_stage)
summary["output_stem"] = output_stem
summary["output_path"] = str(output_path)
return output_path, summary
def save_runtime_vna_history_json_batch(
self,
output_root_dir: Path,
output_name: str,
raw_history: list[SweepCollection],
preprocessed_history: list[SweepCollection],
result_history: list[ResultCollection],
last_n: int,
*,
channel: str = "s21",
primary_stage: str = "preprocessed",
) -> tuple[list[Path], dict[str, Any]]:
"""Save one runtime VNA-history JSON per available combo."""
if last_n <= 0:
raise ValueError("last_n must be > 0")
output_stem = output_name.strip() or datetime.utcnow().strftime("snapshot_%Y%m%d_%H%M%S")
output_stem = sanitize_path_component(output_stem)
output_root_dir.mkdir(parents=True, exist_ok=True)
selected_raw, selected_preprocessed, selected_results, selection_summary = select_aligned_histories(
raw_history,
preprocessed_history,
result_history,
last_n,
)
combos = sorted(
{
(int(trace.combo.input_pos), int(trace.combo.output_pos))
for collection in [*selected_raw, *selected_preprocessed]
for trace in collection.traces
}
)
if not combos:
raise ValueError("No matching raw/preprocessed traces were found in runtime history for any combo.")
output_paths: list[Path] = []
payloads: list[dict[str, Any]] = []
for input_index, output_index in combos:
output_path = output_root_dir / (
f"{output_stem}_i{input_index}_o{output_index}_{channel}_vna_bscan_history.json"
)
if output_path.exists():
raise FileExistsError(f"Output JSON file already exists: {output_path}")
payloads.append(
build_vna_history_payload(
selected_raw,
selected_preprocessed,
selected_results,
input_index=input_index,
output_index=output_index,
channel=channel,
primary_stage=primary_stage,
)
)
output_paths.append(output_path)
for output_path, payload in zip(output_paths, payloads, strict=True):
output_path.write_text(
json.dumps(payload, ensure_ascii=False, indent=2),
encoding="utf-8",
)
summary: dict[str, Any] = dict(selection_summary)
summary["raw_count"] = len(selected_raw)
summary["preprocessed_count"] = len(selected_preprocessed)
summary["result_count"] = len(selected_results)
summary["preprocessed_record_count"] = int(sum(int(payload.get("preprocessed_record_count", 0)) for payload in payloads))
summary["combo_count"] = len(combos)
summary["combos"] = [list(combo) for combo in combos]
summary["channel"] = str(channel)
summary["primary_stage"] = str(primary_stage)
summary["output_stem"] = output_stem
summary["output_paths"] = [str(path) for path in output_paths]
return output_paths, summary
def _set_dir(self, kind: str, radar_key: str) -> Path:
"""Return directory for set kind and radar key."""
return self._root_dir / kind / radar_key