Skip to content

Commit

Permalink
Merge branch 'main' of github.com:SpikeInterface/spikeinterface into …
Browse files Browse the repository at this point in the history
…waveform_tools_speedup
  • Loading branch information
samuelgarcia committed Sep 7, 2023
2 parents 2ae50e7 + c9a5136 commit b23a12a
Show file tree
Hide file tree
Showing 53 changed files with 2,564 additions and 2,075 deletions.
223 changes: 12 additions & 211 deletions doc/how_to/get_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -497,218 +497,19 @@ accomodate the duration:
qm = sqm.compute_quality_metrics(we_TDC, qm_params=qm_params)
display(qm)
.. parsed-literal::
.. raw:: html

<div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>num_spikes</th>
<th>firing_rate</th>
<th>presence_ratio</th>
<th>snr</th>
<th>isi_violations_ratio</th>
<th>isi_violations_count</th>
<th>rp_contamination</th>
<th>rp_violations</th>
<th>sliding_rp_violation</th>
<th>amplitude_cutoff</th>
<th>amplitude_median</th>
<th>drift_ptp</th>
<th>drift_std</th>
<th>drift_mad</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>30</td>
<td>3.0</td>
<td>0.9</td>
<td>27.258799</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>NaN</td>
<td>0.200717</td>
<td>307.199036</td>
<td>1.313088</td>
<td>0.492143</td>
<td>0.476104</td>
</tr>
<tr>
<th>1</th>
<td>51</td>
<td>5.1</td>
<td>1.0</td>
<td>24.213808</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>NaN</td>
<td>0.500000</td>
<td>274.444977</td>
<td>0.934371</td>
<td>0.325045</td>
<td>0.216362</td>
</tr>
<tr>
<th>2</th>
<td>53</td>
<td>5.3</td>
<td>0.9</td>
<td>24.229277</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>NaN</td>
<td>0.500000</td>
<td>270.204590</td>
<td>0.901922</td>
<td>0.392344</td>
<td>0.372247</td>
</tr>
<tr>
<th>3</th>
<td>50</td>
<td>5.0</td>
<td>1.0</td>
<td>27.080778</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>NaN</td>
<td>0.500000</td>
<td>312.545715</td>
<td>0.598991</td>
<td>0.225554</td>
<td>0.185147</td>
</tr>
<tr>
<th>4</th>
<td>36</td>
<td>3.6</td>
<td>1.0</td>
<td>9.544292</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>NaN</td>
<td>0.207231</td>
<td>107.953278</td>
<td>1.913661</td>
<td>0.659317</td>
<td>0.507955</td>
</tr>
<tr>
<th>5</th>
<td>42</td>
<td>4.2</td>
<td>1.0</td>
<td>13.283191</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>NaN</td>
<td>0.204838</td>
<td>151.833191</td>
<td>0.671453</td>
<td>0.231825</td>
<td>0.156004</td>
</tr>
<tr>
<th>6</th>
<td>48</td>
<td>4.8</td>
<td>1.0</td>
<td>8.319447</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>NaN</td>
<td>0.500000</td>
<td>91.358444</td>
<td>2.391275</td>
<td>0.885580</td>
<td>0.772367</td>
</tr>
<tr>
<th>7</th>
<td>193</td>
<td>19.3</td>
<td>1.0</td>
<td>8.690839</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>0.155</td>
<td>0.500000</td>
<td>103.491577</td>
<td>0.710640</td>
<td>0.300565</td>
<td>0.316645</td>
</tr>
<tr>
<th>8</th>
<td>129</td>
<td>12.9</td>
<td>1.0</td>
<td>11.167040</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>0.310</td>
<td>0.500000</td>
<td>128.252319</td>
<td>0.985251</td>
<td>0.375529</td>
<td>0.301622</td>
</tr>
<tr>
<th>9</th>
<td>110</td>
<td>11.0</td>
<td>1.0</td>
<td>8.377251</td>
<td>0.0</td>
<td>0</td>
<td>0.0</td>
<td>0</td>
<td>0.270</td>
<td>0.203415</td>
<td>98.207291</td>
<td>1.386857</td>
<td>0.526532</td>
<td>0.410644</td>
</tr>
</tbody>
</table>
</div>
id num_spikes firing_rate presence_ratio snr isi_violations_ratio isi_violations_count rp_contamination rp_violations sliding_rp_violation amplitude_cutoff amplitude_median drift_ptp drift_std drift_mad
0 30 3.0 0.9 27.258799 0.0 0 0.0 0 NaN 0.200717 307.199036 1.313088 0.492143 0.476104
1 51 5.1 1.0 24.213808 0.0 0 0.0 0 NaN 0.500000 274.444977 0.934371 0.325045 0.216362
2 53 5.3 0.9 24.229277 0.0 0 0.0 0 NaN 0.500000 270.204590 0.901922 0.392344 0.372247
3 50 5.0 1.0 27.080778 0.0 0 0.0 0 NaN 0.500000 312.545715 0.598991 0.225554 0.185147
4 36 3.6 1.0 9.544292 0.0 0 0.0 0 NaN 0.207231 107.953278 1.913661 0.659317 0.507955
5 42 4.2 1.0 13.283191 0.0 0 0.0 0 NaN 0.204838 151.833191 0.671453 0.231825 0.156004
6 48 4.8 1.0 8.319447 0.0 0 0.0 0 NaN 0.500000 91.358444 2.391275 0.885580 0.772367
7 193 19.3 1.0 8.690839 0.0 0 0.0 0 0.155 0.500000 103.491577 0.710640 0.300565 0.316645
8 129 12.9 1.0 11.167040 0.0 0 0.0 0 0.310 0.500000 128.252319 0.985251 0.375529 0.301622
9 110 11.0 1.0 8.377251 0.0 0 0.0 0 0.270 0.203415 98.207291 1.386857 0.526532 0.410644
Quality metrics are also extensions (and become part of the waveform
Expand Down
2 changes: 2 additions & 0 deletions doc/modules/qualitymetrics/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ References
.. [Hruschka] Hruschka, E.R., de Castro, L.N., Campello R.J.G.B. "Evolutionary algorithms for clustering gene-expression data." Fourth IEEE International Conference on Data Mining (ICDM'04) 2004, pp 403-406.
.. [Gruen] Sonja Grün, Moshe Abeles, and Markus Diesmann. Impact of higher-order correlations on coincidence distributions of massively parallel data. In International School on Neural Networks, Initiated by IIASS and EMFCSC, volume 5286, 96–114. Springer, 2007.
.. [IBL] International Brain Laboratory. “Spike sorting pipeline for the International Brain Laboratory”. 4 May 2022.
.. [Jackson] Jadin Jackson, Neil Schmitzer-Torbert, K.D. Harris, and A.D. Redish. Quantitative assessment of extracellular multichannel recording quality using measures of cluster separation. Soc Neurosci Abstr, 518, 01 2005.
Expand Down
49 changes: 49 additions & 0 deletions doc/modules/qualitymetrics/synchrony.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Synchrony Metrics (:code:`synchrony`)
=====================================

Calculation
-----------
This function is providing a metric for the presence of synchronous spiking events across multiple spike trains.

The complexity is used to characterize synchronous events within the same spike train and across different spike
trains. This way synchronous events can be found both in multi-unit and single-unit spike trains.
Complexity is calculated by counting the number of spikes (i.e. non-empty bins) that occur at the same sample index,
within and across spike trains.

Synchrony metrics can be computed for different synchrony sizes (>1), defining the number of simultaneous spikes to count.



Expectation and use
-------------------

A larger value indicates a higher synchrony of the respective spike train with the other spike trains.
Larger values, especially for larger sizes, indicate a higher probability of noisy spikes in spike trains.

Example code
------------

.. code-block:: python
import spikeinterface.qualitymetrics as qm
# Make recording, sorting and wvf_extractor object for your data.
synchrony = qm.compute_synchrony_metrics(wvf_extractor, synchrony_sizes=(2, 4, 8))
# synchrony is a tuple of dicts with the synchrony metrics for each unit
Links to original implementations
---------------------------------

The SpikeInterface implementation is a partial port of the low-level complexity functions from `Elephant - Electrophysiology Analysis Toolkit <https://github.com/NeuralEnsemble/elephant/blob/master/elephant/spike_train_synchrony.py#L245>`_

References
----------

.. automodule:: spikeinterface.toolkit.qualitymetrics.misc_metrics

.. autofunction:: compute_synchrony_metrics

Literature
----------

Based on concepts described in Gruen_
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ full = [
"networkx",
"distinctipy",
"matplotlib",
"cuda-python; sys_platform != 'darwin'",
"cuda-python; platform_system != 'Darwin'",
"numba",
]

Expand Down Expand Up @@ -151,9 +151,9 @@ docs = [
# for notebooks in the gallery
"MEArec", # Use as an example
"datalad==0.16.2", # Download mearec data, not sure if needed as is installed with conda as well because of git-annex
"pandas", # Don't know where this is needed
"hdbscan>=0.8.33", # For sorters, probably spikingcircus
"numba", # For sorters, probably spikingcircus
"pandas", # in the modules gallery comparison tutorial
"hdbscan>=0.8.33", # For sorters spykingcircus2 + tridesclous
"numba", # For many postprocessing functions
# for release we need pypi, so this needs to be commented
"probeinterface @ git+https://github.com/SpikeInterface/probeinterface.git", # We always build from the latest version
"neo @ git+https://github.com/NeuralEnsemble/python-neo.git", # We always build from the latest version
Expand Down
25 changes: 9 additions & 16 deletions src/spikeinterface/comparison/hybrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
BaseSorting,
WaveformExtractor,
NumpySorting,
NpzSortingExtractor,
InjectTemplatesRecording,
)
from spikeinterface.core.core_tools import define_function_from_class
from spikeinterface.core import generate_sorting
from spikeinterface.core.generate import generate_sorting, InjectTemplatesRecording, _ensure_seed


class HybridUnitsRecording(InjectTemplatesRecording):
Expand Down Expand Up @@ -60,6 +58,7 @@ def __init__(
amplitude_std: float = 0.0,
refractory_period_ms: float = 2.0,
injected_sorting_folder: Union[str, Path, None] = None,
seed=None,
):
num_samples = [
parent_recording.get_num_frames(seg_index) for seg_index in range(parent_recording.get_num_segments())
Expand All @@ -80,8 +79,8 @@ def __init__(
num_units=len(templates),
sampling_frequency=fs,
durations=durations,
firing_rate=firing_rate,
refractory_period=refractory_period_ms,
firing_rates=firing_rate,
refractory_period_ms=refractory_period_ms,
)
# save injected sorting if necessary
self.injected_sorting = injected_sorting
Expand All @@ -90,17 +89,10 @@ def __init__(
self.injected_sorting = self.injected_sorting.save(folder=injected_sorting_folder)

if amplitude_factor is None:
amplitude_factor = [
[
np.random.normal(
loc=1.0,
scale=amplitude_std,
size=len(self.injected_sorting.get_unit_spike_train(unit_id, segment_index=seg_index)),
)
for unit_id in self.injected_sorting.unit_ids
]
for seg_index in range(parent_recording.get_num_segments())
]
seed = _ensure_seed(seed)
rng = np.random.default_rng(seed=seed)
num_spikes = self.injected_sorting.to_spike_vector().size
amplitude_factor = rng.normal(loc=1.0, scale=amplitude_std, size=num_spikes)

InjectTemplatesRecording.__init__(
self, self.injected_sorting, templates, nbefore, amplitude_factor, parent_recording, num_samples
Expand All @@ -116,6 +108,7 @@ def __init__(
amplitude_std=amplitude_std,
refractory_period_ms=refractory_period_ms,
injected_sorting_folder=None,
seed=seed,
)


Expand Down
3 changes: 2 additions & 1 deletion src/spikeinterface/comparison/multicomparisons.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ def __init__(
self, sampling_frequency, multisortingcomparison, min_agreement_count=1, min_agreement_count_only=False
):
self._msc = multisortingcomparison
self._is_json_serializable = False

if min_agreement_count_only:
unit_ids = list(
Expand All @@ -245,6 +244,8 @@ def __init__(

BaseSorting.__init__(self, sampling_frequency=sampling_frequency, unit_ids=unit_ids)

self._is_json_serializable = False

if len(unit_ids) > 0:
for k in ("agreement_number", "avg_agreement", "unit_ids"):
values = [self._msc._new_units[unit_id][k] for unit_id in unit_ids]
Expand Down
Loading

0 comments on commit b23a12a

Please sign in to comment.