spikeinterface icon indicating copy to clipboard operation
spikeinterface copied to clipboard

Exception: There are no channel locations

Open TheAnton205 opened this issue 1 year ago • 3 comments

Getting the error message "Exception: There are no channel locations." Running sorting on kilosort2, through the kilosort GUI/MATLAB, sorting seems to work fine so evidently channel locations do exist on their end. Below is the error message;

ss.Kilosort2Sorter.set_kilosort2_path(r"C:\Users\lab-admin\Desktop\AnthonySpikeInterface\Kilosort-2.0")
sorting = ss.run_sorter(sorter_name='kilosort2',recording=recording,remove_existing_folder=True,output_folder='D:\\results_test2',verbose=True)
printf('Found', len(sorting.get_unit_ids()),'units')


---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
Cell In[21], line 2
      1 # run spike sorting on entire recording
----> 2 sorting_KS25 = si.run_sorter('kilosort2', recording,remove_existing_folder=True,output_folder='D:\\results_test2', verbose=True)

File ~\AppData\Roaming\Python\Python311\site-packages\spikeinterface\sorters\runsorter.py:147, in run_sorter(sorter_name, recording, output_folder, remove_existing_folder, delete_output_folder, verbose, raise_error, docker_image, singularity_image, delete_container_files, with_output, **sorter_params)
    140             container_image = singularity_image
    141     return run_sorter_container(
    142         container_image=container_image,
    143         mode=mode,
    144         **common_kwargs,
    145     )
--> 147 return run_sorter_local(**common_kwargs)

File ~\AppData\Roaming\Python\Python311\site-packages\spikeinterface\sorters\runsorter.py:172, in run_sorter_local(sorter_name, recording, output_folder, remove_existing_folder, delete_output_folder, verbose, raise_error, with_output, **sorter_params)
    170 output_folder = SorterClass.initialize_folder(recording, output_folder, verbose, remove_existing_folder)
    171 SorterClass.set_params_to_folder(recording, output_folder, sorter_params, verbose)
--> 172 SorterClass.setup_recording(recording, output_folder, verbose=verbose)
    173 SorterClass.run_from_folder(output_folder, raise_error, verbose)
    174 if with_output:

File ~\AppData\Roaming\Python\Python311\site-packages\spikeinterface\sorters\basesorter.py:226, in BaseSorter.setup_recording(cls, recording, output_folder, verbose)
    224     all_params = json.load(f)
    225     sorter_params = all_params["sorter_params"]
--> 226 cls._setup_recording(recording, sorter_output_folder, sorter_params, verbose)

File ~\AppData\Roaming\Python\Python311\site-packages\spikeinterface\sorters\external\kilosortbase.py:123, in KilosortBase._setup_recording(cls, recording, sorter_output_folder, params, verbose)
    121 @classmethod
    122 def _setup_recording(cls, recording, sorter_output_folder, params, verbose):
--> 123     cls._generate_channel_map_file(recording, sorter_output_folder)
    125     skip_kilosort_preprocessing = params.get("skip_kilosort_preprocessing", False)
    127     if (
    128         recording.binary_compatible_with(dtype="int16", time_axis=0, file_paths_lenght=1)
    129         and not skip_kilosort_preprocessing
    130     ):
    131         # no copy

File ~\AppData\Roaming\Python\Python311\site-packages\spikeinterface\sorters\external\kilosortbase.py:45, in KilosortBase._generate_channel_map_file(recording, sorter_output_folder)
     43 # prepare electrode positions for this group (only one group, the split is done in basesorter)
     44 groups = [1] * recording.get_num_channels()
---> 45 positions = np.array(recording.get_channel_locations())
     46 if positions.shape[1] != 2:
     47     raise RuntimeError("3D 'location' are not supported. Set 2D locations instead")

File ~\AppData\Roaming\Python\Python311\site-packages\spikeinterface\core\baserecordingsnippets.py:345, in BaseRecordingSnippets.get_channel_locations(self, channel_ids, axes)
    343 locations = self.get_property("location")
    344 if locations is None:
--> 345     raise Exception("There are no channel locations")
    346 locations = np.asarray(locations)[channel_indices]
    347 return select_axes(locations, axes)

Exception: There are no channel locations

SpikeInterface version: 0.99.1

My recording data is as follows:

BinaryRecordingExtractor: 384 channels - 20.0kHz - 1 segments - 108,036,352 samples 
                          5,401.82s (1.50 hours) - int16 dtype - 77.27 GiB
  file_paths: ['D:\\2023recording\\2023-12-31_1333_WT-female-adult\\2023-12-31_15-21-08\\Record Node 101\\experiment1\\recording1\\continuous\\Neuropix-PXI-100.ProbeA-AP\\continuous.dat']

Thank you in advance.

TheAnton205 avatar Mar 20 '24 21:03 TheAnton205

Hi,

How do you load the recording? Can you print(recording.get_channel_locations())

alejoe91 avatar Mar 20 '24 21:03 alejoe91

I think you loaded the dat file directly as a binary file. That doesn't load channel locations. You should use the read_openephys function:

recording = se.read_openephys("path-to-2023-12-31_15-21-08")

alejoe91 avatar Mar 21 '24 07:03 alejoe91

This worked perfectly with experiment_names! and stream_name Thank you for the swift response.

However, I am unsure of how to perform spike sorting now. I understand that with most multi segmented recordings, you can concatenate them all together into "one recording." However, in my case the segments are all separate recordings. My following recording looks like this:

recording = se.read_openephys(recording2,experiment_names="experiment1",stream_name="Record_Node_101#Neuropix-PXI-100.ProbeA-AP")
                                   13,728.15s (3.81 hours) - int16 dtype - 294.57 GiB
Segments:
Samples:   108,036,352 | 105,753,348 | 53,943,552 | 71,952,720 | 72,158,448
Durations: 3,601.21s (1.00 hours) | 3,525.11s (58.75 minutes) | 1,798.12s (29.97 minutes) | 2,398.42s (39.97 minutes) | 2,405.28s (40.09 minutes)
Memory:    77.27 GiB | 75.64 GiB | 38.58 GiB | 51.46 GiB | 51.61 GiB

Is there a way to simply set recording to one of these segments? Calling "segment_index" does not work for kilosort2:

# run spike sorting on entire recording
sorting_KS25 = si.run_sorter('kilosort2', recording,remove_existing_folder=True,output_folder='D:\\results_test2', verbose=True,segment_index=1)
ValueError: This sorter kilosort2 does not handle multi-segment recordings, use si.concatenate_recordings(...)

Maybe I am not understandings the arguments for read_openephys. The following is my folder archecture:

**...\Record_Node_101\experiment1**
     recording1
     recording2
     recording3
     recording4
     recording5

**...\Record_Node_101\experiment1\recording1**
     continuous
     events

**...\Record_Node_101\experiment1\recording1\continuous**
     Neuropix-PXI-100.ProbeA-AP
     Neuropix-PXI-100.ProbeA-LFP

**...\Record_Node_101\experiment1\recording1\continuous**
     continuous.dat

TheAnton205 avatar Mar 22 '24 20:03 TheAnton205

Nevermind, there is a function called "select_segment_recording" in the core module that I missed. Thanks for the help!

TheAnton205 avatar Mar 27 '24 19:03 TheAnton205