Repository navigation
Description
I am reviewing #4809 (optimize SpikeRetriever and RAM usage for extensions) and I want to bring back the topic of simplifying the spike vector (time ordered and unit ordered) data model. A lot of the memory cost on @alejoe91's benchmark is the spike vector itself and of that 1/3 is the segment index and the segment index is unnecessary. This is an edge case (most recordings are not multi-segment) and the field is only a convenience, syntactic sugar. These are the main places where we use it:
-
To find the boundaries of a segment (the sorting already caches them as
segment_slices, seeto_spike_vector(return_slices=True)):
s0, s1 = np.searchsorted(spikes["segment_index"], [segment_index, segment_index + 1])
The samenp.searchsortedis repeated three more times inwaveform_tools.pyand inbasesorting.py,zarrextractors.py,sorting_tools.pyandremove_excess_spikes.py. -
To mask the spikes of one unit in one segment (this could be a slice of the segment plus a mask on
unit_index):
spikeinterface/src/spikeinterface/core/analyzer_extension_core.py
Lines 131 to 133 in 93c612f
spike_indices_in_seg = np.flatnonzero( (spikes["segment_index"] == segment_index) & (spikes["unit_index"] == unit_index) ) -
As a sort key when building a sorting from peaks (the slices could be computed once at construction instead):
order = np.lexsort((spikes["sample_index"], spikes["segment_index"]))
As a side effect this would remove the branching for the mono-segment case, like the special cases that #4809 adds to SpikeRetriever, PeakRetriever and _get_spike_vector_segment_slices.
The cost is a big refactor: using the slices wherever we rely on np.searchsorted (which I also think would be more efficient) and a compatibility path for the sortings that were saved with the field.
What do you think? Is there something I am missing?
Activity
alejoe91 commentedon Oct 5, 2026
I agree that the
segment_indexadds a lot of extra complexity for very niche use cases.@samuelgarcia agrees too, but we need to discuss how to properly implement this!
JoeZiminski commentedon Oct 31, 2026
That's a nice idea, so instead a list of slices is maintained to get the spikes-by-segment? Am I correct the ordering is SEGMENT TIME UNIT in the time-ordered array, and becomes UNIT SEGMENT TIME in the unit-ordered array? but all units are from the same segment, and in segment order? so the slice transform should be fairly straightforward?
Personally I would consider a long-term goal to remove the segment infrastructure. As you say its a rarely used case, its not fully supported by the codebase (e.g. motion estimation, KS4) but there is a lot of complexity and machinery added in the codebase to support it. I think for the most part the segment functionality could be fairly easily handled by the user working with a list of recordings?)