From 1744eb180323903f06605c9e85e6dc34648ab2ed Mon Sep 17 00:00:00 2001 From: serversdown Date: Wed, 29 Jul 2026 17:27:36 +0000 Subject: [PATCH] feat(db): persist per-channel ZC freq on insert/upsert Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01YDXjZCr4RqT2U3QvMDhgzf --- sfm/database.py | 34 +++++++++++++++++++++++++++++--- tests/test_zc_freq_columns.py | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/sfm/database.py b/sfm/database.py index 37d0bbb..ff042f9 100644 --- a/sfm/database.py +++ b/sfm/database.py @@ -415,8 +415,12 @@ class SeismoDb: sample_rate, record_type, blastware_filename, blastware_filesize, a5_pickle_filename, sidecar_filename, - device_family) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + device_family, + tran_zc_freq, vert_zc_freq, long_zc_freq, mic_zc_freq, + tran_zc_above_range, vert_zc_above_range, + long_zc_above_range, mic_zc_above_range) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, + ?, ?, ?, ?, ?, ?, ?, ?) """, ( self._new_id(), serial, key, session_id, ts, @@ -436,6 +440,14 @@ class SeismoDb: rec.get("a5_pickle_filename"), rec.get("sidecar_filename"), device_family, + pv.tran_zc_freq if pv else None, + pv.vert_zc_freq if pv else None, + pv.long_zc_freq if pv else None, + pv.mic_zc_freq if pv else None, + (1 if (pv and pv.tran_zc_above_range) else 0), + (1 if (pv and pv.vert_zc_above_range) else 0), + (1 if (pv and pv.long_zc_above_range) else 0), + (1 if (pv and pv.mic_zc_above_range) else 0), ), ) inserted += 1 @@ -477,7 +489,15 @@ class SeismoDb: blastware_filesize = ?, a5_pickle_filename = ?, sidecar_filename = ?, - device_family = COALESCE(?, device_family) + device_family = COALESCE(?, device_family), + tran_zc_freq = ?, + vert_zc_freq = ?, + long_zc_freq = ?, + mic_zc_freq = ?, + tran_zc_above_range = ?, + vert_zc_above_range = ?, + long_zc_above_range = ?, + mic_zc_above_range = ? WHERE serial = ? AND timestamp = ? """, ( @@ -497,6 +517,14 @@ class SeismoDb: rec.get("a5_pickle_filename") if rec else None, rec.get("sidecar_filename") if rec else None, device_family, + pv.tran_zc_freq if pv else None, + pv.vert_zc_freq if pv else None, + pv.long_zc_freq if pv else None, + pv.mic_zc_freq if pv else None, + (1 if (pv and pv.tran_zc_above_range) else 0), + (1 if (pv and pv.vert_zc_above_range) else 0), + (1 if (pv and pv.long_zc_above_range) else 0), + (1 if (pv and pv.mic_zc_above_range) else 0), serial, ts, ), diff --git a/tests/test_zc_freq_columns.py b/tests/test_zc_freq_columns.py index 3bdc607..1b9a456 100644 --- a/tests/test_zc_freq_columns.py +++ b/tests/test_zc_freq_columns.py @@ -85,3 +85,40 @@ def test_apply_bw_report_dict_copies_zc_freq(): assert pv.vert_zc_freq == 85.0 assert pv.tran_zc_above_range is True assert pv.mic_zc_freq == 51.0 + + +def _event_with_zc(waveform_key="01110000"): + from minimateplus.models import Event, Timestamp + ev = Event(index=0) + ev._waveform_key = bytes.fromhex(waveform_key) + ev.timestamp = Timestamp(raw=b"", flag=0x10, year=2026, unknown_byte=0, + month=6, day=25, hour=8, minute=50, second=0) + ev.record_type = "Waveform" + ev.peak_values = PeakValues( + tran=0.075, vert=0.220, long=0.045, peak_vector_sum=0.231, micl=0.01, + tran_zc_freq=100.0, vert_zc_freq=85.0, long_zc_freq=73.0, mic_zc_freq=51.0, + tran_zc_above_range=True, + ) + return ev + + +def test_insert_events_persists_zc_freq(tmp_path: Path): + db = SeismoDb(tmp_path / "seismo_relay.db") + ins, _ = db.insert_events([_event_with_zc()], serial="BE11529") + assert ins == 1 + row = db.query_events(serial="BE11529")[0] + assert row["vert_zc_freq"] == 85.0 + assert row["tran_zc_freq"] == 100.0 + assert row["tran_zc_above_range"] == 1 + assert row["vert_zc_above_range"] == 0 + assert row["mic_zc_freq"] == 51.0 + + +def test_upsert_updates_zc_freq(tmp_path: Path): + db = SeismoDb(tmp_path / "seismo_relay.db") + db.insert_events([_event_with_zc()], serial="BE11529") + ev2 = _event_with_zc() + ev2.peak_values.vert_zc_freq = 91.0 # same (serial, timestamp) → UPSERT + db.insert_events([ev2], serial="BE11529") + row = db.query_events(serial="BE11529")[0] + assert row["vert_zc_freq"] == 91.0