From 3dc57290dbde0aeaa5048f2301ee75015a93fe26 Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Mon, 29 Dec 2025 15:43:44 +0100 Subject: [PATCH 1/4] Test IBL extractors tests failing for PI update --- src/spikeinterface/extractors/tests/test_iblextractors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/extractors/tests/test_iblextractors.py b/src/spikeinterface/extractors/tests/test_iblextractors.py index 972a8e7bb0..56d01e38cf 100644 --- a/src/spikeinterface/extractors/tests/test_iblextractors.py +++ b/src/spikeinterface/extractors/tests/test_iblextractors.py @@ -76,8 +76,8 @@ def test_offsets(self): def test_probe_representation(self): probe = self.recording.get_probe() - expected_probe_representation = "Probe - 384ch - 1shanks" - assert repr(probe) == expected_probe_representation + expected_probe_representation = "Probe - 384ch" + assert expected_probe_representation in repr(probe) def test_property_keys(self): expected_property_keys = [ From 61c317aba92608d9f096a3a374bc3d43e27faaba Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Fri, 6 Mar 2026 10:09:46 -0800 Subject: [PATCH 2/4] Fix OpenEphys tests --- .../extractors/neoextractors/openephys.py | 20 ++++++++++++------- .../extractors/tests/test_neoextractors.py | 3 +++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/spikeinterface/extractors/neoextractors/openephys.py b/src/spikeinterface/extractors/neoextractors/openephys.py index 1c39a1b97c..1d16df534b 100644 --- a/src/spikeinterface/extractors/neoextractors/openephys.py +++ b/src/spikeinterface/extractors/neoextractors/openephys.py @@ -351,13 +351,19 @@ def __init__( # Ensure device channel index corresponds to channel_ids probe_channel_names = probe.contact_annotations.get("channel_name", None) if probe_channel_names is not None and not np.array_equal(probe_channel_names, self.channel_ids): - device_channel_indices = [] - probe_channel_names = list(probe_channel_names) - device_channel_indices = np.zeros(len(self.channel_ids), dtype=int) - for i, ch in enumerate(self.channel_ids): - index_in_probe = probe_channel_names.index(ch) - device_channel_indices[index_in_probe] = i - probe.set_device_channel_indices(device_channel_indices) + if set(probe_channel_names) == set(self.channel_ids): + device_channel_indices = [] + probe_channel_names = list(probe_channel_names) + device_channel_indices = np.zeros(len(self.channel_ids), dtype=int) + for i, ch in enumerate(self.channel_ids): + index_in_probe = probe_channel_names.index(ch) + device_channel_indices[index_in_probe] = i + probe.set_device_channel_indices(device_channel_indices) + else: + warnings.warn( + "Channel names in the probe do not match the channel ids from Neo. " + "Cannot set device channel indices, but this might lead to incorrect probe geometries" + ) if probe.shank_ids is not None: self.set_probe(probe, in_place=True, group_mode="by_shank") diff --git a/src/spikeinterface/extractors/tests/test_neoextractors.py b/src/spikeinterface/extractors/tests/test_neoextractors.py index f80f62ebf0..f40b4d05ab 100644 --- a/src/spikeinterface/extractors/tests/test_neoextractors.py +++ b/src/spikeinterface/extractors/tests/test_neoextractors.py @@ -121,6 +121,9 @@ class OpenEphysBinaryRecordingTest(RecordingCommonTestSuite, unittest.TestCase): ("openephysbinary/v0.5.x_two_nodes", {"stream_id": "0"}), ("openephysbinary/v0.5.x_two_nodes", {"stream_id": "1"}), ("openephysbinary/v0.6.x_neuropixels_multiexp_multistream", {"stream_id": "0", "block_index": 0}), + # TODO: block_indices 1/2 of v0.6.x_neuropixels_multiexp_multistream have a mismatch in the channel names between + # the settings files (starting with CH0) and structure.oebin (starting at CH1). + # Currently, the extractor will skip remapping to match order in oebin and settings file, raising a warning ("openephysbinary/v0.6.x_neuropixels_multiexp_multistream", {"stream_id": "1", "block_index": 1}), ( "openephysbinary/v0.6.x_neuropixels_multiexp_multistream", From 96bd8e98535a52b10eb249f18feedec5ff922b89 Mon Sep 17 00:00:00 2001 From: Chris Halcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Wed, 25 Mar 2026 17:05:34 +0000 Subject: [PATCH 3/4] Make `get_data` for valid unit periods use unit ids, not indices (#4468) --- .../tests/test_valid_unit_periods.py | 17 +++++++++++++---- .../postprocessing/valid_unit_periods.py | 6 +++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/spikeinterface/postprocessing/tests/test_valid_unit_periods.py b/src/spikeinterface/postprocessing/tests/test_valid_unit_periods.py index 6d34264eac..3ba057d059 100644 --- a/src/spikeinterface/postprocessing/tests/test_valid_unit_periods.py +++ b/src/spikeinterface/postprocessing/tests/test_valid_unit_periods.py @@ -34,8 +34,8 @@ def test_user_defined_periods(self): periods[idx]["unit_index"] = unit_index period_start = num_samples // 4 period_duration = num_samples // 2 - periods[idx]["start_sample_index"] = period_start - periods[idx]["end_sample_index"] = period_start + period_duration + periods[idx]["start_sample_index"] = period_start - unit_index * 10 + periods[idx]["end_sample_index"] = period_start + period_duration + unit_index * 10 periods[idx]["segment_index"] = segment_index sorting_analyzer = self._prepare_sorting_analyzer( @@ -48,8 +48,17 @@ def test_user_defined_periods(self): minimum_valid_period_duration=1, ) # check that valid periods correspond to user defined periods - ext_periods = ext.get_data(outputs="numpy") - np.testing.assert_array_equal(ext_periods, periods) + ext_periods_numpy = ext.get_data(outputs="numpy") + np.testing.assert_array_equal(ext_periods_numpy, periods) + + # check that `numpy` and `by_unit` outputs are the same + ext_periods_by_unit = ext.get_data(outputs="by_unit") + for segment_index in range(num_segments): + for unit_index, unit_id in enumerate(unit_ids): + periods_numpy_seg0 = ext_periods_numpy[ext_periods_numpy["segment_index"] == segment_index] + periods_numpy_unit = periods_numpy_seg0[periods_numpy_seg0["unit_index"] == unit_index] + period = [(periods_numpy_unit["start_sample_index"][0], periods_numpy_unit["end_sample_index"][0])] + assert period == ext_periods_by_unit[segment_index][unit_id] def test_user_defined_periods_as_arrays(self): unit_ids = self.sorting.unit_ids diff --git a/src/spikeinterface/postprocessing/valid_unit_periods.py b/src/spikeinterface/postprocessing/valid_unit_periods.py index 020396e38d..a76cd703aa 100644 --- a/src/spikeinterface/postprocessing/valid_unit_periods.py +++ b/src/spikeinterface/postprocessing/valid_unit_periods.py @@ -548,12 +548,12 @@ def _get_data(self, outputs: str = "by_unit"): for segment_index in range(self.sorting_analyzer.get_num_segments()): segment_mask = good_periods_array["segment_index"] == segment_index periods_dict = {} - for unit_index in unit_ids: - periods_dict[unit_index] = [] + for unit_index, unit_id in enumerate(unit_ids): + periods_dict[unit_id] = [] unit_mask = good_periods_array["unit_index"] == unit_index good_periods_unit_segment = good_periods_array[segment_mask & unit_mask] for start, end in good_periods_unit_segment[["start_sample_index", "end_sample_index"]]: - periods_dict[unit_index].append((start, end)) + periods_dict[unit_id].append((start, end)) good_periods.append(periods_dict) return good_periods From c3cd1679a37268bc73b56a06b01f4d35bd1da9bb Mon Sep 17 00:00:00 2001 From: hayleybounds Date: Mon, 30 Mar 2026 08:57:15 +0100 Subject: [PATCH 4/4] =?UTF-8?q?Fix:=20Align=20CompressedBinaryIBLExtractor?= =?UTF-8?q?=20with=20updated=20get=5Fneuropixels=5Fsample=5Fshifts=20s?= =?UTF-8?q?=E2=80=A6=20(#4477)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/spikeinterface/extractors/cbin_ibl.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/spikeinterface/extractors/cbin_ibl.py b/src/spikeinterface/extractors/cbin_ibl.py index 4b222d7e59..2a53b999e3 100644 --- a/src/spikeinterface/extractors/cbin_ibl.py +++ b/src/spikeinterface/extractors/cbin_ibl.py @@ -106,14 +106,7 @@ def __init__(self, folder_path=None, load_sync_channel=False, stream_name="ap", else: self.set_probe(probe, in_place=True) - # load num_channels_per_adc depending on probe type - ptype = probe.annotations["probe_type"] - - if ptype in [21, 24]: # NP2.0 - num_channels_per_adc = 16 - else: # NP1.0 - num_channels_per_adc = 12 - sample_shifts = get_neuropixels_sample_shifts_from_probe(probe, num_channels_per_adc) + sample_shifts = get_neuropixels_sample_shifts_from_probe(probe) self.set_property("inter_sample_shift", sample_shifts) self._kwargs = {