fix(histogram): three defects found by a full series-3 sweep — 11603/11603 clean
Swept every series-3 binary with the live decoder against five independent checks: decode exceptions, zero samples, unequal geo channel lengths, peaks above range full scale, decoded peak vs device-reported PPV, and waveform length vs declared record time. 1. block[22] is NOT a constant and must not be tested. Documented as always 0x00, it carries data on loud blocks, and rejecting those threw away the interval holding the event peak. BE18350/T350L7HR.NL0H block 92 has block[22]=0x26 and a Tran peak of 0x0563 = 1379 counts = 6.895 in/s — exactly the device-reported PPV — while the file decoded to 0.015 in/s. block[0]==0, block[4]==0x0A and the 4-byte tail are six bytes of constraint, which is what keeps trailer content out. 2. Block-model dispatch now goes on signature strength rather than on whichever decoder returns first. A multi-interval body also yields scattered standard-tail blocks by coincidence, so "first non-empty" handed 193 BE18193 files to the standard walker and produced peaks of 149 in/s against a 10 in/s full scale. 3. Multi-interval stride detection requires the block counter to increment by exactly 1. Without it the detector false-positives on ordinary standard-block bodies: they carry a header every 32 bytes, and 192 = 12 + 20*9 and 512 = 12 + 20*25 are both multiples of 32, so a stride "fits" while skipping 6 or 16 real blocks. That misrouted 9,082 files. Partial-block garbage is trimmed within the final block only, stopping at the first slot with a non-zero tail word or a geo peak above full scale (2000 counts in 16-count units). Trimming purely from the end left garbage stranded behind a slot that happened to have a zero tail word; trimming on the tail word alone truncated four BE9440 files by up to 2,800 intervals. Result: 11,603 / 11,603 series-3 binaries clean on every check. Ground truth unchanged: 1211/1211 histograms exact per-interval, 75/75 waveform sample counts exact (73/75 fully exact, the 2 differ by 1 LSB on rail samples), and the multi-interval fixture still matches its BW ASCII export on all 45,680 values. Tests: 259 passed, failure list unchanged from baseline. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HgTe8CamXAHcAmaQ6QNcog
This commit is contained in:
@@ -457,11 +457,22 @@ def test_terminal_block_exempt_from_byte22_constraint():
|
||||
assert ch is not None and len(ch["Tran"]) == 2
|
||||
|
||||
|
||||
def test_standard_block_still_requires_byte22_zero():
|
||||
"""The [22] == 0x00 constraint is what keeps trailer content out, so it
|
||||
must still apply to standard-tail blocks."""
|
||||
ch = decode_histogram_body(_mk_block(b22=0x01))
|
||||
assert ch is None
|
||||
def test_standard_block_accepts_nonzero_byte22():
|
||||
"""block[22] is NOT a constant and must not be tested.
|
||||
|
||||
It was documented as always 0x00, but it carries data on loud blocks.
|
||||
Rejecting those threw away the interval holding the event peak:
|
||||
BE18350/T350L7HR.NL0H block 92 has block[22]=0x26 and a Tran peak of
|
||||
0x0563 = 1379 counts = 6.895 in/s — exactly the device-reported PPV —
|
||||
while the file as a whole decoded to 0.015 in/s.
|
||||
|
||||
block[0]==0x00, block[4]==0x0A and the 4-byte tail are six bytes of
|
||||
constraint, which is what keeps trailer content out.
|
||||
"""
|
||||
ch = decode_histogram_body(_mk_block(t_peak=1379, b22=0x26))
|
||||
assert ch is not None
|
||||
assert ch["Tran"] == [1379]
|
||||
assert geo_count_to_ins(ch["Tran"][0]) == pytest.approx(6.895)
|
||||
|
||||
|
||||
def test_marker_is_single_byte_not_uint16():
|
||||
|
||||
Reference in New Issue
Block a user