Files
overwatch/simulation/tools/export_replay_iq.py
thebadking 34d4406611
Some checks failed
AERIS-10 CI / Python Lint + Tests (push) Has been cancelled
AERIS-10 CI / MCU Firmware Tests (push) Has been cancelled
AERIS-10 CI / FPGA Regression (push) Has been cancelled
AERIS-10 CI / Cross-Layer Contract Tests (push) Has been cancelled
Initial commit.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 07:49:17 +00:00

46 lines
2.0 KiB
Python

"""One-off exporter: PLFM GUI I/Q CSV -> compact XZ binary replay artifact.
Run from the repository root:
.venv/bin/python tools/export_replay_iq.py
Reads `src/defense_sim/radar/data/plfm_gui_samples.csv` (bundled copy of the
upstream GUI `test_radar_data.csv`) and writes
`src/defense_sim/radar/data/plfm_gui_samples.iq.xz`: four int16 planes
(LONG I, SHORT I, LONG Q, SHORT Q), chirp-major x sample-index-minor, XZ
preset 9. Row metadata is not stored because the grid is dense and ordered
(timestamp_ns = 2 * (chirp*512 + sample)); `magnitude_squared` is not stored
because it does not equal I^2 + Q^2 in most rows of the source file
(15,515 of 16,384 mismatch; verified at export time).
"""
import lzma
import numpy as np
def main():
path = "src/defense_sim/radar/data/plfm_gui_samples.csv"
rows = [line.strip().split(",") for line in open(path)][1:]
groups = []
for kind in ("LONG", "SHORT"):
selected = [r for r in rows if r[2] == kind]
chirps = sorted({int(r[1]) for r in selected})
size = max(int(r[3]) for r in selected) + 1
plane = np.zeros((len(chirps), size), np.complex128)
index = {c: i for i, c in enumerate(chirps)}
for r in selected:
plane[index[int(r[1])], int(r[3])] = complex(float(r[4]), float(r[5]))
groups.append(plane)
# magnitude_squared integrity check: the source file's column is not I^2+Q^2.
bad = sum(1 for r in rows if float(r[6]) != (float(r[4])**2 + float(r[5])**2))
print(f"magnitude_squared mismatches: {bad} of {len(rows)}")
planes = [np.round(plane.real).astype(np.int16) for plane in groups]
planes += [np.round(plane.imag).astype(np.int16) for plane in groups]
blob = b"".join(p.tobytes() for p in planes)
out = "src/defense_sim/radar/data/plfm_gui_samples.iq.xz"
with open(out, "wb") as stream:
stream.write(lzma.compress(blob, preset=9))
print(f"wrote {out}: {len(lzma.compress(blob, preset=9))} bytes from {len(blob)} raw")
if __name__ == "__main__":
main()