Skip to content

Commit 3cef709

Browse files
authored
Merge pull request #3740 from h-mayorquin/fix_chris_bug
Fix `aggregate_channels` merging of channel ids with different string sub type
2 parents ec5037e + d5847f7 commit 3cef709

3 files changed

Lines changed: 34 additions & 8 deletions

File tree

src/spikeinterface/core/channelsaggregationrecording.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,17 @@ def __init__(self, recording_list, renamed_channel_ids=None):
3030
), "'renamed_channel_ids' doesn't have the right size or has duplicates!"
3131
channel_ids = list(renamed_channel_ids)
3232
else:
33-
# Collect channel IDs from all recordings
34-
all_channels_have_same_type = np.unique([rec.channel_ids.dtype for rec in recording_list]).size == 1
35-
all_channel_ids_are_unique = False
36-
if all_channels_have_same_type:
33+
34+
# Explicitly check if all channel_ids arrays are either all integers or all strings.
35+
all_ids_are_int_dtype = all(np.issubdtype(rec.channel_ids.dtype, np.integer) for rec in recording_list)
36+
all_ids_are_str_dtype = all(np.issubdtype(rec.channel_ids.dtype, np.str_) for rec in recording_list)
37+
38+
all_ids_have_same_dtype = all_ids_are_int_dtype or all_ids_are_str_dtype
39+
if all_ids_have_same_dtype:
3740
combined_ids = np.concatenate([rec.channel_ids for rec in recording_list])
3841
all_channel_ids_are_unique = np.unique(combined_ids).size == num_all_channels
3942

40-
if all_channels_have_same_type and all_channel_ids_are_unique:
43+
if all_ids_have_same_dtype and all_channel_ids_are_unique:
4144
channel_ids = combined_ids
4245
else:
4346
# If IDs are not unique or not of the same type, use default as stringify IDs

src/spikeinterface/core/channelslice.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@ def __init__(self, parent_recording, channel_ids=None, renamed_channel_ids=None)
3131
parents_chan_ids = parent_recording.get_channel_ids()
3232

3333
# some checks
34-
assert all(
35-
chan_id in parents_chan_ids for chan_id in self._channel_ids
36-
), "ChannelSliceRecording : channel ids are not all in parents"
34+
# We use lists to compare numpy scalar types as their python versions (e.g. int vs int64())
35+
channel_ids_not_in_parents = [id for id in self._channel_ids.tolist() if id not in parents_chan_ids.tolist()]
36+
assert (
37+
len(channel_ids_not_in_parents) == 0
38+
), f"ChannelSliceRecording : channel ids {channel_ids_not_in_parents} are not all in parent ids {parents_chan_ids}"
39+
3740
assert len(self._channel_ids) == len(
3841
self._renamed_channel_ids
3942
), "ChannelSliceRecording: renamed channel_ids must be the same size"

src/spikeinterface/core/tests/test_channelsaggregationrecording.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,25 @@ def test_channel_aggregation_does_not_preserve_ids_not_the_same_type():
118118
assert list(aggregated_recording.get_channel_ids()) == ["0", "1", "2", "3", "4"]
119119

120120

121+
def test_channel_aggregation_with_string_dtypes_of_different_size():
122+
"""
123+
Fixes issue https://github.com/SpikeInterface/spikeinterface/issues/3733
124+
125+
This tests that the channel ids are propagated in the aggregation even if they are strings of different
126+
string dtype sizes.
127+
"""
128+
recording1 = generate_recording(num_channels=2, durations=[10], set_probe=False)
129+
recording1 = recording1.rename_channels(new_channel_ids=np.array(["8", "9"], dtype="<U1"))
130+
131+
recording2 = generate_recording(num_channels=2, durations=[10], set_probe=False)
132+
recording2 = recording2.rename_channels(new_channel_ids=np.array(["10", "11"], dtype="<U2"))
133+
134+
aggregated_recording = aggregate_channels([recording1, recording2])
135+
assert aggregated_recording.get_num_channels() == 4
136+
aggregated_recording_channel_ids = list(aggregated_recording.get_channel_ids())
137+
assert aggregated_recording_channel_ids == ["8", "9", "10", "11"]
138+
assert aggregated_recording.channel_ids.dtype == np.dtype("<U2")
139+
140+
121141
if __name__ == "__main__":
122142
test_channelsaggregationrecording()

0 commit comments

Comments
 (0)