update to 0.26.0. Big chonking update including 0.23, 0.24, and 0.25 as well. #33
+7
-4
@@ -24,13 +24,16 @@ window).
|
|||||||
`SeismoDb()` construction, no manual migration). `query_events` /
|
`SeismoDb()` construction, no manual migration). `query_events` /
|
||||||
`get_event` (and thus `/db/events`) return it automatically (`SELECT *`).
|
`get_event` (and thus `/db/events`) return it automatically (`SELECT *`).
|
||||||
- **Mutual exclusivity with `false_trigger`** — setting `reviewed_real=1`
|
- **Mutual exclusivity with `false_trigger`** — setting `reviewed_real=1`
|
||||||
clears `false_trigger`, and vice versa, both via `set_false_trigger` /
|
clears `false_trigger`, and vice versa, enforced on both review paths:
|
||||||
the sidecar review PATCH path.
|
the sidecar review PATCH (`update_event_review`) and the quick
|
||||||
|
`PATCH /db/events/{id}/false_trigger` endpoint (`set_false_trigger`).
|
||||||
- **`find_twins`** — matches an event's histogram/waveform twins by serial +
|
- **`find_twins`** — matches an event's histogram/waveform twins by serial +
|
||||||
identical peak-vector-sum + a timestamp window.
|
identical peak-vector-sum + a timestamp window.
|
||||||
- **`propagate_review_to_twins`** — copies an event's `false_trigger`/
|
- **`propagate_review_to_twins`** — copies an event's `false_trigger`/
|
||||||
`reviewed_real` state onto its twins, wired into the
|
`reviewed_real` state onto its twins, wired into both the
|
||||||
`PATCH /db/events/{id}/sidecar` review path so flagging one flags both.
|
`PATCH /db/events/{id}/sidecar` review path and the quick
|
||||||
|
`PATCH /db/events/{id}/false_trigger` path, so flagging one flags both
|
||||||
|
regardless of which endpoint made the change.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+28
-5
@@ -610,6 +610,16 @@ class SeismoDb:
|
|||||||
within ``window_seconds`` of this event's timestamp. Excludes the
|
within ``window_seconds`` of this event's timestamp. Excludes the
|
||||||
event itself. Returns [] if the event or any required field
|
event itself. Returns [] if the event or any required field
|
||||||
(serial / peak_vector_sum / timestamp) is missing.
|
(serial / peak_vector_sum / timestamp) is missing.
|
||||||
|
|
||||||
|
Caveat: identical-PVS matching is a proxy for "same physical event
|
||||||
|
recorded twice," not a guarantee. In the rare case where the device
|
||||||
|
clamps/saturates PVS (clamped to sqrt(3) * geo_range), two distinct
|
||||||
|
saturated events on the same serial within the window can share the
|
||||||
|
same clamped PVS value and be matched as twins even though they are
|
||||||
|
different events. This is harmless in practice — false_trigger/
|
||||||
|
reviewed_real are derived/index columns re-derivable from the
|
||||||
|
sidecar source of truth — but worth knowing if twin counts look
|
||||||
|
surprising on a saturated/clamped run.
|
||||||
"""
|
"""
|
||||||
row = self.get_event(event_id)
|
row = self.get_event(event_id)
|
||||||
if not row:
|
if not row:
|
||||||
@@ -652,12 +662,25 @@ class SeismoDb:
|
|||||||
return moved
|
return moved
|
||||||
|
|
||||||
def set_false_trigger(self, event_id: str, value: bool) -> bool:
|
def set_false_trigger(self, event_id: str, value: bool) -> bool:
|
||||||
"""Set or clear the false_trigger flag on an event. Returns True if found."""
|
"""
|
||||||
|
Set or clear the false_trigger flag on an event. Returns True if found.
|
||||||
|
|
||||||
|
Mirrors the 3-state exclusivity enforced by `update_event_review`:
|
||||||
|
setting false_trigger true also clears `reviewed_real` (a false
|
||||||
|
trigger can't also be a confirmed-real event). Clearing false_trigger
|
||||||
|
leaves `reviewed_real` untouched.
|
||||||
|
"""
|
||||||
with self._connect() as conn:
|
with self._connect() as conn:
|
||||||
cur = conn.execute(
|
if value:
|
||||||
"UPDATE events SET false_trigger=? WHERE id=?",
|
cur = conn.execute(
|
||||||
(1 if value else 0, event_id),
|
"UPDATE events SET false_trigger=1, reviewed_real=0 WHERE id=?",
|
||||||
)
|
(event_id,),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
cur = conn.execute(
|
||||||
|
"UPDATE events SET false_trigger=0 WHERE id=?",
|
||||||
|
(event_id,),
|
||||||
|
)
|
||||||
return cur.rowcount > 0
|
return cur.rowcount > 0
|
||||||
|
|
||||||
def delete_event(self, event_id: str) -> Optional[dict]:
|
def delete_event(self, event_id: str) -> Optional[dict]:
|
||||||
|
|||||||
+10
-1
@@ -1957,7 +1957,10 @@ def db_set_false_trigger(
|
|||||||
value: bool = Query(..., description="True to flag as false trigger, False to clear"),
|
value: bool = Query(..., description="True to flag as false trigger, False to clear"),
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""
|
"""
|
||||||
Set or clear the false_trigger flag on a single event.
|
Set or clear the false_trigger flag on a single event. Enforces the
|
||||||
|
same 3-state exclusivity as the sidecar review PATCH (flagging false_trigger
|
||||||
|
clears reviewed_real) and propagates the resulting flags to the event's
|
||||||
|
histogram/waveform twin(s), same as the sidecar path.
|
||||||
|
|
||||||
Used by the terra-view event review UI.
|
Used by the terra-view event review UI.
|
||||||
Returns 404 if the event_id is not found.
|
Returns 404 if the event_id is not found.
|
||||||
@@ -1965,6 +1968,12 @@ def db_set_false_trigger(
|
|||||||
found = _get_db().set_false_trigger(event_id, value)
|
found = _get_db().set_false_trigger(event_id, value)
|
||||||
if not found:
|
if not found:
|
||||||
raise HTTPException(status_code=404, detail=f"Event {event_id} not found")
|
raise HTTPException(status_code=404, detail=f"Event {event_id} not found")
|
||||||
|
|
||||||
|
try:
|
||||||
|
_get_db().propagate_review_to_twins(event_id)
|
||||||
|
except Exception as exc:
|
||||||
|
log.warning("twin review-propagation failed for %s: %s", event_id, exc)
|
||||||
|
|
||||||
return {"status": "ok", "event_id": event_id, "false_trigger": value}
|
return {"status": "ok", "event_id": event_id, "false_trigger": value}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
from sfm.database import SeismoDb
|
||||||
|
from minimateplus.models import Event
|
||||||
|
|
||||||
|
|
||||||
|
def _ins(db, eid_key="01110000", serial="BE1"):
|
||||||
|
ev = Event(index=0); ev._waveform_key = bytes.fromhex(eid_key)
|
||||||
|
db.insert_events([ev], serial=serial)
|
||||||
|
return db.query_events(serial=serial)[0]["id"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_false_trigger_clears_reviewed_real(tmp_path):
|
||||||
|
db = SeismoDb(tmp_path / "s.db"); eid = _ins(db)
|
||||||
|
db.update_event_review(eid, {"reviewed_real": True})
|
||||||
|
assert db.get_event(eid)["reviewed_real"] == 1
|
||||||
|
|
||||||
|
db.set_false_trigger(eid, True)
|
||||||
|
row = db.get_event(eid)
|
||||||
|
assert row["false_trigger"] == 1 and row["reviewed_real"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_clearing_false_trigger_leaves_reviewed_real_untouched(tmp_path):
|
||||||
|
db = SeismoDb(tmp_path / "s.db"); eid = _ins(db)
|
||||||
|
db.update_event_review(eid, {"false_trigger": True})
|
||||||
|
db.set_false_trigger(eid, False)
|
||||||
|
row = db.get_event(eid)
|
||||||
|
assert row["false_trigger"] == 0
|
||||||
|
# reviewed_real was never set true, so it stays 0 either way; the point
|
||||||
|
# is set_false_trigger(False) does not touch the column at all.
|
||||||
|
assert row["reviewed_real"] == 0
|
||||||
Reference in New Issue
Block a user