91 lines
3.3 KiB
Python
91 lines
3.3 KiB
Python
"""CLI to create neutral S21 preprocess sets for a profile (headless).
|
|
|
|
Mirrors the GUI's "Create neutral sets" button: builds calibration = 1+0j and
|
|
reference = 0 collections for every combo of the profile and saves them under
|
|
the profile's radar key, so the data_preprocessor becomes a bit-exact
|
|
pass-through. Needed for replay profiles whose recorded data is already
|
|
preprocessed (see run_config_examples/run_config_replay_vna.example.json).
|
|
|
|
Usage:
|
|
python -m python_app.scripts.create_neutral_preprocess_sets \
|
|
--config run_config_examples/run_config_replay_vna.example.json \
|
|
[--set-name neutral_replay] [--force]
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from python_app.models.run_config_model import RunConfigModel
|
|
from python_app.storage.npz_store import NpzStore, radar_key_from_config
|
|
from python_app.workflows.kamil_adc_neutral_preprocess import (
|
|
build_neutral_s21_sets,
|
|
supports_neutral_preprocess_sets,
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def main() -> int:
|
|
"""Create and save the neutral S21 calibration/reference pair."""
|
|
parser = argparse.ArgumentParser(description="Create neutral S21 preprocess sets")
|
|
parser.add_argument("--config", required=True, type=Path, help="Path to a run_config profile")
|
|
parser.add_argument("--set-name", default="neutral_replay", help="Name for both saved sets")
|
|
parser.add_argument(
|
|
"--force", action="store_true", help="Overwrite the sets if they already exist"
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(levelname)s %(name)s: %(message)s")
|
|
|
|
config = RunConfigModel.load_from_path(args.config)
|
|
config.ensure_combos()
|
|
if not supports_neutral_preprocess_sets(config):
|
|
raise RuntimeError(
|
|
"Neutral S21 sets are available only for kamil_adc and librevna_multi"
|
|
)
|
|
|
|
radar_key = radar_key_from_config(
|
|
model_name=config.radar.model,
|
|
serial=config.radar.serial,
|
|
sweep_start_hz=config.radar.sweep.start_hz,
|
|
sweep_stop_hz=config.radar.sweep.stop_hz,
|
|
sweep_points=config.radar.sweep.points,
|
|
ifbw_hz=config.radar.sweep.if_bandwidth_hz,
|
|
power_dbm=config.radar.sweep.power_dbm,
|
|
extra_serials=config.radar_key_extra_parts() or None,
|
|
)
|
|
store = NpzStore(PROJECT_ROOT / "python_app/data")
|
|
|
|
existing = [
|
|
kind
|
|
for kind in ("s21_calibration", "s21_reference")
|
|
if args.set_name in store.list_sets(kind, radar_key)
|
|
]
|
|
if existing and not args.force:
|
|
logger.info(
|
|
"Sets '%s' already exist for %s (radar_key=%s); nothing to do (use --force to overwrite).",
|
|
args.set_name, ", ".join(existing), radar_key,
|
|
)
|
|
return 0
|
|
|
|
calibration, reference = build_neutral_s21_sets(config)
|
|
store.save_set("s21_calibration", radar_key, args.set_name, calibration)
|
|
store.save_set("s21_reference", radar_key, args.set_name, reference)
|
|
logger.info(
|
|
"Neutral S21 sets saved: set=%s, radar_key=%s, combos=%d, points=%d",
|
|
args.set_name,
|
|
radar_key,
|
|
len(calibration.traces),
|
|
int(calibration.traces[0].frequency_hz.size),
|
|
)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|