annotate_blastware_binary(raw) → a gap-free tiling of labelled Spans (header / STRT / per-channel sample records / footer / unknown) for a hex viewer to paint. Every byte is covered; anything the decoder can't account for is a first-class `unknown` span, so undecoded regions stand out. Composes the existing waveform_codec.walk_records over the body between the STRT record and the 26-byte footer. On the cracking fixtures this already surfaces a ~1700-byte undecoded trailing region (stream-end marker + serial + …) per file — a candidate home for stored spectral/FFT data. TDD: tests assert the spans tile the whole file, STRT is located, the geo sample records are labelled, and the footer is last. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDXjZCr4RqT2U3QvMDhgzf
51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
"""Structural annotation of a Series-3 Blastware binary (for the seismo_lab
|
|
Binary Inspector). The annotator maps byte ranges to labelled spans; anything
|
|
the decoder can't account for is a first-class ``unknown`` span, so the whole
|
|
file is tiled and the gaps (candidate FFT/spectral data) are visible.
|
|
"""
|
|
from pathlib import Path
|
|
|
|
from minimateplus.binary_annotate import annotate_blastware_binary, Span
|
|
|
|
# A known-good full-3-channel Series-3 waveform binary (the V70 cracking fixture).
|
|
FIXTURE = Path(__file__).parent / "fixtures" / "5-11-26" / "M529LL1L.V70"
|
|
|
|
|
|
def _raw() -> bytes:
|
|
return FIXTURE.read_bytes()
|
|
|
|
|
|
def test_spans_tile_the_whole_file():
|
|
raw = _raw()
|
|
spans = annotate_blastware_binary(raw)
|
|
assert spans, "expected at least one span"
|
|
assert spans[0].start == 0
|
|
assert spans[-1].end == len(raw)
|
|
for a, b in zip(spans, spans[1:]):
|
|
assert a.end == b.start, f"gap/overlap between {a!r} and {b!r}"
|
|
for s in spans:
|
|
assert s.start < s.end, f"empty/negative span {s!r}"
|
|
|
|
|
|
def test_strt_record_is_located():
|
|
raw = _raw()
|
|
spans = annotate_blastware_binary(raw)
|
|
strt = [s for s in spans if s.kind == "strt"]
|
|
assert strt, "expected a STRT region"
|
|
assert raw[strt[0].start : strt[0].start + 4] == b"STRT"
|
|
|
|
|
|
def test_geo_sample_records_annotated():
|
|
raw = _raw()
|
|
spans = annotate_blastware_binary(raw)
|
|
chans = {s.label.split()[0] for s in spans if s.kind == "sample"}
|
|
# V70 is a full three-geo-channel event.
|
|
assert {"Tran", "Vert", "Long"} <= chans, f"expected geo records, got {chans}"
|
|
|
|
|
|
def test_footer_is_last():
|
|
raw = _raw()
|
|
spans = annotate_blastware_binary(raw)
|
|
assert spans[-1].kind == "footer"
|
|
assert spans[-1].end - spans[-1].start == 26
|