From 83db429fb814952e6c886b35ee9fa70241a01f12 Mon Sep 17 00:00:00 2001 From: Samuel Garcia Date: Wed, 6 Mar 2024 13:49:37 +0100 Subject: [PATCH 01/28] Update exclude_sweep_ms for SimpleSortersimplesorter --- src/spikeinterface/sorters/internal/simplesorter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/sorters/internal/simplesorter.py b/src/spikeinterface/sorters/internal/simplesorter.py index 69487baf6c..7004514ec7 100644 --- a/src/spikeinterface/sorters/internal/simplesorter.py +++ b/src/spikeinterface/sorters/internal/simplesorter.py @@ -33,7 +33,7 @@ class SimpleSorter(ComponentsBasedSorter): "apply_preprocessing": False, "waveforms": {"ms_before": 1.0, "ms_after": 1.5}, "filtering": {"freq_min": 300, "freq_max": 8000.0}, - "detection": {"peak_sign": "neg", "detect_threshold": 5.0, "exclude_sweep_ms": 0.4}, + "detection": {"peak_sign": "neg", "detect_threshold": 5.0, "exclude_sweep_ms": 1.5, "radius_um": 150.0}, "features": {"n_components": 3}, "clustering": { "method": "hdbscan", From eed92daba476bb3ff140d9bf341045ea00cef704 Mon Sep 17 00:00:00 2001 From: Samuel Garcia Date: Wed, 13 Mar 2024 09:24:49 +0100 Subject: [PATCH 02/28] Proposal for auto load extensions. --- src/spikeinterface/core/sortinganalyzer.py | 43 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index 94bf1ea11c..8b5d876be8 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -8,6 +8,7 @@ import weakref import shutil import warnings +import importlib import numpy as np @@ -1057,7 +1058,7 @@ def register_result_extension(extension_class): _possible_extensions.append(extension_class) -def get_extension_class(extension_name: str): +def get_extension_class(extension_name: str, autoload=True): """ Get extension class from name and check if registered. @@ -1073,9 +1074,19 @@ def get_extension_class(extension_name: str): """ global _possible_extensions extensions_dict = {ext.extension_name: ext for ext in _possible_extensions} - assert ( - extension_name in extensions_dict - ), f"Extension '{extension_name}' is not registered, please import related module before use" + + if extension_name not in extensions_dict: + if extension_name in _builtin_extensions: + if autoload: + module = _builtin_extensions[extension_name] + print(f"module '{module}' is imported automatically for extension '{extension_name}'") + imported_module = importlib.import_module(module) + extensions_dict = {ext.extension_name: ext for ext in _possible_extensions} + else: + raise ValueError(f"Extension '{extension_name}' is not registered, please import related module before use") + else: + raise ValueError(f"Extension '{extension_name}' is unkown maybe this is an external extension or a typo.") + ext_class = extensions_dict[extension_name] return ext_class @@ -1471,3 +1482,27 @@ def get_pipeline_nodes(self): def get_data(self, *args, **kwargs): assert len(self.data) > 0, f"You must run the extension {self.extension_name} before retrieving data" return self._get_data(*args, **kwargs) + + +# this is a hardcoded list to to improve error message and autoload mechanism +# this is important because extension are register when the submodule is imported +_builtin_extensions = { + # from core + "random_spikes": "spikeinterface.core", + "waveforms": "spikeinterface.core", + "templates": "spikeinterface.core", + "fast_templates": "spikeinterface.core", + "noise_levels": "spikeinterface.core", + # from postprocessing + "amplitude_scalings": "spikeinterface.postprocessing", + "correlograms": "spikeinterface.postprocessing", + "isi_histograms": "spikeinterface.postprocessing", + "principal_components": "spikeinterface.postprocessing", + "spike_amplitudes": "spikeinterface.postprocessing", + "spike_locations": "spikeinterface.postprocessing", + "template_metrics": "spikeinterface.postprocessing", + "template_similarity": "spikeinterface.postprocessing", + "unit_locations": "spikeinterface.postprocessing", + # from quality metrics + "quality_metrics": "spikeinterface.qualitymetrics", +} From 3135ba5584d8c74ea73212b24ac3207bc9dbf20a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 08:28:18 +0000 Subject: [PATCH 03/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/spikeinterface/core/sortinganalyzer.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index 8b5d876be8..90853dcf4d 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -1083,10 +1083,12 @@ def get_extension_class(extension_name: str, autoload=True): imported_module = importlib.import_module(module) extensions_dict = {ext.extension_name: ext for ext in _possible_extensions} else: - raise ValueError(f"Extension '{extension_name}' is not registered, please import related module before use") + raise ValueError( + f"Extension '{extension_name}' is not registered, please import related module before use" + ) else: raise ValueError(f"Extension '{extension_name}' is unkown maybe this is an external extension or a typo.") - + ext_class = extensions_dict[extension_name] return ext_class From 887574357c35dedf14e2e2f8e32f05dccf5d0ab9 Mon Sep 17 00:00:00 2001 From: Samuel Garcia Date: Wed, 13 Mar 2024 09:30:51 +0100 Subject: [PATCH 04/28] better error --- src/spikeinterface/core/sortinganalyzer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index 8b5d876be8..1226289378 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -1077,13 +1077,13 @@ def get_extension_class(extension_name: str, autoload=True): if extension_name not in extensions_dict: if extension_name in _builtin_extensions: + module = _builtin_extensions[extension_name] if autoload: - module = _builtin_extensions[extension_name] print(f"module '{module}' is imported automatically for extension '{extension_name}'") imported_module = importlib.import_module(module) extensions_dict = {ext.extension_name: ext for ext in _possible_extensions} else: - raise ValueError(f"Extension '{extension_name}' is not registered, please import related module before use") + raise ValueError(f"Extension '{extension_name}' is not registered, please import related module before use: 'import {module}'") else: raise ValueError(f"Extension '{extension_name}' is unkown maybe this is an external extension or a typo.") From 78d63d2973940158c2486a5f0c92268fabae211d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 08:32:17 +0000 Subject: [PATCH 05/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/spikeinterface/core/sortinganalyzer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index e04f582ac3..9092040d8d 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -1083,7 +1083,9 @@ def get_extension_class(extension_name: str, autoload=True): imported_module = importlib.import_module(module) extensions_dict = {ext.extension_name: ext for ext in _possible_extensions} else: - raise ValueError(f"Extension '{extension_name}' is not registered, please import related module before use: 'import {module}'") + raise ValueError( + f"Extension '{extension_name}' is not registered, please import related module before use: 'import {module}'" + ) else: raise ValueError(f"Extension '{extension_name}' is unkown maybe this is an external extension or a typo.") From 359ebd452785d8bb4a33c82e0ea5fffee25c0f9c Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Wed, 13 Mar 2024 10:34:18 +0000 Subject: [PATCH 06/28] Put SortingAnalyzer in get_started --- examples/how_to/get_started.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/how_to/get_started.py b/examples/how_to/get_started.py index 556153fce5..82e02e55a8 100644 --- a/examples/how_to/get_started.py +++ b/examples/how_to/get_started.py @@ -86,7 +86,7 @@ # `recording` is a `BaseRecording` object, which extracts information about # channel ids, channel locations (if present), the sampling frequency of the recording, and the extracellular -# traces. `sorting_true` is a :`BaseSorting` object, which contains information +# traces. `sorting_true` is a `BaseSorting` object, which contains information # about spike-sorting related information, including unit ids, spike trains, etc. Since the data are simulated, # `sorting_true` has ground-truth information of the spiking activity of each unit. # @@ -121,7 +121,7 @@ print("Spike train of first unit:", spike_train) # - -# SpikeInterface internally uses the [`ProbeInterface`](https://probeinterface.readthedocs.io/en/main/) to handle `probeinterface.Probe` and +# SpikeInterface internally uses the `ProbeInterface `_ package to handle `probeinterface.Probe` and # `probeinterface.ProbeGroup`. So any probe in the probeinterface collections can be downloaded and set to a # `Recording` object. In this case, the MEArec dataset already handles a `Probe` and we don't need to set it *manually*. @@ -134,7 +134,9 @@ _ = plot_probe(probe) # - -# Using the :`spikeinterface.preprocessing`, you can perform preprocessing on the recordings. +# If your recording does not have a `Probe`, you can set it using `set_probe`. There is more information `here `_. + +# Using the `spikeinterface.preprocessing` module, you can perform preprocessing on the recordings. # Each pre-processing function also returns a `BaseRecording`, # which makes it easy to build pipelines. Here, we filter the recording and apply common median reference (CMR). # All these preprocessing steps are "lazy". The computation is done on demand when we call From 8c2b31c1c56f2e3c0d3779d5dcb1637102e23f6e Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Wed, 13 Mar 2024 12:33:11 +0000 Subject: [PATCH 07/28] Add SortingAnalyzer first draft --- examples/how_to/get_started.py | 111 ++++++++++++++++++++++----------- 1 file changed, 75 insertions(+), 36 deletions(-) diff --git a/examples/how_to/get_started.py b/examples/how_to/get_started.py index 82e02e55a8..07c62a65d5 100644 --- a/examples/how_to/get_started.py +++ b/examples/how_to/get_started.py @@ -75,7 +75,8 @@ # First, let's download a simulated dataset from the # https://gin.g-node.org/NeuralEnsemble/ephy_testing_data repo -# +# We download the dataset using DataLad but it can also be downloaded directly. + # Then we can open it. Note that [MEArec](https://mearec.readthedocs.io>) simulated file # contains both a "recording" and a "sorting" object. @@ -121,7 +122,7 @@ print("Spike train of first unit:", spike_train) # - -# SpikeInterface internally uses the `ProbeInterface `_ package to handle `probeinterface.Probe` and +# SpikeInterface internally uses the [ProbeInterface](https://probeinterface.readthedocs.io/en/main/) package to handle `probeinterface.Probe` and # `probeinterface.ProbeGroup`. So any probe in the probeinterface collections can be downloaded and set to a # `Recording` object. In this case, the MEArec dataset already handles a `Probe` and we don't need to set it *manually*. @@ -134,7 +135,7 @@ _ = plot_probe(probe) # - -# If your recording does not have a `Probe`, you can set it using `set_probe`. There is more information `here `_. +# If your recording does not have a `Probe`, you can set it using `set_probe`. There is more information [here](https://spikeinterface.readthedocs.io/en/latest/modules_gallery/core/plot_3_handle_probe_info.html). # Using the `spikeinterface.preprocessing` module, you can perform preprocessing on the recordings. # Each pre-processing function also returns a `BaseRecording`, @@ -198,48 +199,85 @@ print("Units found by tridesclous:", sorting_TDC.get_unit_ids()) print("Units found by spyking-circus2:", sorting_SC2.get_unit_ids()) -# If a sorter is not installed locally, we can also avoid installing it and run it anyways, using a container (Docker or Singularity). For example, let's run `Kilosort2` using Docker: +# If a sorter is not installed locally, we can also avoid installing it and run it anyways, using a container (Docker or Singularity). To do this, you will need to install Docker. More information [here](https://spikeinterface.readthedocs.io/en/latest/modules/sorters.html?highlight=docker#running-sorters-in-docker-singularity-containers). For example, let's run `Kilosort2` using Docker: sorting_KS2 = ss.run_sorter(sorter_name="kilosort2", recording=recording_preprocessed, docker_image=True, verbose=True) print(sorting_KS2) -# SpikeInterface provides a efficient way to extract waveforms from paired recording/sorting objects. -# The `extract_waveforms` function samples some spikes (by default `max_spikes_per_unit=500`) -# for each unit, extracts their waveforms, and stores them to disk. These waveforms are helpful to compute the average waveform, or "template", for each unit and then to compute, for example, quality metrics. +# For postprocessing SpikeInterface pairs recording and sorting objects into a `SortingAnalyzer` object. +# The `SortingAnalyzer` can be loaded in memory or saved in a folder. Here, we save it in binary format. + +sa_TDC = si.create_sorting_analyzer(sorting_TDC, recording_preprocessed, format='binary_folder', folder='sa_TDC_binary') + +# This folder is where all the postprocessing data will be saved such as waveforms and templates. Let's calculate +# some waveforms. To do this the function samples some spikes (by default `max_spikes_per_unit=500`) +# for each unit, extracts their waveforms, and stores them to disk in `extensions/waveforms`. +# These waveforms are helpful to compute the average waveform, or "template", for each unit and then to compute, for example, quality metrics. +# All computations for the `SortingAnalyzer` object are done using the `compute` method: # + -we_TDC = si.extract_waveforms(recording_preprocessed, sorting_TDC, "waveforms_folder", overwrite=True) -print(we_TDC) +sa_TDC.compute("random_spikes") +sa_TDC.compute("waveforms") +# - -unit_id0 = sorting_TDC.unit_ids[0] -wavefroms = we_TDC.get_waveforms(unit_id0) -print(wavefroms.shape) +# The results of these calculations are saved as `extensions`. We access the results by first getting the extension -template = we_TDC.get_template(unit_id0) -print(template.shape) +# + +unit_id0 = sa_TDC.unit_ids[0] +waveforms = sa_TDC.get_extension("waveforms").get_data()[0] +print(waveforms.shape) # - -# `we_TDC` is a `WaveformExtractor` object -# we can post-process, validate, and curate the results. With -# the `spikeinterface.postprocessing` submodule, one can, for example, -# compute spike amplitudes, PCA projections, unit locations, and more. -# -# Let's compute some postprocessing information that will be needed later for computing quality metrics, exporting, and visualization: +# There are many more properties we can calculate + +# + +sa_TDC.compute("noise_levels") +sa_TDC.compute("templates") +sa_TDC.compute("spike_amplitudes") +sa_TDC.compute("unit_locations") +sa_TDC.compute("spike_locations") +sa_TDC.compute("correlograms") +sa_TDC.compute("template_similarity") +# - + +# These calculations are saved in the `extensions` subfolder of the `SortingAnalyzer` folder. +# Similar to the waveforms we can access them using `get_extension` and `get_data`. For example, +# here we can make a historgram of spike amplitudes + +# + +amplitudes = sa_TDC.get_extension("spike_amplitudes").get_data() +plt.hist(amplitudes, bins=50) +plt.show() +# - -amplitudes = spost.compute_spike_amplitudes(we_TDC) -unit_locations = spost.compute_unit_locations(we_TDC) -spike_locations = spost.compute_spike_locations(we_TDC) -correlograms, bins = spost.compute_correlograms(we_TDC) -similarity = spost.compute_template_similarity(we_TDC) +# You can check which extensions have been saved (in the folder) and which have been loaded (in your enviroment)... -# All of these postprocessing functions are saved in the waveforms folder as extensions: +# + +print(sa_TDC.get_saved_extension_names()) +print(sa_TDC.get_loaded_extension_names()) +# - -print(we_TDC.get_available_extension_names()) +# ...or delete an extension... -# Importantly, waveform extractors (and all extensions) can be reloaded at later times: +# + +sa_TDC.delete_extension("spike_amplitudes") +# - -we_loaded = si.load_waveforms("waveforms_folder") -print(we_loaded.get_available_extension_names()) +# This deletes the extension's data in the `SortingAnalyzer` folder. +# +# Importantly, `SortingAnalyzers` (and all extensions) can be reloaded at later times: +# (Note: spike_locations is not loaded, since we just deleted it) + +# + +sa_loaded = si.load_sorting_analyzer('sa_TDC_binary') +print(sa_loaded.get_loaded_extension_names()) +# - + +# And any deleted extensions are easily recomputed + +# + +sa_TDC.compute("spike_amplitudes") +# - # Once we have computed all of the postprocessing information, we can compute quality metrics (different quality metrics require different extensions - e.g., drift metrics require `spike_locations`): @@ -253,18 +291,19 @@ qm_params["drift"]["interval_s"] = 2 qm_params["drift"]["min_spikes_per_interval"] = 2 -qm = sqm.compute_quality_metrics(we_TDC, qm_params=qm_params) +qm = sqm.compute_quality_metrics(sa_TDC, qm_params=qm_params) display(qm) -# Quality metrics are also extensions (and become part of the waveform folder): +# Quality metrics are also extensions (and become part of the SortingAnalyzer folder): # Next, we can use some of the powerful tools for spike sorting visualization. -# + # We can export a sorting summary and quality metrics plot using the `sortingview` backend. This will generate shareable links for web-based visualization. +# For this to work you need to install `sortingview` and construct a `kachery-cloud`: [https://github.com/magland/sortingview](more details). -w1 = sw.plot_quality_metrics(we_TDC, display=False, backend="sortingview") +w1 = sw.plot_quality_metrics(sa_TDC, display=False, backend="sortingview") -w2 = sw.plot_sorting_summary(we_TDC, display=False, curation=True, backend="sortingview") +w2 = sw.plot_sorting_summary(sa_TDC, display=False, curation=True, backend="sortingview") # The sorting summary plot can also be used for manual labeling and curation. In the example above, we manually merged two units (0, 4) and added accept labels (2, 6, 7). After applying our curation, we can click on the "Save as snapshot (sha://)" and copy the URI: @@ -279,7 +318,7 @@ # Alternatively, we can export the data locally to Phy. [Phy]() is a GUI for manual # curation of the spike sorting output. To export to phy you can run: -sexp.export_to_phy(we_TDC, "phy_folder_for_TDC", verbose=True) +sexp.export_to_phy(sa_TDC, "phy_folder_for_TDC", verbose=True) # Then you can run the template-gui with: `phy template-gui phy_folder_for_TDC/params.py` # and manually curate the results. From 9f6414b40a76f1a6e59c106acd047ca1b91fb3d7 Mon Sep 17 00:00:00 2001 From: Samuel Garcia Date: Thu, 14 Mar 2024 09:58:51 +0100 Subject: [PATCH 08/28] CHange strategy for get_saved_extension_names --- src/spikeinterface/core/sortinganalyzer.py | 51 ++++++++++------------ 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index 9092040d8d..a7d8329e3d 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -909,36 +909,30 @@ def compute_several_extensions(self, extensions, save=True, **job_kwargs): def get_saved_extension_names(self): """ - Get extension saved in folder or zarr that can be loaded. + Get extension names saved in folder or zarr that can be loaded. + This do not load data, this only explores the directory. """ - assert self.format != "memory" - global _possible_extensions + saved_extension_names = [] + if self.format == "binary_folder": + ext_folder = self.folder / "extensions" + if ext_folder.is_dir(): + for extension_folder in ext_folder.iterdir(): + is_saved = extension_folder.is_dir() and (extension_folder / "params.json").is_file() + if not is_saved: + continue + saved_extension_names.append(extension_folder.stem) - if self.format == "zarr": + elif self.format == "zarr": zarr_root = self._get_zarr_root(mode="r") if "extensions" in zarr_root.keys(): extension_group = zarr_root["extensions"] - else: - extension_group = None - - saved_extension_names = [] - for extension_class in _possible_extensions: - extension_name = extension_class.extension_name - - if self.format == "binary_folder": - extension_folder = self.folder / "extensions" / extension_name - is_saved = extension_folder.is_dir() and (extension_folder / "params.json").is_file() - elif self.format == "zarr": - if extension_group is not None: - is_saved = ( - extension_name in extension_group.keys() - and "params" in extension_group[extension_name].attrs.keys() - ) - else: - is_saved = False - if is_saved: - saved_extension_names.append(extension_class.extension_name) + for extension_name in extension_group.keys(): + if "params" in extension_group[extension_name].attrs.keys(): + saved_extension_names.append(extension_folder.stem) + else: + raise ValueError("SortingAnalyzer.get_saved_extension_names() works only with binary_folder and zarr") + return saved_extension_names def get_extension(self, extension_name: str): @@ -1058,7 +1052,7 @@ def register_result_extension(extension_class): _possible_extensions.append(extension_class) -def get_extension_class(extension_name: str, autoload=True): +def get_extension_class(extension_name: str, auto_import=True): """ Get extension class from name and check if registered. @@ -1066,6 +1060,8 @@ def get_extension_class(extension_name: str, autoload=True): ---------- extension_name: str The extension name. + auto_import: bool, default True + Auto import the module if the extension class is not registered yet. Returns ------- @@ -1078,8 +1074,7 @@ def get_extension_class(extension_name: str, autoload=True): if extension_name not in extensions_dict: if extension_name in _builtin_extensions: module = _builtin_extensions[extension_name] - if autoload: - print(f"module '{module}' is imported automatically for extension '{extension_name}'") + if auto_import: imported_module = importlib.import_module(module) extensions_dict = {ext.extension_name: ext for ext in _possible_extensions} else: @@ -1486,7 +1481,7 @@ def get_data(self, *args, **kwargs): return self._get_data(*args, **kwargs) -# this is a hardcoded list to to improve error message and autoload mechanism +# this is a hardcoded list to to improve error message and auto_import mechanism # this is important because extension are register when the submodule is imported _builtin_extensions = { # from core From bda7a8ded9baf9dbc0b09e6d189ba65fb6852baa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 09:07:24 +0000 Subject: [PATCH 09/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/spikeinterface/core/sortinganalyzer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index a7d8329e3d..61a7b4c69a 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -932,7 +932,7 @@ def get_saved_extension_names(self): else: raise ValueError("SortingAnalyzer.get_saved_extension_names() works only with binary_folder and zarr") - + return saved_extension_names def get_extension(self, extension_name: str): From 5ceab8ff8781dceb0378e67c9c9cf84cfa607c32 Mon Sep 17 00:00:00 2001 From: Samuel Garcia Date: Thu, 14 Mar 2024 15:42:05 +0100 Subject: [PATCH 10/28] oups --- src/spikeinterface/core/sortinganalyzer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index a7d8329e3d..cb8592e287 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -928,7 +928,7 @@ def get_saved_extension_names(self): extension_group = zarr_root["extensions"] for extension_name in extension_group.keys(): if "params" in extension_group[extension_name].attrs.keys(): - saved_extension_names.append(extension_folder.stem) + saved_extension_names.append(extension_name) else: raise ValueError("SortingAnalyzer.get_saved_extension_names() works only with binary_folder and zarr") From 06ce4cbd9b219134d5b88aef5b41d97fc9f18e99 Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Fri, 15 Mar 2024 12:08:14 +0000 Subject: [PATCH 11/28] Update get started to have SortingAnalyzer --- doc/how_to/get_started.rst | 907 +++++++++++++----- .../get_started_files/get_started_14_0.png | Bin 78990 -> 0 bytes .../get_started_files/get_started_15_0.png | Bin 0 -> 73966 bytes ..._started_14_1.png => get_started_15_1.png} | Bin 14154 -> 14154 bytes ..._started_20_1.png => get_started_21_1.png} | Bin 24804 -> 24804 bytes .../get_started_files/get_started_48_0.png | Bin 0 -> 8955 bytes .../get_started_files/get_started_66_2.png | Bin 25669 -> 0 bytes .../get_started_files/get_started_72_1.png | Bin 14525 -> 0 bytes ..._started_66_1.png => get_started_79_1.png} | Bin 26001 -> 26001 bytes .../get_started_files/get_started_79_2.png | Bin 0 -> 19964 bytes .../get_started_files/get_started_85_1.png | Bin 0 -> 14480 bytes ..._started_72_2.png => get_started_85_2.png} | Bin 12234 -> 12234 bytes examples/how_to/get_started.py | 34 +- 13 files changed, 694 insertions(+), 247 deletions(-) delete mode 100644 doc/how_to/get_started_files/get_started_14_0.png create mode 100644 doc/how_to/get_started_files/get_started_15_0.png rename doc/how_to/get_started_files/{get_started_14_1.png => get_started_15_1.png} (99%) rename doc/how_to/get_started_files/{get_started_20_1.png => get_started_21_1.png} (99%) create mode 100644 doc/how_to/get_started_files/get_started_48_0.png delete mode 100644 doc/how_to/get_started_files/get_started_66_2.png delete mode 100644 doc/how_to/get_started_files/get_started_72_1.png rename doc/how_to/get_started_files/{get_started_66_1.png => get_started_79_1.png} (99%) create mode 100644 doc/how_to/get_started_files/get_started_79_2.png create mode 100644 doc/how_to/get_started_files/get_started_85_1.png rename doc/how_to/get_started_files/{get_started_72_2.png => get_started_85_2.png} (98%) diff --git a/doc/how_to/get_started.rst b/doc/how_to/get_started.rst index a923393916..97dae29f72 100644 --- a/doc/how_to/get_started.rst +++ b/doc/how_to/get_started.rst @@ -5,37 +5,37 @@ How to “get started” ==================== -In this introductory example, you will see how to use the SpikeInterface -to perform a full electrophysiology analysis. We will download simulated +In this introductory example, you will see how to use SpikeInterface to +perform a full electrophysiology analysis. We will download a simulated dataset, and we will then perform some pre-processing, run a spike sorting algorithm, post-process the spike sorting output, perform curation (manual and automatic), and compare spike sorting results. -.. code:: ipython +.. code:: ipython3 import matplotlib.pyplot as plt from pprint import pprint -The spikeinterface module by itself import only the spikeinterface.core +The spikeinterface module by itself imports only the spikeinterface.core submodule which is not useful for end user -.. code:: ipython +.. code:: ipython3 import spikeinterface We need to import one by one different submodules separately -(preferred). There several modules: +(preferred). There are several modules: - ``extractors`` : file IO - ``preprocessing`` : preprocessing - ``sorters`` : Python wrappers of spike sorters - ``postprocessing`` : postprocessing -- ``qualitymetrics`` : quality metrics on units found by sorter +- ``qualitymetrics`` : quality metrics on units found by sorters - ``curation`` : automatic curation of spike sorting output -- ``comparison`` : comparison of spike sorting output +- ``comparison`` : comparison of spike sorting outputs - ``widgets`` : visualization -.. code:: ipython +.. code:: ipython3 import spikeinterface as si # import core only import spikeinterface.extractors as se @@ -48,36 +48,37 @@ We need to import one by one different submodules separately import spikeinterface.curation as scur import spikeinterface.widgets as sw -We can also import all submodules at once with this this internally -import core+extractors+preprocessing+sorters+postprocessing+ +Alternatively, we can import all submodules at once which internally +imports core+extractors+preprocessing+sorters+postprocessing+ qualitymetrics+comparison+widgets+exporters This is useful for notebooks, but it is a heavier import because internally many more dependencies are imported (scipy/sklearn/networkx/matplotlib/h5py…) -.. code:: ipython +.. code:: ipython3 import spikeinterface.full as si Before getting started, we can set some global arguments for parallel processing. For this example, let’s use 4 jobs and time chunks of 1s: -.. code:: ipython +.. code:: ipython3 global_job_kwargs = dict(n_jobs=4, chunk_duration="1s") si.set_global_job_kwargs(**global_job_kwargs) First, let’s download a simulated dataset from the -https://gin.g-node.org/NeuralEnsemble/ephy_testing_data repo +https://gin.g-node.org/NeuralEnsemble/ephy_testing_data repo We download +the dataset using DataLad but it can also be downloaded directly. Then we can open it. Note that -`MEArec `__ simulated file contains -both “recording” and a “sorting” object. +`MEArec `__ simulated files contain +both a “recording” and a “sorting” object. -.. code:: ipython +.. code:: ipython3 - local_path = si.download_dataset(remote_path='mearec/mearec_test_10s.h5') + local_path = si.download_dataset(remote_path="mearec/mearec_test_10s.h5") recording, sorting_true = se.read_mearec(local_path) print(recording) print(sorting_true) @@ -85,50 +86,51 @@ both “recording” and a “sorting” object. .. parsed-literal:: - MEArecRecordingExtractor: 32 channels - 1 segments - 32.0kHz - 10.000s - file_path: /home/alessio/spikeinterface_datasets/ephy_testing_data/mearec/mearec_test_10s.h5 + MEArecRecordingExtractor: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + float32 dtype - 39.06 MiB + file_path: /home/nolanlab/spikeinterface_datasets/ephy_testing_data/mearec/mearec_test_10s.h5 MEArecSortingExtractor: 10 units - 1 segments - 32.0kHz - file_path: /home/alessio/spikeinterface_datasets/ephy_testing_data/mearec/mearec_test_10s.h5 + file_path: /home/nolanlab/spikeinterface_datasets/ephy_testing_data/mearec/mearec_test_10s.h5 ``recording`` is a ``BaseRecording`` object, which extracts information about channel ids, channel locations (if present), the sampling frequency of the recording, and the extracellular traces. -``sorting_true`` is a :``BaseSorting`` object, which contains -information about spike-sorting related information, including unit ids, -spike trains, etc. Since the data are simulated, ``sorting_true`` has +``sorting_true`` is a ``BaseSorting`` object, which contains information +about spike-sorting related information, including unit ids, spike +trains, etc. Since the data are simulated, ``sorting_true`` has ground-truth information of the spiking activity of each unit. Let’s use the ``spikeinterface.widgets`` module to visualize the traces and the raster plots. -.. code:: ipython +.. code:: ipython3 w_ts = sw.plot_traces(recording, time_range=(0, 5)) w_rs = sw.plot_rasters(sorting_true, time_range=(0, 5)) -.. image:: get_started_files/get_started_14_0.png +.. image:: get_started_files/get_started_15_0.png -.. image:: get_started_files/get_started_14_1.png +.. image:: get_started_files/get_started_15_1.png This is how you retrieve info from a ``BaseRecording``\ … -.. code:: ipython +.. code:: ipython3 channel_ids = recording.get_channel_ids() fs = recording.get_sampling_frequency() num_chan = recording.get_num_channels() num_seg = recording.get_num_segments() - - print('Channel ids:', channel_ids) - print('Sampling frequency:', fs) - print('Number of channels:', num_chan) - print('Number of segments:', num_seg) + + print("Channel ids:", channel_ids) + print("Sampling frequency:", fs) + print("Number of channels:", num_chan) + print("Number of segments:", num_seg) .. parsed-literal:: @@ -141,17 +143,17 @@ This is how you retrieve info from a ``BaseRecording``\ … Number of segments: 1 -…and a ``BaseSorting`` +…and from a ``BaseSorting`` -.. code:: ipython +.. code:: ipython3 num_seg = recording.get_num_segments() unit_ids = sorting_true.get_unit_ids() spike_train = sorting_true.get_unit_spike_train(unit_id=unit_ids[0]) - - print('Number of segments:', num_seg) - print('Unit ids:', unit_ids) - print('Spike train of first unit:', spike_train) + + print("Number of segments:", num_seg) + print("Unit ids:", unit_ids) + print("Spike train of first unit:", spike_train) .. parsed-literal:: @@ -167,19 +169,20 @@ This is how you retrieve info from a ``BaseRecording``\ … SpikeInterface internally uses the -```ProbeInterface`` `__ -to handle ``probeinterface.Probe`` and ``probeinterface.ProbeGroup``. So -any probe in the probeinterface collections can be downloaded and set to -a ``Recording`` object. In this case, the MEArec dataset already handles -a ``Probe`` and we don’t need to set it *manually*. +`ProbeInterface `__ +package to handle ``probeinterface.Probe`` and +``probeinterface.ProbeGroup``. So any probe in the probeinterface +collection can be downloaded and set to a ``Recording`` object. In this +case, the MEArec dataset already handles a ``Probe`` and we don’t need +to set it *manually*. -.. code:: ipython +.. code:: ipython3 probe = recording.get_probe() print(probe) - + from probeinterface.plotting import plot_probe - + _ = plot_probe(probe) @@ -189,10 +192,14 @@ a ``Probe`` and we don’t need to set it *manually*. -.. image:: get_started_files/get_started_20_1.png +.. image:: get_started_files/get_started_21_1.png + +If your recording does not have a ``Probe``, you can set it using +``set_probe``. There is more information +`here `__. -Using the :``spikeinterface.preprocessing``, you can perform +Using the ``spikeinterface.preprocessing`` module, you can perform preprocessing on the recordings. Each pre-processing function also returns a ``BaseRecording``, which makes it easy to build pipelines. Here, we filter the recording and apply common median reference (CMR). @@ -200,53 +207,68 @@ All these preprocessing steps are “lazy”. The computation is done on demand when we call ``recording.get_traces(...)`` or when we save the object to disk. -.. code:: ipython +.. code:: ipython3 recording_cmr = recording recording_f = si.bandpass_filter(recording, freq_min=300, freq_max=6000) print(recording_f) - recording_cmr = si.common_reference(recording_f, reference='global', operator='median') + recording_cmr = si.common_reference(recording_f, reference="global", operator="median") print(recording_cmr) - + # this computes and saves the recording after applying the preprocessing chain - recording_preprocessed = recording_cmr.save(format='binary') + recording_preprocessed = recording_cmr.save(format="binary") print(recording_preprocessed) .. parsed-literal:: - BandpassFilterRecording: 32 channels - 1 segments - 32.0kHz - 10.000s - CommonReferenceRecording: 32 channels - 1 segments - 32.0kHz - 10.000s - BinaryFolderRecording: 32 channels - 1 segments - 32.0kHz - 10.000s + BandpassFilterRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + float32 dtype - 39.06 MiB + CommonReferenceRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + float32 dtype - 39.06 MiB + Use cache_folder=/tmp/spikeinterface_cache/tmp8sr7ylv1/PVPX8CJL + write_binary_recording with n_jobs = 4 and chunk_size = 32000 + + + +.. parsed-literal:: + + write_binary_recording: 0%| | 0/10 [00:00`__. +Let’s run ``Kilosort2`` using Docker: -.. code:: ipython +.. code:: ipython3 - sorting_KS2 = ss.run_sorter(sorter_name="kilosort2", recording=recording_preprocessed, - docker_image=True, verbose=True) + sorting_KS2 = ss.run_sorter(sorter_name="kilosort2", recording=recording_preprocessed, docker_image=True, verbose=True) print(sorting_KS2) .. parsed-literal:: + installation_mode='auto' switching to installation_mode: 'dev' Starting container - Installing spikeinterface from sources in spikeinterface/kilosort2-compiled-base - Installing dev spikeinterface from local machine - Installing extra requirements: ['neo', 'mearec'] + Installing spikeinterface with folder in container + Installing neo with pypi in container + Installing mearec with pypi in container Running kilosort2 sorter inside spikeinterface/kilosort2-compiled-base Stopping container + KiloSortSortingExtractor: 19 units - 1 segments - 32.0kHz -.. parsed-literal:: - KiloSortSortingExtractor: 19 units - 1 segments - 32.0kHz +For postprocessing SpikeInterface pairs recording and sorting objects +into a ``SortingAnalyzer`` object. The ``SortingAnalyzer`` can be loaded +in memory or saved in a folder. Here, we save it in binary format. + +.. code:: ipython3 + + sa_TDC = si.create_sorting_analyzer(sorting_TDC, recording_preprocessed, format='binary_folder', folder='sa_TDC_binary') + + + +.. parsed-literal:: + estimate_sparsity: 0%| | 0/10 [00:00 + + + +The results of these calculations are saved as ``extensions``. Some +simple data, such as the ``unit_ids`` can be accessed directly from the +``SortingAnalyzer`` object. Extension data is accessed by first getting +the extension then getting the data + +.. code:: ipython3 + + unit_id0 = sa_TDC.unit_ids[0] + waveforms = sa_TDC.get_extension("waveforms").get_data()[unit_id0] + print(waveforms.shape) + + +.. parsed-literal:: + + (96, 25) + + +There are many more properties we can calculate + +.. code:: ipython3 + + sa_TDC.compute("noise_levels") + sa_TDC.compute("templates") + sa_TDC.compute("spike_amplitudes") + sa_TDC.compute("unit_locations") + sa_TDC.compute("spike_locations") + sa_TDC.compute("correlograms") + sa_TDC.compute("template_similarity") + + + +.. parsed-literal:: + + spike_amplitudes: 0%| | 0/10 [00:00 + + + +These calculations are saved in the ``extensions`` subfolder of the +``SortingAnalyzer`` folder. Similar to the waveforms we can access them +using ``get_extension`` and ``get_data``. For example, here we can make +a historgram of spike amplitudes + +.. code:: ipython3 + + amplitudes = sa_TDC.get_extension("spike_amplitudes").get_data() + plt.hist(amplitudes, bins=50) + plt.show() + + + +.. image:: get_started_files/get_started_48_0.png + + +You can check which extensions have been saved (in your local folder) +and which have been loaded (in your enviroment)… + +.. code:: ipython3 + + print(sa_TDC.get_saved_extension_names()) + print(sa_TDC.get_loaded_extension_names()) -``we_TDC`` is a have the ``WaveformExtractor`` object we can -post-process, validate, and curate the results. With the -``spikeinterface.postprocessing`` submodule, one can, for example, -compute spike amplitudes, PCA projections, unit locations, and more. +.. parsed-literal:: + + ['random_spikes', 'waveforms', 'templates', 'noise_levels', 'template_similarity', 'spike_amplitudes', 'correlograms', 'spike_locations', 'unit_locations'] + ['random_spikes', 'waveforms', 'noise_levels', 'templates', 'spike_amplitudes', 'unit_locations', 'spike_locations', 'correlograms', 'template_similarity'] -Let’s compute some postprocessing information that will be needed later -for computing quality metrics, exporting, and visualization: -.. code:: ipython +…or delete an extension… - amplitudes = spost.compute_spike_amplitudes(we_TDC) - unit_locations = spost.compute_unit_locations(we_TDC) - spike_locations = spost.compute_spike_locations(we_TDC) - correlograms, bins = spost.compute_correlograms(we_TDC) - similarity = spost.compute_template_similarity(we_TDC) +.. code:: ipython3 + sa_TDC.delete_extension("spike_amplitudes") -All of this postprocessing functions are saved in the waveforms folder -as extensions: +This deletes the extension’s data in the ``SortingAnalyzer`` folder. -.. code:: ipython +Importantly, ``SortingAnalyzers`` (and all extensions) can be reloaded +at later times: (Here, ``spike_amplitudes`` is not loaded since we just +deleted it) + +.. code:: ipython3 - print(we_TDC.get_available_extension_names()) + sa_loaded = si.load_sorting_analyzer('sa_TDC_binary') + print(sa_loaded.get_loaded_extension_names()) .. parsed-literal:: - ['similarity', 'spike_amplitudes', 'correlograms', 'spike_locations', 'unit_locations'] + ['random_spikes', 'waveforms', 'templates', 'noise_levels', 'template_similarity', 'correlograms', 'spike_locations', 'unit_locations'] -Importantly, waveform extractors (and all extensions) can be reloaded at -later times: +And any deleted extensions are easily recomputed -.. code:: ipython +.. code:: ipython3 + + sa_TDC.compute("spike_amplitudes") - we_loaded = si.load_waveforms('waveforms_folder') - print(we_loaded.get_available_extension_names()) .. parsed-literal:: - ['similarity', 'spike_amplitudes', 'correlograms', 'spike_locations', 'unit_locations'] + spike_amplitudes: 0%| | 0/10 [00:00 + + + +Once we have computed all of the postprocessing information, we can +compute quality metrics (some quality metrics require certain extensions +- e.g., drift metrics require ``spike_locations``): + +.. code:: ipython3 qm_params = sqm.get_default_qm_params() pprint(qm_params) @@ -451,91 +575,382 @@ extensions - e.g., drift metrics resuire ``spike_locations``): 'histogram_smoothing_value': 3, 'num_histogram_bins': 100, 'peak_sign': 'neg'}, + 'amplitude_cv': {'amplitude_extension': 'spike_amplitudes', + 'average_num_spikes_per_bin': 50, + 'min_num_bins': 10, + 'percentiles': (5, 95)}, 'amplitude_median': {'peak_sign': 'neg'}, 'drift': {'direction': 'y', 'interval_s': 60, 'min_num_bins': 2, 'min_spikes_per_interval': 100}, + 'firing_range': {'bin_size_s': 5, 'percentiles': (5, 95)}, 'isi_violation': {'isi_threshold_ms': 1.5, 'min_isi_ms': 0}, 'nearest_neighbor': {'max_spikes': 10000, 'n_neighbors': 5}, 'nn_isolation': {'max_spikes': 10000, + 'min_fr': 0.0, 'min_spikes': 10, 'n_components': 10, 'n_neighbors': 4, 'peak_sign': 'neg', 'radius_um': 100}, 'nn_noise_overlap': {'max_spikes': 10000, + 'min_fr': 0.0, 'min_spikes': 10, 'n_components': 10, 'n_neighbors': 4, 'peak_sign': 'neg', 'radius_um': 100}, - 'presence_ratio': {'bin_duration_s': 60}, + 'presence_ratio': {'bin_duration_s': 60, 'mean_fr_ratio_thresh': 0.0}, 'rp_violation': {'censored_period_ms': 0.0, 'refractory_period_ms': 1.0}, + 'silhouette': {'method': ('simplified',)}, 'sliding_rp_violation': {'bin_size_ms': 0.25, 'contamination_values': None, 'exclude_ref_period_below_ms': 0.5, 'max_ref_period_ms': 10, + 'min_spikes': 0, 'window_size_s': 1}, - 'snr': {'peak_mode': 'extremum', - 'peak_sign': 'neg', - 'random_chunk_kwargs_dict': None}} + 'snr': {'peak_mode': 'extremum', 'peak_sign': 'neg'}, + 'synchrony': {'synchrony_sizes': (2, 4, 8)}} Since the recording is very short, let’s change some parameters to -accomodate the duration: +accommodate the duration: -.. code:: ipython +.. code:: ipython3 qm_params["presence_ratio"]["bin_duration_s"] = 1 qm_params["amplitude_cutoff"]["num_histogram_bins"] = 5 qm_params["drift"]["interval_s"] = 2 qm_params["drift"]["min_spikes_per_interval"] = 2 -.. code:: ipython +.. code:: ipython3 - qm = sqm.compute_quality_metrics(we_TDC, qm_params=qm_params) + qm = sqm.compute_quality_metrics(sa_TDC, qm_params=qm_params) display(qm) -.. parsed-literal:: - - 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 -folder): +.. raw:: html + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
amplitude_cutoffamplitude_cv_medianamplitude_cv_rangeamplitude_mediandrift_ptpdrift_stddrift_madfiring_rangefiring_rateisi_violations_ratio...num_spikespresence_ratiorp_contaminationrp_violationssd_ratiosliding_rp_violationsnrsync_spike_2sync_spike_4sync_spike_8
00.200717NaNNaN-306.1990361.0525320.4246530.4219920.723.00.0...30.00.90.00.01.536918NaN27.4112950.00.00.0
10.500000NaNNaN-273.4449770.9950040.3449320.2617740.185.10.0...51.01.00.00.01.311148NaN24.2648450.00.00.0
20.500000NaNNaN-269.2045901.3554110.5417360.5673670.905.30.0...53.00.90.00.02.016703NaN24.1773650.00.00.0
30.500000NaNNaN-311.5457150.4215230.1462770.1125800.725.00.0...50.01.00.00.02.011083NaN26.9771210.00.00.0
40.207231NaNNaN-106.9532781.9412050.6882800.5567320.723.60.0...36.01.00.00.00.680199NaN9.6368240.00.00.0
50.204838NaNNaN-150.8331910.9278840.3148120.1861480.364.20.0...42.01.00.00.00.965515NaN13.2439970.00.00.0
60.500000NaNNaN-90.3584442.0845210.7538200.3852040.004.80.0...48.01.00.00.01.177009NaN8.2805310.00.00.0
70.500000NaNNaN-102.4915771.1910620.4526490.4852582.3419.30.0...193.01.00.00.00.9742590.1558.8209360.00.00.0
80.500000NaNNaN-127.2523191.1164800.4407740.4779200.9012.90.0...129.01.00.00.00.9496950.31011.1588750.00.00.0
90.203415NaNNaN-97.2072911.3958520.5610950.6328102.1611.00.0...110.01.00.00.01.0279250.2708.3065560.00.00.0
+

10 rows × 21 columns

+
+ + +Quality metrics are also extensions (and become part of the +``SortingAnalyzer`` folder): Next, we can use some of the powerful tools for spike sorting visualization. We can export a sorting summary and quality metrics plot using the -``sortingview`` backend. This will generate shareble links for web-based -visualization. +``sortingview`` backend. This will generate shareable links for +web-based visualization. For this to work you need to install +``sortingview`` and construct a ``kachery-cloud``: +`https://github.com/magland/sortingview `__. -.. code:: ipython +.. code:: ipython3 - w1 = sw.plot_quality_metrics(we_TDC, display=False, backend="sortingview") + w1 = sw.plot_quality_metrics(sa_TDC, display=False, backend="sortingview") -https://figurl.org/f?v=gs://figurl/spikesortingview-10&d=sha1://901a11ba31ae9ab512a99bdf36a3874173249d87&label=SpikeInterface%20-%20Quality%20Metrics +.. parsed-literal:: + /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/widgets/metrics.py:65: UserWarning: Skipping ['amplitude_cv_median', 'amplitude_cv_range'] because they contain all NaNs + warnings.warn(f"Skipping {nan_metrics} because they contain all NaNs") -.. code:: ipython +https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://7927a56e56bde2e923f85858608dfc38c51da534 - w2 = sw.plot_sorting_summary(we_TDC, display=False, curation=True, backend="sortingview") +.. code:: ipython3 + + w2 = sw.plot_sorting_summary(sa_TDC, display=False, curation=True, backend="sortingview") -https://figurl.org/f?v=gs://figurl/spikesortingview-10&d=sha1://cd190c64eeea6a0ceaf57d1153b6ab4eac351d70&label=SpikeInterface%20-%20Sorting%20Summary +https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://aa8e4c3e7f0f3f041eff55656b6e9151bcdec399 The sorting summary plot can also be used for manual labeling and @@ -543,10 +958,10 @@ curation. In the example above, we manually merged two units (0, 4) and added accept labels (2, 6, 7). After applying our curation, we can click on the “Save as snapshot (sha://)” and copy the URI: -.. code:: ipython +.. code:: ipython3 uri = "sha1://68cb54a9aaed2303fb82dedbc302c853e818f1b6" - + sorting_curated_sv = scur.apply_sortingview_curation(sorting_TDC, uri_or_json=uri) print(sorting_curated_sv) print(sorting_curated_sv.get_property("accept")) @@ -559,18 +974,42 @@ on the “Save as snapshot (sha://)” and copy the URI: Alternatively, we can export the data locally to Phy. -`Phy `_ is a GUI for manual -curation of the spike sorting output. To export to phy you can run: +`Phy `__ is a GUI for manual curation +of the spike sorting output. To export to phy you can run: + +.. code:: ipython3 + + sexp.export_to_phy(sa_TDC, "phy_folder_for_TDC", verbose=True) + + + +.. parsed-literal:: + + write_binary_recording: 0%| | 0/10 [00:00 10) & (qm['isi_violations_ratio'] < 0.01) + keep_mask = (qm["snr"] > 10) & (qm["isi_violations_ratio"] < 0.01) print("Mask:", keep_mask.values) - + sorting_curated_auto = sorting_TDC.select_units(sorting_TDC.unit_ids[keep_mask]) print(sorting_curated_auto) @@ -610,22 +1049,24 @@ outputs. We can either: 1. compare the spike sorting results with the ground-truth sorting ``sorting_true`` -2. compare the output of two (Tridesclous and SpykingCircus2) +2. compare the output of two sorters (e.g. Tridesclous and + SpykingCircus2) -3. compare the output of multiple sorters (Tridesclous, SpykingCircus2, - Kilosort2) +3. compare the output of multiple sorters (e.g. Tridesclous, + SpykingCircus2, and Kilosort2) -.. code:: ipython +.. code:: ipython3 comp_gt = sc.compare_sorter_to_ground_truth(gt_sorting=sorting_true, tested_sorting=sorting_TDC) comp_pair = sc.compare_two_sorters(sorting1=sorting_TDC, sorting2=sorting_SC2) - comp_multi = sc.compare_multiple_sorters(sorting_list=[sorting_TDC, sorting_SC2, sorting_KS2], - name_list=['tdc', 'sc2', 'ks2']) + comp_multi = sc.compare_multiple_sorters( + sorting_list=[sorting_TDC, sorting_SC2, sorting_KS2], name_list=["tdc", "sc2", "ks2"] + ) When comparing with a ground-truth sorting (1,), you can get the sorting performance and plot a confusion matrix -.. code:: ipython +.. code:: ipython3 print(comp_gt.get_performance()) w_conf = sw.plot_confusion_matrix(comp_gt) @@ -635,7 +1076,7 @@ performance and plot a confusion matrix .. parsed-literal:: accuracy recall precision false_discovery_rate miss_rate - gt_unit_id + gt_unit_id #0 1.0 1.0 1.0 0.0 0.0 #1 1.0 1.0 1.0 0.0 0.0 #2 0.976744 0.976744 1.0 0.0 0.023256 @@ -649,17 +1090,17 @@ performance and plot a confusion matrix -.. image:: get_started_files/get_started_66_1.png +.. image:: get_started_files/get_started_79_1.png -.. image:: get_started_files/get_started_66_2.png +.. image:: get_started_files/get_started_79_2.png When comparing two sorters (2.), we can see the matching of units -between sorters. Units which are not matched has -1 as unit id: +between sorters. Units which are not matched have -1 as their unit id: -.. code:: ipython +.. code:: ipython3 comp_pair.hungarian_match_12 @@ -668,22 +1109,23 @@ between sorters. Units which are not matched has -1 as unit id: .. parsed-literal:: - 0 0 - 1 6 - 2 2 - 3 7 - 4 5 - 5 8 - 6 1 - 7 4 - 8 3 - 9 9 + 0 0.0 + 1 1.0 + 2 8.0 + 3 2.0 + 4 5.0 + 5 4.0 + 6 7.0 + 7 6.0 + 8 9.0 + 9 3.0 + dtype: float64 or the reverse: -.. code:: ipython +.. code:: ipython3 comp_pair.hungarian_match_21 @@ -692,16 +1134,17 @@ or the reverse: .. parsed-literal:: - 0 0 - 1 6 - 2 2 - 3 8 - 4 7 - 5 4 - 6 1 - 7 3 - 8 5 - 9 9 + 0 0.0 + 1 1.0 + 2 3.0 + 3 9.0 + 4 5.0 + 5 4.0 + 6 7.0 + 7 6.0 + 8 2.0 + 9 8.0 + dtype: float64 @@ -709,14 +1152,14 @@ When comparing multiple sorters (3.), you can extract a ``BaseSorting`` object with units in agreement between sorters. You can also plot a graph showing how the units are matched between the sorters. -.. code:: ipython +.. code:: ipython3 sorting_agreement = comp_multi.get_agreement_sorting(minimum_agreement_count=2) - - print('Units in agreement between TDC, SC2, and KS2:', sorting_agreement.get_unit_ids()) - - w_multi = sw.plot_multicomp_agreement(comp_multi) - w_multi = sw.plot_multicomp_agreement_by_sorter(comp_multi) + + print("Units in agreement between TDC, SC2, and KS2:", sorting_agreement.get_unit_ids()) + + w_multi = sw.plot_multicomparison_agreement(comp_multi) + w_multi = sw.plot_multicomparison_agreement_by_sorter(comp_multi) .. parsed-literal:: @@ -725,11 +1168,11 @@ graph showing how the units are matched between the sorters. -.. image:: get_started_files/get_started_72_1.png +.. image:: get_started_files/get_started_85_1.png -.. image:: get_started_files/get_started_72_2.png +.. image:: get_started_files/get_started_85_2.png We see that 10 unit were found by all sorters (note that this simulated diff --git a/doc/how_to/get_started_files/get_started_14_0.png b/doc/how_to/get_started_files/get_started_14_0.png deleted file mode 100644 index c6cdd4458c07962d8cab31e9e4a368287fcb4788..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78990 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

bP5bS9r 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 a)%3C@Q)wk}Z}TtN@v|*3ETGyy{@gDS(z*Ts diff --git a/doc/how_to/get_started_files/get_started_15_0.png b/doc/how_to/get_started_files/get_started_15_0.png new file mode 100644 index 0000000000000000000000000000000000000000..d1896ed083951fcd6e4bba52adc10a180083f159 GIT binary patch literal 73966 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 literal 0 HcmV?d00001 diff --git a/doc/how_to/get_started_files/get_started_66_2.png b/doc/how_to/get_started_files/get_started_66_2.png deleted file mode 100644 index 8d59574ec61f77933f77a5f7f55b5dc10e8b3fcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25669 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 Vn;comf9avIdWGfkq-C3e{{>jXKPUhI diff --git a/doc/how_to/get_started_files/get_started_72_1.png b/doc/how_to/get_started_files/get_started_72_1.png deleted file mode 100644 index 108470fbe1a97cca03db81b2cc2d679472fe0c4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14525 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 diff --git a/doc/how_to/get_started_files/get_started_66_1.png b/doc/how_to/get_started_files/get_started_79_1.png similarity index 99% rename from doc/how_to/get_started_files/get_started_66_1.png rename to doc/how_to/get_started_files/get_started_79_1.png index 3d744f3b76f458fe82a0d938dfb0dfe3b7ffe98d..eb00a18ca3dd62f92a68929e56c9bf4630f24299 100644 GIT binary patch delta 45 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 Xlz2+Da~S}>4uoi{>mfg=qN4sAKo-Lp literal 0 HcmV?d00001 diff --git a/doc/how_to/get_started_files/get_started_72_2.png b/doc/how_to/get_started_files/get_started_85_2.png similarity index 98% rename from doc/how_to/get_started_files/get_started_72_2.png rename to doc/how_to/get_started_files/get_started_85_2.png index e3b2433f530071a457fc054392a709d4c488d40e..ba51c7e56d8c6426cb44844ecc4437e7f987947c 100644 GIT binary patch delta 43 zcmX>Ve=2^0n}WHXsg6QMNl8JmmA-y%Vo5Ve=2^0n}VsHk&Z$}Nl8JmmA-y%Vo5) simulated file -# contains both a "recording" and a "sorting" object. +# Then we can open it. Note that [MEArec](https://mearec.readthedocs.io>) simulated files +# contain both a "recording" and a "sorting" object. local_path = si.download_dataset(remote_path="mearec/mearec_test_10s.h5") recording, sorting_true = se.read_mearec(local_path) @@ -123,7 +123,7 @@ # - # SpikeInterface internally uses the [ProbeInterface](https://probeinterface.readthedocs.io/en/main/) package to handle `probeinterface.Probe` and -# `probeinterface.ProbeGroup`. So any probe in the probeinterface collections can be downloaded and set to a +# `probeinterface.ProbeGroup`. So any probe in the probeinterface collection can be downloaded and set to a # `Recording` object. In this case, the MEArec dataset already handles a `Probe` and we don't need to set it *manually*. # + @@ -199,7 +199,9 @@ print("Units found by tridesclous:", sorting_TDC.get_unit_ids()) print("Units found by spyking-circus2:", sorting_SC2.get_unit_ids()) -# If a sorter is not installed locally, we can also avoid installing it and run it anyways, using a container (Docker or Singularity). To do this, you will need to install Docker. More information [here](https://spikeinterface.readthedocs.io/en/latest/modules/sorters.html?highlight=docker#running-sorters-in-docker-singularity-containers). For example, let's run `Kilosort2` using Docker: +# If a sorter is not installed locally, we can also avoid installing it and run it anyways, using a container (Docker or Singularity). +# To do this, you will need to install Docker. More information [here](https://spikeinterface.readthedocs.io/en/latest/modules/sorters.html?highlight=docker#running-sorters-in-docker-singularity-containers). +# Let's run `Kilosort2` using Docker: sorting_KS2 = ss.run_sorter(sorter_name="kilosort2", recording=recording_preprocessed, docker_image=True, verbose=True) print(sorting_KS2) @@ -210,21 +212,22 @@ sa_TDC = si.create_sorting_analyzer(sorting_TDC, recording_preprocessed, format='binary_folder', folder='sa_TDC_binary') # This folder is where all the postprocessing data will be saved such as waveforms and templates. Let's calculate -# some waveforms. To do this the function samples some spikes (by default `max_spikes_per_unit=500`) +# some waveforms. When doing this, the function samples some spikes (by default `max_spikes_per_unit=500`) # for each unit, extracts their waveforms, and stores them to disk in `extensions/waveforms`. # These waveforms are helpful to compute the average waveform, or "template", for each unit and then to compute, for example, quality metrics. -# All computations for the `SortingAnalyzer` object are done using the `compute` method: +# Computations with the `SortingAnalyzer` object are done using the `compute` method: # + sa_TDC.compute("random_spikes") sa_TDC.compute("waveforms") # - -# The results of these calculations are saved as `extensions`. We access the results by first getting the extension +# The results of these calculations are saved as `extensions`. Some simple data, such as the `unit_ids` can be accessed directly +# from the `SortingAnalyzer` object. Extension data is accessed by first getting the extension then getting the data # + unit_id0 = sa_TDC.unit_ids[0] -waveforms = sa_TDC.get_extension("waveforms").get_data()[0] +waveforms = sa_TDC.get_extension("waveforms").get_data()[unit_id0] print(waveforms.shape) # - @@ -250,7 +253,7 @@ plt.show() # - -# You can check which extensions have been saved (in the folder) and which have been loaded (in your enviroment)... +# You can check which extensions have been saved (in your local folder) and which have been loaded (in your enviroment)... # + print(sa_TDC.get_saved_extension_names()) @@ -266,7 +269,7 @@ # This deletes the extension's data in the `SortingAnalyzer` folder. # # Importantly, `SortingAnalyzers` (and all extensions) can be reloaded at later times: -# (Note: spike_locations is not loaded, since we just deleted it) +# (Here, spike_amplitudes is not loaded since we just deleted it) # + sa_loaded = si.load_sorting_analyzer('sa_TDC_binary') @@ -279,7 +282,8 @@ sa_TDC.compute("spike_amplitudes") # - -# Once we have computed all of the postprocessing information, we can compute quality metrics (different quality metrics require different extensions - e.g., drift metrics require `spike_locations`): +# Once we have computed all of the postprocessing information, we can compute quality +# metrics (some quality metrics require certain extensions - e.g., drift metrics require `spike_locations`): qm_params = sqm.get_default_qm_params() pprint(qm_params) @@ -294,7 +298,7 @@ qm = sqm.compute_quality_metrics(sa_TDC, qm_params=qm_params) display(qm) -# Quality metrics are also extensions (and become part of the SortingAnalyzer folder): +# Quality metrics are also extensions (and become part of the `SortingAnalyzer` folder): # Next, we can use some of the powerful tools for spike sorting visualization. From d2c06abc620856319e6fec95b4b0552b54d03b7f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 12:13:40 +0000 Subject: [PATCH 12/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- doc/how_to/get_started.rst | 34 +++++++++++++++++----------------- examples/how_to/get_started.py | 12 ++++++------ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/how_to/get_started.rst b/doc/how_to/get_started.rst index 97dae29f72..30276a32d4 100644 --- a/doc/how_to/get_started.rst +++ b/doc/how_to/get_started.rst @@ -86,7 +86,7 @@ both a “recording” and a “sorting” object. .. parsed-literal:: - MEArecRecordingExtractor: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + MEArecRecordingExtractor: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB file_path: /home/nolanlab/spikeinterface_datasets/ephy_testing_data/mearec/mearec_test_10s.h5 MEArecSortingExtractor: 10 units - 1 segments - 32.0kHz @@ -126,7 +126,7 @@ This is how you retrieve info from a ``BaseRecording``\ … fs = recording.get_sampling_frequency() num_chan = recording.get_num_channels() num_seg = recording.get_num_segments() - + print("Channel ids:", channel_ids) print("Sampling frequency:", fs) print("Number of channels:", num_chan) @@ -150,7 +150,7 @@ This is how you retrieve info from a ``BaseRecording``\ … num_seg = recording.get_num_segments() unit_ids = sorting_true.get_unit_ids() spike_train = sorting_true.get_unit_spike_train(unit_id=unit_ids[0]) - + print("Number of segments:", num_seg) print("Unit ids:", unit_ids) print("Spike train of first unit:", spike_train) @@ -180,9 +180,9 @@ to set it *manually*. probe = recording.get_probe() print(probe) - + from probeinterface.plotting import plot_probe - + _ = plot_probe(probe) @@ -214,7 +214,7 @@ object to disk. print(recording_f) recording_cmr = si.common_reference(recording_f, reference="global", operator="median") print(recording_cmr) - + # this computes and saves the recording after applying the preprocessing chain recording_preprocessed = recording_cmr.save(format="binary") print(recording_preprocessed) @@ -222,9 +222,9 @@ object to disk. .. parsed-literal:: - BandpassFilterRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + BandpassFilterRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB - CommonReferenceRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + CommonReferenceRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB Use cache_folder=/tmp/spikeinterface_cache/tmp8sr7ylv1/PVPX8CJL write_binary_recording with n_jobs = 4 and chunk_size = 32000 @@ -238,7 +238,7 @@ object to disk. .. parsed-literal:: - BinaryFolderRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + BinaryFolderRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB @@ -325,7 +325,7 @@ Alternatively we can pass a full dictionary containing the parameters: other_params = ss.get_default_sorter_params("tridesclous") other_params["detect_threshold"] = 6 - + # parameters set by params dictionary sorting_TDC_2 = ss.run_sorter( sorter_name="tridesclous", recording=recording_preprocessed, output_folder="tdc_output2", **other_params @@ -638,11 +638,11 @@ accommodate the duration: .dataframe tbody tr th:only-of-type { vertical-align: middle; } - + .dataframe tbody tr th { vertical-align: top; } - + .dataframe thead th { text-align: right; } @@ -961,7 +961,7 @@ on the “Save as snapshot (sha://)” and copy the URI: .. code:: ipython3 uri = "sha1://68cb54a9aaed2303fb82dedbc302c853e818f1b6" - + sorting_curated_sv = scur.apply_sortingview_curation(sorting_TDC, uri_or_json=uri) print(sorting_curated_sv) print(sorting_curated_sv.get_property("accept")) @@ -1032,7 +1032,7 @@ above a certain threshold: keep_mask = (qm["snr"] > 10) & (qm["isi_violations_ratio"] < 0.01) print("Mask:", keep_mask.values) - + sorting_curated_auto = sorting_TDC.select_units(sorting_TDC.unit_ids[keep_mask]) print(sorting_curated_auto) @@ -1076,7 +1076,7 @@ performance and plot a confusion matrix .. parsed-literal:: accuracy recall precision false_discovery_rate miss_rate - gt_unit_id + gt_unit_id #0 1.0 1.0 1.0 0.0 0.0 #1 1.0 1.0 1.0 0.0 0.0 #2 0.976744 0.976744 1.0 0.0 0.023256 @@ -1155,9 +1155,9 @@ graph showing how the units are matched between the sorters. .. code:: ipython3 sorting_agreement = comp_multi.get_agreement_sorting(minimum_agreement_count=2) - + print("Units in agreement between TDC, SC2, and KS2:", sorting_agreement.get_unit_ids()) - + w_multi = sw.plot_multicomparison_agreement(comp_multi) w_multi = sw.plot_multicomparison_agreement_by_sorter(comp_multi) diff --git a/examples/how_to/get_started.py b/examples/how_to/get_started.py index 0c403d535a..4b843491fc 100644 --- a/examples/how_to/get_started.py +++ b/examples/how_to/get_started.py @@ -199,8 +199,8 @@ print("Units found by tridesclous:", sorting_TDC.get_unit_ids()) print("Units found by spyking-circus2:", sorting_SC2.get_unit_ids()) -# If a sorter is not installed locally, we can also avoid installing it and run it anyways, using a container (Docker or Singularity). -# To do this, you will need to install Docker. More information [here](https://spikeinterface.readthedocs.io/en/latest/modules/sorters.html?highlight=docker#running-sorters-in-docker-singularity-containers). +# If a sorter is not installed locally, we can also avoid installing it and run it anyways, using a container (Docker or Singularity). +# To do this, you will need to install Docker. More information [here](https://spikeinterface.readthedocs.io/en/latest/modules/sorters.html?highlight=docker#running-sorters-in-docker-singularity-containers). # Let's run `Kilosort2` using Docker: sorting_KS2 = ss.run_sorter(sorter_name="kilosort2", recording=recording_preprocessed, docker_image=True, verbose=True) @@ -213,7 +213,7 @@ # This folder is where all the postprocessing data will be saved such as waveforms and templates. Let's calculate # some waveforms. When doing this, the function samples some spikes (by default `max_spikes_per_unit=500`) -# for each unit, extracts their waveforms, and stores them to disk in `extensions/waveforms`. +# for each unit, extracts their waveforms, and stores them to disk in `extensions/waveforms`. # These waveforms are helpful to compute the average waveform, or "template", for each unit and then to compute, for example, quality metrics. # Computations with the `SortingAnalyzer` object are done using the `compute` method: @@ -258,13 +258,13 @@ # + print(sa_TDC.get_saved_extension_names()) print(sa_TDC.get_loaded_extension_names()) -# - +# - # ...or delete an extension... # + sa_TDC.delete_extension("spike_amplitudes") -# - +# - # This deletes the extension's data in the `SortingAnalyzer` folder. # @@ -282,7 +282,7 @@ sa_TDC.compute("spike_amplitudes") # - -# Once we have computed all of the postprocessing information, we can compute quality +# Once we have computed all of the postprocessing information, we can compute quality # metrics (some quality metrics require certain extensions - e.g., drift metrics require `spike_locations`): qm_params = sqm.get_default_qm_params() From f3330c66587f8ebb69d48b72d7085a4470921dd2 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Fri, 15 Mar 2024 15:30:00 +0000 Subject: [PATCH 13/28] Update examples/how_to/get_started.py Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com> --- examples/how_to/get_started.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/how_to/get_started.py b/examples/how_to/get_started.py index 4b843491fc..a156836424 100644 --- a/examples/how_to/get_started.py +++ b/examples/how_to/get_started.py @@ -59,9 +59,10 @@ import spikeinterface.curation as scur import spikeinterface.widgets as sw -# Alternatively, we can import all submodules at once which +# Alternatively, we can import all submodules at once with `import spikeinterface.full as si` which # internally imports core+extractors+preprocessing+sorters+postprocessing+ -# qualitymetrics+comparison+widgets+exporters +# qualitymetrics+comparison+widgets+exporters. In this case all aliases in the following tutorial +# would be `si` # # This is useful for notebooks, but it is a heavier import because internally many more dependencies # are imported (scipy/sklearn/networkx/matplotlib/h5py...) From b5eb69aab142792abc02c3aef544a4023efe7636 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Fri, 15 Mar 2024 15:30:12 +0000 Subject: [PATCH 14/28] Update examples/how_to/get_started.py Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com> --- examples/how_to/get_started.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/how_to/get_started.py b/examples/how_to/get_started.py index a156836424..7d324378ad 100644 --- a/examples/how_to/get_started.py +++ b/examples/how_to/get_started.py @@ -210,7 +210,7 @@ # For postprocessing SpikeInterface pairs recording and sorting objects into a `SortingAnalyzer` object. # The `SortingAnalyzer` can be loaded in memory or saved in a folder. Here, we save it in binary format. -sa_TDC = si.create_sorting_analyzer(sorting_TDC, recording_preprocessed, format='binary_folder', folder='sa_TDC_binary') +sa_TDC = si.create_sorting_analyzer(sorting=sorting_TDC, recording=recording_preprocessed, format='binary_folder', folder='sa_TDC_binary') # This folder is where all the postprocessing data will be saved such as waveforms and templates. Let's calculate # some waveforms. When doing this, the function samples some spikes (by default `max_spikes_per_unit=500`) From 0da56a659c74b621104908c3f437ed2967d2e22c Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Fri, 15 Mar 2024 16:34:57 +0000 Subject: [PATCH 15/28] Add compute options and change to compute(quality_metrics) --- doc/how_to/get_started.rst | 263 ++++++++++-------- ..._started_15_0.png => get_started_16_0.png} | Bin ..._started_15_1.png => get_started_16_1.png} | Bin ..._started_21_1.png => get_started_22_1.png} | Bin .../get_started_files/get_started_48_0.png | Bin 8955 -> 0 bytes .../get_started_files/get_started_52_0.png | Bin 0 -> 8933 bytes ..._started_79_1.png => get_started_84_1.png} | Bin ..._started_79_2.png => get_started_84_2.png} | Bin ..._started_85_1.png => get_started_90_1.png} | Bin ..._started_85_2.png => get_started_90_2.png} | Bin examples/how_to/get_started.py | 75 ++--- 11 files changed, 195 insertions(+), 143 deletions(-) rename doc/how_to/get_started_files/{get_started_15_0.png => get_started_16_0.png} (100%) rename doc/how_to/get_started_files/{get_started_15_1.png => get_started_16_1.png} (100%) rename doc/how_to/get_started_files/{get_started_21_1.png => get_started_22_1.png} (100%) delete mode 100644 doc/how_to/get_started_files/get_started_48_0.png create mode 100644 doc/how_to/get_started_files/get_started_52_0.png rename doc/how_to/get_started_files/{get_started_79_1.png => get_started_84_1.png} (100%) rename doc/how_to/get_started_files/{get_started_79_2.png => get_started_84_2.png} (100%) rename doc/how_to/get_started_files/{get_started_85_1.png => get_started_90_1.png} (100%) rename doc/how_to/get_started_files/{get_started_85_2.png => get_started_90_2.png} (100%) diff --git a/doc/how_to/get_started.rst b/doc/how_to/get_started.rst index 97dae29f72..d55bbe9fee 100644 --- a/doc/how_to/get_started.rst +++ b/doc/how_to/get_started.rst @@ -17,7 +17,7 @@ curation (manual and automatic), and compare spike sorting results. from pprint import pprint The spikeinterface module by itself imports only the spikeinterface.core -submodule which is not useful for end user +submodule which is not useful for the end user .. code:: ipython3 @@ -48,9 +48,11 @@ We need to import one by one different submodules separately import spikeinterface.curation as scur import spikeinterface.widgets as sw -Alternatively, we can import all submodules at once which internally -imports core+extractors+preprocessing+sorters+postprocessing+ -qualitymetrics+comparison+widgets+exporters +Alternatively, we can import all submodules at once with +``import spikeinterface.full as si`` which internally imports +core+extractors+preprocessing+sorters+postprocessing+ +qualitymetrics+comparison+widgets+exporters. In this case all aliases in +the following tutorial would be ``si``. This is useful for notebooks, but it is a heavier import because internally many more dependencies are imported @@ -111,11 +113,11 @@ and the raster plots. -.. image:: get_started_files/get_started_15_0.png +.. image:: get_started_files/get_started_16_0.png -.. image:: get_started_files/get_started_15_1.png +.. image:: get_started_files/get_started_16_1.png This is how you retrieve info from a ``BaseRecording``\ … @@ -192,7 +194,7 @@ to set it *manually*. -.. image:: get_started_files/get_started_21_1.png +.. image:: get_started_files/get_started_22_1.png If your recording does not have a ``Probe``, you can set it using @@ -226,7 +228,7 @@ object to disk. float32 dtype - 39.06 MiB CommonReferenceRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB - Use cache_folder=/tmp/spikeinterface_cache/tmp8sr7ylv1/PVPX8CJL + Use cache_folder=/tmp/spikeinterface_cache/tmp8zkscdxr/3IT027JP write_binary_recording with n_jobs = 4 and chunk_size = 32000 @@ -396,7 +398,7 @@ in memory or saved in a folder. Here, we save it in binary format. .. code:: ipython3 - sa_TDC = si.create_sorting_analyzer(sorting_TDC, recording_preprocessed, format='binary_folder', folder='sa_TDC_binary') + analyzer_TDC = si.create_sorting_analyzer(sorting=sorting_TDC, recording=recording_preprocessed, format='binary_folder', folder='analyzer_TDC_binary') @@ -416,8 +418,8 @@ and then to compute, for example, quality metrics. Computations with the .. code:: ipython3 - sa_TDC.compute("random_spikes") - sa_TDC.compute("waveforms") + analyzer_TDC.compute("random_spikes") + analyzer_TDC.compute("waveforms") @@ -430,7 +432,7 @@ and then to compute, for example, quality metrics. Computations with the .. parsed-literal:: - + @@ -441,8 +443,8 @@ the extension then getting the data .. code:: ipython3 - unit_id0 = sa_TDC.unit_ids[0] - waveforms = sa_TDC.get_extension("waveforms").get_data()[unit_id0] + unit_id0 = analyzer_TDC.unit_ids[0] + waveforms = analyzer_TDC.get_extension("waveforms").get_data()[unit_id0] print(waveforms.shape) @@ -455,13 +457,9 @@ There are many more properties we can calculate .. code:: ipython3 - sa_TDC.compute("noise_levels") - sa_TDC.compute("templates") - sa_TDC.compute("spike_amplitudes") - sa_TDC.compute("unit_locations") - sa_TDC.compute("spike_locations") - sa_TDC.compute("correlograms") - sa_TDC.compute("template_similarity") + analyzer_TDC.compute("noise_levels") + analyzer_TDC.compute("templates") + analyzer_TDC.compute("spike_amplitudes") @@ -471,6 +469,24 @@ There are many more properties we can calculate + +.. parsed-literal:: + + + + + +Many of the extensions have parameters you can tune + +.. code:: ipython3 + + analyzer_TDC.compute("unit_locations", method="center_of_mass") + analyzer_TDC.compute("spike_locations", ms_before=0.5) + analyzer_TDC.compute("correlograms", bin_ms=0.1) + analyzer_TDC.compute("template_similarity", method="cosine_similarity") + + + .. parsed-literal:: spike_locations: 0%| | 0/10 [00:00 + + +Find out more about the available parameters and extensions +`here `__. -These calculations are saved in the ``extensions`` subfolder of the +The calculations are saved in the ``extensions`` subfolder of the ``SortingAnalyzer`` folder. Similar to the waveforms we can access them using ``get_extension`` and ``get_data``. For example, here we can make a historgram of spike amplitudes .. code:: ipython3 - amplitudes = sa_TDC.get_extension("spike_amplitudes").get_data() + amplitudes = analyzer_TDC.get_extension("spike_amplitudes").get_data() plt.hist(amplitudes, bins=50) plt.show() -.. image:: get_started_files/get_started_48_0.png +.. image:: get_started_files/get_started_52_0.png You can check which extensions have been saved (in your local folder) @@ -505,8 +524,8 @@ and which have been loaded (in your enviroment)… .. code:: ipython3 - print(sa_TDC.get_saved_extension_names()) - print(sa_TDC.get_loaded_extension_names()) + print(analyzer_TDC.get_saved_extension_names()) + print(analyzer_TDC.get_loaded_extension_names()) .. parsed-literal:: @@ -519,18 +538,18 @@ and which have been loaded (in your enviroment)… .. code:: ipython3 - sa_TDC.delete_extension("spike_amplitudes") + analyzer_TDC.delete_extension("spike_amplitudes") This deletes the extension’s data in the ``SortingAnalyzer`` folder. Importantly, ``SortingAnalyzers`` (and all extensions) can be reloaded -at later times: (Here, ``spike_amplitudes`` is not loaded since we just +at later times: (Here, spike_amplitudes is not loaded since we just deleted it) .. code:: ipython3 - sa_loaded = si.load_sorting_analyzer('sa_TDC_binary') - print(sa_loaded.get_loaded_extension_names()) + analyzer_loaded = si.load_sorting_analyzer('analyzer_TDC_binary') + print(analyzer_loaded.get_loaded_extension_names()) .. parsed-literal:: @@ -542,7 +561,7 @@ And any deleted extensions are easily recomputed .. code:: ipython3 - sa_TDC.compute("spike_amplitudes") + analyzer_TDC.compute("spike_amplitudes") @@ -555,7 +574,7 @@ And any deleted extensions are easily recomputed .. parsed-literal:: - + @@ -624,10 +643,24 @@ accommodate the duration: qm_params["drift"]["interval_s"] = 2 qm_params["drift"]["min_spikes_per_interval"] = 2 +Quality metrics are extensions, so computations and data extraction work +in the same way as earlier + .. code:: ipython3 - qm = sqm.compute_quality_metrics(sa_TDC, qm_params=qm_params) - display(qm) + analyzer_TDC.compute("quality_metrics", qm_params) + analyzer_TDC.get_extension("quality_metrics").get_data() + + +.. parsed-literal:: + + /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/qualitymetrics/misc_metrics.py:846: UserWarning: Some units have too few spikes : amplitude_cutoff is set to NaN + warnings.warn(f"Some units have too few spikes : amplitude_cutoff is set to NaN") + /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/qualitymetrics/misc_metrics.py:999: UserWarning: The recording is too short given the specified 'interval_s' and 'min_num_bins'. Drift metrics will be set to NaN + warnings.warn( + /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/qualitymetrics/misc_metrics.py:147: UserWarning: Bin duration of 60s is larger than recording duration. Presence ratios are set to NaN. + warnings.warn( + @@ -677,240 +710,240 @@ accommodate the duration: 0 - 0.200717 + NaN NaN NaN -306.199036 - 1.052532 - 0.424653 - 0.421992 + NaN + NaN + NaN 0.72 3.0 0.0 ... 30.0 - 0.9 + NaN 0.0 0.0 1.536918 NaN - 27.411295 + 27.153605 0.0 0.0 0.0 1 - 0.500000 + NaN NaN NaN -273.444977 - 0.995004 - 0.344932 - 0.261774 + NaN + NaN + NaN 0.18 5.1 0.0 ... 51.0 - 1.0 + NaN 0.0 0.0 1.311148 NaN - 24.264845 + 24.072818 0.0 0.0 0.0 2 - 0.500000 + NaN NaN NaN -269.204590 - 1.355411 - 0.541736 - 0.567367 + NaN + NaN + NaN 0.90 5.3 0.0 ... 53.0 - 0.9 + NaN 0.0 0.0 2.016703 NaN - 24.177365 + 24.172255 0.0 0.0 0.0 3 - 0.500000 + NaN NaN NaN -311.545715 - 0.421523 - 0.146277 - 0.112580 + NaN + NaN + NaN 0.72 5.0 0.0 ... 50.0 - 1.0 + NaN 0.0 0.0 2.011083 NaN - 26.977121 + 26.741690 0.0 0.0 0.0 4 - 0.207231 + NaN NaN NaN -106.953278 - 1.941205 - 0.688280 - 0.556732 + NaN + NaN + NaN 0.72 3.6 0.0 ... 36.0 - 1.0 + NaN 0.0 0.0 0.680199 NaN - 9.636824 + 9.519926 0.0 0.0 0.0 5 - 0.204838 + NaN NaN NaN -150.833191 - 0.927884 - 0.314812 - 0.186148 + NaN + NaN + NaN 0.36 4.2 0.0 ... 42.0 - 1.0 + NaN 0.0 0.0 0.965515 NaN - 13.243997 + 13.052760 0.0 0.0 0.0 6 - 0.500000 + NaN NaN NaN -90.358444 - 2.084521 - 0.753820 - 0.385204 + NaN + NaN + NaN 0.00 4.8 0.0 ... 48.0 - 1.0 + NaN 0.0 0.0 1.177009 NaN - 8.280531 + 8.264430 0.0 0.0 0.0 7 - 0.500000 + NaN NaN NaN -102.491577 - 1.191062 - 0.452649 - 0.485258 + NaN + NaN + NaN 2.34 19.3 0.0 ... 193.0 - 1.0 + NaN 0.0 0.0 - 0.974259 + 0.973417 0.155 - 8.820936 + 8.796671 0.0 0.0 0.0 8 - 0.500000 + NaN NaN NaN -127.252319 - 1.116480 - 0.440774 - 0.477920 + NaN + NaN + NaN 0.90 12.9 0.0 ... 129.0 - 1.0 + NaN 0.0 0.0 0.949695 0.310 - 11.158875 + 11.126467 0.0 0.0 0.0 9 - 0.203415 + NaN NaN NaN -97.207291 - 1.395852 - 0.561095 - 0.632810 + NaN + NaN + NaN 2.16 11.0 0.0 ... 110.0 - 1.0 + NaN 0.0 0.0 - 1.027925 + 1.021080 0.270 - 8.306556 + 8.230328 0.0 0.0 0.0 @@ -921,10 +954,11 @@ accommodate the duration: -Quality metrics are also extensions (and become part of the -``SortingAnalyzer`` folder): -Next, we can use some of the powerful tools for spike sorting +And since the quality metrics are extensions, they are saved +``SortingAnalyzer`` folder. + +Now, we can use some of the powerful tools for spike sorting visualization. We can export a sorting summary and quality metrics plot using the @@ -935,22 +969,28 @@ web-based visualization. For this to work you need to install .. code:: ipython3 - w1 = sw.plot_quality_metrics(sa_TDC, display=False, backend="sortingview") + w1 = sw.plot_quality_metrics(analyzer_TDC, display=False, backend="sortingview") .. parsed-literal:: - /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/widgets/metrics.py:65: UserWarning: Skipping ['amplitude_cv_median', 'amplitude_cv_range'] because they contain all NaNs + /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/widgets/metrics.py:65: UserWarning: Skipping ['amplitude_cutoff', 'amplitude_cv_median', 'amplitude_cv_range', 'drift_ptp', 'drift_std', 'drift_mad', 'presence_ratio'] because they contain all NaNs warnings.warn(f"Skipping {nan_metrics} because they contain all NaNs") -https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://7927a56e56bde2e923f85858608dfc38c51da534 + +.. parsed-literal:: + + https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://167688f4ddfc0b27f5d67d5c9d84f89685e705fa .. code:: ipython3 - w2 = sw.plot_sorting_summary(sa_TDC, display=False, curation=True, backend="sortingview") + w2 = sw.plot_sorting_summary(analyzer_TDC, display=False, curation=True, backend="sortingview") + + +.. parsed-literal:: -https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://aa8e4c3e7f0f3f041eff55656b6e9151bcdec399 + https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://688cd7a233857847b5663e565dbf3f2807887013 The sorting summary plot can also be used for manual labeling and @@ -979,7 +1019,7 @@ of the spike sorting output. To export to phy you can run: .. code:: ipython3 - sexp.export_to_phy(sa_TDC, "phy_folder_for_TDC", verbose=True) + sexp.export_to_phy(analyzer_TDC, "phy_folder_for_TDC", verbose=True) @@ -1030,7 +1070,8 @@ above a certain threshold: .. code:: ipython3 - keep_mask = (qm["snr"] > 10) & (qm["isi_violations_ratio"] < 0.01) + qm_data = analyzer_TDC.get_extension("quality_metrics").get_data() + keep_mask = (qm_data["snr"] > 10) & (qm_data["isi_violations_ratio"] < 0.01) print("Mask:", keep_mask.values) sorting_curated_auto = sorting_TDC.select_units(sorting_TDC.unit_ids[keep_mask]) @@ -1090,11 +1131,11 @@ performance and plot a confusion matrix -.. image:: get_started_files/get_started_79_1.png +.. image:: get_started_files/get_started_84_1.png -.. image:: get_started_files/get_started_79_2.png +.. image:: get_started_files/get_started_84_2.png When comparing two sorters (2.), we can see the matching of units @@ -1168,11 +1209,11 @@ graph showing how the units are matched between the sorters. -.. image:: get_started_files/get_started_85_1.png +.. image:: get_started_files/get_started_90_1.png -.. image:: get_started_files/get_started_85_2.png +.. image:: get_started_files/get_started_90_2.png We see that 10 unit were found by all sorters (note that this simulated diff --git a/doc/how_to/get_started_files/get_started_15_0.png b/doc/how_to/get_started_files/get_started_16_0.png similarity index 100% rename from doc/how_to/get_started_files/get_started_15_0.png rename to doc/how_to/get_started_files/get_started_16_0.png diff --git a/doc/how_to/get_started_files/get_started_15_1.png b/doc/how_to/get_started_files/get_started_16_1.png similarity index 100% rename from doc/how_to/get_started_files/get_started_15_1.png rename to doc/how_to/get_started_files/get_started_16_1.png diff --git a/doc/how_to/get_started_files/get_started_21_1.png b/doc/how_to/get_started_files/get_started_22_1.png similarity index 100% rename from doc/how_to/get_started_files/get_started_21_1.png rename to doc/how_to/get_started_files/get_started_22_1.png diff --git a/doc/how_to/get_started_files/get_started_48_0.png b/doc/how_to/get_started_files/get_started_48_0.png deleted file mode 100644 index 3ad2694dca2b8b26747c8f63ea971c482f143a07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8955 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 diff --git a/doc/how_to/get_started_files/get_started_52_0.png b/doc/how_to/get_started_files/get_started_52_0.png new file mode 100644 index 0000000000000000000000000000000000000000..c31b5baacad10f25c42bed84220f615d86f30fc2 GIT binary patch literal 8933 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 is a GUI for manual # curation of the spike sorting output. To export to phy you can run: -sexp.export_to_phy(sa_TDC, "phy_folder_for_TDC", verbose=True) +sexp.export_to_phy(analyzer_TDC, "phy_folder_for_TDC", verbose=True) # Then you can run the template-gui with: `phy template-gui phy_folder_for_TDC/params.py` # and manually curate the results. @@ -336,7 +346,8 @@ # certain threshold: # + -keep_mask = (qm["snr"] > 10) & (qm["isi_violations_ratio"] < 0.01) +qm_data = analyzer_TDC.get_extension("quality_metrics").get_data() +keep_mask = (qm_data["snr"] > 10) & (qm_data["isi_violations_ratio"] < 0.01) print("Mask:", keep_mask.values) sorting_curated_auto = sorting_TDC.select_units(sorting_TDC.unit_ids[keep_mask]) From 4b9724df967341130c50163a32ed578d6f7ee5da Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Mon, 18 Mar 2024 09:43:30 +0100 Subject: [PATCH 16/28] Delete quality metrics NaN warnings --- doc/how_to/get_started.rst | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/doc/how_to/get_started.rst b/doc/how_to/get_started.rst index 0d7bceb9a7..537df72a1f 100644 --- a/doc/how_to/get_started.rst +++ b/doc/how_to/get_started.rst @@ -651,19 +651,6 @@ in the same way as earlier analyzer_TDC.compute("quality_metrics", qm_params) analyzer_TDC.get_extension("quality_metrics").get_data() - -.. parsed-literal:: - - /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/qualitymetrics/misc_metrics.py:846: UserWarning: Some units have too few spikes : amplitude_cutoff is set to NaN - warnings.warn(f"Some units have too few spikes : amplitude_cutoff is set to NaN") - /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/qualitymetrics/misc_metrics.py:999: UserWarning: The recording is too short given the specified 'interval_s' and 'min_num_bins'. Drift metrics will be set to NaN - warnings.warn( - /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/qualitymetrics/misc_metrics.py:147: UserWarning: Bin duration of 60s is larger than recording duration. Presence ratios are set to NaN. - warnings.warn( - - - - .. raw:: html

From be80833aa0924e85bb756e4543b59e3416159aa9 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Mon, 18 Mar 2024 09:50:59 +0100 Subject: [PATCH 17/28] Add set_probe comment in get_started.rst --- doc/how_to/get_started.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/how_to/get_started.rst b/doc/how_to/get_started.rst index 537df72a1f..3e7c460b84 100644 --- a/doc/how_to/get_started.rst +++ b/doc/how_to/get_started.rst @@ -198,7 +198,9 @@ to set it *manually*. If your recording does not have a ``Probe``, you can set it using -``set_probe``. There is more information +``set_probe``. Note: ``set_probe`` creates a copy of the recording +with the new probe, rather than modifying the existing recording +in place. There is more information `here `__. Using the ``spikeinterface.preprocessing`` module, you can perform From 19236a2f4c985bd1adbbc3e963a39bc56c3ebb25 Mon Sep 17 00:00:00 2001 From: Alessio Buccino Date: Mon, 18 Mar 2024 09:51:31 +0100 Subject: [PATCH 18/28] Add batch size to KS4 wrapper --- src/spikeinterface/sorters/external/kilosort4.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/spikeinterface/sorters/external/kilosort4.py b/src/spikeinterface/sorters/external/kilosort4.py index 9f7ce929c9..78e024a49c 100644 --- a/src/spikeinterface/sorters/external/kilosort4.py +++ b/src/spikeinterface/sorters/external/kilosort4.py @@ -18,6 +18,7 @@ class Kilosort4Sorter(BaseSorter): gpu_capability = "nvidia-optional" _default_params = { + "batch_size": 60000, "nblocks": 1, "Th_universal": 9, "Th_learned": 8, @@ -53,6 +54,7 @@ class Kilosort4Sorter(BaseSorter): } _params_description = { + "batch_size": "Number of samples included in each batch of data.", "nblocks": "Number of non-overlapping blocks for drift correction (additional nblocks-1 blocks are created in the overlaps). Default value: 1.", "Th_universal": "Spike detection threshold for universal templates. Th(1) in previous versions of Kilosort. Default value: 9.", "Th_learned": "Spike detection threshold for learned templates. Th(2) in previous versions of Kilosort. Default value: 8.", From cf6440718c8b93b71aece8086b12be234353fce7 Mon Sep 17 00:00:00 2001 From: chrishalcrow <57948917+chrishalcrow@users.noreply.github.com> Date: Mon, 18 Mar 2024 09:51:57 +0100 Subject: [PATCH 19/28] Add set_probe comment in get_started.py --- examples/how_to/get_started.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/how_to/get_started.py b/examples/how_to/get_started.py index 0295969ead..c34ca228c3 100644 --- a/examples/how_to/get_started.py +++ b/examples/how_to/get_started.py @@ -137,7 +137,10 @@ _ = plot_probe(probe) # - -# If your recording does not have a `Probe`, you can set it using `set_probe`. There is more information [here](https://spikeinterface.readthedocs.io/en/latest/modules_gallery/core/plot_3_handle_probe_info.html). +# If your recording does not have a `Probe`, you can set it using `set_probe`. +# Note: `set_probe` creates a copy of the recording with the new probe, +# rather than modifying the existing recording in place. +# There is more information [here](https://spikeinterface.readthedocs.io/en/latest/modules_gallery/core/plot_3_handle_probe_info.html). # Using the `spikeinterface.preprocessing` module, you can perform preprocessing on the recordings. # Each pre-processing function also returns a `BaseRecording`, From 858e5121c8c5d9cade48625659e53507c931dff8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 08:52:15 +0000 Subject: [PATCH 20/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/how_to/get_started.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/how_to/get_started.py b/examples/how_to/get_started.py index c34ca228c3..cf747bdc94 100644 --- a/examples/how_to/get_started.py +++ b/examples/how_to/get_started.py @@ -137,8 +137,8 @@ _ = plot_probe(probe) # - -# If your recording does not have a `Probe`, you can set it using `set_probe`. -# Note: `set_probe` creates a copy of the recording with the new probe, +# If your recording does not have a `Probe`, you can set it using `set_probe`. +# Note: `set_probe` creates a copy of the recording with the new probe, # rather than modifying the existing recording in place. # There is more information [here](https://spikeinterface.readthedocs.io/en/latest/modules_gallery/core/plot_3_handle_probe_info.html). From 2981e07e80c6511d4bd637fdcf3fa28e8bd1831e Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Mon, 18 Mar 2024 11:07:27 +0100 Subject: [PATCH 21/28] Fix --- src/spikeinterface/core/numpyextractors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/core/numpyextractors.py b/src/spikeinterface/core/numpyextractors.py index b646dab233..41cea28c07 100644 --- a/src/spikeinterface/core/numpyextractors.py +++ b/src/spikeinterface/core/numpyextractors.py @@ -457,7 +457,7 @@ def from_peaks(peaks, sampling_frequency, unit_ids) -> "NumpySorting": spikes["sample_index"] = peaks["sample_index"] spikes["unit_index"] = peaks["channel_index"] spikes["segment_index"] = peaks["segment_index"] - order = np.argsort(spikes["sample_index"]) + order = np.lexsort((spikes["segment_index"], spikes["sample_index"])) spikes = spikes[order] sorting = NumpySorting(spikes, sampling_frequency, unit_ids) From 24b9886d37c16a51095851131b23310351c11b9e Mon Sep 17 00:00:00 2001 From: Pierre Yger Date: Mon, 18 Mar 2024 13:09:21 +0100 Subject: [PATCH 22/28] Patch --- src/spikeinterface/core/numpyextractors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/spikeinterface/core/numpyextractors.py b/src/spikeinterface/core/numpyextractors.py index 41cea28c07..7572c78adb 100644 --- a/src/spikeinterface/core/numpyextractors.py +++ b/src/spikeinterface/core/numpyextractors.py @@ -457,7 +457,7 @@ def from_peaks(peaks, sampling_frequency, unit_ids) -> "NumpySorting": spikes["sample_index"] = peaks["sample_index"] spikes["unit_index"] = peaks["channel_index"] spikes["segment_index"] = peaks["segment_index"] - order = np.lexsort((spikes["segment_index"], spikes["sample_index"])) + order = np.lexsort((spikes["sample_index"], spikes["segment_index"])) spikes = spikes[order] sorting = NumpySorting(spikes, sampling_frequency, unit_ids) From 8e73c3baadb6f9d8a55e25f8a07983346b5bcc3f Mon Sep 17 00:00:00 2001 From: Zach McKenzie <92116279+zm711@users.noreply.github.com> Date: Mon, 18 Mar 2024 08:25:12 -0400 Subject: [PATCH 23/28] fix broken link --- installation_tips/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installation_tips/README.md b/installation_tips/README.md index 59209d01bc..94abaacb63 100644 --- a/installation_tips/README.md +++ b/installation_tips/README.md @@ -48,7 +48,7 @@ If you want to test the spikeinterface install you can: conda activate si_env python check_your_install.py ``` -5. If a windows user to clean-up you will also need to right click + save [`cleanup_for_windows.py`](https://raw.githubusercontent.com/SpikeInterfacemaster/installation_tips/cleanup_for_windows.py) +5. If a windows user to clean-up you will also need to right click + save [`cleanup_for_windows.py`](https://raw.githubusercontent.com/SpikeInterface/master/installation_tips/cleanup_for_windows.py) Then transfer `cleanup_for_windows.py` into your "Documents" folder. Finally run : ``` python cleanup_for_windows.py From 662ee846a8d96b87a9b2b2345652639711a965d5 Mon Sep 17 00:00:00 2001 From: Zach McKenzie <92116279+zm711@users.noreply.github.com> Date: Mon, 18 Mar 2024 08:26:31 -0400 Subject: [PATCH 24/28] switch links to main --- installation_tips/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/installation_tips/README.md b/installation_tips/README.md index 94abaacb63..1257cb6786 100644 --- a/installation_tips/README.md +++ b/installation_tips/README.md @@ -19,8 +19,8 @@ Steps: 1. Download anaconda individual edition [here](https://www.anaconda.com/download) 2. Run the installer. Check the box “Add anaconda3 to my Path environment variable”. It makes life easier for beginners. 3. Download with right click + save the file corresponding to your OS, and put it in "Documents" folder - * [`full_spikeinterface_environment_windows.yml`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/master/installation_tips/full_spikeinterface_environment_windows.yml) - * [`full_spikeinterface_environment_mac.yml`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/master/installation_tips/full_spikeinterface_environment_mac.yml) + * [`full_spikeinterface_environment_windows.yml`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/full_spikeinterface_environment_windows.yml) + * [`full_spikeinterface_environment_mac.yml`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/full_spikeinterface_environment_mac.yml) 4. Then open the "Anaconda Command Prompt" (if Windows, search in your applications) or the Terminal (for Mac users) 5. If not in the "Documents" folder type `cd Documents` 6. Then run this depending on your OS: @@ -38,7 +38,7 @@ Note for **linux** users : this conda recipe should work but we recommend strong If you want to test the spikeinterface install you can: -1. Download with right click + save the file [`check_your_install.py`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/master/installation_tips/check_your_install.py) +1. Download with right click + save the file [`check_your_install.py`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/check_your_install.py) and put it into the "Documents" folder 2. Open the Anaconda Command Prompt (Windows) or Terminal (Mac) @@ -48,7 +48,7 @@ If you want to test the spikeinterface install you can: conda activate si_env python check_your_install.py ``` -5. If a windows user to clean-up you will also need to right click + save [`cleanup_for_windows.py`](https://raw.githubusercontent.com/SpikeInterface/master/installation_tips/cleanup_for_windows.py) +5. If a windows user to clean-up you will also need to right click + save [`cleanup_for_windows.py`](https://raw.githubusercontent.com/SpikeInterface/spikeinterface/main/installation_tips/cleanup_for_windows.py) Then transfer `cleanup_for_windows.py` into your "Documents" folder. Finally run : ``` python cleanup_for_windows.py From efa1923a9dc4bb79fa88abc79254790dc2c70ccb Mon Sep 17 00:00:00 2001 From: Garcia Samuel Date: Mon, 18 Mar 2024 17:31:07 +0100 Subject: [PATCH 25/28] Thanks you Zach and Alessio Co-authored-by: Zach McKenzie <92116279+zm711@users.noreply.github.com> Co-authored-by: Alessio Buccino --- src/spikeinterface/core/sortinganalyzer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/spikeinterface/core/sortinganalyzer.py b/src/spikeinterface/core/sortinganalyzer.py index 1919d15bbf..7138807e73 100644 --- a/src/spikeinterface/core/sortinganalyzer.py +++ b/src/spikeinterface/core/sortinganalyzer.py @@ -1082,7 +1082,7 @@ def get_extension_class(extension_name: str, auto_import=True): f"Extension '{extension_name}' is not registered, please import related module before use: 'import {module}'" ) else: - raise ValueError(f"Extension '{extension_name}' is unkown maybe this is an external extension or a typo.") + raise ValueError(f"Extension '{extension_name}' is unknown maybe this is an external extension or a typo.") ext_class = extensions_dict[extension_name] return ext_class @@ -1482,7 +1482,7 @@ def get_data(self, *args, **kwargs): # this is a hardcoded list to to improve error message and auto_import mechanism -# this is important because extension are register when the submodule is imported +# this is important because extension are registered when the submodule is imported _builtin_extensions = { # from core "random_spikes": "spikeinterface.core", From 97b4dfa9ee346e298b1a8a70f52e34b2610fcf3d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 17:42:17 +0000 Subject: [PATCH 26/28] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 24.2.0 → 24.3.0](https://github.com/psf/black/compare/24.2.0...24.3.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d030e144a3..973959798f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 24.2.0 + rev: 24.3.0 hooks: - id: black files: ^src/ From 526ff1af962f2d3eabb3b67238458b14baa3f678 Mon Sep 17 00:00:00 2001 From: chrishalcrow Date: Tue, 19 Mar 2024 09:48:22 +0000 Subject: [PATCH 27/28] Make filepaths clearer and delete duplication --- doc/how_to/get_started.rst | 95 +++++++++++++++------------------- examples/how_to/get_started.py | 12 ++--- 2 files changed, 49 insertions(+), 58 deletions(-) diff --git a/doc/how_to/get_started.rst b/doc/how_to/get_started.rst index 3e7c460b84..9f5033ba1e 100644 --- a/doc/how_to/get_started.rst +++ b/doc/how_to/get_started.rst @@ -88,7 +88,7 @@ both a “recording” and a “sorting” object. .. parsed-literal:: - MEArecRecordingExtractor: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + MEArecRecordingExtractor: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB file_path: /home/nolanlab/spikeinterface_datasets/ephy_testing_data/mearec/mearec_test_10s.h5 MEArecSortingExtractor: 10 units - 1 segments - 32.0kHz @@ -128,7 +128,7 @@ This is how you retrieve info from a ``BaseRecording``\ … fs = recording.get_sampling_frequency() num_chan = recording.get_num_channels() num_seg = recording.get_num_segments() - + print("Channel ids:", channel_ids) print("Sampling frequency:", fs) print("Number of channels:", num_chan) @@ -152,7 +152,7 @@ This is how you retrieve info from a ``BaseRecording``\ … num_seg = recording.get_num_segments() unit_ids = sorting_true.get_unit_ids() spike_train = sorting_true.get_unit_spike_train(unit_id=unit_ids[0]) - + print("Number of segments:", num_seg) print("Unit ids:", unit_ids) print("Spike train of first unit:", spike_train) @@ -182,9 +182,9 @@ to set it *manually*. probe = recording.get_probe() print(probe) - + from probeinterface.plotting import plot_probe - + _ = plot_probe(probe) @@ -198,9 +198,9 @@ to set it *manually*. If your recording does not have a ``Probe``, you can set it using -``set_probe``. Note: ``set_probe`` creates a copy of the recording -with the new probe, rather than modifying the existing recording -in place. There is more information +``set_probe``. Note: ``set_probe`` creates a copy of the recording with +the new probe, rather than modifying the existing recording in place. +There is more information `here `__. Using the ``spikeinterface.preprocessing`` module, you can perform @@ -218,7 +218,7 @@ object to disk. print(recording_f) recording_cmr = si.common_reference(recording_f, reference="global", operator="median") print(recording_cmr) - + # this computes and saves the recording after applying the preprocessing chain recording_preprocessed = recording_cmr.save(format="binary") print(recording_preprocessed) @@ -226,11 +226,11 @@ object to disk. .. parsed-literal:: - BandpassFilterRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + BandpassFilterRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB - CommonReferenceRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + CommonReferenceRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB - Use cache_folder=/tmp/spikeinterface_cache/tmp8zkscdxr/3IT027JP + Use cache_folder=/tmp/spikeinterface_cache/tmpsgoh2z3y/DLGW1J8V write_binary_recording with n_jobs = 4 and chunk_size = 32000 @@ -242,7 +242,7 @@ object to disk. .. parsed-literal:: - BinaryFolderRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + BinaryFolderRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB @@ -329,7 +329,7 @@ Alternatively we can pass a full dictionary containing the parameters: other_params = ss.get_default_sorter_params("tridesclous") other_params["detect_threshold"] = 6 - + # parameters set by params dictionary sorting_TDC_2 = ss.run_sorter( sorter_name="tridesclous", recording=recording_preprocessed, output_folder="tdc_output2", **other_params @@ -413,7 +413,8 @@ This folder is where all the postprocessing data will be saved such as waveforms and templates. Let’s calculate some waveforms. When doing this, the function samples some spikes (by default ``max_spikes_per_unit=500``) for each unit, extracts their waveforms, -and stores them to disk in ``extensions/waveforms``. These waveforms are +and stores them to disk in +``./analyzer_TDC_binary/extensions/waveforms``. These waveforms are helpful to compute the average waveform, or “template”, for each unit and then to compute, for example, quality metrics. Computations with the ``SortingAnalyzer`` object are done using the ``compute`` method: @@ -434,7 +435,7 @@ and then to compute, for example, quality metrics. Computations with the .. parsed-literal:: - + @@ -474,7 +475,7 @@ There are many more properties we can calculate .. parsed-literal:: - + @@ -498,7 +499,7 @@ Many of the extensions have parameters you can tune .. parsed-literal:: - + @@ -545,12 +546,13 @@ and which have been loaded (in your enviroment)… This deletes the extension’s data in the ``SortingAnalyzer`` folder. Importantly, ``SortingAnalyzers`` (and all extensions) can be reloaded -at later times: (Here, spike_amplitudes is not loaded since we just -deleted it) +at later times from their folders: (Here, spike_amplitudes is not loaded +since we just deleted it) .. code:: ipython3 - analyzer_loaded = si.load_sorting_analyzer('analyzer_TDC_binary') + sorting_analyzer_path = './analyzer_TDC_binary' + analyzer_loaded = si.load_sorting_analyzer(sorting_analyzer_path) print(analyzer_loaded.get_loaded_extension_names()) @@ -576,7 +578,7 @@ And any deleted extensions are easily recomputed .. parsed-literal:: - + @@ -660,11 +662,11 @@ in the same way as earlier .dataframe tbody tr th:only-of-type { vertical-align: middle; } - + .dataframe tbody tr th { vertical-align: top; } - + .dataframe thead th { text-align: right; } @@ -716,7 +718,7 @@ in the same way as earlier 0.0 1.536918 NaN - 27.153605 + 27.140698 0.0 0.0 0.0 @@ -740,7 +742,7 @@ in the same way as earlier 0.0 1.311148 NaN - 24.072818 + 24.059540 0.0 0.0 0.0 @@ -764,7 +766,7 @@ in the same way as earlier 0.0 2.016703 NaN - 24.172255 + 24.387525 0.0 0.0 0.0 @@ -788,7 +790,7 @@ in the same way as earlier 0.0 2.011083 NaN - 26.741690 + 26.948630 0.0 0.0 0.0 @@ -812,7 +814,7 @@ in the same way as earlier 0.0 0.680199 NaN - 9.519926 + 9.585650 0.0 0.0 0.0 @@ -836,7 +838,7 @@ in the same way as earlier 0.0 0.965515 NaN - 13.052760 + 13.196613 0.0 0.0 0.0 @@ -860,7 +862,7 @@ in the same way as earlier 0.0 1.177009 NaN - 8.264430 + 8.193233 0.0 0.0 0.0 @@ -884,7 +886,7 @@ in the same way as earlier 0.0 0.973417 0.155 - 8.796671 + 8.808388 0.0 0.0 0.0 @@ -908,7 +910,7 @@ in the same way as earlier 0.0 0.949695 0.310 - 11.126467 + 11.125336 0.0 0.0 0.0 @@ -932,7 +934,7 @@ in the same way as earlier 0.0 1.021080 0.270 - 8.230328 + 8.281832 0.0 0.0 0.0 @@ -960,16 +962,7 @@ web-based visualization. For this to work you need to install w1 = sw.plot_quality_metrics(analyzer_TDC, display=False, backend="sortingview") - -.. parsed-literal:: - - /home/nolanlab/Chris/Developing/spikeinterface/src/spikeinterface/widgets/metrics.py:65: UserWarning: Skipping ['amplitude_cutoff', 'amplitude_cv_median', 'amplitude_cv_range', 'drift_ptp', 'drift_std', 'drift_mad', 'presence_ratio'] because they contain all NaNs - warnings.warn(f"Skipping {nan_metrics} because they contain all NaNs") - - -.. parsed-literal:: - - https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://167688f4ddfc0b27f5d67d5c9d84f89685e705fa +https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://c0312bc14387471531af9913147098b94cc640cf .. code:: ipython3 @@ -977,9 +970,7 @@ web-based visualization. For this to work you need to install w2 = sw.plot_sorting_summary(analyzer_TDC, display=False, curation=True, backend="sortingview") -.. parsed-literal:: - - https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://688cd7a233857847b5663e565dbf3f2807887013 +https://figurl.org/f?v=npm://@fi-sci/figurl-sortingview@12/dist&d=sha1://688cd7a233857847b5663e565dbf3f2807887013 The sorting summary plot can also be used for manual labeling and @@ -990,7 +981,7 @@ on the “Save as snapshot (sha://)” and copy the URI: .. code:: ipython3 uri = "sha1://68cb54a9aaed2303fb82dedbc302c853e818f1b6" - + sorting_curated_sv = scur.apply_sortingview_curation(sorting_TDC, uri_or_json=uri) print(sorting_curated_sv) print(sorting_curated_sv.get_property("accept")) @@ -1062,7 +1053,7 @@ above a certain threshold: qm_data = analyzer_TDC.get_extension("quality_metrics").get_data() keep_mask = (qm_data["snr"] > 10) & (qm_data["isi_violations_ratio"] < 0.01) print("Mask:", keep_mask.values) - + sorting_curated_auto = sorting_TDC.select_units(sorting_TDC.unit_ids[keep_mask]) print(sorting_curated_auto) @@ -1106,7 +1097,7 @@ performance and plot a confusion matrix .. parsed-literal:: accuracy recall precision false_discovery_rate miss_rate - gt_unit_id + gt_unit_id #0 1.0 1.0 1.0 0.0 0.0 #1 1.0 1.0 1.0 0.0 0.0 #2 0.976744 0.976744 1.0 0.0 0.023256 @@ -1185,9 +1176,9 @@ graph showing how the units are matched between the sorters. .. code:: ipython3 sorting_agreement = comp_multi.get_agreement_sorting(minimum_agreement_count=2) - + print("Units in agreement between TDC, SC2, and KS2:", sorting_agreement.get_unit_ids()) - + w_multi = sw.plot_multicomparison_agreement(comp_multi) w_multi = sw.plot_multicomparison_agreement_by_sorter(comp_multi) diff --git a/examples/how_to/get_started.py b/examples/how_to/get_started.py index cf747bdc94..e6599e5dfa 100644 --- a/examples/how_to/get_started.py +++ b/examples/how_to/get_started.py @@ -59,10 +59,9 @@ import spikeinterface.curation as scur import spikeinterface.widgets as sw -# Alternatively, we can import all submodules at once with `import spikeinterface.full as si` with `import spikeinterface.full as si` which +# Alternatively, we can import all submodules at once with `import spikeinterface.full as si` which # internally imports core+extractors+preprocessing+sorters+postprocessing+ # qualitymetrics+comparison+widgets+exporters. In this case all aliases in the following tutorial -# would be `si`. In this case all aliases in the following tutorial # would be `si`. # This is useful for notebooks, but it is a heavier import because internally many more dependencies @@ -214,11 +213,11 @@ # For postprocessing SpikeInterface pairs recording and sorting objects into a `SortingAnalyzer` object. # The `SortingAnalyzer` can be loaded in memory or saved in a folder. Here, we save it in binary format. -analyzer_TDC = si.create_sorting_analyzer(sorting=sorting=sorting_TDC, recording=recording=recording_preprocessed, format='binary_folder', folder='analyzer_TDC_binary') +analyzer_TDC = si.create_sorting_analyzer(sorting=sorting_TDC, recording=recording_preprocessed, format='binary_folder', folder='analyzer_TDC_binary') # This folder is where all the postprocessing data will be saved such as waveforms and templates. Let's calculate # some waveforms. When doing this, the function samples some spikes (by default `max_spikes_per_unit=500`) -# for each unit, extracts their waveforms, and stores them to disk in `extensions/waveforms`. +# for each unit, extracts their waveforms, and stores them to disk in `./analyzer_TDC_binary/extensions/waveforms`. # These waveforms are helpful to compute the average waveform, or "template", for each unit and then to compute, for example, quality metrics. # Computations with the `SortingAnalyzer` object are done using the `compute` method: @@ -280,11 +279,12 @@ # This deletes the extension's data in the `SortingAnalyzer` folder. # -# Importantly, `SortingAnalyzers` (and all extensions) can be reloaded at later times: +# Importantly, `SortingAnalyzers` (and all extensions) can be reloaded at later times from their folders: # (Here, spike_amplitudes is not loaded since we just deleted it) # + -analyzer_loaded = si.load_sorting_analyzer('analyzer_TDC_binary') +sorting_analyzer_path = './analyzer_TDC_binary' +analyzer_loaded = si.load_sorting_analyzer(sorting_analyzer_path) print(analyzer_loaded.get_loaded_extension_names()) # - From 343f8dbad58e1a93e27c5da6c1c157c3b9cab396 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:48:42 +0000 Subject: [PATCH 28/28] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- doc/how_to/get_started.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/how_to/get_started.rst b/doc/how_to/get_started.rst index 9f5033ba1e..625ebb52e4 100644 --- a/doc/how_to/get_started.rst +++ b/doc/how_to/get_started.rst @@ -88,7 +88,7 @@ both a “recording” and a “sorting” object. .. parsed-literal:: - MEArecRecordingExtractor: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + MEArecRecordingExtractor: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB file_path: /home/nolanlab/spikeinterface_datasets/ephy_testing_data/mearec/mearec_test_10s.h5 MEArecSortingExtractor: 10 units - 1 segments - 32.0kHz @@ -128,7 +128,7 @@ This is how you retrieve info from a ``BaseRecording``\ … fs = recording.get_sampling_frequency() num_chan = recording.get_num_channels() num_seg = recording.get_num_segments() - + print("Channel ids:", channel_ids) print("Sampling frequency:", fs) print("Number of channels:", num_chan) @@ -152,7 +152,7 @@ This is how you retrieve info from a ``BaseRecording``\ … num_seg = recording.get_num_segments() unit_ids = sorting_true.get_unit_ids() spike_train = sorting_true.get_unit_spike_train(unit_id=unit_ids[0]) - + print("Number of segments:", num_seg) print("Unit ids:", unit_ids) print("Spike train of first unit:", spike_train) @@ -182,9 +182,9 @@ to set it *manually*. probe = recording.get_probe() print(probe) - + from probeinterface.plotting import plot_probe - + _ = plot_probe(probe) @@ -218,7 +218,7 @@ object to disk. print(recording_f) recording_cmr = si.common_reference(recording_f, reference="global", operator="median") print(recording_cmr) - + # this computes and saves the recording after applying the preprocessing chain recording_preprocessed = recording_cmr.save(format="binary") print(recording_preprocessed) @@ -226,9 +226,9 @@ object to disk. .. parsed-literal:: - BandpassFilterRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + BandpassFilterRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB - CommonReferenceRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + CommonReferenceRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB Use cache_folder=/tmp/spikeinterface_cache/tmpsgoh2z3y/DLGW1J8V write_binary_recording with n_jobs = 4 and chunk_size = 32000 @@ -242,7 +242,7 @@ object to disk. .. parsed-literal:: - BinaryFolderRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s + BinaryFolderRecording: 32 channels - 32.0kHz - 1 segments - 320,000 samples - 10.00s float32 dtype - 39.06 MiB @@ -329,7 +329,7 @@ Alternatively we can pass a full dictionary containing the parameters: other_params = ss.get_default_sorter_params("tridesclous") other_params["detect_threshold"] = 6 - + # parameters set by params dictionary sorting_TDC_2 = ss.run_sorter( sorter_name="tridesclous", recording=recording_preprocessed, output_folder="tdc_output2", **other_params @@ -662,11 +662,11 @@ in the same way as earlier .dataframe tbody tr th:only-of-type { vertical-align: middle; } - + .dataframe tbody tr th { vertical-align: top; } - + .dataframe thead th { text-align: right; } @@ -981,7 +981,7 @@ on the “Save as snapshot (sha://)” and copy the URI: .. code:: ipython3 uri = "sha1://68cb54a9aaed2303fb82dedbc302c853e818f1b6" - + sorting_curated_sv = scur.apply_sortingview_curation(sorting_TDC, uri_or_json=uri) print(sorting_curated_sv) print(sorting_curated_sv.get_property("accept")) @@ -1053,7 +1053,7 @@ above a certain threshold: qm_data = analyzer_TDC.get_extension("quality_metrics").get_data() keep_mask = (qm_data["snr"] > 10) & (qm_data["isi_violations_ratio"] < 0.01) print("Mask:", keep_mask.values) - + sorting_curated_auto = sorting_TDC.select_units(sorting_TDC.unit_ids[keep_mask]) print(sorting_curated_auto) @@ -1097,7 +1097,7 @@ performance and plot a confusion matrix .. parsed-literal:: accuracy recall precision false_discovery_rate miss_rate - gt_unit_id + gt_unit_id #0 1.0 1.0 1.0 0.0 0.0 #1 1.0 1.0 1.0 0.0 0.0 #2 0.976744 0.976744 1.0 0.0 0.023256 @@ -1176,9 +1176,9 @@ graph showing how the units are matched between the sorters. .. code:: ipython3 sorting_agreement = comp_multi.get_agreement_sorting(minimum_agreement_count=2) - + print("Units in agreement between TDC, SC2, and KS2:", sorting_agreement.get_unit_ids()) - + w_multi = sw.plot_multicomparison_agreement(comp_multi) w_multi = sw.plot_multicomparison_agreement_by_sorter(comp_multi)