Blackrock: improve nev header reading #1771
Merged
+285
−198
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a continuation of #1763
On the main branch, the NEV header reading functionality uses a two-stage mapping system that separates the definition of extended header types from their specification-specific usage. The system first defines all possible extended header types in a general
_nev_ext_header_typesfunction that returns a nested dictionary where packet IDs map to variant letters ("a", "b", "c"), which then map to actual data type definitions:python-neo/neo/rawio/blackrockrawio.py
Line 1545 in b404802
For example,
b"NEUEVWAV"maps to both "a" (for v2.1 with a 10-byte unused field) and "b" (for v2.2+ with a spike_width field and an 8-byte unused field). Each specification-specific function (_read_nev_header_spec_v21,_read_nev_header_spec_v22,_read_nev_header_spec_v30_ptp) then builds its own mapping dictionary that assigns these variant letters to packet IDs, effectively filtering which variants apply to that specification:python-neo/neo/rawio/blackrockrawio.py
Lines 1219 to 1233 in b404802
I think that this dynamic lookup is both inefficient and hard to read. It is inefficient because every spec function needs to read all the spec for all the extended data types anyway and is hard-to-read because that is done implicitly and couples dicts in two different places dynamically. We can do better.
Instead, in this PR I replaced that approach with a declarative module-level dictionary (
NEV_EXT_HEADER_TYPES_BY_SPEC) that directly maps specifications to their complete header type definitions without the intermediate variant letters. I consolidated the three specification-specific header functions into a single_read_nev_headerfunction that takes the specification as a parameter and performs a direct dictionary lookup. This continues the work from #1763, which removed some arbitrary spec references (a,b, etc) but left others embedded in function internals. The new structure separates data from execution, allowing direct resolution of extended data types instead of dynamic lookup, and improves maintainability because of "explicit is better than implicit" reasons.