fix(decode): stamp waveform events with the event time, not the session start
read_blastware_file built ev.timestamp from footer ts1, which for a WAVEFORM is the monitoring-session start (a unit arming at 06:00 stamps 06:00 on every event that day) — so every waveform's time was hours off (vomit-list #3, "~4.5 h off"). The event time is footer ts2 (the recording stop); BW's displayed Date/Time is the trigger = ts2 - record duration. Root cause proven against the BE12844 oracle set: 5 of 7 events decoded to the identical 06:00:13 (the shared session start); ts2 gives distinct plausible event times (N844LQHB ts2 = 10:33:32, BW trigger 10:33:29 = ts2 - 3.0 s rectime). * read_blastware_file now uses ts2 for waveforms (discriminated by which codec decoded the body, not the filename — save_imported_bw passes a tmp name). Histograms keep ts1 (the ~24 h window start, which IS the event time). * Binary-only decode can't get the exact trigger: the STRT record-time byte is a misparsed record-type marker (0x46=70), so ts2 (the stop, ~record duration after the trigger) is the best estimate. A paired BW report carries the exact trigger — apply_report_to_event now overlays event.timestamp from report.event_datetime, matching the existing build-path override (line ~441). Tests: waveform → ts2, histogram → ts1 unchanged, report → exact trigger. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDXjZCr4RqT2U3QvMDhgzf
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"""Event timestamp decode — waveform trigger/stop vs histogram window start.
|
||||
|
||||
The Blastware footer holds two timestamps: ts1 = footer[2:10], ts2 = footer[10:18].
|
||||
Their meaning depends on record type:
|
||||
|
||||
* Waveform: ts1 is the monitoring-SESSION start (e.g. 06:00 for a unit that
|
||||
arms at 06:00 daily — shared across every event that day), and ts2 is THIS
|
||||
event's recording STOP. read_blastware_file used to stamp events with ts1 →
|
||||
every waveform showed the session start (~4.5 h off). Binary-only, the best
|
||||
estimate is ts2 (the stop); the exact trigger BW displays (= ts2 - record
|
||||
duration) comes from the paired report's event_datetime, since the binary
|
||||
STRT record-time byte is a misparsed record-type marker.
|
||||
* Histogram: ts1/ts2 are the ~24 h window [start, stop]; the event time is the
|
||||
window start = ts1 (unchanged).
|
||||
"""
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from minimateplus.event_file_io import read_blastware_file, apply_report_to_event
|
||||
from minimateplus.bw_ascii_report import BwAsciiReport
|
||||
from minimateplus.models import Event
|
||||
|
||||
FIX = Path(__file__).parent / "fixtures"
|
||||
WAVEFORM = FIX / "fft-oracle-2026-09-14" / "N844LQHB.ZT0W" # footer ts2 = 2026-08-25 10:33:32
|
||||
HISTOGRAM = FIX / "ts-fix" / "K441LKZU.C30H" # window start 2026-05-10 19:04:50
|
||||
|
||||
|
||||
def _tuple(ts):
|
||||
return (ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second)
|
||||
|
||||
|
||||
def test_waveform_timestamp_is_event_stop_not_session_start():
|
||||
ev = read_blastware_file(WAVEFORM)
|
||||
# ts2 (the event's recording stop), NOT the 06:00:13 monitoring-session
|
||||
# start the old decode used.
|
||||
assert _tuple(ev.timestamp) == (2026, 8, 25, 10, 33, 32), _tuple(ev.timestamp)
|
||||
|
||||
|
||||
def test_histogram_timestamp_is_window_start_unchanged():
|
||||
ev = read_blastware_file(HISTOGRAM)
|
||||
# Histogram event time = the window start (ts1); must NOT get the waveform
|
||||
# ts2 treatment (that would land ~24 h off).
|
||||
assert _tuple(ev.timestamp) == (2026, 5, 10, 19, 4, 50), _tuple(ev.timestamp)
|
||||
|
||||
|
||||
def test_report_event_datetime_overrides_to_exact_trigger():
|
||||
# A paired BW report carries the exact trigger time; applying it must
|
||||
# override the binary footer's stop time so the event matches BW exactly.
|
||||
ev = read_blastware_file(WAVEFORM)
|
||||
assert _tuple(ev.timestamp) == (2026, 8, 25, 10, 33, 32) # stop, pre-report
|
||||
apply_report_to_event(ev, BwAsciiReport(
|
||||
event_datetime=datetime.datetime(2026, 8, 25, 10, 33, 29)))
|
||||
assert _tuple(ev.timestamp) == (2026, 8, 25, 10, 33, 29) # exact BW trigger
|
||||
Reference in New Issue
Block a user