"""Path and naming helpers for NPZ snapshot storage.""" from __future__ import annotations from python_app.file_io import sanitize_path_component def radar_config_filename_prefix( model_name: str, sweep_start_hz: float, sweep_stop_hz: float, sweep_points: int, power_dbm: float, ) -> str: """Build a readable, filesystem-safe prefix describing the radar acquisition setup. Encodes the radar model, sweep frequency span, point count, and power so a saved dataset's name carries the configuration it was captured with. ADC-mode radars have no fixed sweep, so the point count is reported as ``adc``. """ points_token = "adc" if model_name.strip().lower() == "kamil_adc" else f"{int(sweep_points)}pts" tokens = ( model_name, _format_frequency_span(sweep_start_hz, sweep_stop_hz), points_token, f"{power_dbm:g}dBm", ) return sanitize_path_component("_".join(tokens)) def _format_frequency_span(start_hz: float, stop_hz: float) -> str: """Format a frequency span compactly, both bounds sharing the larger bound's unit.""" unit, scale = _frequency_unit(max(start_hz, stop_hz)) return f"{start_hz / scale:g}-{stop_hz / scale:g}{unit}" def _frequency_unit(hz: float) -> tuple[str, float]: """Pick the largest unit (GHz/MHz/kHz/Hz) that keeps the magnitude at or above one.""" for unit, scale in (("GHz", 1e9), ("MHz", 1e6), ("kHz", 1e3)): if hz >= scale: return unit, scale return "Hz", 1.0 def collection_dir_name(index: int, collection_id: int, monotonic_ns: int) -> str: """Build canonical collection directory name for snapshot stages.""" return f"{index:04d}_id{int(collection_id)}_ns{int(monotonic_ns)}"