Skip to content

Commit 7889b52

Browse files
Add SortingAnalyzer.split() function for aggregated analyzers (#4660)
Co-authored-by: Chris Halcrow <57948917+chrishalcrow@users.noreply.github.com>
1 parent dc7b63a commit 7889b52

2 files changed

Lines changed: 37 additions & 0 deletions

File tree

src/spikeinterface/core/sortinganalyzer.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,37 @@ def get_main_channels(self, outputs: Literal["index", "id"] = "index", with_dict
12801280
else:
12811281
return main_chans
12821282

1283+
def is_aggregated(self):
1284+
"""
1285+
Returns True if the SortingAnalyzer is aggregated, False otherwise.
1286+
"""
1287+
return (
1288+
"aggregation_key" in self.get_sorting_property_keys()
1289+
and "aggregation_key" in self.get_recording_property_keys()
1290+
)
1291+
1292+
def split_by(self):
1293+
"""
1294+
Returns a dictionary of SortingAnalyzer objects, split by the aggregation_key.
1295+
The keys of the dictionary are the unique values of the aggregation_key, and the values
1296+
are the SortingAnalyzer objects corresponding to each unique value.
1297+
"""
1298+
if not self.is_aggregated():
1299+
raise ValueError("SortingAnalyzer is not aggregated")
1300+
1301+
units_aggregation_key = self.get_sorting_property("aggregation_key")
1302+
channel_aggregation_key = self.get_recording_property("aggregation_key")
1303+
unique_keys = np.unique(units_aggregation_key)
1304+
split_analyzers = {}
1305+
for key in unique_keys:
1306+
unit_ids = self.unit_ids[units_aggregation_key == key]
1307+
channel_ids = self.channel_ids[channel_aggregation_key == key]
1308+
analyzer_units = self.select_units(unit_ids)
1309+
analyzer_split = analyzer_units.select_channels(channel_ids)
1310+
split_analyzers[key] = analyzer_split
1311+
1312+
return split_analyzers
1313+
12831314
def are_units_mergeable(
12841315
self,
12851316
merge_unit_groups: list[str | int],

src/spikeinterface/core/tests/test_sortinganalyzer.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,12 @@ def test_create_by_dict():
277277
assert not np.any(sparsity_mask[i][other_group_channel_indices])
278278
assert sparsity_mask[i, main_channel_index]
279279

280+
# test split aggregated
281+
analyzers_split = analyzer_with_sparsity.split_by()
282+
for group, analyzer in analyzers_split.items():
283+
assert np.all(analyzer.get_sorting_property("aggregation_key") == group)
284+
assert np.all(analyzer.recording.get_property("aggregation_key") == group)
285+
280286

281287
def test_load_without_runtime_info(tmp_path, dataset):
282288
import zarr

0 commit comments

Comments
 (0)