Skip to content

Conversation

@chrishalcrow
Copy link
Member

@chrishalcrow chrishalcrow commented Mar 13, 2025

Related to #3711

Allows aggregate_channels to accept a dict of recordings. This allows for the workflow (once #3711 is merged) of the kind:

split_recordings = recording.split_by('group')
preprocessed_recordings = si.common_reference(si.bandpass_filter(split_recordings))
aggregated_preprocessing_recording = si.aggregate_channels(preprocessed_recordings)

or the truly horrifying

preprocessed_recording =  si.aggregate_channels(si.common_reference(si.bandpass_filter(recording.split_by('group'))))

edit: PR is mostly new tests

@chrishalcrow chrishalcrow added enhancement New feature or request preprocessing Related to preprocessing module labels Mar 13, 2025
Comment on lines 23 to 34
# Check if the recordings were previously split using `split_by`
if recording_list[0].get_annotation("split_by_property") is None:
# If default 'group'ing (all equal 0), we label the recordings using the 'group' property
recording_groups = []
for recording in recording_list:
if (group_property := recording.get_property("group")) is not None:
recording_groups.extend(group_property)
else:
recording_groups.extend([0])
if np.all(np.unique(recording_groups) == np.array([0])):
for group_id, recording in enumerate(recording_list):
recording.set_property("group", group_id * np.ones(recording.get_num_channels()))
Copy link
Member

Choose a reason for hiding this comment

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

This should be done after the else, because it applies to both dicts and lists inputs. Right?

Copy link
Member

Choose a reason for hiding this comment

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

No you're right. In case of dicts properties are correctly handled later

Copy link
Member Author

@chrishalcrow chrishalcrow Mar 13, 2025

Choose a reason for hiding this comment

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

I think we're both right: we should use the dictionary keys for group if we don't know how the recording was split up (ie if there's no split_by_property and groups are all 0). I've added this

Copy link
Member Author

Choose a reason for hiding this comment

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

I also refactored a bit so this gross bit of code is contained

Comment on lines 135 to 157
# If we don't label at all, aggregation will add a 'group' label
recording1.set_property("group", [0, 0, 0, 0])
recording2.set_property("group", [0, 0])
aggregated_recording = aggregate_channels([recording1, recording2])
group_property = aggregated_recording.get_property("group")
assert np.all(group_property == [0, 0, 0, 0, 1, 1])

# If we have different group labels, these should be respected
recording1.set_property("group", [2, 2, 2, 2])
recording2.set_property("group", [6, 6])
aggregated_recording = aggregate_channels([recording1, recording2])
group_property = aggregated_recording.get_property("group")
assert np.all(group_property == [2, 2, 2, 2, 6, 6])

# If we use `split_by`, aggregation should retain the split_by property, even if we only pass the list
recording1.set_property("user_group", [6, 7, 6, 7])
recording_list = list(recording1.split_by("user_group").values())
aggregated_recording = aggregate_channels(recording_list)
group_property = aggregated_recording.get_property("group")
assert np.all(group_property == [2, 2, 2, 2])
user_group_property = aggregated_recording.get_property("user_group")
# Note, aggregation reorders the channel_ids into the order of the ids of each individual recording
assert np.all(user_group_property == [6, 6, 7, 7])
Copy link
Member

Choose a reason for hiding this comment

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

Nice :)

Copy link
Member

@zm711 zm711 left a comment

Choose a reason for hiding this comment

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

Two small comments (I think)

@alejoe91
Copy link
Member

Thanks @chrishalcrow

LGTM! Ready to merge?

Copy link
Member

@zm711 zm711 left a comment

Choose a reason for hiding this comment

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

Me too

@alejoe91 alejoe91 merged commit cd75634 into SpikeInterface:main Mar 14, 2025
15 checks passed
@chrishalcrow chrishalcrow deleted the add-dicts-to-aggregate-channels branch March 14, 2025 14:12
@samuelgarcia
Copy link
Member

Parfait.

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

Labels

enhancement New feature or request preprocessing Related to preprocessing module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants