Skip to content

Remove some full lexsort of spikes when not necesary.#4618

Open
samuelgarcia wants to merge 13 commits into
SpikeInterface:mainfrom
samuelgarcia:remove_some_lexsort
Open

Remove some full lexsort of spikes when not necesary.#4618
samuelgarcia wants to merge 13 commits into
SpikeInterface:mainfrom
samuelgarcia:remove_some_lexsort

Conversation

@samuelgarcia

Copy link
Copy Markdown
Member

See discussion: #4606

We do not need strong fulll lexsort in some place because it is not a need.

Important notes : during the version 0.104.0 the zarr format was lexsorting on the fly in init.
This was useless because the lexsort was done before saving in the analyzer create mechanisim.
So we do not need any backward compatibility startegy to handle this.

This should be merge before #4579

@alejoe91

Copy link
Copy Markdown
Member

@samuelgarcia can you check father failing tests? Seems related to MDA sorting tests. Maybe we need to force lexsort there

@alejoe91 alejoe91 added core Changes to core module performance Performance issues/improvements labels Jun 25, 2026
Comment thread src/spikeinterface/core/generate.py Outdated
Comment thread src/spikeinterface/extractors/tests/test_alfsortingextractor.py Outdated
@alejoe91

Copy link
Copy Markdown
Member

@samuelgarcia justa couple of minor comments

Comment thread src/spikeinterface/core/zarrextractors.py Outdated
Co-authored-by: Alessio Buccino <alejoe9187@gmail.com>
Comment thread src/spikeinterface/extractors/tests/test_alfsortingextractor.py Outdated
unit_indices = np.concatenate(unit_indices)

order = np.argsort(sample_indices)
order = np.argsort(sample_indices, stable=True)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking: the reason we do this is because an argsort with stable=True will better respect the original data (for a small number of edge cases)?

Comment on lines +896 to +898
# here we only do a sort by indices a lexsort on sample_indices
# the stable=True is equivalent to np.lexsort((unit_indices, sample_indices, ))
# because because we construct by looping on unit_ids

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# here we only do a sort by indices a lexsort on sample_indices
# the stable=True is equivalent to np.lexsort((unit_indices, sample_indices, ))
# because because we construct by looping on unit_ids
# here, a sort by indices with stable=True is equivalent to
# np.lexsort((unit_indices, sample_indices))
# because we construct by looping on unit_ids

Comment on lines +917 to +918
# the spikes are not lexsorted here because the previous loop ensure that the spike vector is constructucted alway the same way.
# spikes = spikes[np.lexsort((spikes["unit_index"], spikes["sample_index"], spikes["segment_index"]))]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# the spikes are not lexsorted here because the previous loop ensure that the spike vector is constructucted alway the same way.
# spikes = spikes[np.lexsort((spikes["unit_index"], spikes["sample_index"], spikes["segment_index"]))]

Comment on lines +191 to +192
# the spikes do not need a full lexsort because synthesize_poisson_spike_vector() garanty spikes to sorted by frame already
# spikes = spikes[np.lexsort((spikes["unit_index"], spikes["sample_index"], spikes["segment_index"]))]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# the spikes do not need a full lexsort because synthesize_poisson_spike_vector() garanty spikes to sorted by frame already
# spikes = spikes[np.lexsort((spikes["unit_index"], spikes["sample_index"], spikes["segment_index"]))]

# Sort globaly
spike_frames = spike_frames[:num_correct_frames]
sort_indices = np.argsort(spike_frames, kind="stable") # I profiled the different kinds, this is the fastest.
# the stable is important because this guarantees to be equivalent to

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# the stable is important because this guarantees to be equivalent to
# the `stable` is important because this guarantees result is equivalent to

s2 = SX2.to_spike_vector()
if not check_exact_lexsort:
# 2 sorting can be equal even if the internal lexsort is not the same.
# spiketrains still wiwll be the same per units

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# spiketrains still wiwll be the same per units
# spiketrains still will be the same per units

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Changes to core module performance Performance issues/improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants