Skip to content

Commit 813d964

Browse files
authored
Merge pull request #4184 from alejoe91/np-adc-sample-order
Update `get_neuropixels_sample_shifts_from_probe` to use `adc_sample_order`
2 parents 9ec48d7 + 15a591c commit 813d964

1 file changed

Lines changed: 20 additions & 19 deletions

File tree

src/spikeinterface/extractors/neuropixels_utils.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ def get_neuropixels_sample_shifts_from_probe(probe: Probe, stream_name: str = "a
2424
sample_shifts : np.ndarray
2525
Array of relative phase shifts for each channel.
2626
"""
27-
# get inter-sample shifts based on the probe information and mux channels
28-
model_description = probe.annotations.get("description", None)
27+
# get inter-sample shifts based on the probe information and ADC sampling pattern
2928
num_channels_per_adc = probe.annotations.get("num_channels_per_adc", None)
30-
mux_channels = probe.contact_annotations.get("mux_channels", None)
31-
num_readouts_channels = probe.annotations.get("num_readout_channels", None)
29+
adc_sample_order = probe.contact_annotations.get("adc_sample_order", None)
30+
ap_sample_frequency_hz = probe.annotations.get("ap_sample_frequency_hz", None)
31+
lf_sample_frequency_hz = probe.annotations.get("lf_sample_frequency_hz", None)
3232

3333
if (
34-
model_description is None
35-
or num_channels_per_adc is None
36-
or mux_channels is None
37-
or num_readouts_channels is None
34+
num_channels_per_adc is None
35+
or adc_sample_order is None
36+
or ap_sample_frequency_hz is None
37+
or lf_sample_frequency_hz is None
3838
):
3939
warning_message = (
4040
"Unable to find inter-sample shifts in the Neuropixels probe metadata. "
@@ -43,17 +43,18 @@ def get_neuropixels_sample_shifts_from_probe(probe: Probe, stream_name: str = "a
4343
warnings.warn(warning_message, UserWarning, stacklevel=2)
4444
return None
4545

46-
if "2.0" in model_description:
47-
# for Neuropixels 2.0 (and newer), the number of cycles in ADC is equal to the number of channels per ADC
48-
num_cycles_in_adc = num_channels_per_adc
49-
else:
50-
# for Neuropixels 1.0 technology, the number of cycles for the AP stream is +1 because
51-
# the last cycle is used for the LFP stream
52-
num_cycles_in_adc = num_channels_per_adc + 1 if "ap" in stream_name.lower() else num_channels_per_adc
46+
# The number of cycles is determined by the number of channels per ADC times 1 + the ratio
47+
# between the lf and ap sample rate.
48+
# For NP 1.0, this gives 13 cycles: 12 * (1 + 2500 / 30000) = 13
49+
# For NP 2.0, the lf sample rate is 0 and so the number of cycles is equal to the number of
50+
# channels per ADC.
51+
# see: https://github.com/billkarsh/ProbeTable/issues/3#issuecomment-3438263027
52+
num_cycles_in_adc = int(num_channels_per_adc * (1 + lf_sample_frequency_hz / ap_sample_frequency_hz))
5353

54-
sample_shifts = np.zeros_like(mux_channels, dtype=float)
55-
for mux_channel in mux_channels:
56-
sample_shifts[mux_channels == mux_channel] = np.arange(num_channels_per_adc) / num_cycles_in_adc
54+
# The inter-sample shifts are given by the adc sample order divided by the number of cycles in ADC
55+
# This makes sure we also handle cases where only a subset of channels are recorded
56+
# see: https://github.com/SpikeInterface/spikeinterface/issues/4144
57+
sample_shifts = adc_sample_order / num_cycles_in_adc
5758

5859
return sample_shifts
5960

@@ -157,7 +158,7 @@ def get_neuropixels_channel_groups(num_channels=384, num_channels_per_adc=12):
157158
"""
158159
warnings.warn(
159160
"`get_neuropixels_channel_groups` is deprecated and will be removed in 0.104.0. "
160-
"Use the `mux_channels` contact annotation from the `Probe` instead.",
161+
"Use the `adc_group` contact annotation from the `Probe` instead.",
161162
DeprecationWarning,
162163
stacklevel=2,
163164
)

0 commit comments

Comments
 (0)