A real trigger is recorded twice — as a triggered waveform (stamped at the trigger instant) and inside the scheduled histogram whose interval contains it (stamped at the 7am/7pm interval start). The two twins routinely differ by HOURS, so the old ±5-minute window in find_twins silently missed them — which broke review propagation (flagging one twin left its twin unflagged). Twins are now matched by: same serial + identical peak_vector_sum + OPPOSITE record type + the waveform's timestamp falling within the histogram's interval (bounded by the next same-serial histogram). Matching keys off record timestamps (not call-in/received times, which drift with field connectivity). window_seconds is retained but ignored. Rewrote test_find_twins + test_twin_propagation for the new contract (incl. the 75-min-apart UM12947 case, cross-type exclusion, containing-interval selection, open-ended latest interval). Full suite: 264 passed; the 16 failures are pre-existing (missing gitignored fixtures + a v0.26.0 codec case), unchanged from baseline. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDXjZCr4RqT2U3QvMDhgzf
37 lines
1.5 KiB
Python
37 lines
1.5 KiB
Python
import sqlite3
|
|
from sfm.database import SeismoDb
|
|
from minimateplus.models import Event, Timestamp
|
|
|
|
|
|
def _ins(db, key, serial, pvs, ts, record_type="Waveform"):
|
|
ev = Event(index=0)
|
|
ev._waveform_key = bytes.fromhex(key)
|
|
ev.timestamp = ts
|
|
db.insert_events([ev], serial=serial)
|
|
row = [r for r in db.query_events(serial=serial) if r["waveform_key"] == key][0]
|
|
with sqlite3.connect(db.db_path) as c:
|
|
c.execute("UPDATE events SET peak_vector_sum=?, record_type=? WHERE id=?",
|
|
(pvs, record_type, row["id"]))
|
|
return row["id"]
|
|
|
|
|
|
def _ts(hour, minute, second=0, day=25):
|
|
return Timestamp(raw=b"", flag=0x10, year=2026, unknown_byte=0, month=2, day=day,
|
|
hour=hour, minute=minute, second=second)
|
|
|
|
|
|
def test_propagate_copies_flags_across_hours_apart_twins(tmp_path):
|
|
# Flagging the waveform FT propagates to its histogram twin 75 min earlier
|
|
# (the interval matcher pairs them; the old ±5-min window would have missed it).
|
|
db = SeismoDb(tmp_path / "s.db")
|
|
hist = _ins(db, "01110001", "BE1", 0.4763, _ts(19, 31, 17), "Histogram")
|
|
wave = _ins(db, "01110002", "BE1", 0.4763, _ts(20, 46, 44), "Waveform") # twin, 75 min later
|
|
other = _ins(db, "01110003", "BE1", 0.9999, _ts(20, 20, 0), "Waveform") # different pvs
|
|
|
|
db.update_event_review(wave, {"false_trigger": True})
|
|
moved = db.propagate_review_to_twins(wave)
|
|
|
|
assert hist in moved
|
|
assert db.get_event(hist)["false_trigger"] == 1
|
|
assert db.get_event(other)["false_trigger"] == 0
|