Quality Metrics Tutorial

After spike sorting, you might want to validate the goodness of the sorted units. This can be done using the toolkit.qualitymetrics submodule, which computes several quality metrics of the sorted units.

import spikeinterface as si
import spikeinterface.extractors as se
import spikeinterface.toolkit as st

First, let’s download a simulated dataset from the repo ‘https://gin.g-node.org/NeuralEnsemble/ephy_testing_data

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

Out:

MEArecRecordingExtractor: 32 channels - 1 segments - 32.0kHz - 10.000s
  file_path: /home/docs/spikeinterface_datasets/ephy_testing_data/mearec/mearec_test_10s.h5
MEArecSortingExtractor: 10 units - 1 segments - 32.0kHz
  file_path: /home/docs/spikeinterface_datasets/ephy_testing_data/mearec/mearec_test_10s.h5

Extract spike waveforms

For convenience, metrics are computed on the WaveformExtractor object, because it contains a reference to the “Recording” and the “Sorting” objects:

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

Out:

WaveformExtractor: 32 channels - 10 units - 1 segments
  before:32 after64 n_per_units: 500

The spikeinterface.toolkit.qualitymetrics submodule has a set of functions that allow users to compute metrics in a compact and easy way. To compute a single metric, one can simply run one of the quality metric functions as shown below. Each function has a variety of adjustable parameters that can be tuned.

firing_rates = st.compute_firing_rate(we)
print(firing_rates)
isi_violations_rate, isi_violations_count = st.compute_isi_violations(we)
print(isi_violations_rate)
snrs = st.compute_snrs(we)
print(snrs)

Out:

{'#0': 5.3, '#1': 5.0, '#2': 4.3, '#3': 3.0, '#4': 4.8, '#5': 3.7, '#6': 5.1, '#7': 11.1, '#8': 19.5, '#9': 12.9}
{'#0': 0.0, '#1': 0.0, '#2': 0.0, '#3': 0.0, '#4': 0.0, '#5': 0.0, '#6': 0.0, '#7': 0.0, '#8': 0.0, '#9': 0.0}
{'#0': 23.323524, '#1': 25.331213, '#2': 12.077727, '#3': 21.50291, '#4': 6.5995317, '#5': 6.964448, '#6': 20.011555, '#7': 7.321117, '#8': 6.627583, '#9': 7.2109632}

Some metrics are based on the principal component scores, so they require a WaveformsPrincipalComponent object as input:

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

pc_metrics = st.calculate_pc_metrics(pc, metric_names=['nearest_neighbor'])
print(pc_metrics)

Out:

WaveformPrincipalComponent: 32 channels - 1 segments
  mode:by_channel_local n_components:3
{'nn_hit_rate': {'#0': 0.9937106918238994, '#1': 0.9466666666666667, '#2': 0.9069767441860465, '#3': 0.9888888888888889, '#4': 0.9791666666666666, '#5': 0.963963963963964, '#6': 0.9803921568627451, '#7': 0.9333333333333333, '#8': 0.9656357388316151, '#9': 0.9431524547803618}, 'nn_miss_rate': {'#0': 0.004335260115606936, '#1': 0.0019184652278177458, '#2': 0.004273504273504274, '#3': 0.0, '#4': 0.0014347202295552368, '#5': 0.0018832391713747645, '#6': 0.0004803073967339097, '#7': 0.009973753280839895, '#8': 0.016333938294010888, '#9': 0.010822510822510822}}

To compute more than one metric at once, we can use the compute_quality_metrics function and indicate which metrics we want to compute. This will return a pandas dataframe:

metrics = st.compute_quality_metrics(we, waveform_principal_component=pc)
print(metrics)

Out:

    num_spikes  firing_rate  ...       l_ratio    d_prime
#0          53          5.3  ...           NaN  21.714819
#1          50          5.0  ...           NaN  25.501340
#2          43          4.3  ...           NaN  26.145189
#3          30          3.0  ...           NaN  35.540184
#4          48          4.8  ...           NaN  22.019808
#5          37          3.7  ...           NaN  19.050350
#6          51          5.1  ...           NaN  31.515678
#7         111         11.1  ...  5.989993e-05  15.746913
#8         195         19.5  ...  6.829692e-07  15.740553
#9         129         12.9  ...  0.000000e+00  18.791832

[10 rows x 10 columns]

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

Gallery generated by Sphinx-Gallery