Curation Tutorial

After spike sorting and computing quality metrics, you can automatically curate the spike sorting output using the quality metrics.

import spikeinterface as si
import spikeinterface.extractors as se

from spikeinterface.postprocessing import compute_principal_components
from spikeinterface.qualitymetrics import compute_quality_metrics
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/spikeinterface/checkouts/0.98.0/examples/modules_gallery/qualitymetrics/plot_4_curation.py", line 11, in <module>
    import spikeinterface.extractors as se
  File "/home/docs/checkouts/readthedocs.org/user_builds/spikeinterface/conda/0.98.0/lib/python3.9/site-packages/spikeinterface/extractors/__init__.py", line 1, in <module>
    from .extractorlist import *
  File "/home/docs/checkouts/readthedocs.org/user_builds/spikeinterface/conda/0.98.0/lib/python3.9/site-packages/spikeinterface/extractors/extractorlist.py", line 15, in <module>
    from .neoextractors import *
  File "/home/docs/checkouts/readthedocs.org/user_builds/spikeinterface/conda/0.98.0/lib/python3.9/site-packages/spikeinterface/extractors/neoextractors/__init__.py", line 1, in <module>
    from .alphaomega import AlphaOmegaRecordingExtractor, AlphaOmegaEventExtractor, read_alphaomega, read_alphaomega_event
  File "/home/docs/checkouts/readthedocs.org/user_builds/spikeinterface/conda/0.98.0/lib/python3.9/site-packages/spikeinterface/extractors/neoextractors/alphaomega.py", line 3, in <module>
    from .neobaseextractor import NeoBaseRecordingExtractor, NeoBaseEventExtractor
  File "/home/docs/checkouts/readthedocs.org/user_builds/spikeinterface/conda/0.98.0/lib/python3.9/site-packages/spikeinterface/extractors/neoextractors/neobaseextractor.py", line 332, in <module>
    class NeoBaseSortingExtractor(_NeoBaseExtractor, BaseSorting):
  File "/home/docs/checkouts/readthedocs.org/user_builds/spikeinterface/conda/0.98.0/lib/python3.9/site-packages/spikeinterface/extractors/neoextractors/neobaseextractor.py", line 480, in NeoBaseSortingExtractor
    def _infer_t_start_from_signal_stream(self, segment_index: int, stream_id: Optional[str] = None) -> float | None:
TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'
First, let’s download a simulated dataset

from the repo ‘https://gin.g-node.org/NeuralEnsemble/ephy_testing_data

Let’s imagine that the ground-truth sorting is in fact the output of a sorter.

local_path = si.download_dataset(remote_path='mearec/mearec_test_10s.h5')
recording, sorting = se.read_mearec(local_path)
print(recording)
print(sorting)

First, we extract waveforms and compute their PC scores:

folder = 'wfs_mearec'
we = si.extract_waveforms(recording, sorting, folder,
                          ms_before=1, ms_after=2., max_spikes_per_unit=500,
                          n_jobs=1, chunk_size=30000)
print(we)

pc = compute_principal_components(we, load_if_exists=True, n_components=3, mode='by_channel_local')

Then we compute some quality metrics:

metrics = compute_quality_metrics(we, metric_names=['snr', 'isi_violation', 'nearest_neighbor'])
print(metrics)

We can now threshold each quality metric and select units based on some rules.

The easiest and most intuitive way is to use boolean masking with dataframe:

keep_mask = (metrics['snr'] > 7.5) & (metrics['isi_violations_ratio'] < 0.2) & (metrics['nn_hit_rate'] > 0.90)
print(keep_mask)

keep_unit_ids = keep_mask[keep_mask].index.values
print(keep_unit_ids)

And now let’s create a sorting that contains only curated units and save it, for example to an NPZ file.

curated_sorting = sorting.select_units(keep_unit_ids)
print(curated_sorting)
se.NpzSortingExtractor.write_sorting(curated_sorting, 'curated_sorting.pnz')

Total running time of the script: ( 0 minutes 0.002 seconds)

Gallery generated by Sphinx-Gallery