Skip to content

Respect requested unit order for templates and sparsity in SortingAnalyzer.select_units - #4791

Merged
alejoe91 merged 5 commits into
SpikeInterface:mainfrom
grahamfindlay:fix/analyzer-select-units-order
Sep 17, 2026
Merged

alejoe91 merged 5 commits into
SpikeInterface:mainfrom
grahamfindlay:fix/analyzer-select-units-order

Conversation

@grahamfindlay

Copy link
Copy Markdown
Contributor

Commit 1

Bug: When calling SortingAnalyzer.select_units(), the new analyzer's unit_ids follow the order passed to select_units(), but select_units() copies the templates and the channel sparsity from the parent in the parent's order. The analyzer reads row i of those arrays as unit_ids[I], so a selection that is not in the parent's order gives units each other's templates and sparsity without raising an error.

Fix: index both by ids_to_indices(unit_ids), like the other per-unit extensions.

Commit 2

Bug: The selected ACGs were stored under "ccgs", so calling get_data() on an analyzer produced by select_units() raised KeyError("acgs").

Fix: Store ACGs under "acts".

Commit 3

Problem: AnalyzerExtensionCommonTestSuite only tested a reversed-order select_units() on unit_locations.

Fix: Add the missing tests.

Commit 4

There were a bunch of places where mapping unit ids to indices with np.flatnonzero(np.isin(analyzer.unit_ids, unit_ids)) produced correct behavior, but since this is the pattern that caused the earlier bug, it seemed prudent to just use sorting.ids_to_indices(unit_ids) everywhere so there's only one, safe idiom in use.

When calling SortingAnalyzer.select_units(), the new analyzer's unit_ids
follow the order passed to select_units(), but select_units() copies the
templates and the channel sparsity from the parent in the parent's
order. The analyzer reads row i of those arrays as unit_ids[i], so a
selection that is not in the parent's order gives units each other's
templates and sparsity without raising an error.

The solution is to index both by ids_to_indices(unit_ids), like the
other per-unit extensions.
The selected ACGs were stored under "ccgs", so calling get_data() on an
analyzer produced by select_units() raised KeyError("acgs").  It looks
like this was introduced in SpikeInterface#4307.
(AnalyzerExtensionCommonTestSuite only tested a reversed-order
select_units() on unit_locations).
In these cases, mapping unit ids to indices with
np.flatnonzero(np.isin(analyzer.unit_ids, unit_ids)) produced correct
behavior, but since this is the pattern that caused the bugs fixed two
commits prior, it seemed prudent to just use
sorting.ids_to_indices(unit_ids) everywhere so there's only one, safe
idiom in use.
@alejoe91 alejoe91 added bug Something isn't working core Changes to core module labels Sep 17, 2026
@alejoe91 alejoe91 added this to the 0.105.0 milestone Sep 17, 2026

@chrishalcrow chrishalcrow left a comment

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.

This is great, thanks Graham!
I stress test all our curation tools in the GUI, which always follows the parent order, so I totally missed this.

@alejoe91
alejoe91 merged commit ee72360 into SpikeInterface:main Sep 17, 2026
17 checks passed
@grahamfindlay
grahamfindlay deleted the fix/analyzer-select-units-order branch September 17, 2026 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working core Changes to core module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants