VoxelSeriesStore
The storage protocol behind dense, sparse, mapped, and file-backed 4-D containers.
What it is
VoxelSeriesStore is a small structural protocol — five members: shape, dtype, series(...), volume(i), as_matrix() — defined in neuroim.storage. It is the storage contract: a uniform way to pull a voxel’s series, a timepoint’s volume, or the whole time-major matrix, regardless of how the bytes are physically held.
It is @runtime_checkable, so isinstance(obj, VoxelSeriesStore) is a valid structural test.
Conformance is via the adapter
The shipped containers — DenseNeuroVec, SparseNeuroVec, BigNeuroVec, MappedNeuroVec, FileBackedNeuroVec — do not themselves pass isinstance(vec, VoxelSeriesStore). The conformer is NeuroVecStoreAdapter, one frozen wrapper that spans every backend because the per-backend behaviour lives in the wrapped vec’s own series / __getitem__. DenseStore, SparseStore, BigStore, FileBackedStore, MappedStore are all aliases of that one adapter.
from neuroim.storage import VoxelSeriesStore, NeuroVecStoreAdapter
isinstance(bold, VoxelSeriesStore) # False
isinstance(NeuroVecStoreAdapter(bold), VoxelSeriesStore) # TrueTwo layers, kept distinct
- Storage layer (this protocol). Five members. “One protocol, every backend” is true here, through the single adapter.
- Analysis layer (separate).
series_roi,temporal_snr,searchlight_applybehaving identically across dense/sparse/mapped/ file-backed inputs is a related guarantee carried by theNeuroVecsubclasses and their shared contract layer — not by this protocol’s five members. The protocol provides the storage surface the analysis layer is built on; it does not itself provide the analysis surface.
Invariants
shapeis a 4-tuple(nx, ny, nz, nt).as_matrix()is time-major — shape(nt, n_voxels), Fortran-flattened voxel order. A conforming backend must preserve this orientation.- Off-grid access raises.
serieson an off-grid voxel/index raisesIndexErrorperIDX-OOB. A backend that returns wrong-but-plausible bytes instead is non-conforming even if structurally aVoxelSeriesStore. - Multi-source backends enforce frame consistency.
FileBackedNeuroVecvalidates that every per-timepoint file’s affine agrees; drift raisesVolume {idx} has inconsistent affine/space: …before a reduction averages two frames. Backed by scenario S12 (PAIN-12, closed).
What it doesn’t do
- No magic format dispatch. Backends are constructed explicitly (
FileBackedNeuroVec(paths),MappedNeuroVec(path, space)).read_imagereturns dense storage by default; richer backends are explicit caller decisions. - No inheritance hierarchy. Conformance is structural, not via a shared base class.
- No concurrency promise. Concurrent writes into a
MappedNeuroVecare undefined. The protocol covers the read-side storage surface, not write-side concurrency.
See also
- Spec: VoxelSeriesStore protocol — the third-party-implementable contract.
- Reference: DenseNeuroVec, SparseNeuroVec — generated entries for the shipped backends.
- Contract failures — the
IDX-OOB/FB-DRIFTrefusals. - Scenarios: S08, S12.