fix(offset): read the real serial from the file body, not "BE" + the number
The BW filename encodes only the serial NUMBER — `<letter><3 digits>` where
letter = chr(ord('B') + serial // 1000), so `L895…` decodes to 10895. The
two-letter family prefix is not in the filename at all, and every offset
scanner synthesized it as f"BE{num}".
Four of the 43 archive units are BA, not BE. Their binaries say so plainly:
BA9229, BA10060, BA10895, BA15957. Brian caught BA10895 by recognising that
no such unit as BE10895 exists.
serial_of() now reads the serial string out of the file body and falls back
to the old synthesis only when no matching string is found. No analysis
changes: grouping was by the numeric part, which was always correct, and no
unit number maps to more than one serial (checked across all 43).
The same assumption is live in two production sites and is NOT touched here,
because fixing ingest renames rows a running store and Terra-View already
reads them:
- sfm/waveform_store.py:870 `return f"BE{serial_num}"` on import
- minimateplus/client.py:2538 `raw_data.find(b"BE")` in the monitor-log
partial-record decode, which yields serial=None on a BA unit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HgTe8CamXAHcAmaQ6QNcog
This commit is contained in:
+26
-4
@@ -28,9 +28,31 @@ from minimateplus.event_file_io import read_blastware_file
|
||||
GEO=("Tran","Vert","Long"); K=10.0/32000.0
|
||||
_WAVE=re.compile(r"\.[A-Za-z0-9]{2}0[Ww]$"); _STEM=re.compile(r"^([B-Z])(\d{3})")
|
||||
|
||||
def serial_of(n):
|
||||
m=_STEM.match(n)
|
||||
return f"BE{(ord(m.group(1))-ord('B'))*1000+int(m.group(2))}" if m else "?"
|
||||
_SERIAL_RE = re.compile(rb"\b([A-Z]{2}\d{3,6})\b")
|
||||
|
||||
|
||||
def serial_of(name: str, path=None) -> str:
|
||||
"""Real serial for a BW file.
|
||||
|
||||
The filename encodes only the NUMBER: `<letter><3 digits>` where
|
||||
letter = chr(ord('B') + serial // 1000). The two-letter family prefix
|
||||
("BE", "BA", ...) is **not** in the filename, so it must be read out of
|
||||
the file body. Four units in the DL2 archive are BA, not BE — assuming
|
||||
"BE" mislabels BA9229, BA10060, BA10895 and BA15957.
|
||||
"""
|
||||
m = _STEM.match(name)
|
||||
if not m:
|
||||
return "?"
|
||||
num = (ord(m.group(1)) - ord("B")) * 1000 + int(m.group(2))
|
||||
if path is not None:
|
||||
try:
|
||||
for s in _SERIAL_RE.findall(Path(path).read_bytes()):
|
||||
s = s.decode()
|
||||
if s[2:].lstrip("0") == str(num):
|
||||
return s
|
||||
except Exception:
|
||||
pass
|
||||
return f"BE{num}" # last-resort fallback; prefix unverified
|
||||
|
||||
def scan(ps):
|
||||
p=Path(ps)
|
||||
@@ -48,7 +70,7 @@ def scan(ps):
|
||||
mid, end = a[t:2*t], a[2*t:]
|
||||
if not pre or not mid or not end: continue
|
||||
v=[statistics.median(x)*K for x in (pre,mid,end)]
|
||||
out.append({"serial":serial_of(p.name),"timestamp":stamp,
|
||||
out.append({"serial":serial_of(p.name, p),"timestamp":stamp,
|
||||
"filename":p.name,"channel":ch,
|
||||
"pretrig_n": pre_n or 0,
|
||||
"pre":round(v[0],4),"mid":round(v[1],4),"end":round(v[2],4),
|
||||
|
||||
Reference in New Issue
Block a user