Note
Click here to download the full example code
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)