docs(series4): generate IDF filenames rather than detecting record type

Closes the record-type gap flagged earlier, and corrects the premise behind it.

Series III does NOT detect record type from file content --
event_file_io.derive_record_type_from_filename() reads the last character of
the extension (M529LKIQ.G10H -> H -> Histogram). Nothing in the codebase infers
record type from content, for either family.

Nor is there an obvious type field to find in an IDF: the first 64 bytes of a
histogram and a waveform are byte-identical, and they diverge at ~0x0947 into
wholly different structures rather than differing by a flag.

The answer is the Series III pattern -- generate the name. Series III has
blastware_filename(); Series IV needs the same, and its convention is far
simpler:

    <serial>_<YYYYMMDDHHMMSS>.IDF{W,H}     e.g. UM12947_20260923163319.IDFW

against Series III's <letter><serial3><base-36 stem><AB0T ext>.

All three inputs are already available on a direct download: serial and
timestamp from extract_binary_metadata(), and type from the chain walk (SUB
0x0A returns 0x1E for a histogram, 0x00 for a waveform). Verified on all five
bench events -- generated names match real production-store filenames byte for
byte, so a directly downloaded event can be filed under exactly the name Thor
would have given it and /db/import/idf_file needs no change.

The type still comes from the protocol rather than the payload, so a
downloader must carry it out of the chain walk; losing it means losing the
ability to name the file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL
This commit is contained in:
2026-09-23 19:50:45 -04:00
co-authored by Claude Opus 5
parent 02ed22f561
commit 701af47170
+39 -10
View File
@@ -723,18 +723,47 @@ Read-only, over USB, no Instantel software:
Every event arrived at exactly its declared size, every channel came out equal Every event arrived at exactly its declared size, every channel came out equal
length, and the timestamps are sequential across the recording session. length, and the timestamps are sequential across the recording session.
### ⚠ Gap: no content-based record-type discriminator ### Record type + filename: generate it, don't detect it
`read_idf_file()` decides waveform vs histogram from the **filename suffix** `read_idf_file()` decides waveform vs histogram from the **filename suffix** —
(`.IDFH` / `.IDFW`) — and there is no filename when downloading over the wire. and there is no filename when downloading over the wire.
The first 64 bytes of a histogram and a waveform are **byte-identical**, so the
header does not obviously carry the type either.
The protocol does supply one: **`SUB 0x0A` returns length `0x1E` for a ⚠ Worth correcting a natural assumption: **Series III does not detect this from
histogram and `0x00` for a waveform** (see the event-chain section). Any content either.** `event_file_io.derive_record_type_from_filename()` reads the
direct-download implementation must carry the type from the chain walk rather last character of the extension (`M529LKIQ.G10H` → `H` → Histogram). Nothing
than inferring it from the payload, or find the type field inside the IDF in the codebase infers record type from file content, for either family.
header.
And there is no obvious type field to find. The first 64 bytes of a histogram
and a waveform are byte-identical; they diverge at ~`0x0947` into wholly
different structures rather than differing by a flag.
**The answer is the Series III pattern — generate the name.** Series III has
`blastware_filename()`, which builds a name from serial + timestamp + type.
Series IV needs the same thing, and its convention is far simpler:
```
<serial>_<YYYYMMDDHHMMSS>.IDF{W,H} e.g. UM12947_20260923163319.IDFW
```
versus Series III's `<letter><serial3><4-char base-36 stem><AB0T ext>`, where
the stem is base-36 of seconds-since-1985 ÷ 1296.
All three inputs are already available on a direct download:
| input | source |
|---|---|
| serial | `extract_binary_metadata()` — decoded from the IDF header |
| timestamp | `extract_binary_metadata()` — same |
| **type** | **the chain walk** — `SUB 0x0A` length `0x1E` = histogram, `0x00` = waveform |
Verified against all five bench events: the generated names match the
convention of real files in the production store byte for byte. A directly
downloaded event can therefore be filed under exactly the name Thor would have
given it, and `/db/import/idf_file` needs no change at all.
⚠ The type still comes from the *protocol*, not the payload — so a downloader
must carry it out of the chain walk. Losing it means losing the ability to
name the file correctly.
### ⚠ Unresolved: the `0x0C` peak float ### ⚠ Unresolved: the `0x0C` peak float