-
Notifications
You must be signed in to change notification settings - Fork 237
Description
Hi, I’m spike-sorting 128-channel Intan recordings from a flexible probe using Kilosort4 and running quality metrics with SpikeInterface. I generated the probe layout and channel mapping using probeinterface, attached it to the recording, and exported the results to Phy.
However, in Phy I found that the cluster–channel mapping is inconsistent with original mapping(See the screenshots below, using the cluster with the highest firing rate as an example):
I suspect this may be related to the device_channel_indices, channel ordering, or how the probe is attached, but I am not sure what the correct procedure is.
Below is the exact code used for probe construction, channel mapping, attaching the probe, waveform extraction, and exporting:
import spikeinterface.core as si
import spikeinterface.extractors as se
import probeinterface as pi
import numpy as np
from spikeinterface.qualitymetrics import (
compute_snrs,
compute_firing_rates,
compute_isi_violations,
compute_quality_metrics,
)
recording = se.read_intan('E:/Desktop/flexible electrode/LL NO 170/acute-m03-stratium/acute-m03-striatum-3_251209_152340.rhd', stream_id='0')
sorting = se.read_phy('E:/Desktop/flexible electrode/LL NO 170/acute-m03-striatum/kilosort4')
import probeinterface as pi
num_ch = 128
x = np.zeros(num_ch)
y = 776 + np.arange(num_ch) * (1500 / 128)
positions = np.column_stack((x, y))
ks_map = np.array([
73,77,74,82,83,81,90,88,102,104,108,110,117,109,118,114,75,79,
76,80,78,87,89,84,101,107,113,103,115,111,116,112,71,69,72,70,
86,85,91,92,99,100,105,106,119,121,120,122,67,65,68,66,93,64,
94,95,98,96,97,127,123,125,124,126,15,13,16,18,23,17,20,24,43,40,
39,46,47,45,48,50,11,9,12,10,14,19,25,26,37,38,49,44,51,53,52,54,
7,5,8,6,22,21,27,28,35,36,41,42,55,57,56,58,3,1,4,2,29,0,30,31,
34,32,33,63,59,61,60,62
])
ks_map_str = np.array([f"A-{i:03d}" for i in ks_map])
recording = recording.select_channels(ks_map_str)
probe = pi.Probe(ndim=2, si_units="um")
probe.set_contacts(
positions=positions[ks_map],
shapes="circle",
shape_params={"radius": 5}
)
probe.set_device_channel_indices(np.arange(128))
recording = recording.set_probe(probe)
print(probe)obe(probe)
print(probe)
recording_signed = si.unsigned_to_signed(recording)
recording_f = si.bandpass_filter(recording_signed, freq_min=300, freq_max=6000)
print(recording_f)
recording_cmr = si.common_reference(recording_f, reference="global", operator="median")
print(recording_cmr)
analyzer = si.create_sorting_analyzer(sorting=sorting, recording=recording_cmr, format="memory")
analyzer.compute("random_spikes", method="uniform", max_spikes_per_unit=600, seed=2205)
analyzer.compute("waveforms", ms_before=1.3, ms_after=2.6, n_jobs=2)
analyzer.compute("templates", operators=["average", "median", "std"])
analyzer.compute("noise_levels")
analyzer.compute("principal_components", n_components=3, mode="by_channel_global", whiten=True)
metrics = compute_quality_metrics(
analyzer,
metric_names=["snr", "isi_violation", "firing_rate", "presence_ratio", "amplitude_cutoff", "d_prime", "isolation_distance", "l_ratio"],
extension_params = {
"isi_violation":{"isi_threshold_ms":2.0}
}
)
from spikeinterface.exporters import export_to_phy
export_to_phy(sorting_analyzer=analyzer, output_folder='E:/Desktop/flexible electrode/LL NO 170/acute-m03-striatum/phy_with_metrics')Is there anything obviously wrong in my code, especially in how I construct the probe, assign device_channel_indices, or attach the probe to the recording? I’m not sure whether the mismatch in Phy is caused by incorrect channel ordering or by the way I applied the probe mapping.
Any suggestions would be greatly appreciated!

