diff --git a/sfm/database.py b/sfm/database.py index 8ce35d7..464c2b5 100644 --- a/sfm/database.py +++ b/sfm/database.py @@ -426,9 +426,11 @@ class SeismoDb: 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) + long_zc_above_range, mic_zc_above_range, + shape_crest_factor, shape_near_peak_count, + shape_sample_count, shape_axis) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, - ?, ?, ?, ?, ?, ?, ?, ?) + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( self._new_id(), serial, key, session_id, ts, @@ -456,6 +458,10 @@ class SeismoDb: (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), + rec.get("shape_crest_factor"), + rec.get("shape_near_peak_count"), + rec.get("shape_sample_count"), + rec.get("shape_axis"), ), ) inserted += 1 @@ -505,7 +511,11 @@ class SeismoDb: tran_zc_above_range = ?, vert_zc_above_range = ?, long_zc_above_range = ?, - mic_zc_above_range = ? + mic_zc_above_range = ?, + shape_crest_factor = COALESCE(?, shape_crest_factor), + shape_near_peak_count = COALESCE(?, shape_near_peak_count), + shape_sample_count = COALESCE(?, shape_sample_count), + shape_axis = COALESCE(?, shape_axis) WHERE serial = ? AND timestamp = ? """, ( @@ -533,6 +543,10 @@ class SeismoDb: (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), + rec.get("shape_crest_factor") if rec else None, + rec.get("shape_near_peak_count") if rec else None, + rec.get("shape_sample_count") if rec else None, + rec.get("shape_axis") if rec else None, serial, ts, ), diff --git a/tests/test_insert_events_shape.py b/tests/test_insert_events_shape.py new file mode 100644 index 0000000..63e90a6 --- /dev/null +++ b/tests/test_insert_events_shape.py @@ -0,0 +1,69 @@ +from __future__ import annotations +from pathlib import Path + +from sfm.database import SeismoDb +from minimateplus.models import Event, Timestamp, PeakValues + + +def _event(waveform_key="0111abcd"): + 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) + return ev + + +def test_insert_stores_shape_from_record(tmp_path: Path): + db = SeismoDb(tmp_path / "s.db") + ev = _event() + rec = {ev._waveform_key.hex(): { + "filename": "F.CE0W", "filesize": 10, + "shape_crest_factor": 34.0, "shape_near_peak_count": 3, + "shape_sample_count": 1024, "shape_axis": "Long"}} + db.insert_events([ev], serial="BE1", waveform_records=rec) + row = db.query_events(serial="BE1")[0] + assert row["shape_crest_factor"] == 34.0 + assert row["shape_near_peak_count"] == 3 + assert row["shape_axis"] == "Long" + + +def test_upsert_refreshes_shape_from_record(tmp_path: Path): + db = SeismoDb(tmp_path / "s.db") + ev = _event() + rec1 = {ev._waveform_key.hex(): { + "shape_crest_factor": 10.0, "shape_near_peak_count": 1, + "shape_sample_count": 512, "shape_axis": "Tran"}} + db.insert_events([ev], serial="BE1", waveform_records=rec1) + + ev2 = _event() + rec2 = {ev2._waveform_key.hex(): { + "shape_crest_factor": 22.5, "shape_near_peak_count": 7, + "shape_sample_count": 2048, "shape_axis": "Vert"}} + db.insert_events([ev2], serial="BE1", waveform_records=rec2) + + row = db.query_events(serial="BE1")[0] + assert row["shape_crest_factor"] == 22.5 + assert row["shape_near_peak_count"] == 7 + assert row["shape_sample_count"] == 2048 + assert row["shape_axis"] == "Vert" + + +def test_upsert_preserves_shape_when_record_missing(tmp_path: Path): + db = SeismoDb(tmp_path / "s.db") + ev = _event() + rec1 = {ev._waveform_key.hex(): { + "shape_crest_factor": 10.0, "shape_near_peak_count": 1, + "shape_sample_count": 512, "shape_axis": "Tran"}} + db.insert_events([ev], serial="BE1", waveform_records=rec1) + + ev2 = _event() # re-import with no waveform_records (e.g. sample missing) + db.insert_events([ev2], serial="BE1") + + row = db.query_events(serial="BE1")[0] + assert row["shape_crest_factor"] == 10.0 + assert row["shape_near_peak_count"] == 1 + assert row["shape_sample_count"] == 512 + assert row["shape_axis"] == "Tran"