From 0415af19b4b97d97148fe2b5f520f142046209f9 Mon Sep 17 00:00:00 2001 From: Brian Harrison Date: Fri, 24 Apr 2026 20:21:03 -0400 Subject: [PATCH] fix(blastware_file): remove seen_metadata flag and adjust frame processing logic --- minimateplus/blastware_file.py | 38 ++++++++++++++-------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/minimateplus/blastware_file.py b/minimateplus/blastware_file.py index dabcce9..15c9835 100644 --- a/minimateplus/blastware_file.py +++ b/minimateplus/blastware_file.py @@ -677,7 +677,6 @@ def write_blastware_file( term_frame = None all_bytes = bytearray() - seen_metadata = False for fi, frame in enumerate(body_frames): ftype = classify_frame(frame) @@ -687,30 +686,25 @@ def write_blastware_file( # Probe frame: always process regardless of classification. # It holds the STRT record; probe_skip positions us past it. skip = probe_skip - elif seen_metadata: - # Drop all frames that come after the compliance/metadata block. - # (e.g. extra waveform chunks fetched after stop_after_metadata) - log.debug( - "write_blastware_file: frame %d after metadata — skipping", fi + elif ftype == "probe_or_strt": + # Real duplicate probe frames should be skipped (very rare). + log.warning( + "write_blastware_file: frame %d classified as probe_or_strt — skipping", + fi, ) continue - elif ftype in ("waveform", "metadata"): - skip = 13 if fi == 1 else 12 - if ftype == "metadata": - seen_metadata = True else: - # Skip probe_or_strt and unknown frames. - if b"STRT\xff\xfe" in bytes(frame.data): - log.warning( - "write_blastware_file: frame %d (%s) contains STRT — skipping", - fi, ftype, - ) - else: - log.debug( - "write_blastware_file: frame %d classified as %s — skipping", - fi, ftype, - ) - continue + # Waveform chunks, metadata/compliance frames, and unknown frames are all + # included. The A5 stream is collected with stop_after_metadata=True + + # extra_chunks_after_metadata=1, so body_frames contains: + # [0] probe frame + # [1..N] waveform ADC chunks + # [N+1] first compliance frame (contains "Project:", "Client:", etc.) + # [N+2] second compliance frame (continuation of compliance block) + # All of these contribute to the body; the 26-byte footer is separated out + # at the end. Do NOT gate on metadata classification here — the compliance + # block spans 2 frames and skipping frame N+2 produces a truncated file. + skip = 13 if fi == 1 else 12 all_bytes.extend(_frame_body_bytes(frame, skip))