diff --git a/.github/scripts/serialization/objects.py b/.github/scripts/serialization/objects.py
index f2f3469076..9544e4a8d9 100644
--- a/.github/scripts/serialization/objects.py
+++ b/.github/scripts/serialization/objects.py
@@ -140,7 +140,6 @@ def _check_recording_with_probe(rec, check_extra_data=None):
def _build_recording_with_interleaved_probes():
- import numpy as np
from probeinterface import ProbeGroup, generate_linear_probe
from spikeinterface.core import generate_recording
diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml
new file mode 100644
index 0000000000..0860cd8fc9
--- /dev/null
+++ b/.github/workflows/ruff.yml
@@ -0,0 +1,23 @@
+name: Ruff Linting
+
+on:
+ pull_request:
+ types: [synchronize, opened, reopened]
+ branches:
+ - main
+
+concurrency: # Cancel previous workflows on the same pull request
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ run:
+ name: Ruff Linting
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ steps:
+ - uses: actions/checkout@v4
+ - uses: astral-sh/ruff-action@v3
+ with:
+ args: check
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 6d35bc8cd3..157acbefda 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -5,8 +5,18 @@ repos:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
-- repo: https://github.com/psf/black-pre-commit-mirror
- rev: 26.10.1
+- repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.15.0
hooks:
- - id: black
+ - id: ruff-check
+ args: [--fix]
+ files: ^src/
+ # occasional full lint including tests: pre-commit run ruff-check-tests --hook-stage manual --all-files
+ - id: ruff-check
+ alias: ruff-check-tests
+ name: ruff check (including tests)
+ args: [--fix, --config, "lint.exclude = []"]
+ files: ^src/
+ stages: [manual]
+ - id: ruff-format
files: ^src/
diff --git a/conftest.py b/conftest.py
index 6c4bfbef3a..24a74fe1ec 100644
--- a/conftest.py
+++ b/conftest.py
@@ -56,7 +56,7 @@ def pytest_collection_modifyitems(config, items):
try:
rel_path = Path(item.fspath).relative_to(modules_location)
- except:
+ except Exception:
continue
module = rel_path.parts[0]
diff --git a/doc/development/development.rst b/doc/development/development.rst
index 82b17e7a35..dba523b3c4 100644
--- a/doc/development/development.rst
+++ b/doc/development/development.rst
@@ -111,49 +111,65 @@ maintainability of the code, making it easier for contributors to collaborate. T
for the developer we use the following tools and conventions:
-Install Black and pre-commit
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Install ruff and pre-commit
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
-We use the Python formatter Black, with defaults set in the :code:`pyproject.toml`. This allows for
-easy local formatting of code.
+We use `ruff `_ both to format code and to lint it (catch errors such as
+undefined names or unused variables). Its settings live in the :code:`[tool.ruff]` section of :code:`pyproject.toml`.
+We use pre-commit to run ruff, and a few other checks, automatically before every commit.
-To install Black, you can use pip, the Python package installer. Run the following command in your terminal:
+You can install both with pip:
.. code-block:: bash
- pip install black
+ pip install ruff pre-commit
-This will install Black into your current Python environment.
+Then set up the pre-commit hooks for your local repository by running, from the repository root:
-In addition to Black, we use pre-commit to manage a suite of code formatting.
-Pre-commit helps to automate the process of running these tools (including Black) before every commit,
-ensuring that all code is checked for style.
+.. code-block:: bash
+
+ pre-commit install
-You can install pre-commit using pip as well:
+Now, each time you make a commit, pre-commit will run :code:`ruff format` and :code:`ruff check --fix` on the changed files
+under :code:`src/`. If the hooks make changes or find issues, the commit is stopped so you can review the changes, add them and commit again.
+
+You can also run ruff yourself at any time:
.. code-block:: bash
- pip install pre-commit
+ ruff format src # format the code
+ ruff check src # report lint errors
+ ruff check src --fix # report lint errors and apply the safe automatic fixes
+
+A few things to know about the lint configuration:
+* Test files (:code:`tests/` folders, :code:`test_*.py` and :code:`conftest.py`) are excluded from linting.
+* Unused imports (:code:`F401`) and unused variables (:code:`F841`) are reported but never removed automatically,
+ because they are sometimes needed: side-effect imports, re-exports, or function calls that read from a file.
+ Fix them by hand, or keep them and mark the line with :code:`# noqa: F401`.
+* Pytest fixtures shared by several test modules belong in a :code:`conftest.py`, so pytest finds them without an import
+ (an import that ruff would see as unused).
-Once pre-commit is installed, you can set up the pre-commit hooks for your local repository.
-These hooks are scripts that pre-commit will run prior to each commit. To install the pre-commit hooks,
-navigate to your local repository in your terminal and run the following command:
+Since tests are not linted on every commit, it is worth checking them every now and then. A manual pre-commit hook lints
+everything under :code:`src/`, tests included:
.. code-block:: bash
- pre-commit install
+ pre-commit run ruff-check-tests --hook-stage manual --all-files
+
+or, equivalently, with ruff directly:
+
+.. code-block:: bash
-Now, each time you make a commit, pre-commit will automatically run Black and any other configured hooks.
-If the hooks make changes or if there are any issues, the commit will be stopped, and you'll be able to review and add the changes.
+ ruff check src --config 'lint.exclude = []'
-If you want Black to omit a line from formatting, you can add the following comment to the end of the line:
+If you want ruff to leave a line unformatted, add the following comment to the end of the line:
.. code-block:: python
# fmt: skip
-To ignore a block of code you must flank the code with two comments:
+To leave a block of code unformatted, put these two comments around it:
.. code-block:: python
@@ -161,7 +177,7 @@ To ignore a block of code you must flank the code with two comments:
code here
# fmt: on
-As described in the `black documentation `_.
+To silence a single lint error on one line, add :code:`# noqa: ` (for example :code:`# noqa: F401`) to the end of that line.
Docstring Conventions
@@ -202,7 +218,7 @@ This allows users to quickly understand the type of data that should be input in
There should be a space between each parameter and the colon following it. This is neccessary for using the `numpydoc validator `_.
In the above example we demonstrate two other docstring conventions followed by SpikeInterface. First, that all string arguments should be presented
-with double quotes. This is the same stylistic convention followed by Black and enforced by the pre-commit for the repo. Second, when a parameter is a
+with double quotes. This is the same stylistic convention enforced by ruff format in the pre-commit for the repo. Second, when a parameter is a
string with a limited number of values (e.g. :code:`mean` and :code:`median`), rather than give the type a value of :code:`str`, please list the possible strings
so that the user knows what the options are.
diff --git a/doc/images/make_comparison_figures.py b/doc/images/make_comparison_figures.py
index cdf0c03f9f..be88e474b4 100644
--- a/doc/images/make_comparison_figures.py
+++ b/doc/images/make_comparison_figures.py
@@ -11,7 +11,6 @@
sys.path.append('../../examples/modules/comparison/')
from generate_erroneous_sorting import generate_erroneous_sorting
-import spikeinterface.extractors as se
import spikeinterface.comparison as sc
import spikeinterface.widgets as sw
diff --git a/examples/forhowto/plot_extract_lfps.py b/examples/forhowto/plot_extract_lfps.py
index 53c4c256c2..404af6edb6 100644
--- a/examples/forhowto/plot_extract_lfps.py
+++ b/examples/forhowto/plot_extract_lfps.py
@@ -44,12 +44,10 @@
import time
import numpy as np
import matplotlib.pyplot as plt
-from pathlib import Path
import pandas as pd
import seaborn as sns
import spikeinterface as si
-import spikeinterface.extractors as se
import spikeinterface.preprocessing as spre
import spikeinterface.widgets as sw
from spikeinterface.core import generate_ground_truth_recording
diff --git a/examples/get_started/quickstart.py b/examples/get_started/quickstart.py
index 75d5c8d63a..d53bb1d9ea 100644
--- a/examples/get_started/quickstart.py
+++ b/examples/get_started/quickstart.py
@@ -34,7 +34,6 @@
# The spikeinterface module by itself imports only the spikeinterface.core submodule
# which is not useful for the end user
-import spikeinterface
# We need to import one by one different submodules separately (preferred).
# There are several modules:
@@ -50,9 +49,7 @@
import spikeinterface as si # import core only
import spikeinterface.extractors as se
-import spikeinterface.preprocessing as spre
import spikeinterface.sorters as ss
-import spikeinterface.postprocessing as spost
import spikeinterface.metrics as sm
import spikeinterface.comparison as sc
import spikeinterface.exporters as sexp
diff --git a/examples/how_to/auto_label_units.py b/examples/how_to/auto_label_units.py
index b70d5e66b2..ac4fbf13dc 100644
--- a/examples/how_to/auto_label_units.py
+++ b/examples/how_to/auto_label_units.py
@@ -24,7 +24,6 @@
# 3. UnitRefine: pre-trained classifiers to label units as noise or SUA/MUA [Jain]_
# %%
-import numpy as np
import spikeinterface as si
import spikeinterface.curation as sc
diff --git a/examples/how_to/benchmark_with_hybrid_recordings.py b/examples/how_to/benchmark_with_hybrid_recordings.py
index d983578797..ebac618421 100644
--- a/examples/how_to/benchmark_with_hybrid_recordings.py
+++ b/examples/how_to/benchmark_with_hybrid_recordings.py
@@ -32,7 +32,6 @@
import spikeinterface.generation as sgen
import spikeinterface.widgets as sw
-from spikeinterface.sortingcomponents.motion import estimate_motion
import numpy as np
import matplotlib.pyplot as plt
diff --git a/examples/how_to/customize_a_plot.py b/examples/how_to/customize_a_plot.py
index 5568534b52..23bff39d72 100644
--- a/examples/how_to/customize_a_plot.py
+++ b/examples/how_to/customize_a_plot.py
@@ -81,7 +81,6 @@
# Here's an example of making a unit summary plot.
# +
-import matplotlib.pyplot as plt
fig, axs = plt.subplots(ncols=2, nrows=1)
unit_id=8
diff --git a/examples/tutorials/comparison/plot_5_comparison_sorter_weaknesses.py b/examples/tutorials/comparison/plot_5_comparison_sorter_weaknesses.py
index c588ee82cb..68480c6dc7 100644
--- a/examples/tutorials/comparison/plot_5_comparison_sorter_weaknesses.py
+++ b/examples/tutorials/comparison/plot_5_comparison_sorter_weaknesses.py
@@ -34,8 +34,6 @@
##############################################################################
# Import
-import numpy as np
-import pandas as pd
import matplotlib.pyplot as plt
from spikeinterface.comparison import compare_sorter_to_ground_truth
diff --git a/examples/tutorials/core/plot_1_recording_extractor.py b/examples/tutorials/core/plot_1_recording_extractor.py
index a3143161b2..a73ffa2716 100644
--- a/examples/tutorials/core/plot_1_recording_extractor.py
+++ b/examples/tutorials/core/plot_1_recording_extractor.py
@@ -14,7 +14,6 @@
"""
-import matplotlib.pyplot as plt
import numpy as np
import spikeinterface.extractors as se
diff --git a/examples/tutorials/core/plot_5_append_concatenate_segments.py b/examples/tutorials/core/plot_5_append_concatenate_segments.py
index 5cb1cccb6f..29fb9147ca 100644
--- a/examples/tutorials/core/plot_5_append_concatenate_segments.py
+++ b/examples/tutorials/core/plot_5_append_concatenate_segments.py
@@ -22,11 +22,10 @@
Here is a short example.
"""
-import matplotlib.pyplot as plt
import numpy as np
-from spikeinterface import NumpyRecording, NumpySorting
+from spikeinterface import NumpyRecording
from spikeinterface import append_recordings, concatenate_recordings
##############################################################################
diff --git a/examples/tutorials/curation/plot_1_automated_curation.py b/examples/tutorials/curation/plot_1_automated_curation.py
index 97fc05bc6e..8826852cdc 100644
--- a/examples/tutorials/curation/plot_1_automated_curation.py
+++ b/examples/tutorials/curation/plot_1_automated_curation.py
@@ -193,7 +193,7 @@ def calculate_moving_avg(label_df, confidence_label, window_size):
plt.figure(figsize=(6, 6))
plt.plot(p_agreement_sorted, p_agreement_moving_avg, label = 'Moving Average')
plt.axhline(y=1/len(np.unique(predictions)), color='black', linestyle='--', label='Chance')
-plt.xlabel('Confidence'); #plt.xlim(0.5, 1)
+plt.xlabel('Confidence') #plt.xlim(0.5, 1)
plt.ylabel('Proportion Agreement with Human Label'); plt.ylim(0, 1)
plt.title('Agreement vs Confidence (Moving Average)')
plt.legend(); plt.grid(True); plt.show()
diff --git a/examples/tutorials/widgets/plot_3_waveforms_gallery.py b/examples/tutorials/widgets/plot_3_waveforms_gallery.py
index 76041aab1a..94276a72e0 100644
--- a/examples/tutorials/widgets/plot_3_waveforms_gallery.py
+++ b/examples/tutorials/widgets/plot_3_waveforms_gallery.py
@@ -8,7 +8,6 @@
import matplotlib.pyplot as plt
import spikeinterface as si
-import spikeinterface.extractors as se
import spikeinterface.widgets as sw
##############################################################################
diff --git a/installation_tips/check_your_install.py b/installation_tips/check_your_install.py
index caafe09e24..cf9ffe65fd 100644
--- a/installation_tips/check_your_install.py
+++ b/installation_tips/check_your_install.py
@@ -69,7 +69,7 @@ def open_sigui():
folder = f"./analyzer_with_{sorter_name}"
analyzer = si.load_sorting_analyzer(folder)
- win = run_mainwindow(analyzer, start_app=True)
+ _ = run_mainwindow(analyzer, start_app=True)
def _clean():
diff --git a/pyproject.toml b/pyproject.toml
index 4265be1622..e81fba5912 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -51,8 +51,20 @@ include = ["spikeinterface*"]
namespaces = false
exclude = ["spikeinterface.*.tests"]
-[tool.black]
+[tool.ruff]
line-length = 120
+force-exclude = true
+[tool.ruff.lint]
+select = ['E4', 'E7', 'E9', 'F']
+exclude = ["**/tests/**", "**/test_*.py", "**/conftest.py", "examples/**", "doc/conf.py", "installation_tips/**"]
+ignore = ['E741', 'E731', 'F821']
+# report but never auto-remove unused imports/variables: they may be side-effect imports, re-exports, or calls that advance state
+unfixable = ['F401', 'F841']
+[tool.ruff.lint.per-file-ignores]
+"**/__init__.py" = ['F401', 'F403']
+"src/spikeinterface/full.py" = ['F403']
+"src/spikeinterface/core/testing_tools.py" = ['E402', 'F403']
+"src/spikeinterface/extractors/extractor_classes.py" = ['F401', 'F403']
[project.urls]
homepage = "https://github.com/SpikeInterface/spikeinterface"
@@ -232,7 +244,7 @@ docs = [
dev = [
"spikeinterface[docs]",
- "black",
+ "ruff",
"pre-commit",
]
@@ -342,7 +354,7 @@ test-all = [
# Tools for the pre-commit hooks. uv installs this group by default.
dev = [
- "black",
+ "ruff",
"pre-commit",
]
diff --git a/src/spikeinterface/benchmark/benchmark_base.py b/src/spikeinterface/benchmark/benchmark_base.py
index 47ec6a70cd..e301019699 100644
--- a/src/spikeinterface/benchmark/benchmark_base.py
+++ b/src/spikeinterface/benchmark/benchmark_base.py
@@ -8,8 +8,6 @@
from spikeinterface.core import SortingAnalyzer, ChannelSparsity, NumpySorting
-from spikeinterface.core import SortingAnalyzer, NumpySorting
-from spikeinterface.core.job_tools import fix_job_kwargs, split_job_kwargs
from spikeinterface import load, create_sorting_analyzer, load_sorting_analyzer
from spikeinterface.widgets import get_some_colors
@@ -332,7 +330,6 @@ def run(self, case_keys=None, keep=True, verbose=False, **job_kwargs):
job_keys = []
for key in case_keys:
-
result_folder = self.folder / "results" / self.key_to_str(key)
sorter_folder = self.folder / "sorters" / self.key_to_str(key)
@@ -443,9 +440,9 @@ def get_grouped_keys_mapping(self, levels_to_group_by=None, case_keys=None):
keys_mapping = {key: [key] for key in case_keys}
else:
study_levels = self.levels
- assert np.all(
- [l in study_levels for l in levels_to_group_by]
- ), f"levels_to_group_by must be in {study_levels}, got {levels_to_group_by}"
+ assert np.all([l in study_levels for l in levels_to_group_by]), (
+ f"levels_to_group_by must be in {study_levels}, got {levels_to_group_by}"
+ )
keys_mapping = {}
for key in case_keys:
new_key = tuple(key[list(study_levels).index(level)] for level in levels_to_group_by)
@@ -480,7 +477,6 @@ def compute_results(self, case_keys=None, verbose=False, **result_params):
if case_keys is None:
case_keys = list(self.cases.keys())
- job_keys = []
for key in case_keys:
if verbose:
print("### Compute result", key, "###")
@@ -546,7 +542,7 @@ def compute_metrics(self, case_keys=None, metric_names=["snr", "firing_rate"], f
qm_ext = sorting_analyzer.compute("quality_metrics", metric_names=metric_names, **job_kwargs)
# TODO remove this metics CSV file!!!!
- metrics = qm_ext.get_data()
+ # _ = qm_ext.get_data()
# metrics.to_csv(filename, sep="\t", index=True)
def get_metrics(self, key):
@@ -609,7 +605,6 @@ def get_pairs_by_level(self, level):
pairs = []
for key in self.cases.keys():
-
case0 = list(key)
case1 = list(key)
case0[level_index] = possible_values[0]
@@ -702,7 +697,6 @@ def load_folder(cls, folder):
zarr_folder = folder / k
if zarr_folder.exists():
-
result[k] = Templates.from_zarr(zarr_folder)
elif format == "sorting_analyzer":
analyzer_folder = folder / k
diff --git a/src/spikeinterface/benchmark/benchmark_clustering.py b/src/spikeinterface/benchmark/benchmark_clustering.py
index 8b5b6de3b8..0af908ff20 100644
--- a/src/spikeinterface/benchmark/benchmark_clustering.py
+++ b/src/spikeinterface/benchmark/benchmark_clustering.py
@@ -1,20 +1,15 @@
from spikeinterface.sortingcomponents.clustering import find_clusters_from_peaks
from spikeinterface.core import NumpySorting
from spikeinterface.comparison import GroundTruthComparison
-from spikeinterface.widgets import (
- plot_probe_map,
- plot_agreement_matrix,
-)
import numpy as np
-from spikeinterface.core.job_tools import fix_job_kwargs, split_job_kwargs
+from spikeinterface.core.job_tools import fix_job_kwargs
from .benchmark_base import Benchmark, BenchmarkStudy, MixinStudyUnitCount
from spikeinterface.core.sortinganalyzer import create_sorting_analyzer
class ClusteringBenchmark(Benchmark):
-
def __init__(self, recording, gt_sorting, params, indices, peaks, exhaustive_gt=True):
self.recording = recording
self.gt_sorting = gt_sorting
@@ -238,7 +233,6 @@ def plot_error_metrics(self, metric="cosine", case_keys=None, figsize=(15, 5)):
fig, axes = plt.subplots(ncols=len(case_keys), nrows=1, figsize=figsize, squeeze=False)
for count, key in enumerate(case_keys):
-
result = self.get_result(key)
scores = result["gt_comparison"].get_ordered_agreement_scores()
@@ -279,7 +273,6 @@ def plot_metrics_vs_snr(self, metric="agreement", case_keys=None, figsize=(15, 5
fig = None
for count, key in enumerate(case_keys):
-
result = self.get_result(key)
scores = result["gt_comparison"].agreement_scores
@@ -334,7 +327,6 @@ def plot_metrics_vs_depth_and_snr(self, metric="agreement", case_keys=None, figs
fig, axes = plt.subplots(ncols=len(case_keys), nrows=1, figsize=figsize, squeeze=False)
for count, key in enumerate(case_keys):
-
result = self.get_result(key)
scores = result["gt_comparison"].agreement_scores
diff --git a/src/spikeinterface/benchmark/benchmark_matching.py b/src/spikeinterface/benchmark/benchmark_matching.py
index 8f28f18a73..c6d4ec4fa5 100644
--- a/src/spikeinterface/benchmark/benchmark_matching.py
+++ b/src/spikeinterface/benchmark/benchmark_matching.py
@@ -4,7 +4,6 @@
from spikeinterface.core import NumpySorting
from spikeinterface.comparison import CollisionGTComparison, compare_sorter_to_ground_truth
from spikeinterface.widgets import (
- plot_agreement_matrix,
plot_comparison_collision_by_similarity,
)
@@ -14,7 +13,6 @@
class MatchingBenchmark(Benchmark):
-
def __init__(self, recording, gt_sorting, params):
self.recording = recording
self.gt_sorting = gt_sorting
diff --git a/src/spikeinterface/benchmark/benchmark_merging.py b/src/spikeinterface/benchmark/benchmark_merging.py
index 5f16ce3cab..0b25d851fa 100644
--- a/src/spikeinterface/benchmark/benchmark_merging.py
+++ b/src/spikeinterface/benchmark/benchmark_merging.py
@@ -7,12 +7,10 @@
plot_crosscorrelograms,
)
-import numpy as np
from .benchmark_base import Benchmark, BenchmarkStudy
class MergingBenchmark(Benchmark):
-
def __init__(self, recording, splitted_sorting, params, gt_sorting, splitted_cells=None):
self.recording = recording
self.splitted_sorting = splitted_sorting
@@ -45,7 +43,6 @@ def compute_result(self, match_score=0.5, exhaustive_gt=True):
class MergingStudy(BenchmarkStudy):
-
benchmark_class = MergingBenchmark
def create_benchmark(self, key):
diff --git a/src/spikeinterface/benchmark/benchmark_motion_estimation.py b/src/spikeinterface/benchmark/benchmark_motion_estimation.py
index fabca60b2d..d42be84a88 100644
--- a/src/spikeinterface/benchmark/benchmark_motion_estimation.py
+++ b/src/spikeinterface/benchmark/benchmark_motion_estimation.py
@@ -1,6 +1,3 @@
-import json
-from pathlib import Path
-import pickle
import time
import numpy as np
@@ -183,7 +180,6 @@ def plot_drift(
case_keys = list(self.cases.keys())
for key in case_keys:
-
bench = self.benchmarks[key]
fig = plt.figure(figsize=figsize)
@@ -258,7 +254,6 @@ def plot_errors(self, case_keys=None, figsize=None, lim=None):
case_keys = list(self.cases.keys())
for key in case_keys:
-
bench = self.benchmarks[key]
label = self.cases[key]["label"]
@@ -329,7 +324,6 @@ def plot_summary_errors(self, case_keys=None, show_legend=True, figsize=(15, 5))
colors = self.get_colors()
for count, key in enumerate(case_keys):
-
bench = self.benchmarks[key]
label = self.cases[key]["label"]
@@ -357,7 +351,7 @@ def plot_summary_errors(self, case_keys=None, show_legend=True, figsize=(15, 5))
parts[k].set_color(c)
axes[2].plot(motion.spatial_bins_um, depth_error, label=label, color=c)
- ax0 = ax = axes[0]
+ ax = axes[0]
ax.set_xlabel("Time [s]")
ax.set_ylabel("Error [μm]")
if show_legend:
diff --git a/src/spikeinterface/benchmark/benchmark_motion_interpolation.py b/src/spikeinterface/benchmark/benchmark_motion_interpolation.py
index c5e0143961..3e96013e7b 100644
--- a/src/spikeinterface/benchmark/benchmark_motion_interpolation.py
+++ b/src/spikeinterface/benchmark/benchmark_motion_interpolation.py
@@ -95,7 +95,6 @@ def compute_result(self, exhaustive_gt=True, merging_score=0.2):
class MotionInterpolationStudy(BenchmarkStudy):
-
benchmark_class = MotionInterpolationBenchmark
def create_benchmark(self, key):
@@ -133,7 +132,6 @@ def plot_sorting_accuracy(
if mode == "ordered_accuracy":
if ax is None:
-
fig, ax = plt.subplots(figsize=figsize)
else:
fig = ax.figure
diff --git a/src/spikeinterface/benchmark/benchmark_peak_detection.py b/src/spikeinterface/benchmark/benchmark_peak_detection.py
index 4c84304a63..671080b0a7 100644
--- a/src/spikeinterface/benchmark/benchmark_peak_detection.py
+++ b/src/spikeinterface/benchmark/benchmark_peak_detection.py
@@ -17,7 +17,6 @@
class PeakDetectionBenchmark(Benchmark):
-
def __init__(self, recording, gt_sorting, params, gt_peaks, exhaustive_gt=True, delta_t_ms=0.2):
self.recording = recording
self.gt_sorting = gt_sorting
@@ -233,9 +232,7 @@ def plot_mean_deltas(self, case_keys=None, figsize=(15, 5), ax=None):
import matplotlib.pyplot as plt
if ax is None:
- fig, ax = plt.subplots(1, figsize=figsize)
- else:
- fig = ax.get_figure()
+ _, ax = plt.subplots(1, figsize=figsize)
results = {}
labels = []
@@ -283,7 +280,6 @@ def plot_template_similarities(self, case_keys=None, metric="l2", figsize=(15, 5
fig = ax.get_figure()
for key in case_keys:
-
import sklearn.metrics
gt_templates = self.get_result(key)["gt_templates"]
@@ -292,7 +288,6 @@ def plot_template_similarities(self, case_keys=None, metric="l2", figsize=(15, 5
distances = np.zeros(num_templates)
for i in range(num_templates):
-
a = gt_templates[i].flatten()
b = found_templates[i].flatten()
diff --git a/src/spikeinterface/benchmark/benchmark_peak_localization.py b/src/spikeinterface/benchmark/benchmark_peak_localization.py
index f38e1de916..199df36930 100644
--- a/src/spikeinterface/benchmark/benchmark_peak_localization.py
+++ b/src/spikeinterface/benchmark/benchmark_peak_localization.py
@@ -9,7 +9,6 @@
class PeakLocalizationBenchmark(Benchmark):
-
def __init__(self, recording, gt_sorting, params, gt_positions, channel_from_template=False):
self.recording = recording
self.gt_sorting = gt_sorting
@@ -69,7 +68,6 @@ def compute_result(self, **result_params):
class PeakLocalizationStudy(BenchmarkStudy):
-
benchmark_class = PeakLocalizationBenchmark
def create_benchmark(self, key):
@@ -93,14 +91,12 @@ def plot_comparison_positions(self, case_keys=None):
metrics = analyzer.get_extension("quality_metrics").get_data()
snrs = metrics["snr"].values
result = self.get_result(key)
- norms = np.linalg.norm(result["templates"].templates_array, axis=(1, 2))
coordinates = self.benchmarks[key].gt_positions[:, :2].copy()
coordinates[:, 0] -= coordinates[:, 0].mean()
coordinates[:, 1] -= coordinates[:, 1].mean()
distances_to_center = np.linalg.norm(coordinates, axis=1)
zdx = np.argsort(distances_to_center)
- idx = np.argsort(norms)
wdx = np.argsort(snrs)
@@ -152,7 +148,6 @@ def plot_comparison_positions(self, case_keys=None):
class UnitLocalizationBenchmark(Benchmark):
-
def __init__(self, recording, gt_sorting, params, gt_positions):
self.recording = recording
self.gt_sorting = gt_sorting
@@ -255,16 +250,12 @@ def plot_comparison_positions(self, case_keys=None):
metrics = analyzer.get_extension("quality_metrics").get_data()
snrs = metrics["snr"].values
result = self.get_result(key)
- norms = np.linalg.norm(result["templates"].templates_array, axis=(1, 2))
coordinates = self.benchmarks[key].gt_positions[:, :2].copy()
coordinates[:, 0] -= coordinates[:, 0].mean()
coordinates[:, 1] -= coordinates[:, 1].mean()
distances_to_center = np.linalg.norm(coordinates, axis=1)
zdx = np.argsort(distances_to_center)
- idx = np.argsort(norms)
-
- from scipy.signal import savgol_filter
wdx = np.argsort(snrs)
diff --git a/src/spikeinterface/benchmark/benchmark_peak_selection.py b/src/spikeinterface/benchmark/benchmark_peak_selection.py
index a18743f81b..a0b0c72c3d 100644
--- a/src/spikeinterface/benchmark/benchmark_peak_selection.py
+++ b/src/spikeinterface/benchmark/benchmark_peak_selection.py
@@ -1,16 +1,7 @@
-from spikeinterface.sortingcomponents.clustering import find_clusters_from_peaks
-from spikeinterface.core import NumpySorting
-from spikeinterface.comparison import GroundTruthComparison
-from spikeinterface.comparison.comparisontools import make_matching_events
-from spikeinterface.core import get_noise_levels
-
-import numpy as np
-
from .benchmark_base import Benchmark, BenchmarkStudy
class PeakSelectionBenchmark(Benchmark):
-
def __init__(self, recording, gt_sorting, params, indices, exhaustive_gt=True):
pass
@@ -34,7 +25,6 @@ def compute_result(self, **result_params):
class PeakSelectionStudy(BenchmarkStudy):
-
benchmark_class = PeakSelectionBenchmark
def create_benchmark(self, key):
diff --git a/src/spikeinterface/benchmark/benchmark_plot_tools.py b/src/spikeinterface/benchmark/benchmark_plot_tools.py
index 7f0fc64cb4..530678da5b 100644
--- a/src/spikeinterface/benchmark/benchmark_plot_tools.py
+++ b/src/spikeinterface/benchmark/benchmark_plot_tools.py
@@ -1,7 +1,4 @@
-import warnings
-
import numpy as np
-from spikeinterface.widgets import get_some_colors
from .benchmark_tools import sigmoid, fit_sigmoid
@@ -308,7 +305,7 @@ def plot_unit_counts(
else:
yerr = None
- if not "well_detected" in col and revert_bad:
+ if "well_detected" not in col and revert_bad:
y = -y
if i == 0:
@@ -455,7 +452,6 @@ def _plot_performances_vs_metric(
fig = axs[0].get_figure()
for count, performance_name in enumerate(performance_names):
-
ax = axs[count]
if levels_to_group_by is not None:
case_group_keys, labels = study.get_grouped_keys_mapping(
@@ -467,9 +463,9 @@ def _plot_performances_vs_metric(
colors = study.get_colors(levels_to_group_by=levels_to_group_by)
- assert all(
- [key in colors for key in case_group_keys]
- ), f"colors must have a color for each case key: {case_group_keys}"
+ assert all([key in colors for key in case_group_keys]), (
+ f"colors must have a color for each case key: {case_group_keys}"
+ )
for key, key_list in case_group_keys.items():
color = colors[key]
@@ -827,9 +823,9 @@ def plot_performances_swarm(
perfs = study.get_performance_by_unit(case_keys=case_keys)
perfs, case_keys, _, _ = aggregate_dataframe_by_levels(perfs, study, case_keys, levels_to_group_by)
- assert all(
- [key in performance_colors for key in performance_names]
- ), f"performance_colors must have a color for each performance name: {performance_names}"
+ assert all([key in performance_colors for key in performance_names]), (
+ f"performance_colors must have a color for each performance name: {performance_names}"
+ )
if ax is None:
fig, ax = plt.subplots(figsize=figsize)
@@ -897,9 +893,9 @@ def plot_performances_comparison(
num_methods = len(case_keys)
assert num_methods >= 2, "plot_performances_comparison need at least 2 cases!"
- assert all(
- [key in performance_colors for key in performance_names]
- ), f"performance_colors must have a color for each performance name: {performance_names}"
+ assert all([key in performance_colors for key in performance_names]), (
+ f"performance_colors must have a color for each performance name: {performance_names}"
+ )
if axs is None:
fig, axs = plt.subplots(ncols=num_methods - 1, nrows=num_methods - 1, figsize=figsize, squeeze=False)
@@ -1081,7 +1077,6 @@ def plot_performance_losses(
fig = axs[0].get_figure()
for count, perf_name in enumerate(performance_names):
-
ax = axs[count]
positions = study.get_gt_unit_locations(case0)
diff --git a/src/spikeinterface/benchmark/benchmark_sorter.py b/src/spikeinterface/benchmark/benchmark_sorter.py
index 932334f209..e22aafae28 100644
--- a/src/spikeinterface/benchmark/benchmark_sorter.py
+++ b/src/spikeinterface/benchmark/benchmark_sorter.py
@@ -2,7 +2,6 @@
This replace the previous `GroundTruthStudy`
"""
-import numpy as np
from spikeinterface.core import NumpySorting, create_sorting_analyzer
from .benchmark_base import Benchmark, BenchmarkStudy, MixinStudyUnitCount
from spikeinterface.sorters import run_sorter
diff --git a/src/spikeinterface/benchmark/benchmark_sorter_without_gt.py b/src/spikeinterface/benchmark/benchmark_sorter_without_gt.py
index 818ed3f009..c9c26b0d29 100644
--- a/src/spikeinterface/benchmark/benchmark_sorter_without_gt.py
+++ b/src/spikeinterface/benchmark/benchmark_sorter_without_gt.py
@@ -4,7 +4,7 @@
import numpy as np
from spikeinterface.core import NumpySorting, create_sorting_analyzer
-from .benchmark_base import Benchmark, BenchmarkStudy, MixinStudyUnitCount
+from .benchmark_base import Benchmark, BenchmarkStudy
from spikeinterface.sorters import run_sorter
from spikeinterface.comparison import compare_multiple_sorters
@@ -107,7 +107,6 @@ def compute_results(
groups = self._get_comparison_groups()
for data_key, group in groups.items():
-
sorting_list = [self.get_result(key)["sorting"] for key in group]
name_list = [key for key in group]
multi_comp = compare_multiple_sorters(
diff --git a/src/spikeinterface/benchmark/tests/common_benchmark_testing.py b/src/spikeinterface/benchmark/tests/common_benchmark_testing.py
index 49f9e9350a..7a77b40342 100644
--- a/src/spikeinterface/benchmark/tests/common_benchmark_testing.py
+++ b/src/spikeinterface/benchmark/tests/common_benchmark_testing.py
@@ -4,12 +4,9 @@
This only a local testing.
"""
-import pytest
-from pathlib import Path
import os
from spikeinterface.core.job_tools import fix_job_kwargs
-import numpy as np
from spikeinterface.core import (
generate_ground_truth_recording,
diff --git a/src/spikeinterface/benchmark/tests/test_benchmark_clustering.py b/src/spikeinterface/benchmark/tests/test_benchmark_clustering.py
index 971c410807..01ba792fc7 100644
--- a/src/spikeinterface/benchmark/tests/test_benchmark_clustering.py
+++ b/src/spikeinterface/benchmark/tests/test_benchmark_clustering.py
@@ -26,7 +26,6 @@ def test_benchmark_clustering(create_cache_folder):
peaks = {}
for dataset, gt_analyzer in datasets.items():
-
# recording, gt_sorting = datasets[dataset]
# sorting_analyzer = create_sorting_analyzer(gt_sorting, recording, format="memory", sparse=False)
diff --git a/src/spikeinterface/benchmark/tests/test_benchmark_merging.py b/src/spikeinterface/benchmark/tests/test_benchmark_merging.py
index 022ba18ebd..e09faa10af 100644
--- a/src/spikeinterface/benchmark/tests/test_benchmark_merging.py
+++ b/src/spikeinterface/benchmark/tests/test_benchmark_merging.py
@@ -1,6 +1,5 @@
import pytest
from pathlib import Path
-import numpy as np
import shutil
diff --git a/src/spikeinterface/benchmark/tests/test_benchmark_peak_detection.py b/src/spikeinterface/benchmark/tests/test_benchmark_peak_detection.py
index 462ede4375..95f48e9214 100644
--- a/src/spikeinterface/benchmark/tests/test_benchmark_peak_detection.py
+++ b/src/spikeinterface/benchmark/tests/test_benchmark_peak_detection.py
@@ -23,7 +23,6 @@ def test_benchmark_peak_detection(create_cache_folder):
peaks = {}
for dataset in datasets.keys():
-
recording, gt_sorting = datasets[dataset]
sorting_analyzer = create_sorting_analyzer(gt_sorting, recording, format="memory", sparse=False, **job_kwargs)
diff --git a/src/spikeinterface/benchmark/tests/test_benchmark_peak_selection.py b/src/spikeinterface/benchmark/tests/test_benchmark_peak_selection.py
index a6eb090a9d..d56529269b 100644
--- a/src/spikeinterface/benchmark/tests/test_benchmark_peak_selection.py
+++ b/src/spikeinterface/benchmark/tests/test_benchmark_peak_selection.py
@@ -5,7 +5,7 @@
@pytest.mark.skip()
def test_benchmark_peak_selection(create_cache_folder):
- cache_folder = create_cache_folder
+ pass
if __name__ == "__main__":
diff --git a/src/spikeinterface/benchmark/tests/test_benchmark_sorter.py b/src/spikeinterface/benchmark/tests/test_benchmark_sorter.py
index f95edbaaf9..71e670f79b 100644
--- a/src/spikeinterface/benchmark/tests/test_benchmark_sorter.py
+++ b/src/spikeinterface/benchmark/tests/test_benchmark_sorter.py
@@ -65,7 +65,7 @@ def _create_simple_study(study_folder, cache_folder):
},
}
- study = SorterStudy.create(
+ _ = SorterStudy.create(
study_folder, datasets=datasets, cases=cases, levels=["sorter_name", "processing", "probe_type"]
)
# print(study)
@@ -100,7 +100,7 @@ def _create_very_simple_study(study_folder, cache_folder):
},
}
- study = SorterStudy.create(
+ _ = SorterStudy.create(
study_folder, datasets=datasets, cases=cases, levels=["sorter_name", "processing", "probe_type"]
)
# print(study)
@@ -245,7 +245,7 @@ def _create_complex_study(study_folder, cache_folder):
},
}
- study = SorterStudy.create(
+ _ = SorterStudy.create(
study_folder, datasets=datasets, cases=cases, levels=["sorter_name", "processing", "probe_type"]
)
@@ -266,13 +266,16 @@ def test_SorterStudy(create_simple_study):
# this is from the base class
rt = study.get_run_times()
+ assert rt is not None
# rt = study.plot_run_times()
# import matplotlib.pyplot as plt
# plt.show()
perf_by_unit = study.get_performance_by_unit()
+ assert perf_by_unit is not None
# print(perf_by_unit)
count_units = study.get_count_units()
+ assert count_units is not None
# print(count_units)
diff --git a/src/spikeinterface/benchmark/tests/test_benchmark_sorter_without_gt.py b/src/spikeinterface/benchmark/tests/test_benchmark_sorter_without_gt.py
index 62492cbdbe..4055342a46 100644
--- a/src/spikeinterface/benchmark/tests/test_benchmark_sorter_without_gt.py
+++ b/src/spikeinterface/benchmark/tests/test_benchmark_sorter_without_gt.py
@@ -3,7 +3,6 @@
from pathlib import Path
from spikeinterface import generate_ground_truth_recording
-from spikeinterface.preprocessing import bandpass_filter
from spikeinterface.benchmark import SorterStudyWithoutGroundTruth
@@ -42,7 +41,7 @@ def _create_simple_study_no_gt(study_folder):
},
}
- study = SorterStudyWithoutGroundTruth.create(study_folder, datasets=datasets, cases=cases)
+ _ = SorterStudyWithoutGroundTruth.create(study_folder, datasets=datasets, cases=cases)
# print(study)
diff --git a/src/spikeinterface/benchmark/tests/test_residual_analysis.py b/src/spikeinterface/benchmark/tests/test_residual_analysis.py
index 738e4ac3fe..4d01590681 100644
--- a/src/spikeinterface/benchmark/tests/test_residual_analysis.py
+++ b/src/spikeinterface/benchmark/tests/test_residual_analysis.py
@@ -1,6 +1,4 @@
-import shutil
import pytest
-from pathlib import Path
from spikeinterface.benchmark.tests.common_benchmark_testing import make_dataset
diff --git a/src/spikeinterface/comparison/basecomparison.py b/src/spikeinterface/comparison/basecomparison.py
index 3b6dd47c5a..4202d31335 100644
--- a/src/spikeinterface/comparison/basecomparison.py
+++ b/src/spikeinterface/comparison/basecomparison.py
@@ -28,7 +28,6 @@ class BaseMultiComparison(BaseComparison):
"""
def __init__(self, object_list, name_list, match_score=0.5, chance_score=0.1, verbose=False, n_jobs=1):
- import networkx as nx
BaseComparison.__init__(
self,
@@ -187,7 +186,7 @@ def _clean_graph(self):
if edge_to_remove[0] in nodes_duplicate:
node_to_remove = edge_to_remove[0]
else:
- node_to_removed = edge_to_remove[1]
+ node_to_remove = edge_to_remove[1]
if node_to_remove in sg.nodes:
sg.remove_node(node_to_remove)
print(f"Removed node: {node_to_remove}")
diff --git a/src/spikeinterface/comparison/collision.py b/src/spikeinterface/comparison/collision.py
index f6dfcc2e95..ce803b988e 100644
--- a/src/spikeinterface/comparison/collision.py
+++ b/src/spikeinterface/comparison/collision.py
@@ -1,5 +1,3 @@
-import importlib
-
from .paircomparisons import GroundTruthComparison
from .comparisontools import make_collision_events
@@ -161,7 +159,6 @@ def compute_all_pair_collision_bins(self):
loop = tqdm(loop, desc="collision by bin")
for c in loop:
-
score1 = labels_st1[unit_ids1[c]][seg_index][spike_indices1[c]]
score2 = labels_st1[unit_ids2[c]][seg_index][spike_indices2[c]]
diff --git a/src/spikeinterface/comparison/comparisontools.py b/src/spikeinterface/comparison/comparisontools.py
index 4892014575..356976e47c 100644
--- a/src/spikeinterface/comparison/comparisontools.py
+++ b/src/spikeinterface/comparison/comparisontools.py
@@ -275,9 +275,9 @@ def make_match_count_matrix(
num_segments_sorting1 = sorting1.get_num_segments()
num_segments_sorting2 = sorting2.get_num_segments()
- assert (
- num_segments_sorting1 == num_segments_sorting2
- ), "make_match_count_matrix : sorting1 and sorting2 must have the same segment number"
+ assert num_segments_sorting1 == num_segments_sorting2, (
+ "make_match_count_matrix : sorting1 and sorting2 must have the same segment number"
+ )
# Segments should be matched one by one
for segment_index in range(num_segments_sorting1):
@@ -495,7 +495,6 @@ def make_best_match(agreement_scores, min_score) -> "tuple[pd.Series, pd.Series]
best_match_21 : pd.Series
"""
- import pandas as pd
unit1_ids = np.array(agreement_scores.index)
unit2_ids = np.array(agreement_scores.columns)
@@ -539,7 +538,6 @@ def make_hungarian_match(agreement_scores, min_score):
hungarian_match_21 : pd.Series
"""
- import pandas as pd
unit1_ids = np.array(agreement_scores.index)
unit2_ids = np.array(agreement_scores.columns)
@@ -913,7 +911,6 @@ def make_matching_events(times1, times2, delta):
mask2 = membership_sorted[inds] == 2
inds2 = inds[mask2]
- n2 = np.sum(mask2)
matching_event[n1:]["index1"] = spike_index_sorted[inds2 + 1]
matching_event[n1:]["index2"] = spike_index_sorted[inds2]
matching_event[n1:]["delta_frame"] = times_concat_sorted[inds2] - times_concat_sorted[inds2 + 1]
@@ -1328,9 +1325,9 @@ def compute_distance_matrix(
num_segments_sorting1 = sorting1.get_num_segments()
num_segments_sorting2 = sorting2.get_num_segments()
- assert (
- num_segments_sorting1 == num_segments_sorting2
- ), "make_match_count_matrix : sorting1 and sorting2 must have the same number of segments"
+ assert num_segments_sorting1 == num_segments_sorting2, (
+ "make_match_count_matrix : sorting1 and sorting2 must have the same number of segments"
+ )
squared_norm_1_vector = _compute_spike_vector_squared_norm(spike_vector_per_segment1, num_units1, delta_frames)
squared_norm_2_vector = _compute_spike_vector_squared_norm(spike_vector_per_segment2, num_units2, delta_frames)
@@ -1401,9 +1398,9 @@ def calculate_generalized_comparison_metrics(
num_segments_sorting1 = sorting1.get_num_segments()
num_segments_sorting2 = sorting2.get_num_segments()
- assert (
- num_segments_sorting1 == num_segments_sorting2
- ), "make_match_count_matrix : sorting1 and sorting2 must have the same number of segments"
+ assert num_segments_sorting1 == num_segments_sorting2, (
+ "make_match_count_matrix : sorting1 and sorting2 must have the same number of segments"
+ )
squared_norm1 = _compute_spike_vector_squared_norm(spike_vector1_segments, num_units2, delta_frames)
squared_norm2 = _compute_spike_vector_squared_norm(spike_vector2_segments, num_units2, delta_frames)
diff --git a/src/spikeinterface/comparison/multicomparisons.py b/src/spikeinterface/comparison/multicomparisons.py
index a0feda4a52..e3740c7e36 100644
--- a/src/spikeinterface/comparison/multicomparisons.py
+++ b/src/spikeinterface/comparison/multicomparisons.py
@@ -1,11 +1,6 @@
-from pathlib import Path
-import json
-import pickle
-import warnings
-
import numpy as np
-from spikeinterface.core import load, BaseSorting, BaseSortingSegment
+from spikeinterface.core import BaseSorting, BaseSortingSegment
from spikeinterface.core.core_tools import define_function_from_class
from .basecomparison import BaseMultiComparison, MixinSpikeTrainComparison, MixinTemplateComparison
from .paircomparisons import SymmetricSortingComparison, TemplateComparison
diff --git a/src/spikeinterface/comparison/paircomparisons.py b/src/spikeinterface/comparison/paircomparisons.py
index 47e85a03de..be05ca5d8a 100644
--- a/src/spikeinterface/comparison/paircomparisons.py
+++ b/src/spikeinterface/comparison/paircomparisons.py
@@ -39,7 +39,7 @@ def __init__(
if sorting2_name is None:
sorting2_name = "sorting2"
assert sorting1.get_num_segments() == sorting2.get_num_segments(), (
- "The two sortings must have the same " "number of segments! "
+ "The two sortings must have the same number of segments! "
)
BasePairComparison.__init__(
@@ -100,7 +100,6 @@ def _do_agreement(self):
self.match_event_count, self.event_counts1, self.event_counts2
)
elif self.agreement_method == "distance":
-
self.agreement_scores = calculate_agreement_scores_with_distance(
self.sorting1,
self.sorting2,
@@ -294,7 +293,6 @@ def __init__(
compute_misclassifications: bool = False,
verbose: bool = False,
):
- import pandas as pd
if gt_name is None:
gt_name = "ground truth"
diff --git a/src/spikeinterface/comparison/tests/test_comparisontools.py b/src/spikeinterface/comparison/tests/test_comparisontools.py
index 43288415d1..a32bef49ae 100644
--- a/src/spikeinterface/comparison/tests/test_comparisontools.py
+++ b/src/spikeinterface/comparison/tests/test_comparisontools.py
@@ -80,7 +80,10 @@ def test_make_match_count_matrix_with_mismatched_sortings():
delta_frames = 10
sorting1, sorting2 = make_sorting(
- [100, 200, 300, 400], [0, 0, 1, 0], [500, 600, 700, 800], [0, 0, 1, 0] # Completely different spike times
+ [100, 200, 300, 400],
+ [0, 0, 1, 0],
+ [500, 600, 700, 800],
+ [0, 0, 1, 0], # Completely different spike times
)
match_event_count = make_match_count_matrix(sorting1, sorting2, delta_frames)
diff --git a/src/spikeinterface/comparison/tests/test_groundtruthcomparison.py b/src/spikeinterface/comparison/tests/test_groundtruthcomparison.py
index 27b8f73077..34fe86c1f8 100644
--- a/src/spikeinterface/comparison/tests/test_groundtruthcomparison.py
+++ b/src/spikeinterface/comparison/tests/test_groundtruthcomparison.py
@@ -1,4 +1,3 @@
-import numpy as np
from numpy.testing import assert_array_equal
@@ -111,6 +110,7 @@ def test_compare_sorter_to_ground_truth():
bad_ids = sc.get_bad_units()
assert_array_equal(bad_ids, [6, 11])
num_bad = sc.count_bad_units()
+ assert num_bad == 2
# bad units is union of false_positive_units + redundant_units
fpu_ids = sc.get_false_positive_units()
diff --git a/src/spikeinterface/comparison/tests/test_multisortingcomparison.py b/src/spikeinterface/comparison/tests/test_multisortingcomparison.py
index 72f39f74ea..64f4efdc1d 100644
--- a/src/spikeinterface/comparison/tests/test_multisortingcomparison.py
+++ b/src/spikeinterface/comparison/tests/test_multisortingcomparison.py
@@ -8,7 +8,7 @@
from spikeinterface.core import generate_sorting
from spikeinterface.core.job_tools import get_usable_cpu_count
from spikeinterface.extractors import NumpySorting
-from spikeinterface.comparison import compare_multiple_sorters, MultiSortingComparison
+from spikeinterface.comparison import compare_multiple_sorters
ON_GITHUB = bool(os.getenv("GITHUB_ACTIONS"))
diff --git a/src/spikeinterface/comparison/tests/test_templatecomparison.py b/src/spikeinterface/comparison/tests/test_templatecomparison.py
index 001f80f4f6..6879629e6d 100644
--- a/src/spikeinterface/comparison/tests/test_templatecomparison.py
+++ b/src/spikeinterface/comparison/tests/test_templatecomparison.py
@@ -1,5 +1,3 @@
-import shutil
-import pytest
import numpy as np
from spikeinterface.core import create_sorting_analyzer, generate_ground_truth_recording
diff --git a/src/spikeinterface/core/analyzer_extension_core.py b/src/spikeinterface/core/analyzer_extension_core.py
index 070176244f..8159c18160 100644
--- a/src/spikeinterface/core/analyzer_extension_core.py
+++ b/src/spikeinterface/core/analyzer_extension_core.py
@@ -181,7 +181,6 @@ def _run(self, verbose=False, **job_kwargs):
self.data.clear()
recording = self.sorting_analyzer.recording
- sorting = self.sorting_analyzer.sorting
# retrieve spike vector and the sampling
some_spikes = self.sorting_analyzer.get_extension("random_spikes").get_random_spikes()
@@ -252,8 +251,6 @@ def _select_units_extension_data(self, unit_ids):
some_spikes = self.sorting_analyzer.get_extension("random_spikes").get_random_spikes()
keep_unit_indices = self.sorting_analyzer.sorting.ids_to_indices(unit_ids)
- spikes = self.sorting_analyzer.sorting.to_spike_vector()
- # some_spikes = spikes[random_spikes_indices]
keep_spike_mask = np.isin(some_spikes["unit_index"], keep_unit_indices)
new_data = dict()
@@ -529,9 +526,9 @@ def _compute_and_append_from_waveforms(self, operators):
# spikes = self.sorting_analyzer.sorting.to_spike_vector()
# some_spikes = spikes[self.sorting_analyzer.random_spikes_indices]
- assert self.sorting_analyzer.has_extension(
- "random_spikes"
- ), "compute 'templates' requires the random_spikes extension. You can run sorting_analyzer.compute('random_spikes')"
+ assert self.sorting_analyzer.has_extension("random_spikes"), (
+ "compute 'templates' requires the random_spikes extension. You can run sorting_analyzer.compute('random_spikes')"
+ )
some_spikes = self.sorting_analyzer.get_extension("random_spikes").get_random_spikes()
for unit_index, unit_id in enumerate(unit_ids):
spike_mask = some_spikes["unit_index"] == unit_index
@@ -1359,7 +1356,6 @@ def _run(self, **job_kwargs):
# Check if we need to propagate any old metrics. If so, we'll do that.
# Otherwise, we'll avoid attempting to load an empty metrics.
if set(self.params["metrics_to_compute"]) != set(self.params["metric_names"]):
-
extension = self.sorting_analyzer.get_extension(self.extension_name)
if delete_existing_metrics is False and extension is not None and extension.data.get("metrics") is not None:
existing_metrics = extension.params["metric_names"]
@@ -1451,7 +1447,6 @@ def _merge_extension_data(
dict
Dictionary containing the merged metrics DataFrame.
"""
- import pandas as pd
available_metric_names = self.get_available_metric_names()
metric_names = [m for m in self.params["metric_names"] if m in available_metric_names]
@@ -1497,7 +1492,6 @@ def _split_extension_data(
verbose : bool, default: False
Whether to print verbose output.
"""
- import pandas as pd
from itertools import chain
available_metric_names = [m.metric_name for m in self.metric_list]
@@ -1524,7 +1518,6 @@ def _split_extension_data(
return new_data
def set_data(self, ext_data_name, data):
- import pandas as pd
if ext_data_name == "metrics":
metrics = self._cast_metrics(data)
@@ -1629,9 +1622,9 @@ def _get_data(self, outputs="numpy", concatenated=False, return_data_name=None,
if return_data_name is None:
return_data_name = self.nodepipeline_variables[0]
else:
- assert (
- return_data_name in self.nodepipeline_variables
- ), f"return_data_name {return_data_name} not in nodepipeline_variables {self.nodepipeline_variables}"
+ assert return_data_name in self.nodepipeline_variables, (
+ f"return_data_name {return_data_name} not in nodepipeline_variables {self.nodepipeline_variables}"
+ )
all_data = self.data[return_data_name]
# data gathered directly into a zarr store (e.g. by the node pipeline) is kept as a
@@ -1799,12 +1792,10 @@ def _select_channels_sparse_data(old_sorting_analyzer, old_data, new_channel_ids
new_data = np.zeros_like(old_data)
max_num_active_channels = 0
for data_index, (one_old_data, unit_index) in enumerate(zip(old_data, random_spikes["unit_index"])):
-
unit_id = unit_ids[unit_index]
channel_slice = unit_sparsity_slices[unit_id]
if len(channel_slice) > 0:
-
size_of_new_mask = len(channel_slice)
new_data[data_index, :, :size_of_new_mask] = one_old_data[:, channel_slice]
diff --git a/src/spikeinterface/core/base.py b/src/spikeinterface/core/base.py
index dbecd82bbe..eae31791a3 100644
--- a/src/spikeinterface/core/base.py
+++ b/src/spikeinterface/core/base.py
@@ -1,5 +1,4 @@
from pathlib import Path
-import shutil
from typing import Any
from collections.abc import Iterable, Sequence
import importlib
@@ -7,26 +6,19 @@
import weakref
import json
import pickle
-import random
-import string
from packaging.version import parse
from copy import deepcopy
import numpy as np
-from .globals import get_global_tmp_folder, is_set_global_tmp_folder
from .core_tools import (
- clean_zarr_folder_name,
is_dict_extractor,
SIJsonEncoder,
- is_path_remote,
make_paths_relative,
make_paths_absolute,
check_paths_relative,
retrieve_importing_provenance,
- load_properties_from_folder,
)
-from .job_tools import _shared_job_kwargs_doc
# base dtypes used throughout spikeinterface
base_peak_dtype = [
@@ -87,9 +79,9 @@ def __init__(self, main_ids: Sequence) -> None:
# string column. Store it as fixed-width unicode like every other source.
self._main_ids = np.array(self._main_ids.tolist())
if len(self._main_ids) > 0:
- assert (
- self._main_ids.dtype.kind in "uiSU"
- ), f"Main IDs can only be integers (signed/unsigned) or strings, not {self._main_ids.dtype}"
+ assert self._main_ids.dtype.kind in "uiSU", (
+ f"Main IDs can only be integers (signed/unsigned) or strings, not {self._main_ids.dtype}"
+ )
self._segments: "list[BaseSegment]" = []
@@ -117,7 +109,7 @@ def _get_common_repr_html(self, common_style):
html_annotations = f" Annotations
"
for key, value in self._annotations.items():
html_annotations += f"- {key} : {value}
"
- html_annotations += f"
"
+ html_annotations += ""
html_properties = f"Properties
"
for key, value in self._properties.items():
@@ -337,9 +329,9 @@ def set_property(
dtype_kind = dtype.kind
if ids is None:
- assert (
- values.shape[0] == size
- ), f"Values must have the same size as the main ids: {size} but got array of size {values.shape[0]}"
+ assert values.shape[0] == size, (
+ f"Values must have the same size as the main ids: {size} but got array of size {values.shape[0]}"
+ )
self._properties[key] = values
else:
ids = np.array(ids)
@@ -351,7 +343,6 @@ def set_property(
# Sam: this is used because you could set all ids (like the None) but with the vector.
if ids.size < size:
if key not in self._properties:
-
if missing_value is None:
if dtype_kind not in self.default_missing_property_values.keys():
raise ValueError(
@@ -386,9 +377,9 @@ def set_property(
return
else:
existing_property = self._properties[key].dtype
- assert (
- dtype_kind == existing_property.kind
- ), f"Mismatch between existing property dtype {existing_property.kind} and provided values dtype {dtype_kind}."
+ assert dtype_kind == existing_property.kind, (
+ f"Mismatch between existing property dtype {existing_property.kind} and provided values dtype {dtype_kind}."
+ )
indices = self.ids_to_indices(ids)
if dtype_kind == "U":
@@ -690,7 +681,7 @@ def _get_file_path(file_path: str | Path, extensions: Sequence) -> Path:
folder_path = file_path.parent
if Path(file_path).suffix == "":
file_path = folder_path / (str(file_path) + ext)
- assert file_path.suffix in extensions, "'file_path' should have one of the following extensions:" " %s" % (
+ assert file_path.suffix in extensions, "'file_path' should have one of the following extensions: %s" % (
", ".join(extensions)
)
return file_path
@@ -964,7 +955,7 @@ def _get_class_from_string(class_string):
try:
imported_class = getattr(imported_module, class_name)
- except:
+ except Exception:
imported_class = None
return imported_class
diff --git a/src/spikeinterface/core/baseevent.py b/src/spikeinterface/core/baseevent.py
index 2e73774c04..78e542705f 100644
--- a/src/spikeinterface/core/baseevent.py
+++ b/src/spikeinterface/core/baseevent.py
@@ -26,16 +26,16 @@ def __init__(self, channel_ids, structured_dtype):
if not isinstance(structured_dtype, dict):
structured_dtype = {chan_id: structured_dtype for chan_id in channel_ids}
else:
- assert all(
- chan_id in structured_dtype for chan_id in channel_ids
- ), "Missing some channel_ids from structured_dtype dict keys"
+ assert all(chan_id in structured_dtype for chan_id in channel_ids), (
+ "Missing some channel_ids from structured_dtype dict keys"
+ )
# check dtype fields (if present)
for _, dtype in structured_dtype.items():
if dtype.names is not None:
- assert (
- "time" in dtype.names or "timestamp" in dtype.names
- ), "The event dtype need to have the 'time' or 'timestamp' field"
+ assert "time" in dtype.names or "timestamp" in dtype.names, (
+ "The event dtype need to have the 'time' or 'timestamp' field"
+ )
self.structured_dtype = structured_dtype
diff --git a/src/spikeinterface/core/baserecording.py b/src/spikeinterface/core/baserecording.py
index c4f689e9c6..76167ea792 100644
--- a/src/spikeinterface/core/baserecording.py
+++ b/src/spikeinterface/core/baserecording.py
@@ -7,7 +7,6 @@
from .base import BaseExtractor
from .time_series import TimeSeriesSegment, TimeSeries
-from .base import BaseExtractor
from .core_tools import convert_bytes_to_str, convert_seconds_to_str
from .job_tools import split_job_kwargs
from .recording_tools import _set_group_property_based_on_probegroup, check_probe_do_not_overlap
@@ -111,7 +110,7 @@ def _repr_header(self, display_name=True):
sampling_frequency_repr = f"{sf_hz:f} Hz"
else:
# Khz for high sampling rate and Hz for LFP
- sampling_frequency_repr = f"{(sf_hz/1000.0):0.1f}kHz" if sf_hz > 10_000.0 else f"{sf_hz:0.1f}Hz"
+ sampling_frequency_repr = f"{(sf_hz / 1000.0):0.1f}kHz" if sf_hz > 10_000.0 else f"{sf_hz:0.1f}Hz"
if display_name and self.name != self.__class__.__name__:
name = f"{self.name} ({self.__class__.__name__})"
@@ -591,9 +590,9 @@ def _get_probegroup_based_on_device_channel_indices(self, probegroup: ProbeGroup
if not isinstance(probegroup, ProbeGroup):
raise ValueError("The input must be a ProbeGroup or dict")
- assert all(
- probe.device_channel_indices is not None for probe in probegroup.probes
- ), "Probe must have device_channel_indices"
+ assert all(probe.device_channel_indices is not None for probe in probegroup.probes), (
+ "Probe must have device_channel_indices"
+ )
# Remove unconnected contacts and slice the probe group accordingly
device_channel_indices = probegroup.get_global_device_channel_indices()["device_channel_indices"]
@@ -1100,7 +1099,7 @@ def rename_channels(self, new_channel_ids: list | np.ndarray | tuple) -> "BaseRe
from .channelslice import ChannelSliceRecording
assert len(new_channel_ids) == self.get_num_channels(), (
- "new_channel_ids must have the same length as the " "number of channels in the recording"
+ "new_channel_ids must have the same length as the number of channels in the recording"
)
return ChannelSliceRecording(self, renamed_channel_ids=new_channel_ids)
@@ -1144,9 +1143,9 @@ def time_slice(self, start_time: float | None, end_time: float | None) -> "BaseR
A new recording object with only samples between start_time and end_time
"""
num_segments = self.get_num_segments()
- assert (
- num_segments == 1
- ), f"Time slicing is only supported for single segment recordings. Found {num_segments} segments."
+ assert num_segments == 1, (
+ f"Time slicing is only supported for single segment recordings. Found {num_segments} segments."
+ )
t_start = self.get_start_time()
t_end = self.get_end_time()
diff --git a/src/spikeinterface/core/basesorting.py b/src/spikeinterface/core/basesorting.py
index eb59420139..23a2aa4361 100644
--- a/src/spikeinterface/core/basesorting.py
+++ b/src/spikeinterface/core/basesorting.py
@@ -4,7 +4,6 @@
import numpy as np
-from pathlib import Path
from .base import BaseExtractor, BaseSegment, minimum_spike_dtype
from .waveform_tools import has_exceeding_spikes
@@ -112,9 +111,9 @@ def get_num_samples(self, segment_index=None) -> int:
int
The number of samples
"""
- assert (
- self.has_recording()
- ), "This methods requires an associated recording. Call self.register_recording() first."
+ assert self.has_recording(), (
+ "This methods requires an associated recording. Call self.register_recording() first."
+ )
return self._recording.get_num_samples(segment_index=segment_index)
def get_total_samples(self) -> int:
@@ -138,9 +137,9 @@ def get_total_duration(self) -> float:
float
The duration in seconds
"""
- assert (
- self.has_recording()
- ), "This methods requires an associated recording. Call self.register_recording() first."
+ assert self.has_recording(), (
+ "This methods requires an associated recording. Call self.register_recording() first."
+ )
return self._recording.get_total_duration()
def search_cached_spikes_sorted(
@@ -309,7 +308,6 @@ def get_unit_spike_train_in_seconds(
# If sorting has a registered recording, get the frames and get the times from the recording
# Note that this take into account the segment start time of the recording
if self.has_recording():
-
# Get all the spike times and then slice them
start_frame = None
end_frame = None
@@ -378,12 +376,12 @@ def register_recording(self, recording, check_spike_frames: bool = True):
check_spike_frames : bool, default: True
If True, assert for each segment that all spikes are within the recording's range.
"""
- assert np.isclose(
- self.get_sampling_frequency(), recording.get_sampling_frequency(), atol=0.1
- ), "The recording has a different sampling frequency than the sorting!"
- assert (
- self.get_num_segments() == recording.get_num_segments()
- ), "The recording has a different number of segments than the sorting!"
+ assert np.isclose(self.get_sampling_frequency(), recording.get_sampling_frequency(), atol=0.1), (
+ "The recording has a different sampling frequency than the sorting!"
+ )
+ assert self.get_num_segments() == recording.get_num_segments(), (
+ "The recording has a different number of segments than the sorting!"
+ )
if check_spike_frames:
if has_exceeding_spikes(self, recording):
warnings.warn(
diff --git a/src/spikeinterface/core/binaryfolder.py b/src/spikeinterface/core/binaryfolder.py
index 0dc8eaa1a8..65fe6e153b 100644
--- a/src/spikeinterface/core/binaryfolder.py
+++ b/src/spikeinterface/core/binaryfolder.py
@@ -1,7 +1,6 @@
from pathlib import Path
import json
-from copy import deepcopy
import shutil
import numpy as np
@@ -191,7 +190,7 @@ def write_recording(
# All properties, annotations, and probe information are already saved in the folder,
# so we don't need to include them in the si_folder.json
cached = BinaryFolderRecording(folder_path=folder_path)
- si_folder_path = folder_path / f"si_folder.json"
+ si_folder_path = folder_path / "si_folder.json"
cached.dump_to_json(
file_path=si_folder_path,
relative_to=folder_path,
diff --git a/src/spikeinterface/core/binaryrecordingextractor.py b/src/spikeinterface/core/binaryrecordingextractor.py
index cd1fa88940..cdbf722e90 100644
--- a/src/spikeinterface/core/binaryrecordingextractor.py
+++ b/src/spikeinterface/core/binaryrecordingextractor.py
@@ -285,7 +285,7 @@ def __del__(self):
try:
self._time_vector._mmap.close() # Close the underlying mmap object
del self._time_vector
- except Exception as e:
+ except Exception:
pass
diff --git a/src/spikeinterface/core/channelsaggregationrecording.py b/src/spikeinterface/core/channelsaggregationrecording.py
index ae7309d1ab..6af28adeed 100644
--- a/src/spikeinterface/core/channelsaggregationrecording.py
+++ b/src/spikeinterface/core/channelsaggregationrecording.py
@@ -1,5 +1,3 @@
-import warnings
-
import numpy as np
from probeinterface import ProbeGroup
@@ -52,12 +50,11 @@ def __init__(self, recording_list_or_dict=None, renamed_channel_ids=None):
# Generate a default list of channel ids that are unique and consecutive numbers as strings.
num_all_channels = sum(rec.get_num_channels() for rec in recording_list)
if renamed_channel_ids is not None:
- assert (
- len(np.unique(renamed_channel_ids)) == num_all_channels
- ), "'renamed_channel_ids' doesn't have the right size or has duplicates!"
+ assert len(np.unique(renamed_channel_ids)) == num_all_channels, (
+ "'renamed_channel_ids' doesn't have the right size or has duplicates!"
+ )
channel_ids = list(renamed_channel_ids)
else:
-
# Explicitly check if all channel_ids arrays are either all integers or all strings.
all_ids_are_int_dtype = all(np.issubdtype(rec.channel_ids.dtype, np.integer) for rec in recording_list)
all_ids_are_str_dtype = all(np.issubdtype(rec.channel_ids.dtype, np.str_) for rec in recording_list)
@@ -89,7 +86,7 @@ def __init__(self, recording_list_or_dict=None, renamed_channel_ids=None):
property_dict[prop_name] = np.concatenate(
(property_dict[prop_name], rec.get_property(prop_name))
)
- except Exception as e:
+ except Exception:
print(f"Skipping property '{prop_name}' for shape inconsistency")
del property_dict[prop_name]
break
@@ -214,7 +211,7 @@ def __init__(self, channel_map, parent_segments):
else:
for ps in parent_segments:
assert ps.get_times_kwargs()["t_start"] == times_kargs0["t_start"], (
- "All segments should have the same " "t_start"
+ "All segments should have the same t_start"
)
BaseRecordingSegment.__init__(self, **times_kargs0)
diff --git a/src/spikeinterface/core/channelslice.py b/src/spikeinterface/core/channelslice.py
index 13cac8db8d..e1af49a3c2 100644
--- a/src/spikeinterface/core/channelslice.py
+++ b/src/spikeinterface/core/channelslice.py
@@ -17,9 +17,9 @@ def __init__(self, recording, channel_ids=None, renamed_channel_ids=None):
if renamed_channel_ids is None:
renamed_channel_ids = channel_ids
else:
- assert len(renamed_channel_ids) == len(
- np.unique(renamed_channel_ids)
- ), "renamed_channel_ids must be unique!"
+ assert len(renamed_channel_ids) == len(np.unique(renamed_channel_ids)), (
+ "renamed_channel_ids must be unique!"
+ )
self._channel_ids = np.asarray(channel_ids)
self._renamed_channel_ids = np.asarray(renamed_channel_ids)
@@ -29,16 +29,16 @@ def __init__(self, recording, channel_ids=None, renamed_channel_ids=None):
# some checks
# We use lists to compare numpy scalar types as their python versions (e.g. int vs int64())
channel_ids_not_in_parents = [id for id in self._channel_ids.tolist() if id not in parents_chan_ids.tolist()]
- assert (
- len(channel_ids_not_in_parents) == 0
- ), f"ChannelSliceRecording : channel ids {channel_ids_not_in_parents} are not all in parent ids {parents_chan_ids}"
-
- assert len(self._channel_ids) == len(
- self._renamed_channel_ids
- ), "ChannelSliceRecording: renamed channel_ids must be the same size"
- assert (
- self._channel_ids.size == np.unique(self._channel_ids).size
- ), "ChannelSliceRecording : channel_ids are not unique"
+ assert len(channel_ids_not_in_parents) == 0, (
+ f"ChannelSliceRecording : channel ids {channel_ids_not_in_parents} are not all in parent ids {parents_chan_ids}"
+ )
+
+ assert len(self._channel_ids) == len(self._renamed_channel_ids), (
+ "ChannelSliceRecording: renamed channel_ids must be the same size"
+ )
+ assert self._channel_ids.size == np.unique(self._channel_ids).size, (
+ "ChannelSliceRecording : channel_ids are not unique"
+ )
sampling_frequency = recording.get_sampling_frequency()
diff --git a/src/spikeinterface/core/core_tools.py b/src/spikeinterface/core/core_tools.py
index 81678308fd..de551ddadd 100644
--- a/src/spikeinterface/core/core_tools.py
+++ b/src/spikeinterface/core/core_tools.py
@@ -502,7 +502,7 @@ def check_paths_relative(input_dict, relative_folder) -> bool:
# check relative is possible
try:
- p2 = _relative_to(p, relative_folder)
+ _ = _relative_to(p, relative_folder)
except ValueError:
not_possible.append(p)
continue
@@ -562,8 +562,6 @@ def make_paths_absolute(input_dict, base_folder) -> dict:
A copy of the input dict with modified paths.
"""
base_folder = Path(base_folder)
- # use as_posix instead of str to make the path unix like even on window
- func = lambda p: (base_folder / p).resolve().absolute().as_posix()
path_elements_in_dict = [e for e in extractor_dict_iterator(input_dict) if element_is_path(e)]
output_dict = deepcopy(input_dict)
@@ -981,10 +979,10 @@ def load_annotations_from_folder(folder: str | Path, extractor: "BaseExtractor")
def save_provenance_to_folder(folder: str | Path, extractor: "BaseExtractor", relative_to: str | Path | None = None):
folder = Path(folder)
if extractor.check_serializability("json"):
- provenance_file_path = folder / f"provenance.json"
+ provenance_file_path = folder / "provenance.json"
extractor.dump_to_json(file_path=provenance_file_path, relative_to=relative_to)
elif extractor.check_serializability("pickle"):
- provenance_file = folder / f"provenance.pkl"
+ provenance_file = folder / "provenance.pkl"
extractor.dump_to_pickle(provenance_file, relative_to=folder)
else:
warnings.warn("The extractor is not serializable to file. The provenance will not be saved.")
diff --git a/src/spikeinterface/core/frameslicerecording.py b/src/spikeinterface/core/frameslicerecording.py
index bc7913e505..6bb606f5ad 100644
--- a/src/spikeinterface/core/frameslicerecording.py
+++ b/src/spikeinterface/core/frameslicerecording.py
@@ -34,9 +34,9 @@ def __init__(self, recording, start_frame=None, end_frame=None):
assert start_frame >= 0, f"{start_frame=} must be positive"
assert start_frame < end_frame, f"{start_frame=} must be smaller than 'end_frame' {end_frame=}!"
- assert (
- end_frame <= samples_in_recording
- ), f"{end_frame=} must be smaller than or equal to {samples_in_recording=}"
+ assert end_frame <= samples_in_recording, (
+ f"{end_frame=} must be smaller than or equal to {samples_in_recording=}"
+ )
BaseRecording.__init__(
self,
diff --git a/src/spikeinterface/core/frameslicesorting.py b/src/spikeinterface/core/frameslicesorting.py
index 2d3195e8a5..6d0a99ad46 100644
--- a/src/spikeinterface/core/frameslicesorting.py
+++ b/src/spikeinterface/core/frameslicesorting.py
@@ -46,12 +46,12 @@ def __init__(self, parent_sorting, start_frame=None, end_frame=None, check_spike
parent_n_samples = parent_sorting._recording.get_total_samples()
if end_frame is None:
end_frame = parent_n_samples
- assert (
- end_frame <= parent_n_samples
- ), f"`end_frame` should be smaller than the sortings' total number of samples {parent_n_samples}."
- assert (
- start_frame <= parent_n_samples
- ), "`start_frame` should be smaller than the sortings' total number of samples."
+ assert end_frame <= parent_n_samples, (
+ f"`end_frame` should be smaller than the sortings' total number of samples {parent_n_samples}."
+ )
+ assert start_frame <= parent_n_samples, (
+ "`start_frame` should be smaller than the sortings' total number of samples."
+ )
if check_spike_frames and has_exceeding_spikes(parent_sorting, parent_sorting._recording):
raise ValueError(
"The sorting object has spikes whose times go beyond the recording duration."
diff --git a/src/spikeinterface/core/generate.py b/src/spikeinterface/core/generate.py
index eeeb0b91b8..b0c3ad4318 100644
--- a/src/spikeinterface/core/generate.py
+++ b/src/spikeinterface/core/generate.py
@@ -8,9 +8,9 @@
from .basesorting import SpikeVectorSortingSegment
from .numpyextractors import NumpySorting
-from probeinterface import Probe, generate_linear_probe, generate_multi_columns_probe
+from probeinterface import generate_linear_probe, generate_multi_columns_probe
-from spikeinterface.core import BaseRecording, BaseRecordingSegment, BaseSorting
+from spikeinterface.core import BaseRecording, BaseRecordingSegment, BaseSorting, BaseSortingSegment
from .core_tools import define_function_from_class, ms_to_samples, _ensure_seed
@@ -355,11 +355,11 @@ def __init__(
if new_unit_ids is not None:
new_unit_ids = list(new_unit_ids)
- assert ~np.any(
- np.isin(new_unit_ids, sorting.unit_ids)
- ), "some units ids are already present. Consider using added_spikes_existing_units"
+ assert ~np.any(np.isin(new_unit_ids, sorting.unit_ids)), (
+ "some units ids are already present. Consider using added_spikes_existing_units"
+ )
if len(new_unit_ids) > 0:
- assert type(unit_ids[0]) == type(new_unit_ids[0]), "unit_ids should have the same type"
+ assert type(unit_ids[0]) is type(new_unit_ids[0]), "unit_ids should have the same type"
unit_ids = unit_ids + list(new_unit_ids)
BaseSorting.__init__(self, sampling_frequency, unit_ids)
@@ -372,10 +372,9 @@ def __init__(
self.added_spikes_from_new_mask = np.zeros(len(spikes), dtype=bool)
if added_spikes_existing_units is not None and len(added_spikes_existing_units) > 0:
- assert (
- added_spikes_existing_units.dtype == minimum_spike_dtype
- ), "added_spikes_existing_units should be a spike vector"
- added_unit_indices = np.arange(len(self.parent_unit_ids))
+ assert added_spikes_existing_units.dtype == minimum_spike_dtype, (
+ "added_spikes_existing_units should be a spike vector"
+ )
spikes = np.concatenate((spikes, added_spikes_existing_units))
self.added_spikes_from_existing_mask = np.concatenate(
(self.added_spikes_from_existing_mask, np.ones(len(added_spikes_existing_units), dtype=bool))
@@ -385,9 +384,9 @@ def __init__(
)
if added_spikes_new_units is not None and len(added_spikes_new_units) > 0:
- assert (
- added_spikes_new_units.dtype == minimum_spike_dtype
- ), "added_spikes_new_units should be a spike vector"
+ assert added_spikes_new_units.dtype == minimum_spike_dtype, (
+ "added_spikes_new_units should be a spike vector"
+ )
spikes = np.concatenate((spikes, added_spikes_new_units))
self.added_spikes_from_existing_mask = np.concatenate(
(self.added_spikes_from_existing_mask, np.zeros(len(added_spikes_new_units), dtype=bool))
@@ -455,10 +454,10 @@ def add_from_sorting(sorting1: BaseSorting, sorting2: BaseSorting, refractory_pe
of spikes. Any spike times in added_spikes violating the refractory period will be
discarded.
"""
- assert (
- sorting1.get_sampling_frequency() == sorting2.get_sampling_frequency()
- ), "sampling_frequency should be the same"
- assert type(sorting1.unit_ids[0]) == type(sorting2.unit_ids[0]), "unit_ids should have the same type"
+ assert sorting1.get_sampling_frequency() == sorting2.get_sampling_frequency(), (
+ "sampling_frequency should be the same"
+ )
+ assert type(sorting1.unit_ids[0]) is type(sorting2.unit_ids[0]), "unit_ids should have the same type"
# We detect the indices that are shared by the two sortings
mask1 = np.isin(sorting2.unit_ids, sorting1.unit_ids)
common_ids = sorting2.unit_ids[mask1]
@@ -1023,9 +1022,6 @@ def synthesize_amplitude_factor(
return None
-from spikeinterface.core.basesorting import BaseSortingSegment, BaseSorting
-
-
class SortingGenerator(BaseSorting):
def __init__(
self,
@@ -1690,7 +1686,6 @@ def generate_templates(
"""
unit_params = unit_params or dict()
- rng = np.random.default_rng(seed=seed)
# neuron location must be 3D
assert units_locations.shape[1] == 3
@@ -2335,9 +2330,7 @@ def generate_ground_truth_recording(
prb_kwargs = generate_probe_kwargs.copy()
if "num_contact_per_column" in prb_kwargs:
- assert (
- prb_kwargs["num_contact_per_column"] * prb_kwargs["num_columns"]
- ) == num_channels, (
+ assert (prb_kwargs["num_contact_per_column"] * prb_kwargs["num_columns"]) == num_channels, (
"generate_multi_columns_probe : num_channels do not match num_contact_per_column x num_columns"
)
elif "num_contact_per_column" not in prb_kwargs and "num_columns" in prb_kwargs:
diff --git a/src/spikeinterface/core/globals.py b/src/spikeinterface/core/globals.py
index 2712f4db3a..8bfa0f7a06 100644
--- a/src/spikeinterface/core/globals.py
+++ b/src/spikeinterface/core/globals.py
@@ -131,7 +131,7 @@ def set_global_job_kwargs(**job_kwargs):
global global_job_kwargs
for k in job_kwargs:
assert k in job_keys, (
- f"{k} is not a valid job keyword argument. " f"Available keyword arguments are: {list(job_keys)}"
+ f"{k} is not a valid job keyword argument. Available keyword arguments are: {list(job_keys)}"
)
global_job_kwargs.update(job_kwargs)
global global_job_kwargs_set
diff --git a/src/spikeinterface/core/job_tools.py b/src/spikeinterface/core/job_tools.py
index 59af6fd254..1c3a62b9da 100644
--- a/src/spikeinterface/core/job_tools.py
+++ b/src/spikeinterface/core/job_tools.py
@@ -144,7 +144,7 @@ def fix_job_kwargs(runtime_job_kwargs):
for k in runtime_job_kwargs:
assert k in job_keys, (
- f"{k} is not a valid job keyword argument. " f"Available keyword arguments are: {list(job_keys)}"
+ f"{k} is not a valid job keyword argument. Available keyword arguments are: {list(job_keys)}"
)
# remove mutually exclusive from global job kwargs
diff --git a/src/spikeinterface/core/loading.py b/src/spikeinterface/core/loading.py
index 8cc679d95e..24d0588723 100644
--- a/src/spikeinterface/core/loading.py
+++ b/src/spikeinterface/core/loading.py
@@ -1,4 +1,3 @@
-import warnings
from pathlib import Path
import json
@@ -99,7 +98,6 @@ def load(
return _load_object_from_dict(d, object_type, base_folder=base_folder)
elif is_local and file_path.is_dir():
-
folder = file_path
if folder.suffix == ".zarr":
# Local zarr can be
@@ -195,7 +193,7 @@ def _guess_object_from_local_folder(folder):
elif (folder / "waveforms").is_dir():
# before the SortingAnlazer, it was WaveformExtractor (v<0.101)
return "WaveformExtractor"
- elif (folder / f"si_folder.json").is_file():
+ elif (folder / "si_folder.json").is_file():
# In later versions (0.94 None:
if extension_folder.is_dir():
shutil.rmtree(extension_folder)
if self.format == "zarr":
-
zarr_root = self._get_zarr_root(mode="r+")
if extension_name in (root := zarr_root["extensions"]):
del root[extension_name]
@@ -2850,7 +2845,6 @@ def _sort_extensions_by_dependency(extensions):
i = 0
while i < len(extensions_list):
-
extension = extensions_list[i]
extension_params = extension_params_list[i]
@@ -2875,10 +2869,8 @@ def _sort_extensions_by_dependency(extensions):
# Otherwise, should check the dependency which has just been moved => at position i
did_nothing = True
for dependency in dependencies:
-
# if dependency is on the right, move it left of the current dependency
if dependency in extensions_list[i:]:
-
dependency_arg = extensions_list.index(dependency)
extension_params_list.pop(dependency_arg)
@@ -2945,9 +2937,9 @@ def register_result_extension(extension_class):
already_registered = any(extension_class is ext for ext in _possible_extensions)
if not already_registered:
- assert all(
- extension_class.extension_name != ext.extension_name for ext in _possible_extensions
- ), "Extension name already exists"
+ assert all(extension_class.extension_name != ext.extension_name for ext in _possible_extensions), (
+ "Extension name already exists"
+ )
_possible_extensions.append(extension_class)
@@ -2984,7 +2976,7 @@ def get_extension_class(extension_name: str, auto_import=True):
if extension_name in _builtin_extensions:
module = _builtin_extensions[extension_name]
if auto_import:
- imported_module = importlib.import_module(module)
+ _ = importlib.import_module(module)
extensions_dict = {ext.extension_name: ext for ext in _possible_extensions}
else:
raise ValueError(
@@ -3519,7 +3511,6 @@ def run(self, save=True, **kwargs):
self._save_run_info()
self._save_data()
if self.format == "zarr":
-
zarr.consolidate_metadata(self.sorting_analyzer._get_zarr_root(mode="r+").store)
def save(self):
@@ -3530,7 +3521,6 @@ def save(self):
self._save_data()
if self.format == "zarr":
-
zarr.consolidate_metadata(self.sorting_analyzer._get_zarr_root(mode="r+").store)
def _save_data(self):
@@ -3545,11 +3535,10 @@ def _save_data(self):
import pandas as pd
HAS_PANDAS = True
- except:
+ except Exception:
HAS_PANDAS = False
if self.format == "binary_folder":
-
extension_folder = self._get_binary_extension_folder()
for ext_data_name, ext_data in self.data.items():
if isinstance(ext_data, dict):
@@ -3570,10 +3559,9 @@ def _save_data(self):
try:
with (extension_folder / f"{ext_data_name}.pkl").open("wb") as f:
pickle.dump(ext_data, f)
- except:
+ except Exception:
raise Exception(f"Could not save {ext_data_name} as extension data")
elif self.format == "zarr":
-
saving_options = self.sorting_analyzer._backend_options.get("saving_options", {})
extension_group = self._get_zarr_extension_group(mode="r+")
@@ -3619,7 +3607,7 @@ def _save_data(self):
write_pickle_array(
extension_group, ext_data_name, ext_data, compressors=saving_options["compressors"]
)
- except:
+ except Exception:
raise Exception(f"Could not save {ext_data_name} as extension data")
def _reset_extension_folder(self):
@@ -3643,7 +3631,6 @@ def _reset_extension_folder(self):
extension_folder.mkdir(exist_ok=False, parents=True)
elif self.format == "zarr":
-
zarr_root = self.sorting_analyzer._get_zarr_root(mode="r+")
_ = zarr_root["extensions"].create_group(self.extension_name, overwrite=True)
zarr.consolidate_metadata(zarr_root.store)
@@ -3658,7 +3645,6 @@ def _delete_extension_folder(self):
shutil.rmtree(extension_folder)
elif self.format == "zarr":
-
zarr_root = self.sorting_analyzer._get_zarr_root(mode="r+")
if self.extension_name in zarr_root["extensions"]:
del zarr_root["extensions"][self.extension_name]
@@ -3758,16 +3744,16 @@ def _save_run_info(self):
extension_group.attrs["run_info"] = run_info
def get_pipeline_nodes(self):
- assert (
- self.use_nodepipeline
- ), "AnalyzerExtension.get_pipeline_nodes() must be called only when use_nodepipeline=True"
+ assert self.use_nodepipeline, (
+ "AnalyzerExtension.get_pipeline_nodes() must be called only when use_nodepipeline=True"
+ )
return self._get_pipeline_nodes()
def get_data(self, *args, **kwargs):
if self.run_info is not None:
- assert self.run_info[
- "run_completed"
- ], f"You must run the extension {self.extension_name} before retrieving data"
+ assert self.run_info["run_completed"], (
+ f"You must run the extension {self.extension_name} before retrieving data"
+ )
assert len(self.data) > 0, "Extension has been run but no data found."
return self._get_data(*args, **kwargs)
diff --git a/src/spikeinterface/core/sortingfolder.py b/src/spikeinterface/core/sortingfolder.py
index 8879e8e2fc..3c05f52599 100644
--- a/src/spikeinterface/core/sortingfolder.py
+++ b/src/spikeinterface/core/sortingfolder.py
@@ -96,7 +96,7 @@ def write_sorting(
# All properties, annotations, and probe information are already saved in the folder,
# so we don't need to include them in the si_folder.json
cached = NumpyFolderSorting(folder_path=folder_path, mmap_mode=mmap_mode)
- si_folder_path = folder_path / f"si_folder.json"
+ si_folder_path = folder_path / "si_folder.json"
cached.dump_to_json(
file_path=si_folder_path,
relative_to=folder_path,
@@ -176,7 +176,7 @@ def write_sorting(sorting, save_path):
# make the si_folder file to make the load() easier
cached = NpzFolderSorting(folder_path=save_path)
cached._annotations = deepcopy({k: sorting._annotations[k] for k in sorting._annotations.keys()})
- si_folder_path = save_path / f"si_folder.json"
+ si_folder_path = save_path / "si_folder.json"
cached.dump_to_json(file_path=si_folder_path, relative_to=save_path, include_extra_metadata=False)
return cached
diff --git a/src/spikeinterface/core/sparsity.py b/src/spikeinterface/core/sparsity.py
index 9863dfbb77..c109db5cd9 100644
--- a/src/spikeinterface/core/sparsity.py
+++ b/src/spikeinterface/core/sparsity.py
@@ -4,9 +4,7 @@
from .basesorting import BaseSorting
from .baserecording import BaseRecording
-from .sorting_tools import random_spikes_selection
from .job_tools import _shared_job_kwargs_doc
-from .waveform_tools import estimate_templates_with_accumulator
from .core_tools import ms_to_samples
_sparsity_doc = """
@@ -475,9 +473,9 @@ def from_snr(
from .sortinganalyzer import SortingAnalyzer
from .template import Templates
- assert (
- templates_or_sorting_analyzer.sparsity is None
- ), "To compute sparsity you need a dense SortingAnalyzer or Templates"
+ assert templates_or_sorting_analyzer.sparsity is None, (
+ "To compute sparsity you need a dense SortingAnalyzer or Templates"
+ )
unit_ids = templates_or_sorting_analyzer.unit_ids
channel_ids = templates_or_sorting_analyzer.channel_ids
@@ -526,9 +524,9 @@ def from_amplitude(cls, templates_or_sorting_analyzer, threshold, amplitude_mode
from .sortinganalyzer import SortingAnalyzer
from .template import Templates
- assert (
- templates_or_sorting_analyzer.sparsity is None
- ), "To compute sparsity you need a dense SortingAnalyzer or Templates"
+ assert templates_or_sorting_analyzer.sparsity is None, (
+ "To compute sparsity you need a dense SortingAnalyzer or Templates"
+ )
unit_ids = templates_or_sorting_analyzer.unit_ids
channel_ids = templates_or_sorting_analyzer.channel_ids
@@ -625,9 +623,9 @@ def from_property(cls, sorting, recording, by_property):
rec_by = recording.split_by(by_property)
for unit_ind, unit_id in enumerate(sorting.unit_ids):
unit_property = sorting.get_property(by_property)[unit_ind]
- assert (
- unit_property in rec_by.keys()
- ), f"Unit property {unit_property} cannot be found in the recording properties"
+ assert unit_property in rec_by.keys(), (
+ f"Unit property {unit_property} cannot be found in the recording properties"
+ )
chan_inds = recording.ids_to_indices(rec_by[unit_property].get_channel_ids())
mask[unit_ind, chan_inds] = True
return cls(mask, sorting.unit_ids, recording.channel_ids)
@@ -698,26 +696,26 @@ def compute_sparsity(
"snr",
"amplitude",
):
- assert isinstance(
- templates_or_sorting_analyzer, (Templates, SortingAnalyzer)
- ), f"compute_sparsity(method='{method}') need Templates or SortingAnalyzer"
+ assert isinstance(templates_or_sorting_analyzer, (Templates, SortingAnalyzer)), (
+ f"compute_sparsity(method='{method}') need Templates or SortingAnalyzer"
+ )
if isinstance(templates_or_sorting_analyzer, Templates):
- assert (
- peak_sign is not None
- ), "When using `compute_sparsity` with a Templates object, `peak_sign` must be specified."
- assert (
- amplitude_mode is not None
- ), "When using `compute_sparsity` with a Templates object, `amplitude_mode` must be specified."
+ assert peak_sign is not None, (
+ "When using `compute_sparsity` with a Templates object, `peak_sign` must be specified."
+ )
+ assert amplitude_mode is not None, (
+ "When using `compute_sparsity` with a Templates object, `amplitude_mode` must be specified."
+ )
else:
- assert isinstance(
- templates_or_sorting_analyzer, SortingAnalyzer
- ), f"compute_sparsity(method='{method}') need SortingAnalyzer"
- assert (
- peak_sign is None
- ), "When using `compute_sparsity` with an analyzer, `peak_sign` must be None. The `peak_sign is set when you create the analyzer."
- assert (
- amplitude_mode is None
- ), "When using `compute_sparsity` with an analyzer, `amplitude_mode` must be None. The `peak_mode` is set when you create the analyzer."
+ assert isinstance(templates_or_sorting_analyzer, SortingAnalyzer), (
+ f"compute_sparsity(method='{method}') need SortingAnalyzer"
+ )
+ assert peak_sign is None, (
+ "When using `compute_sparsity` with an analyzer, `peak_sign` must be None. The `peak_sign is set when you create the analyzer."
+ )
+ assert amplitude_mode is None, (
+ "When using `compute_sparsity` with an analyzer, `amplitude_mode` must be None. The `peak_mode` is set when you create the analyzer."
+ )
if method == "best_channels":
assert num_channels is not None, "For the 'best_channels' method, 'num_channels' needs to be given"
diff --git a/src/spikeinterface/core/template.py b/src/spikeinterface/core/template.py
index a170dd4e02..07462137c4 100644
--- a/src/spikeinterface/core/template.py
+++ b/src/spikeinterface/core/template.py
@@ -101,17 +101,17 @@ def __post_init__(self):
self.channel_ids = np.arange(self.num_channels)
else:
self.channel_ids = np.asarray(self.channel_ids)
- assert (
- len(self.channel_ids) == self.num_channels
- ), f"length of channel ids {len(self.channel_ids)} must be equal to the number of channels {self.num_channels}"
+ assert len(self.channel_ids) == self.num_channels, (
+ f"length of channel ids {len(self.channel_ids)} must be equal to the number of channels {self.num_channels}"
+ )
if self.unit_ids is None:
self.unit_ids = np.arange(self.num_units)
else:
self.unit_ids = np.asarray(self.unit_ids)
- assert (
- self.unit_ids.size == self.num_units
- ), f"length of units ids {self.unit_ids.size} must be equal to the number of units {self.num_units}"
+ assert self.unit_ids.size == self.num_units, (
+ f"length of units ids {self.unit_ids.size} must be equal to the number of units {self.num_units}"
+ )
if self.sparsity_mask is not None:
self.sparsity = ChannelSparsity(
diff --git a/src/spikeinterface/core/template_tools.py b/src/spikeinterface/core/template_tools.py
index 4b46b4689e..353a654806 100644
--- a/src/spikeinterface/core/template_tools.py
+++ b/src/spikeinterface/core/template_tools.py
@@ -129,9 +129,9 @@ def get_template_amplitudes(
"""
if isinstance(templates_or_sorting_analyzer, SortingAnalyzer):
- assert (
- peak_sign is None
- ), "get_template_amplitudes() peak_sign is now contained in SortingAnalyzer, should be None here"
+ assert peak_sign is None, (
+ "get_template_amplitudes() peak_sign is now contained in SortingAnalyzer, should be None here"
+ )
if peak_sign is None:
peak_sign = templates_or_sorting_analyzer.peak_sign
if peak_mode is None:
diff --git a/src/spikeinterface/core/testing.py b/src/spikeinterface/core/testing.py
index 6ad7458c37..ddea78d343 100644
--- a/src/spikeinterface/core/testing.py
+++ b/src/spikeinterface/core/testing.py
@@ -1,4 +1,3 @@
-import warnings
import numpy as np
from numpy.testing import assert_array_equal
from .baserecording import BaseRecording
@@ -117,7 +116,6 @@ def check_sortings_equal(
(None, max_spike_index - 30),
(30, max_spike_index - 30),
]:
-
slice1 = _slice_spikes(s1, start_frame, end_frame)
slice2 = _slice_spikes(s2, start_frame, end_frame)
assert np.array_equal(slice1, slice2)
diff --git a/src/spikeinterface/core/testing_tools.py b/src/spikeinterface/core/testing_tools.py
index 101dfaea46..82be0f58d6 100644
--- a/src/spikeinterface/core/testing_tools.py
+++ b/src/spikeinterface/core/testing_tools.py
@@ -1,7 +1,7 @@
import warnings
warnings.warn(
- "The 'testing_tools' submodule is deprecated. " "Use spikeinterface.core.generate instead",
+ "The 'testing_tools' submodule is deprecated. Use spikeinterface.core.generate instead",
FutureWarning,
stacklevel=2,
)
diff --git a/src/spikeinterface/core/tests/test_analyzer_extension_core.py b/src/spikeinterface/core/tests/test_analyzer_extension_core.py
index 6423ce11ce..030f4f50b3 100644
--- a/src/spikeinterface/core/tests/test_analyzer_extension_core.py
+++ b/src/spikeinterface/core/tests/test_analyzer_extension_core.py
@@ -40,7 +40,7 @@ def get_sorting_analyzer(cache_folder, format="memory", sparse=True):
elif format == "binary_folder":
folder = cache_folder / f"test_ComputeWaveforms_{format}"
elif format == "zarr":
- folder = cache_folder / f"test_ComputeWaveforms.zarr"
+ folder = cache_folder / "test_ComputeWaveforms.zarr"
if folder and folder.exists():
shutil.rmtree(folder)
@@ -66,12 +66,13 @@ def _check_result_extension(sorting_analyzer, extension_name, cache_folder):
folder = None
# check unit slice
+ original_data = sorting_analyzer.get_extension(extension_name).data
keep_unit_ids = sorting_analyzer.sorting.unit_ids[::2]
sorting_analyzer2 = sorting_analyzer.select_units(unit_ids=keep_unit_ids, format=format, folder=folder)
data = sorting_analyzer2.get_extension(extension_name).data
- # for k, arr in data.items():
- # print(k, arr.shape)
+ for k in original_data:
+ assert k in data
@pytest.mark.parametrize("format", ["memory", "binary_folder", "zarr"])
@@ -112,8 +113,7 @@ def test_ComputeWaveforms(format, sparse, create_cache_folder):
job_kwargs = dict(n_jobs=2, chunk_duration="1s", progress_bar=True)
sorting_analyzer.compute("random_spikes", max_spikes_per_unit=50, seed=2205)
- ext = sorting_analyzer.compute("waveforms", **job_kwargs)
- wfs = ext.data["waveforms"]
+ _ = sorting_analyzer.compute("waveforms", **job_kwargs)
_check_result_extension(sorting_analyzer, "waveforms", cache_folder)
@@ -212,8 +212,10 @@ def test_ComputeTemplates(format, sparse, create_cache_folder):
# ask for more operator later
temp_ext = sorting_analyzer.get_extension("templates")
- templated_median = temp_ext.get_templates(operator="median")
+ template_median = temp_ext.get_templates(operator="median")
+ assert template_median is not None
templated_per_5 = temp_ext.get_templates(operator="percentile", percentile=5.0)
+ assert templated_per_5 is not None
# they all should be in data
data = sorting_analyzer.get_extension("templates").data
diff --git a/src/spikeinterface/core/tests/test_base.py b/src/spikeinterface/core/tests/test_base.py
index c81d24963c..57a50eb940 100644
--- a/src/spikeinterface/core/tests/test_base.py
+++ b/src/spikeinterface/core/tests/test_base.py
@@ -94,7 +94,7 @@ def test_name_and_repr():
assert "MyRecording" not in str(test_recording2)
assert test_recording2.__class__.__name__ in str(test_recording2)
# above 10khz, sampling frequency is printed in kHz
- assert f"kHz" in rec_str
+ assert "kHz" in rec_str
# below 10khz sampling frequency is printed in Hz
test_rec_low_fs = generate_recording(seed=0, durations=[2], sampling_frequency=5000)
rec_str = str(test_rec_low_fs)
diff --git a/src/spikeinterface/core/tests/test_baserecording.py b/src/spikeinterface/core/tests/test_baserecording.py
index d5aa3c154b..5fa0948a49 100644
--- a/src/spikeinterface/core/tests/test_baserecording.py
+++ b/src/spikeinterface/core/tests/test_baserecording.py
@@ -11,12 +11,11 @@
import numpy as np
from numpy.testing import assert_raises
-from probeinterface import Probe, ProbeGroup, generate_linear_probe
+from probeinterface import Probe
from spikeinterface.core import (
BinaryRecordingExtractor,
NumpyRecording,
- load,
get_default_zarr_compressor,
load,
)
diff --git a/src/spikeinterface/core/tests/test_basesorting.py b/src/spikeinterface/core/tests/test_basesorting.py
index 554d145c4c..cf71afdd88 100644
--- a/src/spikeinterface/core/tests/test_basesorting.py
+++ b/src/spikeinterface/core/tests/test_basesorting.py
@@ -20,7 +20,6 @@
generate_recording,
generate_sorting,
create_sorting_npz,
- generate_sorting,
load,
)
from spikeinterface.core.base import BaseExtractor, minimum_spike_dtype, unit_period_dtype
@@ -133,9 +132,14 @@ def test_BaseSorting(create_cache_folder):
)
assert np.array_equal(spikes[order], ordered_spikes)
- num_spikes_per_unit = sorting.count_num_spikes_per_unit(outputs="dict")
+ num_spikes_per_unit_dict = sorting.count_num_spikes_per_unit(outputs="dict")
+ assert isinstance(num_spikes_per_unit_dict, dict)
+ assert all(unit in num_spikes_per_unit_dict for unit in sorting.unit_ids)
num_spikes_per_unit = sorting.count_num_spikes_per_unit(outputs="array")
+ assert isinstance(num_spikes_per_unit, np.ndarray)
+ assert num_spikes_per_unit.size == sorting.unit_ids.size
total_spikes = sorting.count_total_num_spikes()
+ assert total_spikes == num_spikes_per_unit.sum()
# select units
keep_units = [0, 1]
diff --git a/src/spikeinterface/core/tests/test_binaryfolder.py b/src/spikeinterface/core/tests/test_binaryfolder.py
index 8272a7e29d..7fefc68bdf 100644
--- a/src/spikeinterface/core/tests/test_binaryfolder.py
+++ b/src/spikeinterface/core/tests/test_binaryfolder.py
@@ -1,9 +1,7 @@
import pytest
import json
-from pathlib import Path
import shutil
-
import numpy as np
from spikeinterface.core import load
diff --git a/src/spikeinterface/core/tests/test_binaryrecordingextractor.py b/src/spikeinterface/core/tests/test_binaryrecordingextractor.py
index 853271066c..869b4a34da 100644
--- a/src/spikeinterface/core/tests/test_binaryrecordingextractor.py
+++ b/src/spikeinterface/core/tests/test_binaryrecordingextractor.py
@@ -6,7 +6,6 @@
from spikeinterface.core import BinaryRecordingExtractor, MockRecording
from spikeinterface.core.base import BaseExtractor
from spikeinterface.core.numpyextractors import NumpyRecording
-from spikeinterface.core.core_tools import measure_memory_allocation
def test_BinaryRecordingExtractor(create_cache_folder):
diff --git a/src/spikeinterface/core/tests/test_channelsaggregationrecording.py b/src/spikeinterface/core/tests/test_channelsaggregationrecording.py
index 4702acca93..a851925724 100644
--- a/src/spikeinterface/core/tests/test_channelsaggregationrecording.py
+++ b/src/spikeinterface/core/tests/test_channelsaggregationrecording.py
@@ -40,7 +40,6 @@ def test_channelsaggregationrecording():
]
for recordings_list in recordings_list_possibilities:
-
# test num channels
recording_agg = aggregate_channels(recordings_list)
assert len(recording_agg.get_channel_ids()) == 3 * num_channels
diff --git a/src/spikeinterface/core/tests/test_channelslicerecording.py b/src/spikeinterface/core/tests/test_channelslicerecording.py
index 0f8247e85e..1756c022a6 100644
--- a/src/spikeinterface/core/tests/test_channelslicerecording.py
+++ b/src/spikeinterface/core/tests/test_channelslicerecording.py
@@ -75,7 +75,7 @@ def test_failure_with_non_unique_channel_ids():
seed = 10
rec = generate_recording(num_channels=4, durations=durations, set_probe=False, seed=seed)
with pytest.raises(AssertionError):
- rec_sliced = ChannelSliceRecording(rec, channel_ids=["0", "1"], renamed_channel_ids=[0, 0])
+ _ = ChannelSliceRecording(rec, channel_ids=["0", "1"], renamed_channel_ids=[0, 0])
def test_remove_channels():
diff --git a/src/spikeinterface/core/tests/test_core_tools.py b/src/spikeinterface/core/tests/test_core_tools.py
index 5c2a3b085c..443a262a6d 100644
--- a/src/spikeinterface/core/tests/test_core_tools.py
+++ b/src/spikeinterface/core/tests/test_core_tools.py
@@ -1,6 +1,5 @@
import platform
import math
-from pathlib import Path
import pytest
import numpy as np
diff --git a/src/spikeinterface/core/tests/test_frameslicerecording.py b/src/spikeinterface/core/tests/test_frameslicerecording.py
index fa0b76862d..248e930b35 100644
--- a/src/spikeinterface/core/tests/test_frameslicerecording.py
+++ b/src/spikeinterface/core/tests/test_frameslicerecording.py
@@ -1,7 +1,6 @@
-import pytest
import numpy as np
-from spikeinterface.core import FrameSliceRecording, NumpyRecording
+from spikeinterface.core import NumpyRecording
def test_FrameSliceRecording():
diff --git a/src/spikeinterface/core/tests/test_generate.py b/src/spikeinterface/core/tests/test_generate.py
index 66f84a2914..d1360473dc 100644
--- a/src/spikeinterface/core/tests/test_generate.py
+++ b/src/spikeinterface/core/tests/test_generate.py
@@ -33,16 +33,6 @@
strategy_list = ["tile_pregenerated", "on_the_fly"]
-def test_generate_recording():
- # TODO even this is extensively tested in all other functions
- pass
-
-
-def test_generate_sorting():
- # TODO even this is extensively tested in all other functions
- pass
-
-
def test_generate_sorting_with_spikes_on_borders():
num_spikes_on_borders = 10
border_size_samples = 10
@@ -108,7 +98,7 @@ def test_memory_sorting_generator():
seed = 0
before_instanciation_MiB = measure_memory_allocation() / bytes_to_MiB_factor
- sorting = SortingGenerator(
+ _ = SortingGenerator(
num_units=num_units,
sampling_frequency=sampling_frequency,
durations=durations,
@@ -118,9 +108,9 @@ def test_memory_sorting_generator():
memory_usage_MiB = after_instanciation_MiB - before_instanciation_MiB
ratio = memory_usage_MiB / before_instanciation_MiB
expected_allocation_MiB = 0
- assert (
- ratio <= 1.0 + relative_tolerance
- ), f"SortingGenerator wrong memory {memory_usage_MiB} instead of {expected_allocation_MiB}"
+ assert ratio <= 1.0 + relative_tolerance, (
+ f"SortingGenerator wrong memory {memory_usage_MiB} instead of {expected_allocation_MiB}"
+ )
def test_sorting_generator_consisency_across_calls():
@@ -175,11 +165,10 @@ def test_noise_generator_memory():
dtype = np.dtype("float32")
num_channels = 384
seed = 0
- num_samples = int(durations[0] * sampling_frequency)
# case 1 preallocation of noise use one noise block 88M for 60000 sample of 384
before_instanciation_MiB = measure_memory_allocation() / bytes_to_MiB_factor
- rec1 = MockRecording(
+ _ = MockRecording(
num_channels=num_channels,
sampling_frequency=sampling_frequency,
durations=durations,
@@ -192,13 +181,13 @@ def test_noise_generator_memory():
memory_usage_MiB = after_instanciation_MiB - before_instanciation_MiB
expected_allocation_MiB = dtype.itemsize * num_channels * noise_block_size / bytes_to_MiB_factor
ratio = expected_allocation_MiB / expected_allocation_MiB
- assert (
- ratio <= 1.0 + relative_tolerance
- ), f"MockRecording with 'tile_pregenerated' wrong memory {memory_usage_MiB} instead of {expected_allocation_MiB}"
+ assert ratio <= 1.0 + relative_tolerance, (
+ f"MockRecording with 'tile_pregenerated' wrong memory {memory_usage_MiB} instead of {expected_allocation_MiB}"
+ )
# case 2: no preallocation very few memory (under 2 MiB)
before_instanciation_MiB = measure_memory_allocation() / bytes_to_MiB_factor
- rec2 = MockRecording(
+ _ = MockRecording(
num_channels=num_channels,
sampling_frequency=sampling_frequency,
durations=durations,
@@ -370,17 +359,12 @@ def test_noise_generator_consistency_after_dump(strategy, seed):
assert np.allclose(traces0, traces1)
-def test_generate_recording():
- # check the high level function
- rec = generate_recording()
-
-
def test_generate_single_fake_waveform():
sampling_frequency = 30000.0
ms_before = 1.0
ms_after = 3.0
wf = generate_single_fake_waveform(ms_before=ms_before, ms_after=ms_after, sampling_frequency=sampling_frequency)
-
+ assert wf.shape == (int((ms_before + ms_after) / 1000 * sampling_frequency),)
# import matplotlib.pyplot as plt
# times = np.arange(wf.size) / sampling_frequency * 1000 - ms_before
# fig, ax = plt.subplots()
diff --git a/src/spikeinterface/core/tests/test_jsonification.py b/src/spikeinterface/core/tests/test_jsonification.py
index 316dac3abc..9850156829 100644
--- a/src/spikeinterface/core/tests/test_jsonification.py
+++ b/src/spikeinterface/core/tests/test_jsonification.py
@@ -7,8 +7,6 @@
from spikeinterface.core.core_tools import SIJsonEncoder
from spikeinterface.core.generate import generate_recording, generate_sorting
-from pathlib import Path
-
@pytest.fixture(scope="module")
def numpy_generated_sorting():
diff --git a/src/spikeinterface/core/tests/test_loading.py b/src/spikeinterface/core/tests/test_loading.py
index 8d57a3412f..340a44674b 100644
--- a/src/spikeinterface/core/tests/test_loading.py
+++ b/src/spikeinterface/core/tests/test_loading.py
@@ -1,5 +1,6 @@
import pytest
import zarr
+import importlib.util
import numpy as np
from spikeinterface import (
@@ -16,13 +17,13 @@
from spikeinterface.core.testing import check_recordings_equal, check_sortings_equal
from spikeinterface.core.zarrextractors import ZarrRecordingExtractor
-try:
- import s3fs
+if importlib.util.find_spec("s3fs") is not None:
HAVE_S3 = True
-except ImportError:
+else:
HAVE_S3 = False
+
computed_extensions = ["waveforms", "templates", "noise_levels", "random_spikes"]
diff --git a/src/spikeinterface/core/tests/test_motion_core.py b/src/spikeinterface/core/tests/test_motion_core.py
index 28d1ef7385..506d2c1e79 100644
--- a/src/spikeinterface/core/tests/test_motion_core.py
+++ b/src/spikeinterface/core/tests/test_motion_core.py
@@ -1,5 +1,4 @@
import pickle
-import shutil
import numpy as np
from spikeinterface.core.motion import Motion
diff --git a/src/spikeinterface/core/tests/test_node_pipeline.py b/src/spikeinterface/core/tests/test_node_pipeline.py
index a721fc3367..7ff3fae682 100644
--- a/src/spikeinterface/core/tests/test_node_pipeline.py
+++ b/src/spikeinterface/core/tests/test_node_pipeline.py
@@ -1,6 +1,5 @@
import pytest
import numpy as np
-from pathlib import Path
import shutil
from spikeinterface import create_sorting_analyzer, generate_ground_truth_recording
@@ -75,8 +74,6 @@ def test_run_node_pipeline(cache_folder_creation):
# job_kwargs = dict(chunk_duration="0.5s", n_jobs=2, progress_bar=False)
job_kwargs = dict(chunk_duration="0.5s", n_jobs=1, progress_bar=False)
- spikes = sorting.to_spike_vector()
-
# create peaks from spikes
sorting_analyzer = create_sorting_analyzer(sorting, recording, format="memory")
sorting_analyzer.compute(["random_spikes", "templates"], **job_kwargs)
@@ -269,6 +266,7 @@ def test_run_node_pipeline(cache_folder_creation):
pickled_node = pickle.dumps(node)
unpickled_node = pickle.loads(pickled_node)
+ assert isinstance(unpickled_node, type(node))
def test_gather_to_zarr_chunking(tmp_path):
diff --git a/src/spikeinterface/core/tests/test_noise_levels_propagation.py b/src/spikeinterface/core/tests/test_noise_levels_propagation.py
index 98e7a929fd..d553348d51 100644
--- a/src/spikeinterface/core/tests/test_noise_levels_propagation.py
+++ b/src/spikeinterface/core/tests/test_noise_levels_propagation.py
@@ -1,18 +1,14 @@
-import pytest
from pathlib import Path
-import shutil
-from spikeinterface import set_global_tmp_folder, get_noise_levels
-from spikeinterface.core import generate_recording, concatenate_recordings, aggregate_channels
-
-import numpy as np
+from spikeinterface import get_noise_levels
+from spikeinterface.core import generate_recording, concatenate_recordings
def test_skip_noise_levels_propagation(create_cache_folder):
rec = generate_recording(durations=[5.0], num_channels=4)
rec.set_property("test", ["1", "2", "3", "4"])
rec = rec.save(folder=create_cache_folder / "rec_saved_noise")
- noise_level_raw = get_noise_levels(rec, return_in_uV=False, method="mad")
+ _ = get_noise_levels(rec, return_in_uV=False, method="mad")
assert "noise_level_mad_raw" in rec.get_property_keys()
rec_frame_slice = rec.frame_slice(start_frame=0, end_frame=1000)
@@ -22,7 +18,7 @@ def test_skip_noise_levels_propagation(create_cache_folder):
# make scaled
rec.set_channel_gains([100] * 4)
rec.set_channel_offsets([0] * 4)
- noise_level_scaled = get_noise_levels(rec, return_in_uV=True, method="std")
+ _ = get_noise_levels(rec, return_in_uV=True, method="std")
assert "noise_level_std_scaled" in rec.get_property_keys()
rec_frame_slice = rec.frame_slice(start_frame=0, end_frame=1000)
diff --git a/src/spikeinterface/core/tests/test_npzsortingextractor.py b/src/spikeinterface/core/tests/test_npzsortingextractor.py
index 4d84ee9a4d..90a8061bb8 100644
--- a/src/spikeinterface/core/tests/test_npzsortingextractor.py
+++ b/src/spikeinterface/core/tests/test_npzsortingextractor.py
@@ -1,8 +1,6 @@
-import pytest
-from pathlib import Path
-
from spikeinterface.core import NpzSortingExtractor
from spikeinterface.core import create_sorting_npz
+from spikeinterface.core.testing import check_sortings_equal
def test_NpzSortingExtractor(create_cache_folder):
@@ -16,12 +14,9 @@ def test_NpzSortingExtractor(create_cache_folder):
for segment_index in range(num_seg):
for unit_id in (0, 1, 2):
- st = sorting.get_unit_spike_train(unit_id, segment_index=segment_index)
+ _ = sorting.get_unit_spike_train(unit_id, segment_index=segment_index)
file_path_copy = cache_folder / "test_NpzSortingExtractor_copy.npz"
NpzSortingExtractor.write_sorting(sorting, file_path_copy)
sorting_copy = NpzSortingExtractor(file_path_copy)
-
-
-if __name__ == "__main__":
- test_NpzSortingExtractor()
+ check_sortings_equal(sorting, sorting_copy)
diff --git a/src/spikeinterface/core/tests/test_numpy_extractors.py b/src/spikeinterface/core/tests/test_numpy_extractors.py
index 8ccbaf2a4d..25f5bb063c 100644
--- a/src/spikeinterface/core/tests/test_numpy_extractors.py
+++ b/src/spikeinterface/core/tests/test_numpy_extractors.py
@@ -27,8 +27,6 @@ def setup_NumpyRecording(tmp_path_factory):
rec = NumpyRecording(timeseries_list, sampling_frequency)
# print(rec)
-
- times1 = rec.get_times(1)
cache_folder = tmp_path_factory.mktemp("cache_folder")
rec.save(folder=cache_folder / "test_NumpyRecording")
return cache_folder
diff --git a/src/spikeinterface/core/tests/test_read_python_safe.py b/src/spikeinterface/core/tests/test_read_python_safe.py
index 63d9a7d73f..1ad8f81861 100644
--- a/src/spikeinterface/core/tests/test_read_python_safe.py
+++ b/src/spikeinterface/core/tests/test_read_python_safe.py
@@ -6,7 +6,6 @@
Run: pytest test_read_python_safe.py -v
"""
-import os
import re
import inspect
from spikeinterface.core.core_tools import read_python
@@ -15,9 +14,7 @@
def test_read_python_does_not_execute_config(tmp_path):
marker = tmp_path / "pwned.txt"
p = tmp_path / "params.py"
- p.write_text(
- "sample_rate = 30000\n" "dtype = 'int16'\n" "import os\n" f"os.system('echo x> {marker.as_posix()}')\n"
- )
+ p.write_text(f"sample_rate = 30000\ndtype = 'int16'\nimport os\nos.system('echo x> {marker.as_posix()}')\n")
md = read_python(str(p))
assert not marker.exists(), "read_python executed code from the config file (CWE-95)"
assert md.get("sample_rate") == 30000 # literal assignments still parse
diff --git a/src/spikeinterface/core/tests/test_recording_tools.py b/src/spikeinterface/core/tests/test_recording_tools.py
index 13d68e3b45..0166c3bfdd 100644
--- a/src/spikeinterface/core/tests/test_recording_tools.py
+++ b/src/spikeinterface/core/tests/test_recording_tools.py
@@ -1,5 +1,3 @@
-from pathlib import Path
-import platform
import numpy as np
from spikeinterface.core import NumpyRecording, generate_recording, MockRecording
@@ -13,7 +11,6 @@
get_random_data_chunks,
get_chunk_with_margin,
get_closest_channels,
- get_channel_distances,
get_noise_levels,
order_channels_by_depth,
do_recording_attributes_match,
@@ -176,8 +173,6 @@ def test_get_closest_channels():
closest_channels_inds, distances = get_closest_channels(rec)
closest_channels_inds, distances = get_closest_channels(rec, num_channels=4)
- dist = get_channel_distances(rec)
-
def test_get_noise_levels():
job_kwargs = dict(n_jobs=1, progress_bar=True)
@@ -188,9 +183,8 @@ def test_get_noise_levels():
rec.set_channel_gains(0.1)
rec.set_channel_offsets(0)
- noise_levels = get_noise_levels(rec, return_in_uV=True, force_recompute=True, **job_kwargs)
-
- noise_levels = get_noise_levels(rec, return_in_uV=True, method="std", **job_kwargs)
+ _ = get_noise_levels(rec, return_in_uV=True, force_recompute=True, **job_kwargs)
+ _ = get_noise_levels(rec, return_in_uV=True, method="std", **job_kwargs)
# Generate a recording following a gaussian distribution to check the result of get_noise.
std = 6.0
@@ -302,10 +296,9 @@ def test_order_channels_by_depth():
locations_copy = locations_copy[::-1]
rec.set_channel_locations(locations_copy)
- order_1d, order_r1d = order_channels_by_depth(rec, dimensions="y")
+ order_1d, _ = order_channels_by_depth(rec, dimensions="y")
order_2d, order_r2d = order_channels_by_depth(rec, dimensions=("x", "y"))
- locations_rev = locations_copy[order_1d][order_r1d]
- order_2d_fliped, order_r2d_fliped = order_channels_by_depth(rec, dimensions=("x", "y"), flip=True)
+ order_2d_fliped, _ = order_channels_by_depth(rec, dimensions=("x", "y"), flip=True)
assert np.array_equal(locations[:, 1], locations_copy[order_1d][:, 1])
assert np.array_equal(locations_copy[order_1d][:, 1], locations_copy[order_2d][:, 1])
diff --git a/src/spikeinterface/core/tests/test_segmentutils.py b/src/spikeinterface/core/tests/test_segmentutils.py
index e2c22fc24c..9e0b82377e 100644
--- a/src/spikeinterface/core/tests/test_segmentutils.py
+++ b/src/spikeinterface/core/tests/test_segmentutils.py
@@ -1,7 +1,6 @@
import warnings
import numpy as np
-import pytest
from numpy.testing import assert_raises
from spikeinterface.core import (
@@ -13,9 +12,7 @@
concatenate_sortings,
select_segment_recording,
split_recording,
- split_sorting,
)
-from spikeinterface.core.testing import check_sorted_arrays_equal
def test_append_concatenate_recordings():
diff --git a/src/spikeinterface/core/tests/test_sorting_folder.py b/src/spikeinterface/core/tests/test_sorting_folder.py
index 8d78a89ebd..5da96a5758 100644
--- a/src/spikeinterface/core/tests/test_sorting_folder.py
+++ b/src/spikeinterface/core/tests/test_sorting_folder.py
@@ -1,11 +1,10 @@
-import pytest
import shutil
import numpy as np
from spikeinterface.core import NpzFolderSorting, NumpyFolderSorting
from spikeinterface.core import generate_sorting
-from spikeinterface.core.testing import check_sorted_arrays_equal, check_sortings_equal
+from spikeinterface.core.testing import check_sortings_equal
def test_NumpyFolderSorting(create_cache_folder):
diff --git a/src/spikeinterface/core/tests/test_sorting_tools.py b/src/spikeinterface/core/tests/test_sorting_tools.py
index 821b8b1631..1cb413c915 100644
--- a/src/spikeinterface/core/tests/test_sorting_tools.py
+++ b/src/spikeinterface/core/tests/test_sorting_tools.py
@@ -14,7 +14,6 @@
_get_ids_after_merging,
generate_unit_ids_for_merge_group,
remap_unit_indices_in_vector,
- set_properties_after_merging,
set_properties_after_splits,
reorder_spike_vector_by_unit_and_segment,
get_segment_durations,
@@ -192,7 +191,6 @@ def test_random_spikes_selection():
random_spikes_indices = random_spikes_selection(
sorting, num_samples, method="uniform", max_spikes_per_unit=max_spikes_per_unit, margin_size=None, seed=2205
)
- random_spikes_indices1 = random_spikes_indices
spikes = sorting.to_spike_vector()
some_spikes = spikes[random_spikes_indices]
for unit_index, unit_id in enumerate(sorting.unit_ids):
diff --git a/src/spikeinterface/core/tests/test_sortinganalyzer.py b/src/spikeinterface/core/tests/test_sortinganalyzer.py
index 50eb925444..ab01eca320 100644
--- a/src/spikeinterface/core/tests/test_sortinganalyzer.py
+++ b/src/spikeinterface/core/tests/test_sortinganalyzer.py
@@ -641,12 +641,14 @@ def test_extension_params():
assert ext in computable_extension
if mod == "spikeinterface.core":
default_params = get_default_analyzer_extension_params(ext)
+ assert default_params is not None
# print(ext, default_params)
else:
try:
default_params = get_default_analyzer_extension_params(ext)
+ assert default_params is not None
# print(ext, default_params)
- except:
+ except Exception:
print(f"Failed to import {ext}")
@@ -1130,7 +1132,6 @@ def test_select_channels_sparse_waveforms_templates(dataset):
selected_waveforms = analyzer_selected.get_extension("waveforms")
for unit_index, unit_id in enumerate(sorting_analyzer.unit_ids):
-
original_units_to_channels = sorting_analyzer.sparsity.unit_id_to_channel_ids[unit_id]
selected_units_to_channels = analyzer_selected.sparsity.unit_id_to_channel_ids[unit_id]
@@ -1139,7 +1140,6 @@ def test_select_channels_sparse_waveforms_templates(dataset):
for channel_id in select_channel_ids:
if channel_id in original_units_to_channels:
-
# Check templates, which are dense
original_channel_index = original_id_index_map[channel_id]
selected_channel_index = selected_id_index_map[channel_id]
diff --git a/src/spikeinterface/core/tests/test_sparsity.py b/src/spikeinterface/core/tests/test_sparsity.py
index cc9da07387..99457d4686 100644
--- a/src/spikeinterface/core/tests/test_sparsity.py
+++ b/src/spikeinterface/core/tests/test_sparsity.py
@@ -299,10 +299,10 @@ def test_compute_sparsity():
# Check that we can still pass sparsity kwargs using the old signature (e.g. passing radius_um)
with pytest.warns(FutureWarning):
# radius_um is a sparsity kwarg
- sorting_analyzer_old_kwargs = create_sorting_analyzer(sorting=sorting, recording=recording, radius_um=50)
+ _ = create_sorting_analyzer(sorting=sorting, recording=recording, radius_um=50)
with pytest.warns(FutureWarning):
# n_jobs is a job kwarg
- sorting_analyzer_old_kwargs = create_sorting_analyzer(sorting=sorting, recording=recording, n_jobs=2)
+ _ = create_sorting_analyzer(sorting=sorting, recording=recording, n_jobs=2)
sorting_analyzer.compute("random_spikes")
sorting_analyzer.compute(
@@ -313,30 +313,24 @@ def test_compute_sparsity():
# this is needed for method="energy"
# using object SortingAnalyzer
- sparsity = compute_sparsity(sorting_analyzer, method="best_channels", num_channels=2)
- sparsity = compute_sparsity(sorting_analyzer, method="radius", radius_um=50.0)
- sparsity = compute_sparsity(sorting_analyzer, method="closest_channels", num_channels=2)
- sparsity = compute_sparsity(sorting_analyzer, method="snr", threshold=5)
- sparsity = compute_sparsity(sorting_analyzer, method="amplitude", threshold=5)
- sparsity = compute_sparsity(sorting_analyzer, method="energy", threshold=5)
- sparsity = compute_sparsity(sorting_analyzer, method="by_property", by_property="group")
+ _ = compute_sparsity(sorting_analyzer, method="best_channels", num_channels=2)
+ _ = compute_sparsity(sorting_analyzer, method="radius", radius_um=50.0)
+ _ = compute_sparsity(sorting_analyzer, method="closest_channels", num_channels=2)
+ _ = compute_sparsity(sorting_analyzer, method="snr", threshold=5)
+ _ = compute_sparsity(sorting_analyzer, method="amplitude", threshold=5)
+ _ = compute_sparsity(sorting_analyzer, method="energy", threshold=5)
+ _ = compute_sparsity(sorting_analyzer, method="by_property", by_property="group")
# using object Templates
templates = sorting_analyzer.get_extension("templates").get_data(outputs="Templates")
noise_levels = sorting_analyzer.get_extension("noise_levels").get_data()
- sparsity = compute_sparsity(
- templates, method="best_channels", num_channels=2, peak_sign="neg", amplitude_mode="extremum"
- )
- sparsity = compute_sparsity(
- templates, method="radius", radius_um=50.0, peak_sign="both", amplitude_mode="peak_to_peak"
- )
- sparsity = compute_sparsity(
+ _ = compute_sparsity(templates, method="best_channels", num_channels=2, peak_sign="neg", amplitude_mode="extremum")
+ _ = compute_sparsity(templates, method="radius", radius_um=50.0, peak_sign="both", amplitude_mode="peak_to_peak")
+ _ = compute_sparsity(
templates, method="snr", noise_levels=noise_levels, threshold=5, peak_sign="neg", amplitude_mode="extremum"
)
- sparsity = compute_sparsity(
- templates, method="amplitude", threshold=5, peak_sign="neg", amplitude_mode="peak_to_peak"
- )
- sparsity = compute_sparsity(
+ _ = compute_sparsity(templates, method="amplitude", threshold=5, peak_sign="neg", amplitude_mode="peak_to_peak")
+ _ = compute_sparsity(
templates, method="closest_channels", num_channels=2, peak_sign="neg", amplitude_mode="extremum"
)
diff --git a/src/spikeinterface/core/tests/test_template_class.py b/src/spikeinterface/core/tests/test_template_class.py
index 953527c8d5..b9b77bc6c7 100644
--- a/src/spikeinterface/core/tests/test_template_class.py
+++ b/src/spikeinterface/core/tests/test_template_class.py
@@ -112,7 +112,7 @@ def test_get_dense_templates(template_type, is_in_uV):
def test_initialization_fail_with_dense_templates():
with pytest.raises(ValueError, match="Sparsity mask passed but the templates are not sparse"):
- template = generate_test_template(template_type="sparse_with_dense_templates")
+ _ = generate_test_template(template_type="sparse_with_dense_templates")
@pytest.mark.parametrize("is_in_uV", [True, False])
diff --git a/src/spikeinterface/core/tests/test_time_handling.py b/src/spikeinterface/core/tests/test_time_handling.py
index 2f3cc1a6bf..eb872a6f4a 100644
--- a/src/spikeinterface/core/tests/test_time_handling.py
+++ b/src/spikeinterface/core/tests/test_time_handling.py
@@ -55,7 +55,6 @@ def _get_time_vector_recording(self, raw_recording):
times_recording = raw_recording.clone()
all_time_vectors = []
for segment_index in range(raw_recording.get_num_segments()):
-
t_start = segment_index + 1 * 100
t_stop = t_start + raw_recording.get_duration(segment_index) + segment_index + 1
@@ -80,7 +79,6 @@ def _get_t_start_recording(self, raw_recording):
all_t_starts = []
for segment_index in range(raw_recording.get_num_segments()):
-
t_start = (segment_index + 1) * 100
all_t_starts.append(t_start + t_start_recording.get_times(segment_index))
@@ -110,7 +108,6 @@ def test_has_time_vector(self, time_vector_recording):
raw_recording, times_recording, _ = time_vector_recording
for segment_idx in range(raw_recording.get_num_segments()):
-
assert raw_recording.has_time_vector(segment_idx) is False
assert times_recording.has_time_vector(segment_idx) is True
@@ -169,7 +166,6 @@ def test_times_propagated_to_sorting(self, request, fixture_name):
recording_for_durations=raw_recording, recording_to_attach=times_recording
)
for segment_index in range(raw_recording.get_num_segments()):
-
if fixture_name == "time_vector_recording":
assert sorting.has_time_vector(segment_index=segment_index)
@@ -187,7 +183,6 @@ def test_time_sample_converters(self, request, fixture_name):
assert "Provide 'segment_index'" in str(e)
for segment_index in range(times_recording.get_num_segments()):
-
sample_index = np.random.randint(low=0, high=times_recording.get_num_samples(segment_index))
time_ = times_recording.sample_index_to_time(sample_index, segment_index=segment_index)
@@ -258,7 +253,6 @@ def test_get_durations(self, time_vector_recording, t_start_recording):
all_raw_durations = []
all_vector_durations = []
for segment_index in range(raw_recording.get_num_segments()):
-
# Test before `t_start` and `t_start` (`t_start` is just an offset,
# should not affect duration).
raw_duration = all_t_starts[segment_index][-1] - all_t_starts[segment_index][0] + ts
@@ -342,7 +336,6 @@ def test_shift_times_different_segments(self, request, fixture_name, shift):
# For each segment, shift the segment only and check the
# times are updated as expected.
for idx in range(num_segments):
-
scaler = idx + 2
times_recording.shift_times(shift * scaler, segment_index=idx)
diff --git a/src/spikeinterface/core/tests/test_unitsaggregationsorting.py b/src/spikeinterface/core/tests/test_unitsaggregationsorting.py
index c04c66d60c..f648a25407 100644
--- a/src/spikeinterface/core/tests/test_unitsaggregationsorting.py
+++ b/src/spikeinterface/core/tests/test_unitsaggregationsorting.py
@@ -26,7 +26,6 @@ def test_unitsaggregationsorting_spiketrains():
# test spike trains
for segment_index in range(sorting1.get_num_segments()):
-
spiketrain1 = sorting1.get_unit_spike_train(unit_ids[1], segment_index=segment_index)
assert np.all(spiketrain1 == sorting_agg.get_unit_spike_train(unit_ids[1], segment_index=segment_index))
diff --git a/src/spikeinterface/core/tests/test_unitsselectionsorting.py b/src/spikeinterface/core/tests/test_unitsselectionsorting.py
index 890bc0a93e..d01f5d302b 100644
--- a/src/spikeinterface/core/tests/test_unitsselectionsorting.py
+++ b/src/spikeinterface/core/tests/test_unitsselectionsorting.py
@@ -42,7 +42,7 @@ def test_failure_with_non_unique_unit_ids():
seed = 10
sorting = generate_sorting(num_units=3, durations=[0.100], sampling_frequency=30000.0, seed=seed)
with pytest.raises(AssertionError):
- sorting2 = UnitsSelectionSorting(sorting, unit_ids=["0", "2"], renamed_unit_ids=["a", "a"])
+ _ = UnitsSelectionSorting(sorting, unit_ids=["0", "2"], renamed_unit_ids=["a", "a"])
def test_compute_and_cache_spike_vector():
diff --git a/src/spikeinterface/core/tests/test_waveform_tools.py b/src/spikeinterface/core/tests/test_waveform_tools.py
index 6623c92046..24784538ea 100644
--- a/src/spikeinterface/core/tests/test_waveform_tools.py
+++ b/src/spikeinterface/core/tests/test_waveform_tools.py
@@ -5,7 +5,7 @@
import numpy as np
-from spikeinterface.core import generate_recording, generate_sorting, generate_ground_truth_recording, ms_to_samples
+from spikeinterface.core import generate_recording, generate_ground_truth_recording, ms_to_samples
from spikeinterface.core.waveform_tools import (
extract_waveforms_to_buffers,
extract_waveforms_to_single_buffer,
diff --git a/src/spikeinterface/core/tests/test_waveforms_extractor_backwards_compatibility.py b/src/spikeinterface/core/tests/test_waveforms_extractor_backwards_compatibility.py
index efb3de7464..629778bfd1 100644
--- a/src/spikeinterface/core/tests/test_waveforms_extractor_backwards_compatibility.py
+++ b/src/spikeinterface/core/tests/test_waveforms_extractor_backwards_compatibility.py
@@ -61,17 +61,16 @@ def test_extract_waveforms(create_cache_folder):
print(we_mock)
for we in (we_old, we_mock):
-
- selected_spikes = we.get_sampled_indices(unit_id=sorting.unit_ids[0])
+ _ = we.get_sampled_indices(unit_id=sorting.unit_ids[0])
# print(selected_spikes.size, selected_spikes.dtype)
- wfs = we.get_waveforms(sorting.unit_ids[0])
+ _ = we.get_waveforms(sorting.unit_ids[0])
# print(wfs.shape)
- wfs = we.get_waveforms(sorting.unit_ids[0], force_dense=True)
+ _ = we.get_waveforms(sorting.unit_ids[0], force_dense=True)
# print(wfs.shape)
- templates = we.get_all_templates()
+ _ = we.get_all_templates()
# print(templates.shape)
# test reading old WaveformsExtractor folder
diff --git a/src/spikeinterface/core/time_series_tools.py b/src/spikeinterface/core/time_series_tools.py
index 5f10107677..bf94bfe82f 100644
--- a/src/spikeinterface/core/time_series_tools.py
+++ b/src/spikeinterface/core/time_series_tools.py
@@ -352,9 +352,9 @@ def _write_time_series_to_zarr(
assert dataset_paths is not None, "Provide 'dataset_paths' to save data in zarr format"
if dataset_timestamps_paths is not None:
- assert (
- len(dataset_timestamps_paths) == time_series.get_num_segments()
- ), "dataset_timestamps_paths should have the same length as the number of segments in the time_series"
+ assert len(dataset_timestamps_paths) == time_series.get_num_segments(), (
+ "dataset_timestamps_paths should have the same length as the number of segments in the time_series"
+ )
else:
dataset_timestamps_paths = [None] * time_series.get_num_segments()
@@ -425,8 +425,6 @@ def _write_time_series_to_zarr(
def _init_zarr_worker(time_series, zarr_datasets, dtype, buffer_megabytes, zarr_timestamps_datasets=None):
- import zarr
-
# create a local dict per worker
worker_ctx = {}
worker_ctx["time_series"] = time_series
diff --git a/src/spikeinterface/core/unitsaggregationsorting.py b/src/spikeinterface/core/unitsaggregationsorting.py
index 3f650cd802..f18c458743 100644
--- a/src/spikeinterface/core/unitsaggregationsorting.py
+++ b/src/spikeinterface/core/unitsaggregationsorting.py
@@ -38,7 +38,7 @@ def __init__(self, sorting_list, renamed_unit_ids=None, sampling_frequency_max_d
num_all_units = sum([sort.get_num_units() for sort in sorting_list])
if renamed_unit_ids is not None:
assert len(np.unique(renamed_unit_ids)) == num_all_units, (
- "'renamed_unit_ids' doesn't have the right size" "or has duplicates!"
+ "'renamed_unit_ids' doesn't have the right sizeor has duplicates!"
)
unit_ids = list(renamed_unit_ids)
else:
@@ -96,7 +96,6 @@ def __init__(self, sorting_list, renamed_unit_ids=None, sampling_frequency_max_d
# Check if all the sortings have the same properties
properties_set = set(np.concatenate([sorting.get_property_keys() for sorting in sorting_list]))
for prop_name in properties_set:
-
dtypes_per_sorting = []
for sort in sorting_list:
if prop_name in sort.get_property_keys():
@@ -110,7 +109,6 @@ def __init__(self, sorting_list, renamed_unit_ids=None, sampling_frequency_max_d
all_property_values = []
for sort in sorting_list:
-
# If one of the sortings doesn't have the property, use the default missing property value
if prop_name not in sort.get_property_keys():
try:
@@ -118,7 +116,7 @@ def __init__(self, sorting_list, renamed_unit_ids=None, sampling_frequency_max_d
sort.get_num_units(),
BaseExtractor.default_missing_property_values[dtypes_per_sorting[0]],
)
- except:
+ except Exception:
warnings.warn(f"Skipping property '{prop_name}: cannot inpute missing property values.'")
break
else:
diff --git a/src/spikeinterface/core/waveform_tools.py b/src/spikeinterface/core/waveform_tools.py
index a557c52ba6..d4ea6bc0db 100644
--- a/src/spikeinterface/core/waveform_tools.py
+++ b/src/spikeinterface/core/waveform_tools.py
@@ -10,12 +10,9 @@
"""
from pathlib import Path
-import warnings
import numpy as np
-from spikeinterface.core.baserecording import BaseRecording
-
from .baserecording import BaseRecording
from .job_tools import TimeSeriesChunkExecutor, _shared_job_kwargs_doc
from .core_tools import make_shared_array
@@ -367,7 +364,6 @@ def _worker_distribute_buffers(segment_index, start_frame, end_frame, worker_dic
num_samples = recording.get_num_samples(segment_index=segment_index)
if l1 > l0:
-
sub_spikes = in_seg_spikes[i0:i1]
start = sub_spikes[0]["sample_index"] - nbefore
end = sub_spikes[-1]["sample_index"] + nafter
@@ -1137,7 +1133,6 @@ def _init_worker_estimate_templates(
worker_dict["sparsity_mask"] = sparsity_mask
from multiprocessing.shared_memory import SharedMemory
- import multiprocessing
shm = SharedMemory(shm_name)
waveform_accumulator_per_worker = np.ndarray(shape=shape, dtype=dtype, buffer=shm.buf)
@@ -1204,7 +1199,6 @@ def _worker_estimate_templates(segment_index, start_frame, end_frame, worker_dic
unit_indices = sub_spikes["unit_index"]
for sample_index, unit_index in zip(sample_indices, unit_indices):
-
# sample_index < 0 only near the segment start, near the segment end wf is shorter
wf_start = max(0, -sample_index)
wf = traces[sample_index + wf_start : sample_index + offset, :]
@@ -1222,4 +1216,4 @@ def _worker_estimate_templates(segment_index, start_frame, end_frame, worker_dic
if waveform_squared_accumulator_per_worker is not None:
waveform_squared_accumulator_per_worker[
worker_index, unit_index, wf_start:wf_end, : wf.shape[1]
- ] += (wf**2)
+ ] += wf**2
diff --git a/src/spikeinterface/core/waveforms_extractor_backwards_compatibility.py b/src/spikeinterface/core/waveforms_extractor_backwards_compatibility.py
index 56f2177e70..178e6b4546 100644
--- a/src/spikeinterface/core/waveforms_extractor_backwards_compatibility.py
+++ b/src/spikeinterface/core/waveforms_extractor_backwards_compatibility.py
@@ -255,9 +255,9 @@ def get_sampled_indices(self, unit_id):
selected_spikes = []
for segment_index in range(self.get_num_segments()):
# inds = self.sorting_analyzer.get_selected_indices_in_spike_train(unit_id, segment_index)
- assert self.sorting_analyzer.has_extension(
- "random_spikes"
- ), "get_sampled_indices() requires the 'random_spikes' extension."
+ assert self.sorting_analyzer.has_extension("random_spikes"), (
+ "get_sampled_indices() requires the 'random_spikes' extension."
+ )
inds = self.sorting_analyzer.get_extension("random_spikes").get_selected_indices_in_spike_train(
unit_id, segment_index
)
@@ -281,9 +281,9 @@ def get_waveforms(
ext = self.sorting_analyzer.get_extension("waveforms")
unit_index = self.sorting.id_to_index(unit_id)
- assert self.sorting_analyzer.has_extension(
- "random_spikes"
- ), "get_sampled_indices() requires the 'random_spikes' extension."
+ assert self.sorting_analyzer.has_extension("random_spikes"), (
+ "get_sampled_indices() requires the 'random_spikes' extension."
+ )
some_spikes = self.sorting_analyzer.get_extension("random_spikes").get_random_spikes()
@@ -291,9 +291,9 @@ def get_waveforms(
wfs = ext.data["waveforms"][spike_mask, :, :]
if sparsity is not None:
- assert (
- self.sorting_analyzer.sparsity is None
- ), "Waveforms are alreayd sparse! Cannot apply an additional sparsity."
+ assert self.sorting_analyzer.sparsity is None, (
+ "Waveforms are alreayd sparse! Cannot apply an additional sparsity."
+ )
wfs = wfs[:, :, sparsity.mask[self.sorting.id_to_index(unit_id)]]
if force_dense:
@@ -475,12 +475,12 @@ def _read_old_waveforms_extractor_binary(folder, sorting):
if (folder / "recording.json").exists():
try:
recording = load(folder / "recording.json", base_folder=folder)
- except:
+ except Exception:
pass
elif (folder / "recording.pickle").exists():
try:
recording = load(folder / "recording.pickle", base_folder=folder)
- except:
+ except Exception:
pass
# sorting
@@ -505,7 +505,6 @@ def _read_old_waveforms_extractor_binary(folder, sorting):
# need to concatenate sampled_index and order it
waveform_folder = folder / "waveforms"
if waveform_folder.exists():
-
spikes = sorting.to_spike_vector()
random_spike_mask = np.zeros(spikes.size, dtype="bool")
@@ -686,7 +685,7 @@ def make_ext_params_up_to_date(ext, old_params, new_params):
# try:
# recording_dict = waveforms_root.attrs["recording"]
# recording = load(recording_dict, base_folder=folder)
-# except:
+# except Exception:
# pass
# # sorting
diff --git a/src/spikeinterface/core/zarr_tools.py b/src/spikeinterface/core/zarr_tools.py
index 41ff57a358..a12c4ceec2 100644
--- a/src/spikeinterface/core/zarr_tools.py
+++ b/src/spikeinterface/core/zarr_tools.py
@@ -61,9 +61,9 @@ def adjust_chunks_shards_and_job_kwargs(
if shards is not None:
assert len(shards) == len(chunks), "Shards and chunks must have the same number of dimensions"
for dim in range(len(chunks)):
- assert (
- shards[dim] >= chunks[dim] and shards[dim] % chunks[dim] == 0
- ), "Shard size must be a multiple of chunk size"
+ assert shards[dim] >= chunks[dim] and shards[dim] % chunks[dim] == 0, (
+ "Shard size must be a multiple of chunk size"
+ )
# When sharding is used, chunk_size in job_kwargs is used to determine the number of samples per chunk to
# write in each job. Each process will write all chunks in a shard.
job_kwargs["chunk_size"] = shards[0]
diff --git a/src/spikeinterface/core/zarrextractors.py b/src/spikeinterface/core/zarrextractors.py
index 2889a47a83..9f06b80e3e 100644
--- a/src/spikeinterface/core/zarrextractors.py
+++ b/src/spikeinterface/core/zarrextractors.py
@@ -13,7 +13,6 @@
from .core_tools import (
define_function_from_class,
check_json,
- is_path_remote,
retrieve_importing_provenance,
is_path_remote,
)
@@ -165,9 +164,9 @@ def __init__(
cr_by_segment = {}
for segment_index in range(num_segments):
trace_name = f"traces_seg{segment_index}"
- assert (
- len(channel_ids) == self._root[trace_name].shape[1]
- ), f"Segment {segment_index} has the wrong number of channels!"
+ assert len(channel_ids) == self._root[trace_name].shape[1], (
+ f"Segment {segment_index} has the wrong number of channels!"
+ )
time_kwargs = {}
time_vector = self._root.get(f"times_seg{segment_index}", None)
@@ -944,7 +943,7 @@ def add_recording_to_zarr_group(
channel_ids = recording.channel_ids
if channel_ids.dtype.kind in ("U", "S"):
channel_ids = channel_ids.astype("T")
- arr = zarr_group.create_array(name="channel_ids", data=channel_ids, compressors=None)
+ _ = zarr_group.create_array(name="channel_ids", data=channel_ids, compressors=None)
dataset_paths = [f"traces_seg{i}" for i in range(recording.get_num_segments())]
dataset_timestamps_paths: list | None = None
if any(recording.has_time_vector(i) for i in range(recording.get_num_segments())):
diff --git a/src/spikeinterface/curation/auto_merge.py b/src/spikeinterface/curation/auto_merge.py
index a31b841882..17a3eb28af 100644
--- a/src/spikeinterface/curation/auto_merge.py
+++ b/src/spikeinterface/curation/auto_merge.py
@@ -227,7 +227,6 @@ def compute_merge_unit_groups(
outs = dict()
for step in steps:
-
if step in _required_extensions:
for ext in _required_extensions[step]:
if sorting_analyzer.has_extension(ext):
@@ -374,7 +373,6 @@ def compute_merge_unit_groups(
outs["pairs_decreased_score"] = pairs_decreased_score
elif step == "slay_score":
-
M_ij = compute_slay_matrix(
sorting_analyzer, params["k1"], params["k2"], templates_diff=outs["templates_diff"], pair_mask=pair_mask
)
@@ -641,7 +639,6 @@ def auto_merge_units(
}
for to_launch, params in zip(to_be_launched, steps_params):
-
if launch_mode == "presets":
compute_merge_kwargs = {"preset": to_launch}
elif launch_mode == "steps":
@@ -802,7 +799,7 @@ def smooth_correlogram(correlograms, bins, sigma_smooth_ms=0.6):
"""
Smooths cross-correlogram with a Gaussian kernel.
"""
- from scipy.signal import fftconvolve, butter, filtfilt
+ from scipy.signal import fftconvolve
# OLD implementation : smooth correlogram by low pass filter
# b, a = butter(N=2, Wn = correlogram_low_pass / (1e3 / bin_ms /2), btype="low")
@@ -1432,7 +1429,6 @@ def compute_xcorr_and_rp(sorting_analyzer: SortingAnalyzer, pair_mask: np.ndarra
for unit_index_1, _ in enumerate(sorting_analyzer.unit_ids):
for unit_index_2, _ in enumerate(sorting_analyzer.unit_ids):
-
# Don't waste time computing the other metrics if units not candidates merges
if not pair_mask[unit_index_1, unit_index_2]:
continue
diff --git a/src/spikeinterface/curation/bombcell_curation.py b/src/spikeinterface/curation/bombcell_curation.py
index f41b25f8e8..a16a1904c2 100644
--- a/src/spikeinterface/curation/bombcell_curation.py
+++ b/src/spikeinterface/curation/bombcell_curation.py
@@ -245,9 +245,9 @@ def bombcell_label_units(
if external_metrics is None:
raise ValueError("Either sorting_analyzer or external_metrics must be provided")
if isinstance(external_metrics, list):
- assert all(
- isinstance(df, pd.DataFrame) for df in external_metrics
- ), "All items in external_metrics must be DataFrames"
+ assert all(isinstance(df, pd.DataFrame) for df in external_metrics), (
+ "All items in external_metrics must be DataFrames"
+ )
combined_metrics = pd.concat(external_metrics, axis=1)
else:
combined_metrics = external_metrics
diff --git a/src/spikeinterface/curation/curation_format.py b/src/spikeinterface/curation/curation_format.py
index cf5b952376..84ae86ed47 100644
--- a/src/spikeinterface/curation/curation_format.py
+++ b/src/spikeinterface/curation/curation_format.py
@@ -190,12 +190,12 @@ def apply_curation(
curated_sorting_or_analyzer : Sorting | SortingAnalyzer
The curated object.
"""
- assert isinstance(
- sorting_or_analyzer, (BaseSorting, SortingAnalyzer)
- ), f"`sorting_or_analyzer` must be a Sorting or a SortingAnalyzer, not an object of type {type(sorting_or_analyzer)}"
- assert isinstance(
- curation_dict_or_model, (dict, list, Curation, SequentialCuration)
- ), f"`curation_dict_or_model` must be a dict, Curation or a SequentialCuration not an object of type {type(curation_dict_or_model)}"
+ assert isinstance(sorting_or_analyzer, (BaseSorting, SortingAnalyzer)), (
+ f"`sorting_or_analyzer` must be a Sorting or a SortingAnalyzer, not an object of type {type(sorting_or_analyzer)}"
+ )
+ assert isinstance(curation_dict_or_model, (dict, list, Curation, SequentialCuration)), (
+ f"`curation_dict_or_model` must be a dict, Curation or a SequentialCuration not an object of type {type(curation_dict_or_model)}"
+ )
if isinstance(curation_dict_or_model, dict):
curation_model = Curation(**curation_dict_or_model)
elif isinstance(curation_dict_or_model, list):
diff --git a/src/spikeinterface/curation/curation_model.py b/src/spikeinterface/curation/curation_model.py
index 128bc0e6ba..f0e915aa02 100644
--- a/src/spikeinterface/curation/curation_model.py
+++ b/src/spikeinterface/curation/curation_model.py
@@ -1,7 +1,6 @@
-import warnings
from typing import Literal, List
from itertools import chain, combinations
-from pydantic import BaseModel, Field, model_validator, field_validator, field_serializer
+from pydantic import BaseModel, Field, model_validator, field_validator
import numpy as np
@@ -504,7 +503,6 @@ def validate_sequential_curation(self):
)
for curation_index in range(len(self.curation_steps))[:-1]:
-
curation_1 = self.curation_steps[curation_index]
curation_2 = self.curation_steps[curation_index + 1]
@@ -513,7 +511,7 @@ def validate_sequential_curation(self):
if not (set(previous_model_final_ids) == set(next_model_initial_ids)):
raise ValueError(
- f"The initial unit_ids of curation {curation_index+1} do not match the final unit_ids of curation {curation_index}."
+ f"The initial unit_ids of curation {curation_index + 1} do not match the final unit_ids of curation {curation_index}."
)
return self
diff --git a/src/spikeinterface/curation/curationsorting.py b/src/spikeinterface/curation/curationsorting.py
index 1e0e8fc1d0..52b879fb64 100644
--- a/src/spikeinterface/curation/curationsorting.py
+++ b/src/spikeinterface/curation/curationsorting.py
@@ -119,7 +119,7 @@ def merge(self, units_to_merge, new_unit_id=None, delta_time_ms=0.4):
if new_unit_id is None:
new_unit_id = self._get_unused_id()[0]
elif new_unit_id not in units_to_merge:
- assert new_unit_id not in current_sorting.unit_ids, f"new_unit_id already exists!"
+ assert new_unit_id not in current_sorting.unit_ids, "new_unit_id already exists!"
new_sorting = MergeUnitsSorting(
sorting=current_sorting,
units_to_merge=units_to_merge,
diff --git a/src/spikeinterface/curation/mergeunitssorting.py b/src/spikeinterface/curation/mergeunitssorting.py
index 314a1a417e..4d8fdddb82 100644
--- a/src/spikeinterface/curation/mergeunitssorting.py
+++ b/src/spikeinterface/curation/mergeunitssorting.py
@@ -59,7 +59,7 @@ def __init__(self, sorting, units_to_merge, new_unit_ids=None, properties_policy
# some checks
for ids in units_to_merge:
assert all(u in parents_unit_ids for u in ids), "units to merge are not all in parent"
- assert properties_policy in ("keep", "remove"), "properties_policy must be " "keep" " or " "remove" ""
+ assert properties_policy in ("keep", "remove"), "properties_policy must be keep or remove"
# new units are put at the end
unit_ids = keep_unit_ids + list(new_unit_ids)
diff --git a/src/spikeinterface/curation/model_based_curation.py b/src/spikeinterface/curation/model_based_curation.py
index 69c7f75419..b1f1184d16 100644
--- a/src/spikeinterface/curation/model_based_curation.py
+++ b/src/spikeinterface/curation/model_based_curation.py
@@ -1,7 +1,6 @@
from pathlib import Path
import json
import warnings
-import re
from packaging.version import parse
from copy import deepcopy
@@ -141,7 +140,7 @@ def predict_labels(
label_conversion = {}
for key, value in string_label_conversion.items():
label_conversion[int(key)] = value
- except:
+ except Exception:
warnings.warn("Could not find `label_conversion` key in `model_info.json` file")
metrics = _format_metric_dataframe(metrics)
@@ -190,13 +189,11 @@ def _check_params_for_classification(self, enforce_metric_params=False, model_in
metric_extensions = [self.sorting_analyzer.get_extension(extension_name) for extension_name in extension_names]
for metric_extension, extension_name in zip(metric_extensions, extension_names):
-
# remove the 's' at the end of the extension name
extension_name = extension_name[:-1]
model_extension_params = model_info["metric_params"].get(extension_name + "_params")
if metric_extension is not None and model_extension_params is not None:
-
metric_params = metric_extension.params["metric_params"]
inconsistent_metrics = []
@@ -450,7 +447,6 @@ def _load_model_from_folder(model_folder=None, model_name=None, trust_model=Fals
"""
import skops.io as skio
- from skops.io.exceptions import UntrustedTypesFoundException
folder = Path(model_folder)
assert folder.is_dir(), f"The folder {folder}, does not exist."
diff --git a/src/spikeinterface/curation/remove_duplicated_spikes.py b/src/spikeinterface/curation/remove_duplicated_spikes.py
index f8716ba54a..e494e43ddb 100644
--- a/src/spikeinterface/curation/remove_duplicated_spikes.py
+++ b/src/spikeinterface/curation/remove_duplicated_spikes.py
@@ -80,9 +80,9 @@ def get_unit_spike_train(self, unit_id, start_frame: int | None = None, end_fram
spike_train = np.delete(spike_train, self._duplicated_spikes[unit_id])
- if start_frame == None:
+ if start_frame is None:
start_frame = 0
- if end_frame == None:
+ if end_frame is None:
end_frame = spike_train[-1] if len(spike_train) > 0 else 0
start = np.searchsorted(spike_train, start_frame, side="left")
diff --git a/src/spikeinterface/curation/remove_excess_spikes.py b/src/spikeinterface/curation/remove_excess_spikes.py
index a2b8ebb20a..13c2c761f4 100644
--- a/src/spikeinterface/curation/remove_excess_spikes.py
+++ b/src/spikeinterface/curation/remove_excess_spikes.py
@@ -25,9 +25,9 @@ class RemoveExcessSpikesSorting(BaseSorting):
def __init__(self, sorting: BaseSorting, recording: BaseRecording) -> None:
super().__init__(sorting.get_sampling_frequency(), sorting.unit_ids)
- assert (
- sorting.get_num_segments() == recording.get_num_segments()
- ), "The sorting and recording objects must have the same number of samples!"
+ assert sorting.get_num_segments() == recording.get_num_segments(), (
+ "The sorting and recording objects must have the same number of samples!"
+ )
self._parent_sorting = sorting
self._num_samples = np.empty(sorting.get_num_segments(), dtype=np.int64)
diff --git a/src/spikeinterface/curation/sortingview_curation.py b/src/spikeinterface/curation/sortingview_curation.py
index 657dcb9cde..7cde276936 100644
--- a/src/spikeinterface/curation/sortingview_curation.py
+++ b/src/spikeinterface/curation/sortingview_curation.py
@@ -74,7 +74,7 @@ def apply_sortingview_curation(
try:
curation_dict = ka.load_json(uri=uri_or_json)
- except:
+ except Exception:
raise Exception(f"Could not retrieve curation from SortingView uri: {uri_or_json}")
if curation_dict is None:
diff --git a/src/spikeinterface/curation/splitunitsorting.py b/src/spikeinterface/curation/splitunitsorting.py
index 087a808b02..a7af7c8994 100644
--- a/src/spikeinterface/curation/splitunitsorting.py
+++ b/src/spikeinterface/curation/splitunitsorting.py
@@ -38,9 +38,9 @@ def __init__(self, sorting, split_unit_id, indices_list, new_unit_ids=None, prop
if type(indices_list) is not list:
indices_list = [indices_list]
parents_unit_ids = sorting.unit_ids
- assert sorting.get_num_segments() == len(
- indices_list
- ), "The length of indices_list must be the same as parent_sorting.get_num_segments"
+ assert sorting.get_num_segments() == len(indices_list), (
+ "The length of indices_list must be the same as parent_sorting.get_num_segments"
+ )
split_unit_indices = np.unique([np.unique(v) for v in indices_list])
tot_splits = len(split_unit_indices)
unchanged_units = parents_unit_ids[parents_unit_ids != split_unit_id]
@@ -63,12 +63,10 @@ def __init__(self, sorting, split_unit_id, indices_list, new_unit_ids=None, prop
assert len(new_unit_ids) <= tot_splits, "indices_list has more id indices than the length of new_unit_ids"
assert split_unit_id in parents_unit_ids, "Unit to split must be in parent sorting"
- assert properties_policy == "keep" or properties_policy == "remove", (
- "properties_policy must be " "keep" " or " "remove" ""
+ assert properties_policy == "keep" or properties_policy == "remove", "properties_policy must be keep or remove"
+ assert not any(np.isin(new_unit_ids, unchanged_units)), (
+ "new_unit_ids should be new unit ids or no more than one unit id can be found in split_unit_id"
)
- assert not any(
- np.isin(new_unit_ids, unchanged_units)
- ), "new_unit_ids should be new unit ids or no more than one unit id can be found in split_unit_id"
sampling_frequency = sorting.get_sampling_frequency()
units_ids = np.concatenate([unchanged_units, new_unit_ids])
@@ -76,9 +74,9 @@ def __init__(self, sorting, split_unit_id, indices_list, new_unit_ids=None, prop
self._parent_sorting = sorting
BaseSorting.__init__(self, sampling_frequency, units_ids)
- assert all(
- np.isin(unchanged_units, self.unit_ids)
- ), "new_unit_ids should have a compatible format with the parent ids"
+ assert all(np.isin(unchanged_units, self.unit_ids)), (
+ "new_unit_ids should have a compatible format with the parent ids"
+ )
for si, parent_segment in enumerate(self._parent_sorting.segments):
sub_segment = SplitSortingUnitSegment(parent_segment, split_unit_id, indices_zero_based[si], new_unit_ids)
diff --git a/src/spikeinterface/curation/tests/common.py b/src/spikeinterface/curation/tests/common.py
index 20dbd2f1f2..e69de29bb2 100644
--- a/src/spikeinterface/curation/tests/common.py
+++ b/src/spikeinterface/curation/tests/common.py
@@ -1,124 +0,0 @@
-import pytest
-
-from spikeinterface.core import generate_ground_truth_recording, create_sorting_analyzer, aggregate_units
-from spikeinterface.core.generate import inject_some_split_units
-from spikeinterface.curation import train_model
-from pathlib import Path
-
-extensions = [
- "noise_levels",
- "random_spikes",
- "waveforms",
- "templates",
- "unit_locations",
- "spike_amplitudes",
- "spike_locations",
- "correlograms",
- "template_similarity",
-]
-
-
-def make_sorting_analyzer(sparse=True, num_units=5, durations=[300.0]):
- recording, sorting = generate_ground_truth_recording(
- durations=durations,
- sampling_frequency=30000.0,
- num_channels=4,
- num_units=num_units,
- generate_sorting_kwargs=dict(firing_rates=20.0, refractory_period_ms=4.0),
- noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"),
- seed=2205,
- )
-
- sorting_analyzer = create_sorting_analyzer(
- sorting=sorting,
- recording=recording,
- format="memory",
- sparse=sparse,
- )
- sorting_analyzer.compute(extensions)
-
- return sorting_analyzer
-
-
-def make_sorting_analyzer_with_splits(sorting_analyzer, num_unit_splitted=1, num_split=2):
- sorting = sorting_analyzer.sorting
-
- split_ids = sorting.unit_ids[:num_unit_splitted]
- sorting_with_split, other_ids = inject_some_split_units(
- sorting,
- split_ids=split_ids,
- num_split=num_split,
- output_ids=True,
- seed=42,
- )
-
- sorting_analyzer_with_splits = create_sorting_analyzer(
- sorting=sorting_with_split, recording=sorting_analyzer.recording, format="memory", sparse=True
- )
- sorting_analyzer_with_splits.compute(extensions)
-
- return sorting_analyzer_with_splits, num_unit_splitted, other_ids
-
-
-@pytest.fixture(scope="module")
-def sorting_analyzer_for_curation():
- return make_sorting_analyzer(sparse=True)
-
-
-@pytest.fixture(scope="module")
-def sorting_analyzer_for_unitrefine_curation():
- """Makes an analyzer whose first 10 units are good normal units, and 10 which are noise. We make them
- noise by using a spike trains which are uncorrelated with the recording for `sorting2`."""
-
- recording, sorting_1 = generate_ground_truth_recording(num_channels=4, seed=1, num_units=6)
- _, sorting_2 = generate_ground_truth_recording(num_channels=4, seed=2, num_units=6)
- both_sortings = aggregate_units([sorting_1, sorting_2])
- analyzer = create_sorting_analyzer(sorting=both_sortings, recording=recording)
- analyzer.compute(["random_spikes", "noise_levels", "templates"])
- return analyzer
-
-
-@pytest.fixture(scope="module")
-def sorting_analyzer_multi_segment_for_curation():
- return make_sorting_analyzer(sparse=True, durations=[50.0, 30.0])
-
-
-@pytest.fixture(scope="module")
-def sorting_analyzer_with_splits():
- sorting_analyzer = make_sorting_analyzer(sparse=True, durations=[50.0])
- return make_sorting_analyzer_with_splits(sorting_analyzer)
-
-
-@pytest.fixture(scope="module")
-def trained_pipeline_path(sorting_analyzer_for_unitrefine_curation):
- """
- Makes a model saved at "./trained_pipeline" which will be used by other tests in the module.
- If the model already exists, this function does nothing.
- """
- trained_model_folder = Path(__file__).parent / Path("trained_pipeline")
- if trained_model_folder.is_dir():
- yield trained_model_folder
- else:
- analyzer = sorting_analyzer_for_unitrefine_curation
- analyzer.compute(
- {
- "quality_metrics": {"metric_names": ["snr"]},
- "template_metrics": {"metric_names": ["half_width", "peak_to_trough_duration", "number_of_peaks"]},
- }
- )
- train_model(
- analyzers=[analyzer] * 5,
- folder=trained_model_folder,
- labels=[[1] * 6 + [0] * 6] * 5,
- imputation_strategies=["median"],
- scaling_techniques=["standard_scaler"],
- classifiers=["RandomForestClassifier"],
- overwrite=True,
- search_kwargs={"cv": 3, "scoring": "balanced_accuracy", "n_iter": 2},
- )
- yield trained_model_folder
-
-
-if __name__ == "__main__":
- sorting_analyzer = make_sorting_analyzer(sparse=False)
- print(sorting_analyzer)
diff --git a/src/spikeinterface/curation/tests/conftest.py b/src/spikeinterface/curation/tests/conftest.py
new file mode 100644
index 0000000000..ad8c42a884
--- /dev/null
+++ b/src/spikeinterface/curation/tests/conftest.py
@@ -0,0 +1,120 @@
+import pytest
+from pathlib import Path
+
+from spikeinterface.core import generate_ground_truth_recording, create_sorting_analyzer, aggregate_units
+from spikeinterface.curation import train_model
+from spikeinterface.core.generate import inject_some_split_units
+
+
+extensions = [
+ "noise_levels",
+ "random_spikes",
+ "waveforms",
+ "templates",
+ "unit_locations",
+ "spike_amplitudes",
+ "spike_locations",
+ "correlograms",
+ "template_similarity",
+]
+
+
+def make_sorting_analyzer(sparse=True, num_units=5, durations=[300.0]):
+ recording, sorting = generate_ground_truth_recording(
+ durations=durations,
+ sampling_frequency=30000.0,
+ num_channels=4,
+ num_units=num_units,
+ generate_sorting_kwargs=dict(firing_rates=20.0, refractory_period_ms=4.0),
+ noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"),
+ seed=2205,
+ )
+
+ sorting_analyzer = create_sorting_analyzer(
+ sorting=sorting,
+ recording=recording,
+ format="memory",
+ sparse=sparse,
+ )
+ sorting_analyzer.compute(extensions)
+
+ return sorting_analyzer
+
+
+def make_sorting_analyzer_with_splits(sorting_analyzer, num_unit_splitted=1, num_split=2):
+ sorting = sorting_analyzer.sorting
+
+ split_ids = sorting.unit_ids[:num_unit_splitted]
+ sorting_with_split, other_ids = inject_some_split_units(
+ sorting,
+ split_ids=split_ids,
+ num_split=num_split,
+ output_ids=True,
+ seed=42,
+ )
+
+ sorting_analyzer_with_splits = create_sorting_analyzer(
+ sorting=sorting_with_split, recording=sorting_analyzer.recording, format="memory", sparse=True
+ )
+ sorting_analyzer_with_splits.compute(extensions)
+
+ return sorting_analyzer_with_splits, num_unit_splitted, other_ids
+
+
+@pytest.fixture(scope="module")
+def sorting_analyzer_for_curation():
+ return make_sorting_analyzer(sparse=True)
+
+
+@pytest.fixture(scope="module")
+def sorting_analyzer_for_unitrefine_curation():
+ """Makes an analyzer whose first 10 units are good normal units, and 10 which are noise. We make them
+ noise by using a spike trains which are uncorrelated with the recording for `sorting2`."""
+
+ recording, sorting_1 = generate_ground_truth_recording(num_channels=4, seed=1, num_units=6)
+ _, sorting_2 = generate_ground_truth_recording(num_channels=4, seed=2, num_units=6)
+ both_sortings = aggregate_units([sorting_1, sorting_2])
+ analyzer = create_sorting_analyzer(sorting=both_sortings, recording=recording)
+ analyzer.compute(["random_spikes", "noise_levels", "templates"])
+ return analyzer
+
+
+@pytest.fixture(scope="module")
+def sorting_analyzer_multi_segment_for_curation():
+ return make_sorting_analyzer(sparse=True, durations=[50.0, 30.0])
+
+
+@pytest.fixture(scope="module")
+def sorting_analyzer_with_splits():
+ sorting_analyzer = make_sorting_analyzer(sparse=True, durations=[50.0])
+ return make_sorting_analyzer_with_splits(sorting_analyzer)
+
+
+@pytest.fixture(scope="module")
+def trained_pipeline_path(sorting_analyzer_for_unitrefine_curation):
+ """
+ Makes a model saved at "./trained_pipeline" which will be used by other tests in the module.
+ If the model already exists, this function does nothing.
+ """
+ trained_model_folder = Path(__file__).parent / Path("trained_pipeline")
+ if trained_model_folder.is_dir():
+ yield trained_model_folder
+ else:
+ analyzer = sorting_analyzer_for_unitrefine_curation
+ analyzer.compute(
+ {
+ "quality_metrics": {"metric_names": ["snr"]},
+ "template_metrics": {"metric_names": ["half_width", "peak_to_trough_duration", "number_of_peaks"]},
+ }
+ )
+ train_model(
+ analyzers=[analyzer] * 5,
+ folder=trained_model_folder,
+ labels=[[1] * 6 + [0] * 6] * 5,
+ imputation_strategies=["median"],
+ scaling_techniques=["standard_scaler"],
+ classifiers=["RandomForestClassifier"],
+ overwrite=True,
+ search_kwargs={"cv": 3, "scoring": "balanced_accuracy", "n_iter": 2},
+ )
+ yield trained_model_folder
diff --git a/src/spikeinterface/curation/tests/test_auto_merge.py b/src/spikeinterface/curation/tests/test_auto_merge.py
index cab508f4fb..05d5a22994 100644
--- a/src/spikeinterface/curation/tests/test_auto_merge.py
+++ b/src/spikeinterface/curation/tests/test_auto_merge.py
@@ -6,14 +6,6 @@
from spikeinterface.generation import split_sorting_by_times
-from spikeinterface.curation.tests.common import (
- make_sorting_analyzer,
- sorting_analyzer_for_curation,
- sorting_analyzer_with_splits,
- sorting_analyzer_multi_segment_for_curation,
-)
-
-
@pytest.mark.parametrize(
"preset", ["x_contaminations", "feature_neighbors", "temporal_splits", "similarity_correlograms", "slay", None]
)
@@ -62,7 +54,7 @@ def test_compute_merge_unit_groups_multi_segment(sorting_analyzer_multi_segment_
sorting_analyzer = sorting_analyzer_multi_segment_for_curation
print(sorting_analyzer)
- merge_unit_groups = compute_merge_unit_groups(
+ _ = compute_merge_unit_groups(
sorting_analyzer,
preset=preset,
)
diff --git a/src/spikeinterface/curation/tests/test_bombcell_curation.py b/src/spikeinterface/curation/tests/test_bombcell_curation.py
index 768d28c143..6a3d9f2c6c 100644
--- a/src/spikeinterface/curation/tests/test_bombcell_curation.py
+++ b/src/spikeinterface/curation/tests/test_bombcell_curation.py
@@ -1,6 +1,4 @@
import pytest
-from pathlib import Path
-from spikeinterface.curation.tests.common import sorting_analyzer_for_curation, trained_pipeline_path
from spikeinterface.curation.bombcell_curation import bombcell_label_units
@@ -31,7 +29,6 @@ def test_bombcell_label_units_with_external_metrics(sorting_analyzer_with_metric
sorting_analyzer = sorting_analyzer_with_metrics
# Create external metrics DataFrame
- import pandas as pd
metrics_df = sorting_analyzer.get_metrics_extension_data()
diff --git a/src/spikeinterface/curation/tests/test_curation_format.py b/src/spikeinterface/curation/tests/test_curation_format.py
index 40e0a9b2b7..e3d6dcb262 100644
--- a/src/spikeinterface/curation/tests/test_curation_format.py
+++ b/src/spikeinterface/curation/tests/test_curation_format.py
@@ -234,7 +234,6 @@ def test_to_from_json_file(tmp_path):
for curation_index, curation_dict in enumerate(
[curation_ids_int, curation_ids_str, curation_ids_int_dict, curation_with_splits]
):
-
temp_filepath = tmp_path / f"data_{curation_index}.json"
with open(temp_filepath, "w") as f:
@@ -331,7 +330,6 @@ def test_apply_curation_with_split():
def test_apply_curation_with_split_multi_segment():
recording, sorting = generate_ground_truth_recording(durations=[10.0, 10.0], num_units=9, seed=2205)
sorting = sorting.rename_units(np.array([1, 2, 3, 6, 10, 14, 20, 31, 42]))
- analyzer = create_sorting_analyzer(sorting, recording, sparse=False)
num_segments = sorting.get_num_segments()
curation_with_splits_multi_segment = curation_with_splits.copy()
diff --git a/src/spikeinterface/curation/tests/test_curation_model.py b/src/spikeinterface/curation/tests/test_curation_model.py
index 48102096a6..5005cfa3fc 100644
--- a/src/spikeinterface/curation/tests/test_curation_model.py
+++ b/src/spikeinterface/curation/tests/test_curation_model.py
@@ -1,7 +1,6 @@
import pytest
from pydantic import ValidationError
-import numpy as np
from spikeinterface.curation.curation_model import Curation, SequentialCuration, LabelDefinition
diff --git a/src/spikeinterface/curation/tests/test_curationsorting.py b/src/spikeinterface/curation/tests/test_curationsorting.py
index cca3407ef5..b1a063eac5 100644
--- a/src/spikeinterface/curation/tests/test_curationsorting.py
+++ b/src/spikeinterface/curation/tests/test_curationsorting.py
@@ -52,13 +52,12 @@ def test_split_merge():
merged = MergeUnitsSorting(splitted, units_to_merge=[[8, 10]], new_unit_ids=[4], properties_policy="keep")
for i in range(len(spikestimes)):
- assert (
- all(parent_sort.get_unit_spike_train(4, segment_index=i) == merged.get_unit_spike_train(4, segment_index=i))
- == True
+ assert all(
+ parent_sort.get_unit_spike_train(4, segment_index=i) == merged.get_unit_spike_train(4, segment_index=i)
), "splir or merge error"
- assert parent_sort.get_unit_property(4, "someprop") == merged.get_unit_property(
- 4, "someprop"
- ), "property wasn't kept"
+ assert parent_sort.get_unit_property(4, "someprop") == merged.get_unit_property(4, "someprop"), (
+ "property wasn't kept"
+ )
# 1d
assert merged.get_unit_property(4, "some_str_prop") == "", "error with array property"
assert merged.get_unit_property(4, "some_prop_to_keep") == 1, "error with array property"
@@ -67,9 +66,9 @@ def test_split_merge():
# 2d
assert np.array_equal(merged.get_unit_property(4, "some_array_prop_to_keep"), [1, 1]), "error with array property"
assert np.all(np.isnan(merged.get_unit_property(4, "some_array_prop_to_remove"))), "error with array property"
- assert np.array_equal(
- merged.get_unit_property(4, "some_array_prop_to_none"), [None, None]
- ), "error with array property"
+ assert np.array_equal(merged.get_unit_property(4, "some_array_prop_to_none"), [None, None]), (
+ "error with array property"
+ )
merged_with_dups = MergeUnitsSorting(
parent_sort, new_unit_ids=[8], units_to_merge=[[0, 1]], properties_policy="remove", delta_time_ms=0.5
@@ -139,7 +138,7 @@ def test_curation():
)
# Test with empty sorting
- empty_sorting = CurationSorting(NumpySorting.from_unit_dict({}, parent_sort.sampling_frequency))
+ _ = CurationSorting(NumpySorting.from_unit_dict({}, parent_sort.sampling_frequency))
if __name__ == "__main__":
diff --git a/src/spikeinterface/curation/tests/test_model_based_curation.py b/src/spikeinterface/curation/tests/test_model_based_curation.py
index 800817cdda..8563c8130e 100644
--- a/src/spikeinterface/curation/tests/test_model_based_curation.py
+++ b/src/spikeinterface/curation/tests/test_model_based_curation.py
@@ -1,7 +1,6 @@
import pytest
from pathlib import Path
-from spikeinterface.curation.tests.common import sorting_analyzer_for_unitrefine_curation, trained_pipeline_path
from spikeinterface.curation.model_based_curation import ModelBasedClassification
from spikeinterface.curation import (
model_based_label_units,
@@ -97,9 +96,7 @@ def test_model_based_classification_get_metrics_for_classification(
all_metric_names, all_metric_columns, qm_names, tm_names = required_metrics
- model_based_classification = ModelBasedClassification(
- sorting_analyzer=sorting_analyzer_for_unitrefine_curation, pipeline=model[0]
- )
+ _ = ModelBasedClassification(sorting_analyzer=sorting_analyzer_for_unitrefine_curation, pipeline=model[0])
# Compute some (but not all) of the required metrics in sorting_analyzer, should still error
sorting_analyzer_for_unitrefine_curation.compute("quality_metrics", metric_names=[all_metric_names[0]])
@@ -158,7 +155,7 @@ def test_predict_labels_with_phy_export(sorting_analyzer_for_unitrefine_curation
model_based_classification = ModelBasedClassification(
sorting_analyzer=sorting_analyzer_for_unitrefine_curation, pipeline=model[0]
)
- classified_units = model_based_classification.predict_labels(export_to_phy=True, phy_folder=phy_folder)
+ _ = model_based_classification.predict_labels(export_to_phy=True, phy_folder=phy_folder)
# Check that the cluster_prediction.tsv file was created in the specified phy_folder
assert (phy_folder / "cluster_prediction.tsv").exists()
diff --git a/src/spikeinterface/curation/tests/test_remove_redundant.py b/src/spikeinterface/curation/tests/test_remove_redundant.py
index 43a7cd1951..4e74a738a5 100644
--- a/src/spikeinterface/curation/tests/test_remove_redundant.py
+++ b/src/spikeinterface/curation/tests/test_remove_redundant.py
@@ -2,8 +2,6 @@
from spikeinterface import create_sorting_analyzer
from spikeinterface.core.generate import inject_some_duplicate_units
-from spikeinterface.curation.tests.common import make_sorting_analyzer, sorting_analyzer_for_curation
-
from spikeinterface.curation import remove_redundant_units
@@ -22,8 +20,3 @@ def test_remove_redundant_units(sorting_analyzer_for_curation):
for remove_strategy in ("max_spikes", "minimum_shift", "highest_amplitude"):
sorting_clean = remove_redundant_units(sorting_analyzer, remove_strategy=remove_strategy)
assert np.all(sorting_clean.unit_ids == sorting.unit_ids)
-
-
-if __name__ == "__main__":
- sorting_analyzer = make_sorting_analyzer(sparse=True)
- test_remove_redundant_units(sorting_analyzer)
diff --git a/src/spikeinterface/curation/tests/test_sortingview_curation.py b/src/spikeinterface/curation/tests/test_sortingview_curation.py
index 9b1305205a..22ce09f7b8 100644
--- a/src/spikeinterface/curation/tests/test_sortingview_curation.py
+++ b/src/spikeinterface/curation/tests/test_sortingview_curation.py
@@ -4,16 +4,8 @@
import importlib.util
import numpy as np
-import spikeinterface as si
from spikeinterface.core import generate_sorting
import spikeinterface.extractors as se
-from spikeinterface import set_global_tmp_folder
-from spikeinterface.postprocessing import (
- compute_correlograms,
- compute_unit_locations,
- compute_template_similarity,
- compute_spike_amplitudes,
-)
from spikeinterface.curation import apply_sortingview_curation
parent_folder = Path(__file__).parent
@@ -103,7 +95,6 @@ def test_sha1_curation():
assert "accept" in sorting_curated_sha1.get_property_keys()
assert "mua" in sorting_curated_sha1.get_property_keys()
assert "artifact" in sorting_curated_sha1.get_property_keys()
- unit_ids = sorting_curated_sha1.unit_ids
sorting_curated_sha1_accepted = apply_sortingview_curation(sorting, uri_or_json=sha1_uri, include_labels=["accept"])
sorting_curated_sha1_mua = apply_sortingview_curation(sorting, uri_or_json=sha1_uri, exclude_labels=["mua"])
sorting_curated_sha1_art_mua = apply_sortingview_curation(
@@ -263,7 +254,7 @@ def test_json_no_merge_curation():
sorting = sorting.rename_units(new_unit_ids=unit_ids_as_int)
json_file = parent_folder / "sv-sorting-curation-no-merge.json"
- sorting_curated = apply_sortingview_curation(sorting, uri_or_json=json_file)
+ _ = apply_sortingview_curation(sorting, uri_or_json=json_file)
if __name__ == "__main__":
diff --git a/src/spikeinterface/curation/tests/test_train_manual_curation.py b/src/spikeinterface/curation/tests/test_train_manual_curation.py
index 21df26128a..65c0be3947 100644
--- a/src/spikeinterface/curation/tests/test_train_manual_curation.py
+++ b/src/spikeinterface/curation/tests/test_train_manual_curation.py
@@ -1,9 +1,10 @@
import pytest
import numpy as np
-import tempfile, csv
+import tempfile
+import csv
from pathlib import Path
-from spikeinterface.curation.tests.common import make_sorting_analyzer
+from spikeinterface.curation.tests.conftest import make_sorting_analyzer
from spikeinterface.curation.train_manual_curation import CurationTrainer, train_model
diff --git a/src/spikeinterface/curation/tests/test_unitrefine_curation.py b/src/spikeinterface/curation/tests/test_unitrefine_curation.py
index 314fcb5878..7c8fb29705 100644
--- a/src/spikeinterface/curation/tests/test_unitrefine_curation.py
+++ b/src/spikeinterface/curation/tests/test_unitrefine_curation.py
@@ -1,6 +1,5 @@
import pytest
-from spikeinterface.curation.tests.common import sorting_analyzer_for_unitrefine_curation, trained_pipeline_path
from spikeinterface.curation import unitrefine_label_units
@@ -49,7 +48,7 @@ def test_unitrefine_label_units_hf(sorting_analyzer_for_unitrefine_curation):
# test passing none
with pytest.raises(ValueError):
- labels = unitrefine_label_units(
+ _ = unitrefine_label_units(
sorting_analyzer_for_unitrefine_curation,
noise_neural_classifier=None,
sua_mua_classifier=None,
@@ -57,14 +56,14 @@ def test_unitrefine_label_units_hf(sorting_analyzer_for_unitrefine_curation):
# test warnings when unexpected labels are returned
with pytest.warns(UserWarning):
- labels = unitrefine_label_units(
+ _ = unitrefine_label_units(
sorting_analyzer_for_unitrefine_curation,
noise_neural_classifier="SpikeInterface/UnitRefine_sua_mua_classifier_lightweight",
sua_mua_classifier=None,
)
with pytest.warns(UserWarning):
- labels = unitrefine_label_units(
+ _ = unitrefine_label_units(
sorting_analyzer_for_unitrefine_curation,
noise_neural_classifier=None,
sua_mua_classifier="SpikeInterface/UnitRefine_noise_neural_classifier_lightweight",
@@ -79,13 +78,13 @@ def test_unitrefine_label_units_with_local_models(sorting_analyzer_for_unitrefin
sorting_analyzer_for_unitrefine_curation.compute("quality_metrics")
# test passing model folder
- labels = unitrefine_label_units(
+ _ = unitrefine_label_units(
sorting_analyzer_for_unitrefine_curation,
noise_neural_classifier=trained_pipeline_path,
)
# test passing model folder
- labels = unitrefine_label_units(
+ _ = unitrefine_label_units(
sorting_analyzer_for_unitrefine_curation,
noise_neural_classifier=trained_pipeline_path / "best_model.skops",
)
diff --git a/src/spikeinterface/curation/threshold_metrics_curation.py b/src/spikeinterface/curation/threshold_metrics_curation.py
index b9b5ca1a86..9a76dbc3f4 100644
--- a/src/spikeinterface/curation/threshold_metrics_curation.py
+++ b/src/spikeinterface/curation/threshold_metrics_curation.py
@@ -3,7 +3,6 @@
import numpy as np
-from spikeinterface.core.analyzer_extension_core import SortingAnalyzer
from .curation_tools import is_threshold_disabled
diff --git a/src/spikeinterface/curation/train_manual_curation.py b/src/spikeinterface/curation/train_manual_curation.py
index e34951820a..f6dd01e161 100644
--- a/src/spikeinterface/curation/train_manual_curation.py
+++ b/src/spikeinterface/curation/train_manual_curation.py
@@ -265,7 +265,6 @@ def load_and_preprocess_analyzers(self, analyzers, enforce_metric_params):
metric_extensions = [analyzers[0].get_extension(extension_name) for extension_name in extension_names]
for metric_extension, extension_name in zip(metric_extensions, extension_names):
-
# remove the 's' at the end of the extension name
extension_name = extension_name[:-1]
if metric_extension is not None:
@@ -289,11 +288,9 @@ def _check_metrics_parameters(self, analyzers, enforce_metric_params):
conflicting_metrics = []
for analyzer_index_1, analyzer_1 in enumerate(analyzers):
for analyzer_index_2, analyzer_2 in enumerate(analyzers):
-
if analyzer_index_1 <= analyzer_index_2:
continue
else:
-
metric_params_1 = {}
metric_params_2 = {}
@@ -389,7 +386,7 @@ def process_test_data_for_classification(self):
def apply_scaling_imputation(self, imputation_strategy, scaling_technique, X_train, X_test, y_train, y_test):
"""Impute and scale the data using the specified techniques."""
- from sklearn.experimental import enable_iterative_imputer
+ from sklearn.experimental import enable_iterative_imputer # noqa: F401 (side-effect import, required by IterativeImputer)
from sklearn.impute import SimpleImputer, KNNImputer, IterativeImputer
from sklearn.ensemble import HistGradientBoostingRegressor
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
@@ -587,14 +584,14 @@ def _save(self):
import pandas as pd
# export training data and labels
- pd.DataFrame(self.X).to_csv(self.folder / f"training_data.csv", index_label="unit_id")
- pd.DataFrame(self.y).to_csv(self.folder / f"labels.csv", index_label="unit_index")
+ pd.DataFrame(self.X).to_csv(self.folder / "training_data.csv", index_label="unit_id")
+ pd.DataFrame(self.y).to_csv(self.folder / "labels.csv", index_label="unit_index")
self.requirements["scikit-learn"] = sklearn.__version__
# Dump to skops if folder is provided
- dump(self.best_pipeline, self.folder / f"best_model.skops")
- self.test_accuracies_df.to_csv(self.folder / f"model_accuracies.csv", float_format="%.4f")
+ dump(self.best_pipeline, self.folder / "best_model.skops")
+ self.test_accuracies_df.to_csv(self.folder / "model_accuracies.csv", float_format="%.4f")
model_info = {}
model_info["metric_params"] = self.metrics_params
@@ -629,7 +626,7 @@ def _train_and_evaluate(
random_state=self.seed,
**search_kwargs,
)
- except:
+ except Exception:
if self.verbose is True:
print("BayesSearchCV from scikit-optimize not available, using RandomizedSearchCV")
from sklearn.model_selection import RandomizedSearchCV
@@ -787,7 +784,7 @@ def try_to_get_metrics_from_analyzer(sorting_analyzer):
for metric_extension in metric_extensions:
try:
metric_extensions_data.append(metric_extension.get_data())
- except:
+ except Exception:
metric_extensions_data.append(None)
return metric_extensions_data
diff --git a/src/spikeinterface/exporters/report.py b/src/spikeinterface/exporters/report.py
index ae1341afbc..95a184917c 100644
--- a/src/spikeinterface/exporters/report.py
+++ b/src/spikeinterface/exporters/report.py
@@ -71,12 +71,9 @@ def export_report(
)
# load or compute correlograms
- if sorting_analyzer.has_extension("correlograms"):
- correlograms, bins = sorting_analyzer.get_extension("correlograms").get_data()
- elif force_computation:
- correlograms, bins = compute_correlograms(sorting_analyzer, window_ms=100.0, bin_ms=1.0)
+ if not sorting_analyzer.has_extension("correlograms") and force_computation:
+ _ = compute_correlograms(sorting_analyzer, window_ms=100.0, bin_ms=1.0)
else:
- correlograms = None
warnings.warn(
"export_report(): correlograms will not be exported. Use sorting_analyzer.compute('correlograms') if you want to include them."
)
@@ -107,13 +104,13 @@ def export_report(
# global figures
fig = plt.figure(figsize=(20, 10))
- w = sw.plot_unit_locations(sorting_analyzer, figure=fig, unit_colors=unit_colors)
+ _ = sw.plot_unit_locations(sorting_analyzer, figure=fig, unit_colors=unit_colors)
fig.savefig(output_folder / f"unit_locations.{format}")
if not show_figures:
plt.close(fig)
fig, ax = plt.subplots(figsize=(20, 10))
- sw.plot_unit_depths(sorting_analyzer, ax=ax, unit_colors=unit_colors)
+ _ = sw.plot_unit_depths(sorting_analyzer, ax=ax, unit_colors=unit_colors)
fig.savefig(output_folder / f"unit_depths.{format}")
if not show_figures:
plt.close(fig)
diff --git a/src/spikeinterface/exporters/tests/common.py b/src/spikeinterface/exporters/tests/common.py
index 3b85c11d54..e69de29bb2 100644
--- a/src/spikeinterface/exporters/tests/common.py
+++ b/src/spikeinterface/exporters/tests/common.py
@@ -1,79 +0,0 @@
-import pytest
-from pathlib import Path
-
-from spikeinterface.core import generate_ground_truth_recording, create_sorting_analyzer, compute_sparsity
-
-
-def make_sorting_analyzer(sparse=True, with_group=False):
- recording, sorting = generate_ground_truth_recording(
- durations=[30.0],
- sampling_frequency=28000.0,
- num_channels=8,
- num_units=4,
- generate_probe_kwargs=dict(
- num_columns=2,
- xpitch=20,
- ypitch=20,
- contact_shapes="circle",
- contact_shape_params={"radius": 6},
- ),
- generate_sorting_kwargs=dict(firing_rates=10.0, refractory_period_ms=4.0),
- noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"),
- seed=2205,
- )
-
- if with_group:
-
- # this is a bit painful. We need to figure out which units belong to which group
- initial_sorting_analyzer = create_sorting_analyzer(
- sorting=sorting, recording=recording, format="memory", sparse=True
- )
- main_channels = initial_sorting_analyzer.main_channel_indices
- sorting_groups = [0 if main_channel < 4 else 1 for main_channel in main_channels]
- recording.set_channel_groups([0, 0, 0, 0, 1, 1, 1, 1])
- sorting.set_property("group", sorting_groups)
-
- # Now we know that, we can make an analyzer with a working sparsity_group
- sorting_analyzer_unused = create_sorting_analyzer(
- sorting=sorting, recording=recording, format="memory", sparse=False, sparsity=None
- )
- sparsity_group = compute_sparsity(sorting_analyzer_unused, method="by_property", by_property="group")
- sorting_analyzer = create_sorting_analyzer(
- sorting=sorting, recording=recording, format="memory", sparse=False, sparsity=sparsity_group
- )
- else:
- sorting_analyzer = create_sorting_analyzer(sorting=sorting, recording=recording, format="memory", sparse=sparse)
-
- sorting_analyzer.compute("random_spikes")
- sorting_analyzer.compute("waveforms")
- sorting_analyzer.compute("templates")
- sorting_analyzer.compute("noise_levels")
- sorting_analyzer.compute("principal_components")
- sorting_analyzer.compute("template_similarity")
- sorting_analyzer.compute("spike_amplitudes")
- sorting_analyzer.compute(
- "quality_metrics", metric_names=["snr", "amplitude_median", "isi_violation", "amplitude_cutoff"]
- )
- sorting_analyzer.compute(["spike_amplitudes", "spike_locations"])
-
- return sorting_analyzer
-
-
-@pytest.fixture(scope="module")
-def sorting_analyzer_dense_for_export():
- return make_sorting_analyzer(sparse=False)
-
-
-@pytest.fixture(scope="module")
-def sorting_analyzer_with_group_for_export():
- return make_sorting_analyzer(sparse=False, with_group=True)
-
-
-@pytest.fixture(scope="module")
-def sorting_analyzer_sparse_for_export():
- return make_sorting_analyzer(sparse=True)
-
-
-if __name__ == "__main__":
- sorting_analyzer = make_sorting_analyzer(sparse=False)
- print(sorting_analyzer)
diff --git a/src/spikeinterface/exporters/tests/conftest.py b/src/spikeinterface/exporters/tests/conftest.py
new file mode 100644
index 0000000000..a524c3b965
--- /dev/null
+++ b/src/spikeinterface/exporters/tests/conftest.py
@@ -0,0 +1,72 @@
+import pytest
+
+from spikeinterface.core import generate_ground_truth_recording, create_sorting_analyzer, compute_sparsity
+
+
+def make_sorting_analyzer(sparse=True, with_group=False):
+ recording, sorting = generate_ground_truth_recording(
+ durations=[30.0],
+ sampling_frequency=28000.0,
+ num_channels=8,
+ num_units=4,
+ generate_probe_kwargs=dict(
+ num_columns=2,
+ xpitch=20,
+ ypitch=20,
+ contact_shapes="circle",
+ contact_shape_params={"radius": 6},
+ ),
+ generate_sorting_kwargs=dict(firing_rates=10.0, refractory_period_ms=4.0),
+ noise_kwargs=dict(noise_levels=5.0, strategy="on_the_fly"),
+ seed=2205,
+ )
+
+ if with_group:
+ # this is a bit painful. We need to figure out which units belong to which group
+ initial_sorting_analyzer = create_sorting_analyzer(
+ sorting=sorting, recording=recording, format="memory", sparse=True
+ )
+ main_channels = initial_sorting_analyzer.main_channel_indices
+ sorting_groups = [0 if main_channel < 4 else 1 for main_channel in main_channels]
+ recording.set_channel_groups([0, 0, 0, 0, 1, 1, 1, 1])
+ sorting.set_property("group", sorting_groups)
+
+ # Now we know that, we can make an analyzer with a working sparsity_group
+ sorting_analyzer_unused = create_sorting_analyzer(
+ sorting=sorting, recording=recording, format="memory", sparse=False, sparsity=None
+ )
+ sparsity_group = compute_sparsity(sorting_analyzer_unused, method="by_property", by_property="group")
+ sorting_analyzer = create_sorting_analyzer(
+ sorting=sorting, recording=recording, format="memory", sparse=False, sparsity=sparsity_group
+ )
+ else:
+ sorting_analyzer = create_sorting_analyzer(sorting=sorting, recording=recording, format="memory", sparse=sparse)
+
+ sorting_analyzer.compute("random_spikes")
+ sorting_analyzer.compute("waveforms")
+ sorting_analyzer.compute("templates")
+ sorting_analyzer.compute("noise_levels")
+ sorting_analyzer.compute("principal_components")
+ sorting_analyzer.compute("template_similarity")
+ sorting_analyzer.compute("spike_amplitudes")
+ sorting_analyzer.compute(
+ "quality_metrics", metric_names=["snr", "amplitude_median", "isi_violation", "amplitude_cutoff"]
+ )
+ sorting_analyzer.compute(["spike_amplitudes", "spike_locations"])
+
+ return sorting_analyzer
+
+
+@pytest.fixture(scope="module")
+def sorting_analyzer_dense_for_export():
+ return make_sorting_analyzer(sparse=False)
+
+
+@pytest.fixture(scope="module")
+def sorting_analyzer_with_group_for_export():
+ return make_sorting_analyzer(sparse=False, with_group=True)
+
+
+@pytest.fixture(scope="module")
+def sorting_analyzer_sparse_for_export():
+ return make_sorting_analyzer(sparse=True)
diff --git a/src/spikeinterface/exporters/tests/test_export_to_ibl.py b/src/spikeinterface/exporters/tests/test_export_to_ibl.py
index c7be6911cc..ee11d40695 100644
--- a/src/spikeinterface/exporters/tests/test_export_to_ibl.py
+++ b/src/spikeinterface/exporters/tests/test_export_to_ibl.py
@@ -2,10 +2,7 @@
from spikeinterface.preprocessing import bandpass_filter, decimate
from spikeinterface.exporters import export_to_ibl_gui
-from spikeinterface.exporters.tests.common import (
- make_sorting_analyzer,
- sorting_analyzer_sparse_for_export,
-)
+
required_output_files = [
"spikes.times.npy",
@@ -107,8 +104,3 @@ def test_missing_info(sorting_analyzer_sparse_for_export, create_cache_folder):
with pytest.raises(ValueError, match="Missing required extension"):
export_to_ibl_gui(sorting_analyzer, output_folder, n_jobs=-1)
-
-
-if __name__ == "__main__":
- sorting_analyzer = make_sorting_analyzer(sparse=True)
- test_export_ap_to_ibl(sorting_analyzer)
diff --git a/src/spikeinterface/exporters/tests/test_export_to_phy.py b/src/spikeinterface/exporters/tests/test_export_to_phy.py
index f46ecd3260..08c91fa0f2 100644
--- a/src/spikeinterface/exporters/tests/test_export_to_phy.py
+++ b/src/spikeinterface/exporters/tests/test_export_to_phy.py
@@ -6,13 +6,6 @@
from spikeinterface.core import generate_ground_truth_recording, create_sorting_analyzer
from spikeinterface.exporters import export_to_phy
-from spikeinterface.exporters.tests.common import (
- make_sorting_analyzer,
- sorting_analyzer_dense_for_export,
- sorting_analyzer_sparse_for_export,
- sorting_analyzer_with_group_for_export,
-)
-
def test_export_to_phy_dense(sorting_analyzer_dense_for_export, create_cache_folder):
cache_folder = create_cache_folder
@@ -286,13 +279,3 @@ def test_export_to_phy_add_waveforms_missing_extension(create_cache_folder):
assert not (output_folder / "_phy_spikes_subset.spikes.npy").is_file()
assert not (output_folder / "_phy_spikes_subset.channels.npy").is_file()
assert not (output_folder / "_phy_spikes_subset.waveforms.npy").is_file()
-
-
-if __name__ == "__main__":
- sorting_analyzer_sparse = make_sorting_analyzer(sparse=True)
- sorting_analyzer_group = make_sorting_analyzer(sparse=False, with_group=True)
- sorting_analyzer_dense = make_sorting_analyzer(sparse=False)
-
- test_export_to_phy_dense(sorting_analyzer_dense)
- test_export_to_phy_sparse(sorting_analyzer_sparse)
- test_export_to_phy_by_property(sorting_analyzer_group)
diff --git a/src/spikeinterface/exporters/tests/test_report.py b/src/spikeinterface/exporters/tests/test_report.py
index a2ee9e885c..7f9e7636d6 100644
--- a/src/spikeinterface/exporters/tests/test_report.py
+++ b/src/spikeinterface/exporters/tests/test_report.py
@@ -1,12 +1,6 @@
import shutil
from spikeinterface.exporters import export_report
-from spikeinterface.exporters.tests.common import (
- make_sorting_analyzer,
- sorting_analyzer_dense_for_export,
- sorting_analyzer_sparse_for_export,
- sorting_analyzer_with_group_for_export,
-)
def test_export_report(sorting_analyzer_sparse_for_export, create_cache_folder):
@@ -19,8 +13,3 @@ def test_export_report(sorting_analyzer_sparse_for_export, create_cache_folder):
job_kwargs = dict(n_jobs=1, chunk_size=30000, progress_bar=True)
export_report(sorting_analyzer, report_folder, force_computation=True, **job_kwargs)
-
-
-if __name__ == "__main__":
- sorting_analyzer = make_sorting_analyzer(sparse=True)
- test_export_report(sorting_analyzer)
diff --git a/src/spikeinterface/exporters/to_phy.py b/src/spikeinterface/exporters/to_phy.py
index c6ea703770..40dae800f1 100644
--- a/src/spikeinterface/exporters/to_phy.py
+++ b/src/spikeinterface/exporters/to_phy.py
@@ -79,9 +79,9 @@ def export_to_phy(
assert isinstance(sorting_analyzer, SortingAnalyzer), "sorting_analyzer must be a SortingAnalyzer object"
sorting = sorting_analyzer.sorting
- assert (
- sorting_analyzer.get_num_segments() == 1
- ), f"Export to phy only works with one segment, your extractor has {sorting_analyzer.get_num_segments()} segments"
+ assert sorting_analyzer.get_num_segments() == 1, (
+ f"Export to phy only works with one segment, your extractor has {sorting_analyzer.get_num_segments()} segments"
+ )
num_chans = sorting_analyzer.get_num_channels()
fs = sorting_analyzer.sampling_frequency
@@ -159,7 +159,7 @@ def export_to_phy(
with (output_folder / "params.py").open("w") as f:
if use_relative_path:
if copy_binary:
- f.write(f"dat_path = r'recording.dat'\n")
+ f.write("dat_path = r'recording.dat'\n")
elif rec_path == "None":
f.write(f"dat_path = {rec_path}\n")
else:
@@ -168,7 +168,7 @@ def export_to_phy(
f.write(f"dat_path = r'{str(rec_path)}'\n")
f.write(f"n_channels_dat = {num_chans}\n")
f.write(f"dtype = '{dtype_str}'\n")
- f.write(f"offset = 0\n")
+ f.write("offset = 0\n")
f.write(f"sample_rate = {fs}\n")
f.write(f"hp_filtered = {sorting_analyzer.is_filtered()}")
diff --git a/src/spikeinterface/extractors/cbin_ibl.py b/src/spikeinterface/extractors/cbin_ibl.py
index adf04f366a..0a47d7efab 100644
--- a/src/spikeinterface/extractors/cbin_ibl.py
+++ b/src/spikeinterface/extractors/cbin_ibl.py
@@ -1,6 +1,5 @@
from pathlib import Path
import re
-import warnings
import numpy as np
import probeinterface
@@ -142,9 +141,9 @@ def __init__(self, folder_path=None, load_sync_channel=False, stream_name="ap",
# snippets downloaded from IBL have the .stream.cbin suffix
cbin_stream_files = list(folder_path.glob(f"*.{stream_name}.stream.cbin"))
curr_cbin_files = cbin_stream_files if len(cbin_stream_files) > len(cbin_files) else cbin_files
- assert (
- len(curr_cbin_files) == 1
- ), f"There should only be one `*.cbin` file in the folder, but {print(curr_cbin_files)} have been found"
+ assert len(curr_cbin_files) == 1, (
+ f"There should only be one `*.cbin` file in the folder, but {print(curr_cbin_files)} have been found"
+ )
cbin_file_path = curr_cbin_files[0]
else:
cbin_file_path = Path(cbin_file_path)
@@ -274,7 +273,7 @@ def extract_stream_info(meta_file, meta):
gain_factor = float(meta["imAiRangeMax"]) / max_int
channel_gains = gain_factor * per_channel_gain * 1e6
else:
- raise NotImplementedError("This meta file version of spikeglx" " is not implemented")
+ raise NotImplementedError("This meta file version of spikeglx is not implemented")
info = {}
info["fname"] = fname
diff --git a/src/spikeinterface/extractors/cellexplorersortingextractor.py b/src/spikeinterface/extractors/cellexplorersortingextractor.py
index 8659baded8..953c9c315a 100644
--- a/src/spikeinterface/extractors/cellexplorersortingextractor.py
+++ b/src/spikeinterface/extractors/cellexplorersortingextractor.py
@@ -157,9 +157,9 @@ def _retrieve_sampling_frequency_from_session_info_file(self) -> float:
self.session_info_file_path = self.session_path / f"{self.session_id}.sessionInfo.mat"
self.session_info_file_path = Path(self.session_info_file_path).absolute()
- assert (
- self.session_info_file_path.is_file()
- ), f"No {self.session_id}.sessionInfo.mat file found in the {self.session_path}!, can't inferr sampling rate, please pass the sampling rate at initialization"
+ assert self.session_info_file_path.is_file(), (
+ f"No {self.session_id}.sessionInfo.mat file found in the {self.session_path}!, can't inferr sampling rate, please pass the sampling rate at initialization"
+ )
session_info_mat = read_mat(self.session_info_file_path)
rates = session_info_mat["sessionInfo"]["rates"]
diff --git a/src/spikeinterface/extractors/combinatoextractors.py b/src/spikeinterface/extractors/combinatoextractors.py
index 5ecc5cdf24..011af94ba9 100644
--- a/src/spikeinterface/extractors/combinatoextractors.py
+++ b/src/spikeinterface/extractors/combinatoextractors.py
@@ -56,7 +56,6 @@ def __init__(self, folder_path, sampling_frequency=None, user="simple", det_sign
unit_counter = 0
spiketrains = {}
metadata = {}
- unsorted = []
with h5py.File(det_file, mode="r") as fdet:
for sign, sfile in sort_cat_files:
with h5py.File(sfile, mode="r") as f:
diff --git a/src/spikeinterface/extractors/extractor_classes.py b/src/spikeinterface/extractors/extractor_classes.py
index 21c383309f..e398300f8e 100644
--- a/src/spikeinterface/extractors/extractor_classes.py
+++ b/src/spikeinterface/extractors/extractor_classes.py
@@ -18,7 +18,7 @@
# sorting/recording/event from neo
from .neoextractors import *
-from .neoextractors import read_neuroscope
+from .neoextractors import neo_recording_extractors_dict, neo_sorting_extractors_dict, neo_event_extractors_dict
from .neoextractors.intan import read_split_intan_files, IntanSplitFilesRecordingExtractor
# non-NEO objects implemented in neo folder
diff --git a/src/spikeinterface/extractors/iblextractors.py b/src/spikeinterface/extractors/iblextractors.py
index 8a57e40ec3..69c072931b 100644
--- a/src/spikeinterface/extractors/iblextractors.py
+++ b/src/spikeinterface/extractors/iblextractors.py
@@ -172,9 +172,9 @@ def __init__(
else:
stream_names = IblRecordingExtractor.get_stream_names(eid=eid, cache_folder=cache_folder, one=one)
if len(stream_names) > 1:
- assert (
- stream_name is not None
- ), f"Multiple streams found for session. Please specify a stream name from {stream_names}."
+ assert stream_name is not None, (
+ f"Multiple streams found for session. Please specify a stream name from {stream_names}."
+ )
assert stream_name in stream_names, (
f"The `stream_name` '{stream_name}' is not available for this experiment {eid}! "
f"Please choose one of {stream_names}."
@@ -320,7 +320,7 @@ class IblSortingExtractor(BaseSorting):
The loaded data.
"""
- installation_mesg = "IBL extractors require ibllib as a dependency." " To install, run: \n\n pip install ibllib\n\n"
+ installation_mesg = "IBL extractors require ibllib as a dependency. To install, run: \n\n pip install ibllib\n\n"
def __init__(
self, pid: str, good_clusters_only: bool = False, load_unit_properties: bool = True, one=None, **kwargs
diff --git a/src/spikeinterface/extractors/klustaextractors.py b/src/spikeinterface/extractors/klustaextractors.py
index d18c8d831f..604e31bad5 100644
--- a/src/spikeinterface/extractors/klustaextractors.py
+++ b/src/spikeinterface/extractors/klustaextractors.py
@@ -61,7 +61,7 @@ def __init__(self, file_or_folder_path, exclude_cluster_groups=None):
config_file = [f for f in klustafolder.iterdir() if f.suffix == ".prm"][0]
config = read_python(str(config_file))
sampling_frequency = config["traces"]["sample_rate"]
- except Exception as e:
+ except Exception:
print("Could not load sampling frequency info")
kf_reader = h5py.File(kwikfile, "r")
@@ -96,9 +96,9 @@ def __init__(self, file_or_folder_path, exclude_cluster_groups=None):
"cluster_group"
]
- assert (
- cluster_group in self.default_cluster_groups.keys()
- ), f'cluster_group not in "default_dict: {cluster_group}'
+ assert cluster_group in self.default_cluster_groups.keys(), (
+ f'cluster_group not in "default_dict: {cluster_group}'
+ )
cluster_group_name = self.default_cluster_groups[cluster_group]
if cluster_group_name.lower() in cs_to_exclude:
diff --git a/src/spikeinterface/extractors/matlabhelpers.py b/src/spikeinterface/extractors/matlabhelpers.py
index f7ffb45065..8ffe31d665 100644
--- a/src/spikeinterface/extractors/matlabhelpers.py
+++ b/src/spikeinterface/extractors/matlabhelpers.py
@@ -18,7 +18,8 @@
class MatlabHelper:
installation_mesg = (
- "To use the MATSortingExtractor install h5py and scipy: " "\n\n pip install h5py scipy\n\n"
+ "To use the MATSortingExtractor install h5py and scipy: "
+ "\n\n pip install h5py scipy\n\n"
) # error message when not installed
def __init__(self, file_path):
diff --git a/src/spikeinterface/extractors/mcsh5extractors.py b/src/spikeinterface/extractors/mcsh5extractors.py
index 3e295f33b4..df0004f09a 100644
--- a/src/spikeinterface/extractors/mcsh5extractors.py
+++ b/src/spikeinterface/extractors/mcsh5extractors.py
@@ -111,7 +111,7 @@ def openMCSH5File(filename, stream_id):
stream_name = "Stream_" + str(stream_id)
analog_stream_names = list(rf.require_group("/Data/Recording_0/AnalogStream").keys())
assert stream_name in analog_stream_names, (
- f"Specified stream does not exist. " f"Available streams: {analog_stream_names}"
+ f"Specified stream does not exist. Available streams: {analog_stream_names}"
)
stream = rf.require_group("/Data/Recording_0/AnalogStream/" + stream_name)
@@ -141,9 +141,9 @@ def openMCSH5File(filename, stream_id):
timestep_avg = np.mean(TimeVals[1:] - TimeVals[0:-1])
timestep_min = np.min(TimeVals[1:] - TimeVals[0:-1])
timestep_max = np.min(TimeVals[1:] - TimeVals[0:-1])
- assert all(
- np.abs(np.array((timestep_min, timestep_max)) - timestep_avg) / timestep_avg < 1e-6
- ), "Time steps vary by more than 1 ppm"
+ assert all(np.abs(np.array((timestep_min, timestep_max)) - timestep_avg) / timestep_avg < 1e-6), (
+ "Time steps vary by more than 1 ppm"
+ )
samplingRate = 1.0 / timestep_avg
mcs_info = {
diff --git a/src/spikeinterface/extractors/mdaextractors.py b/src/spikeinterface/extractors/mdaextractors.py
index 12a7474df7..639c77597f 100644
--- a/src/spikeinterface/extractors/mdaextractors.py
+++ b/src/spikeinterface/extractors/mdaextractors.py
@@ -43,8 +43,7 @@ def __init__(self, folder_path, raw_fname="raw.mda", params_fname="params.json",
dtype = self._diskreadmda.dt()
num_channels = self._diskreadmda.N1()
assert geom.shape[0] == self._diskreadmda.N1(), (
- f"Incompatible dimensions between geom.csv and timeseries "
- f"file: {geom.shape[0]} <> {self._diskreadmda.N1()}"
+ f"Incompatible dimensions between geom.csv and timeseries file: {geom.shape[0]} <> {self._diskreadmda.N1()}"
)
sampling_frequency = float(self._dataset_params["samplerate"])
BaseRecording.__init__(
@@ -102,7 +101,7 @@ def write_recording(
"""
job_kwargs = fix_job_kwargs(job_kwargs)
assert recording.get_num_segments() == 1, (
- "MdaRecording.write_recording() can only write a single segment " "recording"
+ "MdaRecording.write_recording() can only write a single segment recording"
)
save_path = Path(save_path)
save_path.mkdir(parents=True, exist_ok=True)
@@ -434,7 +433,7 @@ def _read_chunk_1d(self, i, N):
tmp_fname = _download_bytes_to_tmpfile(self._path, offset, offset + self._header.num_bytes_per_entry * N)
try:
ret = self._read_chunk_1d_helper(tmp_fname, N, offset=0)
- except:
+ except Exception:
ret = None
return ret
return self._read_chunk_1d_helper(self._path, N, offset=offset)
@@ -482,7 +481,7 @@ def _read_header(path):
raise Exception("Problem downloading bytes from " + path)
try:
ret = _read_header(tmp_fname)
- except:
+ except Exception:
ret = None
Path(tmp_fname).unlink()
return ret
@@ -490,7 +489,7 @@ def _read_header(path):
f = open(path, "rb")
try:
dt_code = _read_int32(f)
- num_bytes_per_entry = _read_int32(f)
+ _read_int32(f) # num_bytes_per_entry: unused, but must be read to advance the file pointer
num_dims = _read_int32(f)
uses64bitdims = False
if num_dims < 0:
@@ -689,7 +688,7 @@ def _writemda(X, fname, dt):
print(f"Unexpected data type: {dt}")
return False
- if type(fname) == str:
+ if type(fname) is str:
f = open(fname, "wb")
else:
f = fname
@@ -706,13 +705,13 @@ def _writemda(X, fname, dt):
bytes0 = X.astype(dt).tobytes(order="F")
f.write(bytes0)
- if type(fname) == str:
+ if type(fname) is str:
f.close()
return True
except Exception as e: # catch *all* exceptions
traceback.print_exc()
print(e)
- if type(fname) == str:
+ if type(fname) is str:
f.close()
return False
@@ -791,7 +790,7 @@ def appendmda(X, path):
def file_extension(fname):
- if type(fname) == str:
+ if type(fname) is str:
filename, ext = os.path.splitext(fname)
return ext
else:
@@ -817,7 +816,7 @@ def _write_int64(f, val):
def _header_from_file(f):
try:
dt_code = _read_int32(f)
- num_bytes_per_entry = _read_int32(f)
+ _read_int32(f) # num_bytes_per_entry: unused, but must be read to advance the file pointer
num_dims = _read_int32(f)
uses64bitdims = False
if num_dims < 0:
diff --git a/src/spikeinterface/extractors/neoextractors/intan.py b/src/spikeinterface/extractors/neoextractors/intan.py
index 877f7f33b2..4f0fd31ea5 100644
--- a/src/spikeinterface/extractors/neoextractors/intan.py
+++ b/src/spikeinterface/extractors/neoextractors/intan.py
@@ -156,7 +156,7 @@ def __init__(
if mode not in ("append", "concatenate"):
mode_error = (
- "Possible options for the `mode` argument are 'concatenate' or 'append', you have entered " f"{mode}."
+ f"Possible options for the `mode` argument are 'concatenate' or 'append', you have entered {mode}."
)
raise ValueError(mode_error)
diff --git a/src/spikeinterface/extractors/neoextractors/neo_utils.py b/src/spikeinterface/extractors/neoextractors/neo_utils.py
index 9a0a01e50a..1bc1e486eb 100644
--- a/src/spikeinterface/extractors/neoextractors/neo_utils.py
+++ b/src/spikeinterface/extractors/neoextractors/neo_utils.py
@@ -1,6 +1,3 @@
-from .neobaseextractor import NeoBaseRecordingExtractor
-
-
def get_neo_streams(extractor_name, *args, **kwargs):
"""Returns the NEO streams (stream names and stream ids) associated to a dataset.
For multi-stream datasets, the `stream_id` or `stream_name` arguments can be used
@@ -57,7 +54,7 @@ def get_neo_extractor(extractor_name):
from spikeinterface.extractors.neoextractors import neo_recording_class_dict
assert extractor_name in neo_recording_class_dict, (
- f"{extractor_name} not an extractor name:" f"\n{list(neo_recording_class_dict.keys())}"
+ f"{extractor_name} not an extractor name:\n{list(neo_recording_class_dict.keys())}"
)
neo_extractor = neo_recording_class_dict[extractor_name]
return neo_extractor
diff --git a/src/spikeinterface/extractors/neoextractors/neobaseextractor.py b/src/spikeinterface/extractors/neoextractors/neobaseextractor.py
index b9832f7fe8..7e70adcbda 100644
--- a/src/spikeinterface/extractors/neoextractors/neobaseextractor.py
+++ b/src/spikeinterface/extractors/neoextractors/neobaseextractor.py
@@ -230,9 +230,9 @@ def __init__(
if use_names_as_ids:
chan_names = signal_channels["name"]
- assert (
- chan_names.size == np.unique(chan_names).size
- ), "use_names_as_ids=True is not possible, channel names are not unique"
+ assert chan_names.size == np.unique(chan_names).size, (
+ "use_names_as_ids=True is not possible, channel names are not unique"
+ )
chan_ids = chan_names
else:
# unique in all cases
@@ -577,9 +577,7 @@ def _infer_t_start_from_signal_stream(self, segment_index: int, stream_id: str |
if len(unique_t_starts) == 0:
t_start = None
- warning_message = (
- "No stream ids with corresponding sampling frequency found \n " "Setting t_start to None. \n"
- )
+ warning_message = "No stream ids with corresponding sampling frequency found \n Setting t_start to None. \n"
warnings.warn(warning_message)
if len(unique_t_starts) == 1:
@@ -671,9 +669,9 @@ def __init__(self, block_index=None, use_names_as_ids: bool = False, **neo_kwarg
if use_names_as_ids:
channel_ids = event_channels["name"]
- assert (
- event_channels.size == np.unique(channel_ids).size
- ), "use_name_as_ids=True is not possible, channel names are not unique"
+ assert event_channels.size == np.unique(channel_ids).size, (
+ "use_name_as_ids=True is not possible, channel names are not unique"
+ )
else:
channel_ids = event_channels["id"]
diff --git a/src/spikeinterface/extractors/neoextractors/neuroscope.py b/src/spikeinterface/extractors/neoextractors/neuroscope.py
index 7064ea1303..bc02faa0e3 100644
--- a/src/spikeinterface/extractors/neoextractors/neuroscope.py
+++ b/src/spikeinterface/extractors/neoextractors/neuroscope.py
@@ -188,21 +188,20 @@ def __init__(
):
from lxml import etree as et
- assert not (
- folder_path is None and resfile_path is None and clufile_path is None
- ), "Either pass a single folder_path location, or a pair of resfile_path and clufile_path! None received."
+ assert not (folder_path is None and resfile_path is None and clufile_path is None), (
+ "Either pass a single folder_path location, or a pair of resfile_path and clufile_path! None received."
+ )
if resfile_path is not None:
assert clufile_path is not None, "If passing resfile_path or clufile_path, both are required!"
resfile_path = Path(resfile_path)
clufile_path = Path(clufile_path)
- assert (
- resfile_path.is_file() and clufile_path.is_file()
- ), f"The resfile_path ({resfile_path}) and clufile_path ({clufile_path}) must be .res and .clu files!"
+ assert resfile_path.is_file() and clufile_path.is_file(), (
+ f"The resfile_path ({resfile_path}) and clufile_path ({clufile_path}) must be .res and .clu files!"
+ )
assert folder_path is None, (
- "Pass either a single folder_path location, "
- "or a pair of resfile_path and clufile_path! All received."
+ "Pass either a single folder_path location, or a pair of resfile_path and clufile_path! All received."
)
folder_path_passed = False
folder_path = resfile_path.parent
@@ -225,9 +224,9 @@ def __init__(
folder_path_passed = True # flag for setting kwargs for proper dumping
if exclude_shanks is not None: # dumping checks do not like having an empty list as default
- assert all(
- [isinstance(x, (int, np.integer)) and x >= 0 for x in exclude_shanks]
- ), "Optional argument 'exclude_shanks' must contain positive integers only!"
+ assert all([isinstance(x, (int, np.integer)) and x >= 0 for x in exclude_shanks]), (
+ "Optional argument 'exclude_shanks' must contain positive integers only!"
+ )
else:
exclude_shanks = []
xml_file_path = _handle_xml_file_path(folder_path=folder_path, initial_xml_file_path=xml_file_path)
@@ -248,9 +247,9 @@ def __init__(
resfile_names = [x.name[: x.name.find(".res")] for x in res_files]
clufile_names = [x.name[: x.name.find(".clu")] for x in clu_files]
- assert np.all(
- r == c for (r, c) in zip(resfile_names, clufile_names)
- ), "Some of the .res.%i and .clu.%i files do not share the same name!"
+ assert np.all(r == c for (r, c) in zip(resfile_names, clufile_names)), (
+ "Some of the .res.%i and .clu.%i files do not share the same name!"
+ )
all_unit_ids = []
all_spiketrains = []
@@ -272,9 +271,9 @@ def __init__(
n_clu = clu[0]
clu = np.delete(clu, 0)
unique_ids = np.unique(clu)
- assert (
- len(unique_ids) == n_clu
- ), "First value of .clu file ({clufile_path}) does not match number of unique IDs!"
+ assert len(unique_ids) == n_clu, (
+ "First value of .clu file ({clufile_path}) does not match number of unique IDs!"
+ )
unit_map = dict(zip(unique_ids, list(range(1, n_clu + 1))))
if 0 in unique_ids:
diff --git a/src/spikeinterface/extractors/neoextractors/spike2.py b/src/spikeinterface/extractors/neoextractors/spike2.py
index 6283176def..e41dac547d 100644
--- a/src/spikeinterface/extractors/neoextractors/spike2.py
+++ b/src/spikeinterface/extractors/neoextractors/spike2.py
@@ -2,7 +2,7 @@
from spikeinterface.core.core_tools import define_function_from_class
-from .neobaseextractor import NeoBaseRecordingExtractor, NeoBaseSortingExtractor
+from .neobaseextractor import NeoBaseRecordingExtractor
class Spike2RecordingExtractor(NeoBaseRecordingExtractor):
diff --git a/src/spikeinterface/extractors/neuropixels_utils.py b/src/spikeinterface/extractors/neuropixels_utils.py
index df66230548..115a43be4b 100644
--- a/src/spikeinterface/extractors/neuropixels_utils.py
+++ b/src/spikeinterface/extractors/neuropixels_utils.py
@@ -90,33 +90,33 @@ def compute_saturation_threshold_from_probe(probe: Probe, stream_name: str) -> f
return None
-def synchronize_neuropixel_streams(recording_ref, recording_other):
- """
- Use the last "sync" channel from spikeglx or openephys neuropixels to synchronize
- recordings.
-
- Method used :
- 1. detect pulse times on both streams.
- 2. make a linear regression from "other" to "ref".
- The slope is nclose to 1 and corresponds to the sample rate correction
- The intercept is close to 0 and corresponds to the delta time start
-
- """
- # This will be done very very soon, I promise.
- raise NotImplementedError
-
- synhcro_chan_id = recording_ref.channel_ids[-1]
- trig_ref = recording_ref.get_traces(channel_ids=[synhcro_chan_id], return_in_uV=False)
- trig_ref = trig_ref[:, 0]
- times_ref = recording_ref.get_times()
-
- synhcro_chan_id = recording_other.channel_ids[-1]
- trig_other = recording_other.get_traces(channel_ids=[synhcro_chan_id], return_in_uV=False)
- trig_other = trig_other[:, 0]
- times_other = recording_other.get_times()
-
- # import matplotlib.pyplot as plt
- # fig, ax = plt.subplots()
- # ax.plot(times_ref, trig_ref)
- # ax.plot(times_other, trig_other)
- # plt.show()
+# def synchronize_neuropixel_streams(recording_ref, recording_other):
+# """
+# Use the last "sync" channel from spikeglx or openephys neuropixels to synchronize
+# recordings.
+
+# Method used :
+# 1. detect pulse times on both streams.
+# 2. make a linear regression from "other" to "ref".
+# The slope is nclose to 1 and corresponds to the sample rate correction
+# The intercept is close to 0 and corresponds to the delta time start
+
+# """
+# # This will be done very very soon, I promise.
+# raise NotImplementedError
+
+# synhcro_chan_id = recording_ref.channel_ids[-1]
+# trig_ref = recording_ref.get_traces(channel_ids=[synhcro_chan_id], return_in_uV=False)
+# trig_ref = trig_ref[:, 0]
+# times_ref = recording_ref.get_times()
+
+# synhcro_chan_id = recording_other.channel_ids[-1]
+# trig_other = recording_other.get_traces(channel_ids=[synhcro_chan_id], return_in_uV=False)
+# trig_other = trig_other[:, 0]
+# times_other = recording_other.get_times()
+
+# # import matplotlib.pyplot as plt
+# # fig, ax = plt.subplots()
+# # ax.plot(times_ref, trig_ref)
+# # ax.plot(times_other, trig_other)
+# # plt.show()
diff --git a/src/spikeinterface/extractors/nwbextractors.py b/src/spikeinterface/extractors/nwbextractors.py
index 2ed8d490b5..c8536b35e4 100644
--- a/src/spikeinterface/extractors/nwbextractors.py
+++ b/src/spikeinterface/extractors/nwbextractors.py
@@ -420,8 +420,6 @@ def _retrieve_electrodes_indices_from_electrical_series_backend(open_file, elect
"""
if "electrodes" not in electrical_series:
if backend == "zarr":
- import zarr
-
# links must be resolved
zarr_links = electrical_series.attrs.get("_LINKS", electrical_series.attrs.get("zarr_link", []))
electrodes_path = None
@@ -658,9 +656,7 @@ def _locate_units_table(self, backend):
return self.file[self.unit_table_path]
except KeyError:
available = _find_neurodata_type_from_backend(self.file, neurodata_type="Units", backend=backend)
- raise ValueError(
- f"{self.unit_table_path} not found in the NWB file!" f"Available options are: {available}."
- )
+ raise ValueError(f"{self.unit_table_path} not found in the NWB file!Available options are: {available}.")
@staticmethod
def available_units_tables(file_path, stream_mode=None, storage_options=None):
@@ -838,7 +834,7 @@ def _locate_electrical_series(self, backend):
except KeyError:
available = _find_neurodata_type_from_backend(self.file, neurodata_type="ElectricalSeries", backend=backend)
raise ValueError(
- f"{self.electrical_series_path} not found in the NWB file!" f"Available options are: {available}."
+ f"{self.electrical_series_path} not found in the NWB file!Available options are: {available}."
)
# --- electrodes table ----------------------------------------------------------------------
diff --git a/src/spikeinterface/extractors/phykilosortextractors.py b/src/spikeinterface/extractors/phykilosortextractors.py
index 300a9b4662..995ffffe31 100644
--- a/src/spikeinterface/extractors/phykilosortextractors.py
+++ b/src/spikeinterface/extractors/phykilosortextractors.py
@@ -17,7 +17,7 @@
from spikeinterface.core.core_tools import define_function_from_class
from spikeinterface.core.base import minimum_spike_dtype
-from spikeinterface.postprocessing import ComputeSpikeAmplitudes, ComputeSpikeLocations
+from spikeinterface.postprocessing import ComputeSpikeLocations
from probeinterface import read_prb, Probe, ProbeGroup
@@ -164,7 +164,6 @@ def __init__(
del cluster_info["id"]
if remove_empty_units:
-
unique_unit_ids_list = [int(clust) for clust in unique_unit_ids]
cluster_info = cluster_info.query(f"cluster_id in {unique_unit_ids_list}")
@@ -574,7 +573,6 @@ def _make_templates(
# Used for kilosort 2, 2.5 and 3
else:
-
warnings.warn("Can't extract `ms_before` and `ms_after` from Kilosort output. Guessing a sensible value.")
samples_in_templates = np.shape(new_templates)[1]
diff --git a/src/spikeinterface/extractors/shybridextractors.py b/src/spikeinterface/extractors/shybridextractors.py
index eca7d46724..9aa7439fab 100644
--- a/src/spikeinterface/extractors/shybridextractors.py
+++ b/src/spikeinterface/extractors/shybridextractors.py
@@ -41,9 +41,7 @@ class SHYBRIDRecordingExtractor(BinaryRecordingExtractor):
Loaded data.
"""
- installation_mesg = (
- "To use the SHYBRID extractors, install SHYBRID and pyyaml: " "\n\n pip install shybrid pyyaml\n\n"
- )
+ installation_mesg = "To use the SHYBRID extractors, install SHYBRID and pyyaml: \n\n pip install shybrid pyyaml\n\n"
def __init__(self, file_path):
if HAVE_SHYBRID:
diff --git a/src/spikeinterface/extractors/sinapsrecordingextractors.py b/src/spikeinterface/extractors/sinapsrecordingextractors.py
index 3e50a17fb0..b3e55437bb 100644
--- a/src/spikeinterface/extractors/sinapsrecordingextractors.py
+++ b/src/spikeinterface/extractors/sinapsrecordingextractors.py
@@ -276,7 +276,7 @@ def get_sinaps_probe(probe_type: str) -> Probe:
try:
probe = get_probe(manufacturer="sinaps-research-platform", probe_name=f"{probe_type}")
- except:
+ except Exception:
# check if custom version of probe was used such as "p256s1_camera"
if "_" in probe_type:
probe_type = probe_type.split("_")[0]
@@ -287,7 +287,7 @@ def get_sinaps_probe(probe_type: str) -> Probe:
try:
probe = get_probe(manufacturer="sinaps-research-platform", probe_name=f"{probe_type}")
- except:
+ except Exception:
warnings.warn(
f"Could not load probe information for {probe_type}. Probe needs to be linked manually with rec.set_probe()"
)
@@ -322,13 +322,13 @@ def parse_sinaps_meta(meta_file: str | Path) -> dict:
val = val.replace("\n", "")
try:
val = int(val)
- except:
+ except Exception:
pass
try:
val = ast.literal_eval(val)
if isinstance(val, tuple):
val = float(str(val[0]) + "." + str(val[1]))
- except:
+ except Exception:
pass
sinaps_info[key] = val
return sinaps_info
diff --git a/src/spikeinterface/extractors/tests/common_tests.py b/src/spikeinterface/extractors/tests/common_tests.py
index ea733a368b..0741785d9f 100644
--- a/src/spikeinterface/extractors/tests/common_tests.py
+++ b/src/spikeinterface/extractors/tests/common_tests.py
@@ -102,7 +102,7 @@ def test_neo_annotations(self):
path = entity
kwargs = {}
if hasattr(self.ExtractorClass, "NeoRawIOClass"):
- rec = self.ExtractorClass(self.get_full_path(path), all_annotations=True, **kwargs)
+ _ = self.ExtractorClass(self.get_full_path(path), all_annotations=True, **kwargs)
def test_pickling(self):
for entity in self.entities:
diff --git a/src/spikeinterface/extractors/tests/test_bidsextractors.py b/src/spikeinterface/extractors/tests/test_bidsextractors.py
index 2c78c844ce..075c8e7166 100644
--- a/src/spikeinterface/extractors/tests/test_bidsextractors.py
+++ b/src/spikeinterface/extractors/tests/test_bidsextractors.py
@@ -5,6 +5,7 @@
@pytest.mark.skip("BIDS is tested locally only at the moment")
def test_read_bids_folder():
+ import spikeinterface.full as si
# gin get NeuralEnsemble/BEP032-examples
# cd BEP032-examples
# gin get NeuralEnsemble/BEP032-examples
@@ -16,12 +17,10 @@ def test_read_bids_folder():
recordings = read_bids(folder_path)
# ~ print(recordings)
- rec0 = recordings[0]
+ _ = recordings[0]
rec1 = recordings[1]
rec2 = recordings[2]
- import spikeinterface.full as si
-
sorting = si.run_sorter("herdingspikes", rec1)
print(sorting)
exit()
@@ -32,7 +31,6 @@ def test_read_bids_folder():
import matplotlib.pyplot as plt
from probeinterface.plotting import plot_probe_group
- fig, ax = plt.subplots()
probegroup = rec2.get_probegroup()
print(probegroup)
plot_probe_group(
diff --git a/src/spikeinterface/extractors/tests/test_cbin_ibl_extractors.py b/src/spikeinterface/extractors/tests/test_cbin_ibl_extractors.py
index bc508979b9..b3f6036373 100644
--- a/src/spikeinterface/extractors/tests/test_cbin_ibl_extractors.py
+++ b/src/spikeinterface/extractors/tests/test_cbin_ibl_extractors.py
@@ -3,7 +3,7 @@
import numpy as np
-from spikeinterface.extractors.extractor_classes import CompressedBinaryIblExtractor, read_cbin_ibl
+from spikeinterface.extractors.extractor_classes import CompressedBinaryIblExtractor
from spikeinterface.extractors.cbin_ibl import (
_get_saved_channel_indices,
@@ -13,7 +13,7 @@
extract_stream_info,
)
-from spikeinterface.extractors.tests.common_tests import RecordingCommonTestSuite, SortingCommonTestSuite
+from spikeinterface.extractors.tests.common_tests import RecordingCommonTestSuite
class CompressedBinaryIblExtractorTest(RecordingCommonTestSuite, unittest.TestCase):
diff --git a/src/spikeinterface/extractors/tests/test_datalad_downloading.py b/src/spikeinterface/extractors/tests/test_datalad_downloading.py
index 8abccc6707..082fe52da3 100644
--- a/src/spikeinterface/extractors/tests/test_datalad_downloading.py
+++ b/src/spikeinterface/extractors/tests/test_datalad_downloading.py
@@ -13,6 +13,7 @@ def test_download_dataset():
# local_folder automatic
local_path = download_dataset(repo=repo, remote_path=remote_path, local_folder=None)
+ assert local_path is not None
if __name__ == "__main__":
diff --git a/src/spikeinterface/extractors/tests/test_herdingspikesextractors.py b/src/spikeinterface/extractors/tests/test_herdingspikesextractors.py
index 2286e229c0..15828c4c70 100644
--- a/src/spikeinterface/extractors/tests/test_herdingspikesextractors.py
+++ b/src/spikeinterface/extractors/tests/test_herdingspikesextractors.py
@@ -1,7 +1,5 @@
import pytest
-from spikeinterface.extractors import *
-
@pytest.mark.skip("HerdingSpikes can be tested after running run_herdingspikes()")
def test_herdingspikesextractors():
diff --git a/src/spikeinterface/extractors/tests/test_iblextractors.py b/src/spikeinterface/extractors/tests/test_iblextractors.py
index eb87b34829..f09ebf8354 100644
--- a/src/spikeinterface/extractors/tests/test_iblextractors.py
+++ b/src/spikeinterface/extractors/tests/test_iblextractors.py
@@ -1,4 +1,3 @@
-import sys
from re import escape
from unittest import TestCase
@@ -27,7 +26,7 @@ def setUpClass(cls):
silent=True,
cache_dir=None,
)
- except:
+ except Exception:
print("Skipping test due to server being down.")
pytest.skip("Skipping test due to server being down.")
try:
@@ -124,7 +123,7 @@ def setUpClass(cls):
silent=True,
cache_dir=None,
)
- except:
+ except Exception:
pytest.skip("Skipping test due to server being down.")
cls.recording = read_ibl_recording(eid=cls.eid, stream_name="probe00.ap", load_sync_channel=True, one=cls.one)
cls.small_scaled_trace = cls.recording.get_traces(start_frame=5, end_frame=26, return_in_uV=True)
@@ -200,7 +199,7 @@ def test_ibl_sorting_extractor(self):
silent=True,
cache_dir=None,
)
- except:
+ except Exception:
pytest.skip("Skipping test due to server being down.")
sorting = read_ibl_sorting(pid=PID, one=one, revision="2023-12-05")
assert len(sorting.unit_ids) == 733
diff --git a/src/spikeinterface/extractors/tests/test_mdaextractors.py b/src/spikeinterface/extractors/tests/test_mdaextractors.py
index 88daddeab4..e0db494eb2 100644
--- a/src/spikeinterface/extractors/tests/test_mdaextractors.py
+++ b/src/spikeinterface/extractors/tests/test_mdaextractors.py
@@ -17,7 +17,7 @@ def test_mda_extractors(create_cache_folder):
MdaRecordingExtractor.write_recording(rec, cache_folder / "mdatest")
rec_mda = MdaRecordingExtractor(cache_folder / "mdatest")
- probe = rec_mda.get_probe()
+ assert rec_mda.has_probe()
check_recordings_equal(rec, rec_mda, return_in_uV=False)
diff --git a/src/spikeinterface/extractors/tests/test_neoextractors.py b/src/spikeinterface/extractors/tests/test_neoextractors.py
index 228409b8f9..d7833c90cd 100644
--- a/src/spikeinterface/extractors/tests/test_neoextractors.py
+++ b/src/spikeinterface/extractors/tests/test_neoextractors.py
@@ -2,7 +2,6 @@
import platform
import subprocess
import os
-from packaging import version
import importlib.util
import pytest
@@ -37,7 +36,6 @@
AxonaRecordingExtractor,
Plexon2EventExtractor,
MaxwellRecordingExtractor,
- CedRecordingExtractor,
AlphaOmegaRecordingExtractor,
Spike2RecordingExtractor,
EDFRecordingExtractor,
diff --git a/src/spikeinterface/extractors/tests/test_nwbextractors.py b/src/spikeinterface/extractors/tests/test_nwbextractors.py
index b442216d86..ba724b4731 100644
--- a/src/spikeinterface/extractors/tests/test_nwbextractors.py
+++ b/src/spikeinterface/extractors/tests/test_nwbextractors.py
@@ -447,7 +447,7 @@ def test_failure_with_wrong_electrical_series_path(generate_nwbfile, use_pynwb):
"""Test that the extractor raises an error if the electrical series name is not found."""
path_to_nwbfile, _ = generate_nwbfile
with pytest.raises(ValueError):
- recording_extractor = NwbRecordingExtractor(
+ _ = NwbRecordingExtractor(
path_to_nwbfile,
electrical_series_path="acquisition/ElectricalSeries3",
use_pynwb=use_pynwb,
@@ -627,7 +627,7 @@ def test_sorting_extraction_start_time(tmp_path, use_pynwb):
def test_sorting_extraction_start_time_from_series(tmp_path, use_pynwb):
from pynwb import NWBHDF5IO
from pynwb.testing.mock.file import mock_NWBFile
- from pynwb.ecephys import ElectricalSeries, LFP, FilteredEphys
+ from pynwb.ecephys import ElectricalSeries
from pynwb.testing.mock.ecephys import mock_electrodes
@@ -860,7 +860,7 @@ def test_sorting_electrical_series_path_and_time_base_are_mutually_exclusive(tmp
**extra_kwarg,
)
expected_error = (
- "Provide either 'electrical_series_path' or the time base ('sampling_frequency' and " "'t_start'), not both."
+ "Provide either 'electrical_series_path' or the time base ('sampling_frequency' and 't_start'), not both."
)
assert str(exc_info.value) == expected_error
@@ -1097,7 +1097,7 @@ def test_multiple_unit_tables(tmp_path, use_pynwb):
# passing a non existing unit table name should raise an error
with pytest.raises(ValueError):
- sorting_extractor = NwbSortingExtractor(
+ _ = NwbSortingExtractor(
file_path=file_path, sampling_frequency=10.0, t_start=0, use_pynwb=use_pynwb, unit_table_path="units2"
)
diff --git a/src/spikeinterface/extractors/tests/test_nwbextractors_streaming.py b/src/spikeinterface/extractors/tests/test_nwbextractors_streaming.py
index 7d43253acf..691f0c978b 100644
--- a/src/spikeinterface/extractors/tests/test_nwbextractors_streaming.py
+++ b/src/spikeinterface/extractors/tests/test_nwbextractors_streaming.py
@@ -10,7 +10,7 @@
from spikeinterface import load
from spikeinterface.core.testing import check_recordings_equal
-from spikeinterface.core.testing import check_recordings_equal, check_sortings_equal
+from spikeinterface.core.testing import check_sortings_equal
from spikeinterface.extractors.extractor_classes import NwbRecordingExtractor, NwbSortingExtractor
py_version = sys.version_info
@@ -42,8 +42,6 @@ def test_recording_s3_nwb_fsspec(tmp_path, cache):
dtype = rec.get_dtype()
for segment_index in range(num_seg):
- num_samples = rec.get_num_samples(segment_index=segment_index)
-
full_traces = rec.get_traces(segment_index=segment_index, start_frame=start_frame, end_frame=end_frame)
assert full_traces.shape == (num_frames, num_chans)
assert full_traces.dtype == dtype
@@ -78,8 +76,6 @@ def test_recording_s3_nwb_remfile():
dtype = rec.get_dtype()
for segment_index in range(num_seg):
- num_samples = rec.get_num_samples(segment_index=segment_index)
-
full_traces = rec.get_traces(segment_index=segment_index, start_frame=start_frame, end_frame=end_frame)
assert full_traces.shape == (num_frames, num_chans)
assert full_traces.dtype == dtype
@@ -108,8 +104,6 @@ def test_recording_s3_nwb_remfile_file_like(tmp_path):
dtype = rec.get_dtype()
for segment_index in range(num_seg):
- num_samples = rec.get_num_samples(segment_index=segment_index)
-
full_traces = rec.get_traces(segment_index=segment_index, start_frame=start_frame, end_frame=end_frame)
assert full_traces.shape == (num_frames, num_chans)
assert full_traces.dtype == dtype
diff --git a/src/spikeinterface/extractors/tests/test_shybridextractors.py b/src/spikeinterface/extractors/tests/test_shybridextractors.py
index e4458f0b36..b69e37cdbd 100644
--- a/src/spikeinterface/extractors/tests/test_shybridextractors.py
+++ b/src/spikeinterface/extractors/tests/test_shybridextractors.py
@@ -22,6 +22,7 @@ def test_shybrid_extractors(create_cache_folder):
)
rec_shybrid = SHYBRIDRecordingExtractor(cache_folder / "shybridtest" / "recording.yml")
probe = rec_shybrid.get_probe()
+ assert probe is not None
check_recordings_equal(rec, rec_shybrid, return_in_uV=False)
diff --git a/src/spikeinterface/extractors/tests/test_toy_example.py b/src/spikeinterface/extractors/tests/test_toy_example.py
index fccb977c85..f863d89cdb 100644
--- a/src/spikeinterface/extractors/tests/test_toy_example.py
+++ b/src/spikeinterface/extractors/tests/test_toy_example.py
@@ -12,6 +12,7 @@ def test_toy_example():
assert sorting.get_num_segments() == 1
probe = rec.get_probe()
+ assert probe is not None
if __name__ == "__main__":
diff --git a/src/spikeinterface/extractors/yassextractors.py b/src/spikeinterface/extractors/yassextractors.py
index 38efeae996..e03a0ba969 100644
--- a/src/spikeinterface/extractors/yassextractors.py
+++ b/src/spikeinterface/extractors/yassextractors.py
@@ -25,7 +25,7 @@ class YassSortingExtractor(BaseSorting):
def __init__(self, folder_path):
try:
import yaml
- except:
+ except Exception:
raise ImportError(self.installation_mesg)
folder_path = Path(folder_path)
diff --git a/src/spikeinterface/generation/drift_tools.py b/src/spikeinterface/generation/drift_tools.py
index 6b95ac3834..da0e85cc32 100644
--- a/src/spikeinterface/generation/drift_tools.py
+++ b/src/spikeinterface/generation/drift_tools.py
@@ -71,7 +71,6 @@ def interpolate_templates(
template = templates_array[template_index, sample_index, :]
if interpolation_method == "thin_plate":
-
if "neighbors" not in interpolation_kwargs:
# If neighbors it not passed, `RBFInterpolator` uses all channels.
# This works poorly for standard ephys template interpolation.
@@ -389,9 +388,9 @@ def __init__(
):
from scipy.spatial import distance
- assert isinstance(
- drifting_templates, DriftingTemplates
- ), "drifting_templates must be a DriftingTemplates object"
+ assert isinstance(drifting_templates, DriftingTemplates), (
+ "drifting_templates must be a DriftingTemplates object"
+ )
self.drifting_templates = drifting_templates
if parent_recording is None:
@@ -419,15 +418,15 @@ def __init__(
amplitude_vector = amplitude_factor
if parent_recording is not None:
- assert (
- parent_recording.get_num_segments() == sorting.get_num_segments()
- ), "parent_recording must have the same number of segments as sorting"
- assert (
- parent_recording.get_sampling_frequency() == sorting.get_sampling_frequency()
- ), "parent_recording must have the same sampling frequency as sorting"
- assert (
- parent_recording.get_num_channels() == drifting_templates.num_channels
- ), "parent_recording must have the same number of channels as templates"
+ assert parent_recording.get_num_segments() == sorting.get_num_segments(), (
+ "parent_recording must have the same number of segments as sorting"
+ )
+ assert parent_recording.get_sampling_frequency() == sorting.get_sampling_frequency(), (
+ "parent_recording must have the same sampling frequency as sorting"
+ )
+ assert parent_recording.get_num_channels() == drifting_templates.num_channels, (
+ "parent_recording must have the same number of channels as templates"
+ )
parent_recording.copy_metadata(self)
if num_samples is None:
@@ -441,29 +440,29 @@ def __init__(
num_samples = [num_samples]
# check drift vector shape and length
- assert (
- len(displacement_vectors) == sorting.get_num_segments()
- ), "displacement_vectors must have the same number of segments as sorting"
+ assert len(displacement_vectors) == sorting.get_num_segments(), (
+ "displacement_vectors must have the same number of segments as sorting"
+ )
if displacement_unit_factor is None:
displacement_unit_factor = np.ones(sorting.get_num_units(), dtype="float32")
- assert displacement_unit_factor.shape[0] == len(
- sorting.unit_ids
- ), "displacement_unit_factor must have the same number of units as sorting"
+ assert displacement_unit_factor.shape[0] == len(sorting.unit_ids), (
+ "displacement_unit_factor must have the same number of units as sorting"
+ )
# displacement_vectors_indices = []
for num_segment in range(sorting.get_num_segments()):
duration = displacement_vectors[num_segment].shape[0] / displacement_sampling_frequency
- assert (
- duration >= num_samples[num_segment] / sorting.get_sampling_frequency()
- ), "displacement_vectors duration must span the entire recording segment"
- assert (
- displacement_vectors[num_segment].shape[2] == displacement_unit_factor.shape[1]
- ), "displacement_vectors and displacement_unit_factor must have the same number of motions"
+ assert duration >= num_samples[num_segment] / sorting.get_sampling_frequency(), (
+ "displacement_vectors duration must span the entire recording segment"
+ )
+ assert displacement_vectors[num_segment].shape[2] == displacement_unit_factor.shape[1], (
+ "displacement_vectors and displacement_unit_factor must have the same number of motions"
+ )
# TODO SharedMem for templates
if mode == "precompute":
- assert (
- drifting_templates.templates_array_moved is not None
- ), "drifting_templates must have precomputed displacements"
+ assert drifting_templates.templates_array_moved is not None, (
+ "drifting_templates must have precomputed displacements"
+ )
displacements = drifting_templates.displacements
# compute the displacement indices
diff --git a/src/spikeinterface/generation/drifting_generator.py b/src/spikeinterface/generation/drifting_generator.py
index f217dda1b3..1d3cda2e16 100644
--- a/src/spikeinterface/generation/drifting_generator.py
+++ b/src/spikeinterface/generation/drifting_generator.py
@@ -124,8 +124,8 @@ def make_one_displacement_vector(
t_start_drift = 0.0 if t_start_drift is None else t_start_drift
t_end_drift = duration if t_end_drift is None else t_end_drift
- assert t_start_drift < duration, f"'t_start_drift' must preceed 'duration'!"
- assert t_end_drift <= duration, f"'t_end_drift' must preceed 'duration'!"
+ assert t_start_drift < duration, "'t_start_drift' must preceed 'duration'!"
+ assert t_end_drift <= duration, "'t_end_drift' must preceed 'duration'!"
start_drift_index = int(t_start_drift * displacement_sampling_frequency)
end_drift_index = int(t_end_drift * displacement_sampling_frequency)
@@ -133,7 +133,6 @@ def make_one_displacement_vector(
displacement_vector = np.zeros(num_samples, dtype="float32")
if drift_mode == "zigzag":
-
times = np.arange(end_drift_index - start_drift_index) / displacement_sampling_frequency
freq = 1.0 / period_s
@@ -455,9 +454,9 @@ def generate_drifting_recording(
num_units = sorting.get_num_units()
sampling_frequency = sorting.sampling_frequency
if sorting._recording is not None:
- assert (
- sorting.get_total_duration() == duration
- ), "Sorting should have the same duration as the generated data"
+ assert sorting.get_total_duration() == duration, (
+ "Sorting should have the same duration as the generated data"
+ )
# probe
if probe is None:
diff --git a/src/spikeinterface/generation/hybrid_tools.py b/src/spikeinterface/generation/hybrid_tools.py
index 426699f743..7fad61ee48 100644
--- a/src/spikeinterface/generation/hybrid_tools.py
+++ b/src/spikeinterface/generation/hybrid_tools.py
@@ -121,9 +121,9 @@ def select_templates(
Templates
The selected templates
"""
- assert (
- min_amplitude is not None or max_amplitude is not None or min_depth is not None or max_depth is not None
- ), "At least one of min_amplitude, max_amplitude, min_depth, max_depth should be provided"
+ assert min_amplitude is not None or max_amplitude is not None or min_depth is not None or max_depth is not None, (
+ "At least one of min_amplitude, max_amplitude, min_depth, max_depth should be provided"
+ )
# get template amplitudes and depth
main_channel_indices = templates.get_main_channels(outputs="index", with_dict=False)
@@ -400,9 +400,9 @@ def generate_hybrid_recording(
durations = num_samples / sampling_frequency
channel_locations = probe.contact_positions
- assert (
- templates is not None or sorting is not None or generate_sorting_kwargs is not None
- ), "Provide templates or sorting or generate_sorting_kwargs"
+ assert templates is not None or sorting is not None or generate_sorting_kwargs is not None, (
+ "Provide templates or sorting or generate_sorting_kwargs"
+ )
# check num_units
num_units = None
@@ -444,9 +444,9 @@ def generate_hybrid_recording(
from spikeinterface.postprocessing.localization_tools import compute_monopolar_triangulation
assert isinstance(templates, Templates), "templates should be a Templates object"
- assert (
- templates.num_channels == recording.get_num_channels()
- ), "templates and recording should have the same number of channels"
+ assert templates.num_channels == recording.get_num_channels(), (
+ "templates and recording should have the same number of channels"
+ )
nbefore = templates.nbefore
nafter = templates.nafter
unit_locations = compute_monopolar_triangulation(templates, peak_sign="both", peak_mode="extremum")
@@ -485,9 +485,9 @@ def generate_hybrid_recording(
num_spikes = sorting.to_spike_vector().size
sorting.set_property("gt_unit_locations", unit_locations)
- assert (nbefore + nafter) == templates_array.shape[
- 1
- ], "templates and ms_before, ms_after should have the same length"
+ assert (nbefore + nafter) == templates_array.shape[1], (
+ "templates and ms_before, ms_after should have the same length"
+ )
if templates_array.ndim == 3:
upsample_vector = None
diff --git a/src/spikeinterface/generation/noise_tools.py b/src/spikeinterface/generation/noise_tools.py
index 7fbecf0c9b..3820c55b20 100644
--- a/src/spikeinterface/generation/noise_tools.py
+++ b/src/spikeinterface/generation/noise_tools.py
@@ -81,9 +81,9 @@ def __init__(
num_segments = len(durations)
if cov_matrix is not None:
- assert (
- cov_matrix.shape[0] == cov_matrix.shape[1] == num_channels
- ), "cov_matrix should have a size (num_channels, num_channels)"
+ assert cov_matrix.shape[0] == cov_matrix.shape[1] == num_channels, (
+ "cov_matrix should have a size (num_channels, num_channels)"
+ )
# very important here when multiprocessing and dump/load
seed = _ensure_seed(seed)
diff --git a/src/spikeinterface/generation/template_database.py b/src/spikeinterface/generation/template_database.py
index 83fb42fe38..999f46ebf3 100644
--- a/src/spikeinterface/generation/template_database.py
+++ b/src/spikeinterface/generation/template_database.py
@@ -109,12 +109,12 @@ def query_templates_from_database(template_df: "pandas.DataFrame", verbose: bool
current_channel_locations = templates.get_channel_locations()
current_sampling_frequency = templates.sampling_frequency
- assert (
- current_nbefore == nbefore
- ), f"Number of samples before the peak is not consistent across datasets: {current_nbefore} != {nbefore}"
- assert (
- current_sampling_frequency == sampling_frequency
- ), f"Sampling frequency is not consistent across datasets: {current_sampling_frequency} != {sampling_frequency}"
+ assert current_nbefore == nbefore, (
+ f"Number of samples before the peak is not consistent across datasets: {current_nbefore} != {nbefore}"
+ )
+ assert current_sampling_frequency == sampling_frequency, (
+ f"Sampling frequency is not consistent across datasets: {current_sampling_frequency} != {sampling_frequency}"
+ )
assert np.array_equal(
current_channel_locations - current_channel_locations[0],
channel_locations - channel_locations[0],
diff --git a/src/spikeinterface/generation/tests/test_drifing_generator.py b/src/spikeinterface/generation/tests/test_drifing_generator.py
index 5eb49a04c6..99210abb6b 100644
--- a/src/spikeinterface/generation/tests/test_drifing_generator.py
+++ b/src/spikeinterface/generation/tests/test_drifing_generator.py
@@ -9,17 +9,13 @@
def test_make_one_displacement_vector():
- displacement_vector = make_one_displacement_vector(
- drift_mode="zigzag", duration=700.0, period_s=300, t_start_drift=100.0
- )
+ _ = make_one_displacement_vector(drift_mode="zigzag", duration=700.0, period_s=300, t_start_drift=100.0)
- displacement_vector = make_one_displacement_vector(
+ _ = make_one_displacement_vector(
drift_mode="bump", duration=700.0, period_s=300, bump_interval_s=(30, 90.0), t_start_drift=100.0, seed=2205
)
- displacement_vector = make_one_displacement_vector(
- drift_mode="random_walk", duration=700.0, t_start_drift=100.0, seed=2205
- )
+ _ = make_one_displacement_vector(drift_mode="random_walk", duration=700.0, t_start_drift=100.0, seed=2205)
# import matplotlib.pyplot as plt
# fig, ax = plt.subplots()
diff --git a/src/spikeinterface/generation/tests/test_noise_tools.py b/src/spikeinterface/generation/tests/test_noise_tools.py
index f633ed1de4..d09ea86fde 100644
--- a/src/spikeinterface/generation/tests/test_noise_tools.py
+++ b/src/spikeinterface/generation/tests/test_noise_tools.py
@@ -8,7 +8,7 @@
def test_generate_noise():
probe = probeinterface.generate_multi_columns_probe()
- noise = generate_noise(
+ _ = generate_noise(
probe,
sampling_frequency=25000.0,
durations=[10.0],
@@ -18,7 +18,7 @@ def test_generate_noise():
seed=2205,
)
- noise = generate_noise(
+ _ = generate_noise(
probe,
sampling_frequency=25000.0,
durations=[10.0],
diff --git a/src/spikeinterface/metrics/quality/misc_metrics.py b/src/spikeinterface/metrics/quality/misc_metrics.py
index 9c5c3fa258..016a2d24f9 100644
--- a/src/spikeinterface/metrics/quality/misc_metrics.py
+++ b/src/spikeinterface/metrics/quality/misc_metrics.py
@@ -88,7 +88,7 @@ def compute_presence_ratios(
mean_fr_ratio_thresh = float(mean_fr_ratio_thresh)
if mean_fr_ratio_thresh < 0:
raise ValueError(
- f"Expected positive float for `mean_fr_ratio_thresh` param." f"Provided value: {mean_fr_ratio_thresh}"
+ f"Expected positive float for `mean_fr_ratio_thresh` param.Provided value: {mean_fr_ratio_thresh}"
)
if mean_fr_ratio_thresh > 1:
warnings.warn("`mean_fr_ratio_thres` parameter above 1 might lead to low presence ratios.")
@@ -96,11 +96,10 @@ def compute_presence_ratios(
presence_ratios = {}
if total_samples < bin_duration_samples:
warnings.warn(
- f"Bin duration of {bin_duration_s}s is larger than recording duration. " f"Presence ratios are set to NaN."
+ f"Bin duration of {bin_duration_s}s is larger than recording duration. Presence ratios are set to NaN."
)
presence_ratios = {unit_id: np.nan for unit_id in unit_ids}
else:
-
for unit_id in unit_ids:
if num_spikes[unit_id] == 0:
presence_ratios[unit_id] = np.nan
@@ -1240,9 +1239,7 @@ def compute_drift_metrics(
segment_samples = [sorting_analyzer.get_num_samples(i) for i in range(sorting_analyzer.get_num_segments())]
data = spike_locations_by_unit[unit_ids[0]]
- assert direction in data.dtype.names, (
- f"Direction {direction} is invalid. Available directions: " f"{data.dtype.names}"
- )
+ assert direction in data.dtype.names, f"Direction {direction} is invalid. Available directions: {data.dtype.names}"
bin_edges_for_units = compute_bin_edges_per_unit(
sorting, segment_samples=segment_samples, periods=periods, bin_duration_s=interval_s, concatenated=False
)
diff --git a/src/spikeinterface/metrics/quality/pca_metrics.py b/src/spikeinterface/metrics/quality/pca_metrics.py
index 9134648fe1..d9f5a4a904 100644
--- a/src/spikeinterface/metrics/quality/pca_metrics.py
+++ b/src/spikeinterface/metrics/quality/pca_metrics.py
@@ -31,7 +31,7 @@ def _mahalanobis_metrics_function(sorting_analyzer, unit_ids, tmp_data, **metric
try:
isolation_distance, l_ratio = mahalanobis_metrics(pcs_flat, labels, unit_id)
- except:
+ except Exception:
isolation_distance = np.nan
l_ratio = np.nan
@@ -71,7 +71,7 @@ def _d_prime_metric_function(sorting_analyzer, unit_ids, tmp_data, **metric_para
try:
d_prime = d_prime_metric(pcs_flat, labels, unit_id)
- except:
+ except Exception:
d_prime = np.nan
d_prime_dict[unit_id] = d_prime
@@ -94,7 +94,7 @@ def _nn_one_unit(args):
try:
nn_hit_rate, nn_miss_rate = nearest_neighbors_metrics(pcs_flat, labels, unit_id, **metric_params)
- except:
+ except Exception:
nn_hit_rate = np.nan
nn_miss_rate = np.nan
@@ -116,7 +116,7 @@ def _nearest_neighbor_metric_function(sorting_analyzer, unit_ids, tmp_data, **me
try:
nn_hit_rate, nn_miss_rate = nearest_neighbors_metrics(pcs_flat, labels, unit_id, **metric_params)
- except:
+ except Exception:
nn_hit_rate = np.nan
nn_miss_rate = np.nan
@@ -176,7 +176,7 @@ def _nn_advanced_one_unit(args):
seed=seed,
**nn_isolation_params,
)
- except:
+ except Exception:
nn_isolation, nn_unit_id = np.nan, np.nan
# NN Noise Overlap
@@ -189,7 +189,7 @@ def _nn_advanced_one_unit(args):
seed=seed,
**nn_noise_params,
)
- except:
+ except Exception:
nn_noise_overlap = np.nan
return unit_id, nn_isolation, nn_unit_id, nn_noise_overlap
@@ -321,7 +321,7 @@ def _silhouette_metric_function(sorting_analyzer, unit_ids, tmp_data, **metric_p
silhouette_value = simplified_silhouette_score(pcs_flat, labels, unit_id)
else: # method == "full"
silhouette_value = silhouette_score(pcs_flat, labels, unit_id)
- except:
+ except Exception:
silhouette_value = np.nan
silhouette_dict[unit_id] = silhouette_value
diff --git a/src/spikeinterface/metrics/quality/tests/test_metrics_functions.py b/src/spikeinterface/metrics/quality/tests/test_metrics_functions.py
index 4e793f130b..6d69324ae9 100644
--- a/src/spikeinterface/metrics/quality/tests/test_metrics_functions.py
+++ b/src/spikeinterface/metrics/quality/tests/test_metrics_functions.py
@@ -315,7 +315,7 @@ def test_calculate_firing_range(sorting_analyzer_simple):
firing_ranges_empty = compute_firing_ranges(sorting_analyzer, periods=empty_periods)
assert np.all(np.isnan(np.array(list(firing_ranges_empty.values()))))
- with pytest.warns(UserWarning) as w:
+ with pytest.warns(UserWarning):
firing_ranges_nan = compute_firing_ranges(
sorting_analyzer, bin_size_s=sorting_analyzer.get_total_duration() + 1
)
@@ -400,6 +400,7 @@ def test_calculate_amplitude_cv_metrics(sorting_analyzer_simple, periods_simple)
def test_calculate_snrs(sorting_analyzer_simple, periods_simple):
sorting_analyzer = sorting_analyzer_simple
snrs = compute_snrs(sorting_analyzer)
+ assert isinstance(snrs, dict)
# SNR doesn't support periods
# testing method accuracy with magic number is not a good pratcice, I remove this.
@@ -786,7 +787,7 @@ def test_unit_structure_in_output(small_sorting_analyzer):
metric_fun = metric.metric_function
try:
qm_param = qm_params[metric_name]
- except:
+ except Exception:
qm_param = {}
result_all = metric_fun(sorting_analyzer=small_sorting_analyzer, **qm_param)
@@ -802,7 +803,6 @@ def test_unit_structure_in_output(small_sorting_analyzer):
else:
for result_ind, result in enumerate(result_sub):
-
assert list(result_all[result_ind].keys()) == ["#3", "#9", "#4"], error
assert result_sub[result_ind].keys() == set(["#4", "#9"]), error
diff --git a/src/spikeinterface/metrics/quality/tests/test_quality_metric_calculator.py b/src/spikeinterface/metrics/quality/tests/test_quality_metric_calculator.py
index 823d53f347..2f45a45449 100644
--- a/src/spikeinterface/metrics/quality/tests/test_quality_metric_calculator.py
+++ b/src/spikeinterface/metrics/quality/tests/test_quality_metric_calculator.py
@@ -217,7 +217,7 @@ def test_quality_metrics_with_periods():
periods[idx]["end_sample_index"] = period_end
periods[idx]["segment_index"] = segment_index
- metrics_ext_periods = compute_quality_metrics(
+ _ = compute_quality_metrics(
sorting_analyzer,
metric_names=None,
skip_pc_metrics=True,
@@ -239,7 +239,7 @@ def test_quality_metrics_with_periods():
# should not fail if external periods are the same as valid unit periods
valid_periods = sorting_analyzer.get_extension("valid_unit_periods").get_data(outputs="numpy")
- metrics_ext_periods = compute_quality_metrics(
+ _ = compute_quality_metrics(
sorting_analyzer,
metric_names=None,
skip_pc_metrics=True,
@@ -261,7 +261,6 @@ def test_quality_metrics_with_periods():
if __name__ == "__main__":
-
sorting_analyzer = get_sorting_analyzer()
print(sorting_analyzer)
diff --git a/src/spikeinterface/metrics/template/template_metrics.py b/src/spikeinterface/metrics/template/template_metrics.py
index a23343d0ec..dd79983949 100644
--- a/src/spikeinterface/metrics/template/template_metrics.py
+++ b/src/spikeinterface/metrics/template/template_metrics.py
@@ -88,7 +88,6 @@ def _handle_backward_compatibility_on_load(self):
# For backwards compatibility - this reformats metrics_kwargs as metric_params
if (metrics_kwargs := self.params.get("metrics_kwargs")) is not None:
-
metric_params = {}
for metric_name in self.params["metric_names"]:
metric_params[metric_name] = deepcopy(metrics_kwargs)
diff --git a/src/spikeinterface/metrics/template/tests/test_template_metrics.py b/src/spikeinterface/metrics/template/tests/test_template_metrics.py
index 30314615d1..75204e543d 100644
--- a/src/spikeinterface/metrics/template/tests/test_template_metrics.py
+++ b/src/spikeinterface/metrics/template/tests/test_template_metrics.py
@@ -6,7 +6,7 @@
compute_template_metrics,
get_single_channel_template_metric_names,
)
-from spikeinterface.metrics.template.metrics import single_channel_metrics, multi_channel_metrics
+from spikeinterface.metrics.template.metrics import single_channel_metrics
template_metrics = get_single_channel_template_metric_names()
@@ -137,7 +137,6 @@ def test_save_template_metrics(small_sorting_analyzer, create_cache_folder):
class TestTemplateMetrics(AnalyzerExtensionCommonTestSuite):
-
@pytest.mark.parametrize(
"params",
[
diff --git a/src/spikeinterface/postprocessing/__init__.py b/src/spikeinterface/postprocessing/__init__.py
index 2495536d03..fc5c878fe0 100644
--- a/src/spikeinterface/postprocessing/__init__.py
+++ b/src/spikeinterface/postprocessing/__init__.py
@@ -41,8 +41,6 @@
from .alignsorting import align_sorting, AlignSortingExtractor
-from .noise_level import compute_noise_levels, ComputeNoiseLevels
-
from .valid_unit_periods import (
ComputeValidUnitPeriods,
compute_valid_unit_periods,
diff --git a/src/spikeinterface/postprocessing/amplitude_scalings.py b/src/spikeinterface/postprocessing/amplitude_scalings.py
index 3b6653f70c..6e555c512e 100644
--- a/src/spikeinterface/postprocessing/amplitude_scalings.py
+++ b/src/spikeinterface/postprocessing/amplitude_scalings.py
@@ -93,22 +93,20 @@ def _get_pipeline_nodes(self):
# if ms_before / ms_after are set in params then the original templates are shorten
if self.params["ms_before"] is not None:
cut_out_before = ms_to_samples(self.params["ms_before"], self.sorting_analyzer.sampling_frequency)
- assert (
- cut_out_before <= nbefore
- ), f"`ms_before` must be smaller than `ms_before` used in ComputeTemplates: {nbefore}"
+ assert cut_out_before <= nbefore, (
+ f"`ms_before` must be smaller than `ms_before` used in ComputeTemplates: {nbefore}"
+ )
else:
cut_out_before = nbefore
if self.params["ms_after"] is not None:
cut_out_after = ms_to_samples(self.params["ms_after"], self.sorting_analyzer.sampling_frequency)
- assert (
- cut_out_after <= nafter
- ), f"`ms_after` must be smaller than `ms_after` used in templates: {templates_ext.params['ms_after']}"
+ assert cut_out_after <= nafter, (
+ f"`ms_after` must be smaller than `ms_after` used in templates: {templates_ext.params['ms_after']}"
+ )
else:
cut_out_after = nafter
- extremum_channels_indices = self.sorting_analyzer.get_main_channels(outputs="index", with_dict=True)
-
# collisions
handle_collisions = self.params["handle_collisions"]
delta_collision_ms = self.params["delta_collision_ms"]
@@ -120,9 +118,9 @@ def _get_pipeline_nodes(self):
sparsity = self.params["sparsity"]
# assert provided sparsity is sparser than the one in the waveform extractor
waveform_sparsity = self.sorting_analyzer.sparsity
- assert np.all(
- np.sum(waveform_sparsity.mask, 1) - np.sum(sparsity.mask, 1) > 0
- ), "The provided sparsity needs to be sparser than the one in the waveform extractor!"
+ assert np.all(np.sum(waveform_sparsity.mask, 1) - np.sum(sparsity.mask, 1) > 0), (
+ "The provided sparsity needs to be sparser than the one in the waveform extractor!"
+ )
elif not self.sorting_analyzer.is_sparse() and self.params["sparsity"] is not None:
sparsity = self.params["sparsity"]
else:
@@ -189,9 +187,9 @@ def __init__(
self._offsets = None
self._dtype = np.float32
spike_retriever = find_parent_of_type(parents, SpikeRetriever)
- assert isinstance(
- spike_retriever, SpikeRetriever
- ), "SpikeAmplitudeNode needs a single SpikeRetriever as a parent"
+ assert isinstance(spike_retriever, SpikeRetriever), (
+ "SpikeAmplitudeNode needs a single SpikeRetriever as a parent"
+ )
assert spike_retriever.include_spikes_in_margin, "Need SpikeRetriever with include_spikes_in_margin=True"
if not handle_collisions:
self._margin = max(nbefore, nafter)
@@ -659,7 +657,6 @@ def fit_collision(
y = local_waveform.T.flatten()
X = np.zeros((len(y), len(collision)))
for i, spike in enumerate(collision):
-
# float64 like X, so templates are not truncated to the dtype of unscaled integer or float16 traces
full_template = np.zeros(local_waveform.shape)
@@ -716,14 +713,14 @@ def _plot_collisions(sorting_analyzer, sparsity=None, num_collisions=None):
# TODO: this is broken, sac no longer (06/06/2024)
# has _extension_data and its collisions attribute is unused
- collisions = sac._extension_data[f"collisions"]
+ collisions = sac._extension_data["collisions"]
collision_keys = list(collisions.keys())
num_collisions = num_collisions or len(collisions)
num_collisions = min(num_collisions, len(collisions))
for i in range(num_collisions):
overlapping_spikes = collisions[collision_keys[i]]
- ax = _plot_one_collision(
+ _ = _plot_one_collision(
sorting_analyzer, collision_keys[i], overlapping_spikes, spikes, scalings=scalings, sparsity=sparsity
)
diff --git a/src/spikeinterface/postprocessing/localization_tools.py b/src/spikeinterface/postprocessing/localization_tools.py
index 60746c11e9..06af4a46bd 100644
--- a/src/spikeinterface/postprocessing/localization_tools.py
+++ b/src/spikeinterface/postprocessing/localization_tools.py
@@ -1,5 +1,3 @@
-from typing import Literal
-
import warnings
import importlib.util
@@ -110,9 +108,6 @@ def compute_monopolar_triangulation(
for i, unit_id in enumerate(unit_ids):
chan_inds = sparsity.unit_id_to_channel_indices[unit_id]
neighbours_mask[i, chan_inds] = True
- enforce_decrease_radial_parents = make_radial_order_parents(contact_locations, neighbours_mask)
-
- best_channels = sorting_analyzer_or_templates.get_main_channels(outputs="index", with_dict=True)
unit_location = np.zeros((unit_ids.size, 4), dtype="float64")
for i, unit_id in enumerate(unit_ids):
diff --git a/src/spikeinterface/postprocessing/noise_level.py b/src/spikeinterface/postprocessing/noise_level.py
deleted file mode 100644
index 59ede21fcb..0000000000
--- a/src/spikeinterface/postprocessing/noise_level.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# "noise_levels" extensions is now in core
-# this is kept name space compatibility but should be removed soon
-from spikeinterface.core.analyzer_extension_core import ComputeNoiseLevels, compute_noise_levels
diff --git a/src/spikeinterface/postprocessing/principal_component.py b/src/spikeinterface/postprocessing/principal_component.py
index 225b37c9f0..63bc0ee26d 100644
--- a/src/spikeinterface/postprocessing/principal_component.py
+++ b/src/spikeinterface/postprocessing/principal_component.py
@@ -394,9 +394,9 @@ def run_for_all_spikes(self, file_path=None, verbose=False, **job_kwargs):
p = self.params
sorting_analyzer = self.sorting_analyzer
sorting = sorting_analyzer.sorting
- assert (
- sorting_analyzer.has_recording() or sorting_analyzer.has_temporary_recording()
- ), "To compute PCA projections for all spikes, the sorting analyzer needs the recording"
+ assert sorting_analyzer.has_recording() or sorting_analyzer.has_temporary_recording(), (
+ "To compute PCA projections for all spikes, the sorting analyzer needs the recording"
+ )
recording = sorting_analyzer.recording
# assert sorting.get_num_segments() == 1
@@ -422,7 +422,7 @@ def run_for_all_spikes(self, file_path=None, verbose=False, **job_kwargs):
num_spikes = sorting.to_spike_vector().size
shape = (num_spikes, p["n_components"], max_channels_per_template)
- all_pcs = np.lib.format.open_memmap(filename=file_path, mode="w+", dtype="float32", shape=shape)
+ _ = np.lib.format.open_memmap(filename=file_path, mode="w+", dtype="float32", shape=shape)
all_pcs_args = dict(filename=file_path, mode="r+", dtype="float32", shape=shape)
waveforms_ext = self.sorting_analyzer.get_extension("waveforms")
@@ -578,7 +578,7 @@ def _transform_waveforms(self, spikes, waveforms, pca_model, progress_bar):
try:
proj = pca_model.transform(wfs[:, :, wf_ind])
pca_projection[:, :, wf_ind][spike_mask, :] = proj
- except:
+ except Exception:
# this could happen if len(wfs) is less then n_comp for a channel
project_on_non_fitted = True
if project_on_non_fitted:
diff --git a/src/spikeinterface/postprocessing/spike_amplitudes.py b/src/spikeinterface/postprocessing/spike_amplitudes.py
index 3c2020a64e..0621419835 100644
--- a/src/spikeinterface/postprocessing/spike_amplitudes.py
+++ b/src/spikeinterface/postprocessing/spike_amplitudes.py
@@ -75,9 +75,9 @@ def __init__(
self._gains = None
self._offsets = None
spike_retriever = find_parent_of_type(parents, SpikeRetriever)
- assert isinstance(
- spike_retriever, SpikeRetriever
- ), "SpikeAmplitudeNode needs a single SpikeRetriever as a parent"
+ assert isinstance(spike_retriever, SpikeRetriever), (
+ "SpikeAmplitudeNode needs a single SpikeRetriever as a parent"
+ )
# put peak_shifts in vector way
self._peak_shifts = np.array(list(peak_shifts.values()), dtype="int64")
self._margin = np.max(np.abs(self._peak_shifts))
diff --git a/src/spikeinterface/postprocessing/template_similarity.py b/src/spikeinterface/postprocessing/template_similarity.py
index ef40671b1f..a65bd8fb54 100644
--- a/src/spikeinterface/postprocessing/template_similarity.py
+++ b/src/spikeinterface/postprocessing/template_similarity.py
@@ -1,5 +1,4 @@
import numpy as np
-import warnings
from itertools import chain
import importlib.util
from spikeinterface.core.core_tools import slice_rows, materialize_array
@@ -259,7 +258,6 @@ def _compute_similarity_matrix_numpy(
if HAVE_NUMBA:
-
from math import sqrt
from numba import jit, typed, prange
@@ -304,7 +302,6 @@ def _compute_similarity_matrix_numba(
for src_unit in range(num_templates):
start = src_unit if same_array else 0
for tgt_unit in range(start, other_num_templates):
-
if support == "intersection":
ch = np.where(sparsity_mask[src_unit] & other_sparsity_mask[tgt_unit])[0].astype(np.uint16)
@@ -417,12 +414,12 @@ def compute_similarity_with_templates_array(
if method not in all_metrics:
raise ValueError(f"compute_template_similarity (method {method}) not exists")
- assert (
- templates_array.shape[1] == other_templates_array.shape[1]
- ), "The number of samples in the templates should be the same for both arrays"
- assert (
- templates_array.shape[2] == other_templates_array.shape[2]
- ), "The number of channels in the templates should be the same for both arrays"
+ assert templates_array.shape[1] == other_templates_array.shape[1], (
+ "The number of samples in the templates should be the same for both arrays"
+ )
+ assert templates_array.shape[2] == other_templates_array.shape[2], (
+ "The number of channels in the templates should be the same for both arrays"
+ )
# num_templates = templates_array.shape[0]
num_samples = templates_array.shape[1]
# num_channels = templates_array.shape[2]
diff --git a/src/spikeinterface/postprocessing/tests/test_amplitude_scalings.py b/src/spikeinterface/postprocessing/tests/test_amplitude_scalings.py
index cb523038df..d5f0bf947a 100644
--- a/src/spikeinterface/postprocessing/tests/test_amplitude_scalings.py
+++ b/src/spikeinterface/postprocessing/tests/test_amplitude_scalings.py
@@ -139,7 +139,6 @@ def test_unit_pair_overlap_matrix_matches_naive_reference():
class TestAmplitudeScalingsExtension(AnalyzerExtensionCommonTestSuite):
-
@pytest.mark.parametrize("params", [dict(handle_collisions=True), dict(handle_collisions=False)])
def test_extension(self, params):
self.run_extension_tests(ComputeAmplitudeScalings, params)
diff --git a/src/spikeinterface/postprocessing/tests/test_correlograms.py b/src/spikeinterface/postprocessing/tests/test_correlograms.py
index 5b3410ed39..e93f97d5c1 100644
--- a/src/spikeinterface/postprocessing/tests/test_correlograms.py
+++ b/src/spikeinterface/postprocessing/tests/test_correlograms.py
@@ -1,21 +1,7 @@
-import numpy as np
-import importlib.util
-
-numba_spec = importlib.util.find_spec("numba")
-if numba_spec is not None:
- HAVE_NUMBA = True
-else:
- HAVE_NUMBA = False
-
-npyx_spec = importlib.util.find_spec("npyx")
-if npyx_spec is not None:
- HAVE_NPYX = True
-else:
- HAVE_NPYX = False
-
-
import pytest
from pytest import param
+import numpy as np
+import importlib.util
from spikeinterface import NumpySorting, generate_sorting
from spikeinterface.postprocessing import ComputeACG3D, ComputeCorrelograms, ComputeAutoCorrelograms
@@ -32,6 +18,19 @@
)
from spikeinterface.postprocessing.tests.common_extension_tests import AnalyzerExtensionCommonTestSuite
+
+numba_spec = importlib.util.find_spec("numba")
+if numba_spec is not None:
+ HAVE_NUMBA = True
+else:
+ HAVE_NUMBA = False
+
+npyx_spec = importlib.util.find_spec("npyx")
+if npyx_spec is not None:
+ HAVE_NPYX = True
+else:
+ HAVE_NPYX = False
+
SKIP_NUMBA = pytest.mark.skipif(not HAVE_NUMBA, reason="Numba not available")
@@ -254,27 +253,6 @@ def test_equal_results_auto_correlograms(window_and_bin_ms):
assert np.array_equal(result_numpy, result_numba)
-@pytest.mark.skipif(not HAVE_NUMBA, reason="Numba not available")
-@pytest.mark.parametrize("window_and_bin_ms", [(60.0, 2.0), (3.57, 1.6421)])
-def test_equal_results_auto_correlograms(window_and_bin_ms):
- """
- Test that the 2 methods have same results with some varied time bins
- that are not tested in other tests.
- """
-
- window_ms, bin_ms = window_and_bin_ms
- sorting = generate_sorting(num_units=5, sampling_frequency=30000.0, durations=[10.325, 3.5], seed=0)
-
- result_numpy, bins_numpy = _compute_auto_correlograms_on_sorting(
- sorting, window_ms=window_ms, bin_ms=bin_ms, method="numpy"
- )
- result_numba, bins_numba = _compute_auto_correlograms_on_sorting(
- sorting, window_ms=window_ms, bin_ms=bin_ms, method="numba"
- )
-
- assert np.array_equal(result_numpy, result_numba)
-
-
@pytest.mark.parametrize("method", ["numpy", param("numba", marks=SKIP_NUMBA)])
def test_flat_cross_correlogram(method):
"""
@@ -647,9 +625,9 @@ def test_acgs_3d_original_implementation(window_ms, bin_ms, num_firing_rate_quan
)
assert np.allclose(npyx_3dacg, acg_3d, rtol=1e-2, atol=1e-2), "3D-ACG result does not match original implementation"
- assert np.allclose(
- npyx_quantiles, firing_rate_quantiles, rtol=1e-5, atol=1e-5
- ), "3D-ACG quantiles do not match original implementation"
+ assert np.allclose(npyx_quantiles, firing_rate_quantiles, rtol=1e-5, atol=1e-5), (
+ "3D-ACG quantiles do not match original implementation"
+ )
# Check in the case where we have segments
@@ -693,6 +671,6 @@ def test_acgs_3d_original_implementation_with_segments(window_ms, bin_ms, num_fi
)
# Use a less strict tolerance here as we are only simulating a single segment
- assert np.allclose(
- npyx_3dacg, acg_3d, rtol=5e-2, atol=5e-2
- ), f"3D-ACG result for {segments} segments does not match original implementation with concatenated times"
+ assert np.allclose(npyx_3dacg, acg_3d, rtol=5e-2, atol=5e-2), (
+ f"3D-ACG result for {segments} segments does not match original implementation with concatenated times"
+ )
diff --git a/src/spikeinterface/postprocessing/tests/test_extension_merges.py b/src/spikeinterface/postprocessing/tests/test_extension_merges.py
index e4f858223e..ca47d7dd26 100644
--- a/src/spikeinterface/postprocessing/tests/test_extension_merges.py
+++ b/src/spikeinterface/postprocessing/tests/test_extension_merges.py
@@ -27,7 +27,6 @@ def test_correlograms_merge():
for new_id_strategy in ["append", "take_first", "user"]:
for merge_unit_groups, new_unit_id in zip(trial_merges, new_unit_ids):
-
# first, compute the correlograms of the merged units using the merge method
if new_id_strategy == "user":
merged_sorting_analyzer = sorting_analyzer.merge_units(
@@ -87,7 +86,6 @@ def test_acgs_3d_merge(sparse):
for new_id_strategy in ["append", "take_first"]:
for merge_unit_groups in trial_merges:
-
merged_sorting_analyzer = sorting_analyzer.merge_units(
merge_unit_groups=merge_unit_groups, new_id_strategy=new_id_strategy
)
diff --git a/src/spikeinterface/postprocessing/tests/test_isi.py b/src/spikeinterface/postprocessing/tests/test_isi.py
index b24a3b0405..f426569a33 100644
--- a/src/spikeinterface/postprocessing/tests/test_isi.py
+++ b/src/spikeinterface/postprocessing/tests/test_isi.py
@@ -15,7 +15,6 @@
class TestComputeISIHistograms(AnalyzerExtensionCommonTestSuite):
-
@pytest.mark.parametrize(
"params",
[
diff --git a/src/spikeinterface/postprocessing/tests/test_multi_extensions.py b/src/spikeinterface/postprocessing/tests/test_multi_extensions.py
index 17f51fd1ce..d8180b6e1d 100644
--- a/src/spikeinterface/postprocessing/tests/test_multi_extensions.py
+++ b/src/spikeinterface/postprocessing/tests/test_multi_extensions.py
@@ -1,6 +1,5 @@
import pytest
-import time
import numpy as np
from spikeinterface import (
@@ -140,7 +139,7 @@ def test_SortingAnalyzer_merge_all_extensions(dataset_to_merge, lazy, sparse, fo
set_global_job_kwargs(n_jobs=1)
- rng = np.random.default_rng(seed=2308)
+ _ = np.random.default_rng(seed=2308)
recording, sorting, other_ids = dataset_to_merge
diff --git a/src/spikeinterface/postprocessing/tests/test_principal_component.py b/src/spikeinterface/postprocessing/tests/test_principal_component.py
index 879f4ff055..493f36e797 100644
--- a/src/spikeinterface/postprocessing/tests/test_principal_component.py
+++ b/src/spikeinterface/postprocessing/tests/test_principal_component.py
@@ -8,7 +8,6 @@
class TestPrincipalComponentsExtension(AnalyzerExtensionCommonTestSuite):
-
@pytest.mark.parametrize(
"params",
[
@@ -223,7 +222,6 @@ def test_select_channels_sparse_pca():
selected_pca = analyzer_selected.get_extension("principal_components")
for unit_id in sorting_analyzer.unit_ids:
-
original_units_to_channels = sorting_analyzer.sparsity.unit_id_to_channel_ids[unit_id]
selected_units_to_channels = analyzer_selected.sparsity.unit_id_to_channel_ids[unit_id]
@@ -232,7 +230,6 @@ def test_select_channels_sparse_pca():
for channel_id in select_channel_ids:
if channel_id in original_units_to_channels:
-
# Now check waveforms and PCs, which are sparse
channel_index_in_original = np.where(original_units_to_channels == channel_id)[0][0]
original_unit_pca = original_pca_one_unit[:, :, channel_index_in_original]
diff --git a/src/spikeinterface/postprocessing/tests/test_spike_amplitudes.py b/src/spikeinterface/postprocessing/tests/test_spike_amplitudes.py
index a68483a1b2..4ab77f2b0a 100644
--- a/src/spikeinterface/postprocessing/tests/test_spike_amplitudes.py
+++ b/src/spikeinterface/postprocessing/tests/test_spike_amplitudes.py
@@ -3,6 +3,5 @@
class TestComputeSpikeAmplitudes(AnalyzerExtensionCommonTestSuite):
-
def test_extension(self):
self.run_extension_tests(ComputeSpikeAmplitudes, params=dict())
diff --git a/src/spikeinterface/postprocessing/tests/test_spike_locations.py b/src/spikeinterface/postprocessing/tests/test_spike_locations.py
index 3810a470be..33871d90dc 100644
--- a/src/spikeinterface/postprocessing/tests/test_spike_locations.py
+++ b/src/spikeinterface/postprocessing/tests/test_spike_locations.py
@@ -4,7 +4,6 @@
class TestSpikeLocationsExtension(AnalyzerExtensionCommonTestSuite):
-
@pytest.mark.parametrize(
"params",
[
diff --git a/src/spikeinterface/postprocessing/tests/test_template_similarity.py b/src/spikeinterface/postprocessing/tests/test_template_similarity.py
index fd963fa013..ef35858fbb 100644
--- a/src/spikeinterface/postprocessing/tests/test_template_similarity.py
+++ b/src/spikeinterface/postprocessing/tests/test_template_similarity.py
@@ -14,7 +14,6 @@
)
if importlib.util.find_spec("numba") is not None:
-
HAVE_NUMBA = True
from spikeinterface.postprocessing.template_similarity import _compute_similarity_matrix_numba
else:
@@ -25,7 +24,6 @@
class TestSimilarityExtension(AnalyzerExtensionCommonTestSuite):
-
@pytest.mark.parametrize(
"params",
[
diff --git a/src/spikeinterface/postprocessing/tests/test_unit_locations.py b/src/spikeinterface/postprocessing/tests/test_unit_locations.py
index 5f0a90d966..4c7db3bbd3 100644
--- a/src/spikeinterface/postprocessing/tests/test_unit_locations.py
+++ b/src/spikeinterface/postprocessing/tests/test_unit_locations.py
@@ -7,7 +7,6 @@
class TestUnitLocationsExtension(AnalyzerExtensionCommonTestSuite):
-
@pytest.mark.parametrize(
"params",
[
@@ -60,7 +59,6 @@ def test_2d_and_3d_unit_localization():
analyzer_2D.compute(["random_spikes", "templates"])
for method in ["center_of_mass", "grid_convolution", "monopolar_triangulation", "max_channel"]:
-
analyzer_2D.compute("unit_locations", method=method)
analyzer_3D.compute("unit_locations", method=method)
unit_locations_2D = analyzer_2D.get_extension("unit_locations").get_data()
diff --git a/src/spikeinterface/postprocessing/tests/test_valid_unit_periods.py b/src/spikeinterface/postprocessing/tests/test_valid_unit_periods.py
index 3ba057d059..a929f01881 100644
--- a/src/spikeinterface/postprocessing/tests/test_valid_unit_periods.py
+++ b/src/spikeinterface/postprocessing/tests/test_valid_unit_periods.py
@@ -7,7 +7,6 @@
class TestComputeValidUnitPeriods(AnalyzerExtensionCommonTestSuite):
-
@pytest.mark.parametrize(
"params",
[
diff --git a/src/spikeinterface/postprocessing/unit_locations.py b/src/spikeinterface/postprocessing/unit_locations.py
index 7cd94d7ee9..da4e39730c 100644
--- a/src/spikeinterface/postprocessing/unit_locations.py
+++ b/src/spikeinterface/postprocessing/unit_locations.py
@@ -1,7 +1,7 @@
import numpy as np
from itertools import chain
-from spikeinterface.core.core_tools import slice_rows, materialize_array
+from spikeinterface.core.core_tools import slice_rows
from spikeinterface.core.sortinganalyzer import register_result_extension, AnalyzerExtension
from .localization_tools import _unit_location_methods
diff --git a/src/spikeinterface/postprocessing/valid_unit_periods.py b/src/spikeinterface/postprocessing/valid_unit_periods.py
index da28b20e00..d24f206e2b 100644
--- a/src/spikeinterface/postprocessing/valid_unit_periods.py
+++ b/src/spikeinterface/postprocessing/valid_unit_periods.py
@@ -137,9 +137,9 @@ def _set_params(
# subperiods
assert period_mode in ("absolute", "relative"), f"Invalid subperiod_size_mode: {period_mode}"
- assert (
- period_duration_s_absolute > 0 or period_target_num_spikes > 0
- ), "Either period_duration_s_absolute or period_target_num_spikes must be positive."
+ assert period_duration_s_absolute > 0 or period_target_num_spikes > 0, (
+ "Either period_duration_s_absolute or period_target_num_spikes must be positive."
+ )
assert isinstance(period_target_num_spikes, (int)), "period_target_num_spikes must be an integer."
# user_defined_periods formatting
@@ -147,7 +147,7 @@ def _set_params(
if user_defined_periods is not None:
try:
user_defined_periods = np.asarray(user_defined_periods)
- except Exception as e:
+ except Exception:
raise ValueError(
(
"user_defined_periods must be some (n_periods, 3) [unit, good_period_start, good_period_end] "
@@ -362,12 +362,10 @@ def _run(self, unit_ids=None, verbose=False, **job_kwargs):
def _compute_valid_periods(self, sorting_analyzer, unit_ids=None, **job_kwargs):
if self.params["method"] == "user_defined":
-
# directly use user defined periods
return self.user_defined_periods, None, None, None
elif self.params["method"] in ["false_positives_and_negatives", "combined"]:
-
# dict: unit_id -> list of subperiod, each subperiod is an array of dtype unit_period_dtype with 4 fields
all_periods, all_periods_w_margins = compute_subperiods(
sorting_analyzer,
@@ -394,7 +392,7 @@ def _compute_valid_periods(self, sorting_analyzer, unit_ids=None, **job_kwargs):
# Each item is one computation of fp and fn for one period and one unit
items = [(period,) for period in all_periods_w_margins]
- job_name = f"computing false positives and negatives"
+ job_name = "computing false positives and negatives"
# parallel
with ProcessPoolExecutor(
diff --git a/src/spikeinterface/preprocessing/average_across_direction.py b/src/spikeinterface/preprocessing/average_across_direction.py
index f87a79e2b4..2fb1c36dcf 100644
--- a/src/spikeinterface/preprocessing/average_across_direction.py
+++ b/src/spikeinterface/preprocessing/average_across_direction.py
@@ -5,7 +5,6 @@
class AverageAcrossDirectionRecording(BaseRecording):
-
def __init__(
self,
recording: BaseRecording,
diff --git a/src/spikeinterface/preprocessing/common_reference.py b/src/spikeinterface/preprocessing/common_reference.py
index 6da823d0e4..9ca5143409 100644
--- a/src/spikeinterface/preprocessing/common_reference.py
+++ b/src/spikeinterface/preprocessing/common_reference.py
@@ -139,13 +139,13 @@ def __init__(
if np.isscalar(ref_channel_ids):
ref_channel_ids = [ref_channel_ids]
else:
- assert (
- len(ref_channel_ids) == 1
- ), "'ref_channel_ids' with no 'groups' must be a single channel id or a list of one element"
+ assert len(ref_channel_ids) == 1, (
+ "'ref_channel_ids' with no 'groups' must be a single channel id or a list of one element"
+ )
ref_channel_ids = np.asarray(ref_channel_ids)
- assert np.all(
- [ch in recording.channel_ids for ch in ref_channel_ids]
- ), "Some 'ref_channel_ids' are wrong!"
+ assert np.all([ch in recording.channel_ids for ch in ref_channel_ids]), (
+ "Some 'ref_channel_ids' are wrong!"
+ )
elif reference == "local":
assert groups is None, "With 'local' CAR, the group option should not be used."
closest_inds, dist = get_closest_channels(recording)
diff --git a/src/spikeinterface/preprocessing/decimate.py b/src/spikeinterface/preprocessing/decimate.py
index 147e685118..16bd21445d 100644
--- a/src/spikeinterface/preprocessing/decimate.py
+++ b/src/spikeinterface/preprocessing/decimate.py
@@ -70,7 +70,7 @@ def __init__(
# Original sampling frequency
self._orig_samp_freq = recording.get_sampling_frequency()
if not isinstance(decimation_factor, int) or decimation_factor <= 0:
- raise ValueError(f"Expecting strictly positive integer for `decimation_factor` arg")
+ raise ValueError("Expecting strictly positive integer for `decimation_factor` arg")
self._decimation_factor = decimation_factor
if not isinstance(decimation_offset, int) or decimation_offset < 0:
raise ValueError("Expecting a nonnegative integer for `decimation_offset` arg")
@@ -79,8 +79,8 @@ def __init__(
)
if decimation_offset >= decimation_factor or decimation_offset >= parent_min_n_samp:
raise ValueError(
- f"Expecting `decimation_offset` < `decimation_factor` and `decimation_offset` < parent_segment.get_num_samples() for all segments. "
- f"Consider combining DecimateRecording with FrameSliceRecording for fine control on the recording start/end frames."
+ "Expecting `decimation_offset` < `decimation_factor` and `decimation_offset` < parent_segment.get_num_samples() for all segments. "
+ "Consider combining DecimateRecording with FrameSliceRecording for fine control on the recording start/end frames."
)
self._decimation_offset = decimation_offset
decimated_sampling_frequency = self._orig_samp_freq / self._decimation_factor
@@ -179,9 +179,7 @@ def get_traces(self, start_frame, end_frame, channel_indices):
parent_start_frame,
parent_end_frame,
channel_indices,
- )[
- :: self._decimation_factor
- ].astype(self._dtype)
+ )[:: self._decimation_factor].astype(self._dtype)
return get_polyphase_resampled_traces(
self._parent_segment,
diff --git a/src/spikeinterface/preprocessing/deepinterpolation/deepinterpolation.py b/src/spikeinterface/preprocessing/deepinterpolation/deepinterpolation.py
index e324048c5a..cc9802df90 100644
--- a/src/spikeinterface/preprocessing/deepinterpolation/deepinterpolation.py
+++ b/src/spikeinterface/preprocessing/deepinterpolation/deepinterpolation.py
@@ -64,9 +64,9 @@ def __init__(
if parse(importlib.metadata.version("deepinterpolation")) < parse("0.2.0"):
raise ImportError("DeepInterpolation version must be at least 0.2.0")
- assert has_tf(
- use_gpu, disable_tf_logger, memory_gpu
- ), "To use DeepInterpolation, you first need to install `tensorflow`."
+ assert has_tf(use_gpu, disable_tf_logger, memory_gpu), (
+ "To use DeepInterpolation, you first need to install `tensorflow`."
+ )
self.tf = import_tf(use_gpu, disable_tf_logger, memory_gpu=memory_gpu)
@@ -80,12 +80,12 @@ def __init__(
# check shape (this will need to be done at inference)
network_input_shape = model.get_config()["layers"][0]["config"]["batch_input_shape"]
desired_shape = network_input_shape[1:3]
- assert (
- desired_shape[0] * desired_shape[1] == recording.get_num_channels()
- ), "The desired shape of the network input must match the number of channels in the recording"
- assert (
- network_input_shape[-1] == pre_frame + post_frame
- ), "The desired shape of the network input must match the pre and post frames"
+ assert desired_shape[0] * desired_shape[1] == recording.get_num_channels(), (
+ "The desired shape of the network input must match the number of channels in the recording"
+ )
+ assert network_input_shape[-1] == pre_frame + post_frame, (
+ "The desired shape of the network input must match the pre and post frames"
+ )
self.model = model
# add segment
diff --git a/src/spikeinterface/preprocessing/deepinterpolation/generators.py b/src/spikeinterface/preprocessing/deepinterpolation/generators.py
index dbf869997d..2520a62f39 100644
--- a/src/spikeinterface/preprocessing/deepinterpolation/generators.py
+++ b/src/spikeinterface/preprocessing/deepinterpolation/generators.py
@@ -28,9 +28,9 @@ def __init__(
recordings = [recordings]
self.recordings = recordings
if len(recordings) > 1:
- assert (
- r.get_num_channels() == recordings[0].get_num_channels() for r in recordings[1:]
- ), "All recordings must have the same number of channels"
+ assert (r.get_num_channels() == recordings[0].get_num_channels() for r in recordings[1:]), (
+ "All recordings must have the same number of channels"
+ )
total_num_samples = sum([r.get_total_samples() for r in recordings])
# In case of multiple recordings and/or multiple segments, we calculate the frame periods to be excluded (borders)
@@ -58,9 +58,9 @@ def __init__(
)
self.total_samples = int(total_valid_samples) if total_samples == -1 else total_samples
assert len(desired_shape) == 2, "desired_shape should be 2D"
- assert (
- desired_shape[0] * desired_shape[1] == recording.get_num_channels()
- ), f"The product of desired_shape dimensions should be the number of channels: {recording.get_num_channels()}"
+ assert desired_shape[0] * desired_shape[1] == recording.get_num_channels(), (
+ f"The product of desired_shape dimensions should be the number of channels: {recording.get_num_channels()}"
+ )
self.desired_shape = desired_shape
start_frame = start_frame if start_frame is not None else 0
diff --git a/src/spikeinterface/preprocessing/deepinterpolation/tests/test_deepinterpolation.py b/src/spikeinterface/preprocessing/deepinterpolation/tests/test_deepinterpolation.py
index 8d2558531f..d61aca4239 100644
--- a/src/spikeinterface/preprocessing/deepinterpolation/tests/test_deepinterpolation.py
+++ b/src/spikeinterface/preprocessing/deepinterpolation/tests/test_deepinterpolation.py
@@ -11,7 +11,6 @@
from spikeinterface.preprocessing import depth_order, zscore
from spikeinterface.preprocessing.deepinterpolation import train_deepinterpolation, deepinterpolate
-from spikeinterface.preprocessing.deepinterpolation.train import train_deepinterpolation_process
tensorflow_spec = importlib.util.find_spec("tensorflow")
deepinter_spec = importlib.util.find_spec("deepinterpolation")
@@ -98,12 +97,8 @@ def deepinterpolation_model(recording_and_shape_fixture, create_cache_folder):
@pytest.mark.skipif(not HAVE_DEEPINTERPOLATION, reason="requires deepinterpolation")
-def test_deepinterpolation_transfer(
- recording_and_shape_fixture, tmp_path, create_cache_folder, deepinterpolation_model
-):
+def test_deepinterpolation_transfer(recording_and_shape_fixture, tmp_path, deepinterpolation_model):
recording, desired_shape = recording_and_shape_fixture
- cache_folder = create_cache_folder
-
existing_model_path = deepinterpolation_model
model_folder = Path(tmp_path) / "transfer"
@@ -128,10 +123,9 @@ def test_deepinterpolation_transfer(
@pytest.mark.skipif(not HAVE_DEEPINTERPOLATION, reason="requires deepinterpolation")
-def test_deepinterpolation_inference(recording_and_shape_fixture, create_cache_folder, deepinterpolation_model):
+def test_deepinterpolation_inference(recording_and_shape_fixture, deepinterpolation_model):
recording, _ = recording_and_shape_fixture
pre_frame = post_frame = 20
- cache_folder = create_cache_folder
existing_model_path = deepinterpolation_model
recording_di = deepinterpolate(
recording, model_path=existing_model_path, pre_frame=pre_frame, post_frame=post_frame, pre_post_omission=1
diff --git a/src/spikeinterface/preprocessing/detect_artifacts.py b/src/spikeinterface/preprocessing/detect_artifacts.py
index 80aa88c73c..cbe5488bb9 100644
--- a/src/spikeinterface/preprocessing/detect_artifacts.py
+++ b/src/spikeinterface/preprocessing/detect_artifacts.py
@@ -671,9 +671,9 @@ def detect_artifact_periods(
Array with dtype ``artifact_dtype`` describing each detected artifact
period.
"""
- assert (
- method in _method_to_function
- ), f"Method {method} not recognized. Valid methods are: {_method_to_function.keys()}"
+ assert method in _method_to_function, (
+ f"Method {method} not recognized. Valid methods are: {_method_to_function.keys()}"
+ )
if method_kwargs is None:
method_kwargs = dict()
diff --git a/src/spikeinterface/preprocessing/directional_derivative.py b/src/spikeinterface/preprocessing/directional_derivative.py
index f302708055..457c6edc69 100644
--- a/src/spikeinterface/preprocessing/directional_derivative.py
+++ b/src/spikeinterface/preprocessing/directional_derivative.py
@@ -5,7 +5,6 @@
class DirectionalDerivativeRecording(BasePreprocessor):
-
def __init__(
self,
recording: BaseRecording,
diff --git a/src/spikeinterface/preprocessing/highpass_spatial_filter.py b/src/spikeinterface/preprocessing/highpass_spatial_filter.py
index 979bb00908..838672ab4b 100644
--- a/src/spikeinterface/preprocessing/highpass_spatial_filter.py
+++ b/src/spikeinterface/preprocessing/highpass_spatial_filter.py
@@ -112,13 +112,13 @@ def __init__(
# Fix channel padding and tapering
n_channels = recording.get_num_channels()
n_channel_pad = 0 if n_channel_pad is None else int(n_channel_pad)
- assert (
- n_channel_pad <= recording.get_num_channels()
- ), "'n_channel_pad' must be less than the number of channels in recording."
+ assert n_channel_pad <= recording.get_num_channels(), (
+ "'n_channel_pad' must be less than the number of channels in recording."
+ )
n_channel_taper = n_channel_pad if n_channel_taper is None else int(n_channel_taper)
- assert (
- n_channel_taper <= recording.get_num_channels()
- ), "'n_channel_taper' must be less than the number of channels in recording."
+ assert n_channel_taper <= recording.get_num_channels(), (
+ "'n_channel_taper' must be less than the number of channels in recording."
+ )
# Fix Automatic Gain Control options
sampling_interval = 1 / recording.sampling_frequency
diff --git a/src/spikeinterface/preprocessing/interpolate_bad_channels.py b/src/spikeinterface/preprocessing/interpolate_bad_channels.py
index f2ae77f3d7..a5eb206f70 100644
--- a/src/spikeinterface/preprocessing/interpolate_bad_channels.py
+++ b/src/spikeinterface/preprocessing/interpolate_bad_channels.py
@@ -8,7 +8,6 @@
detect_bad_channels,
_get_all_detect_bad_channel_kwargs,
)
-from inspect import signature
class InterpolateBadChannelsRecording(BasePreprocessor):
diff --git a/src/spikeinterface/preprocessing/motion.py b/src/spikeinterface/preprocessing/motion.py
index 388605c166..2629b118c1 100644
--- a/src/spikeinterface/preprocessing/motion.py
+++ b/src/spikeinterface/preprocessing/motion.py
@@ -12,7 +12,6 @@
from spikeinterface.core import get_noise_levels, fix_job_kwargs
from spikeinterface.core.job_tools import _shared_job_kwargs_doc
from spikeinterface.core.core_tools import SIJsonEncoder
-from spikeinterface.core.job_tools import _shared_job_kwargs_doc
from spikeinterface.core import BaseRecording
motion_options_preset = {
@@ -336,7 +335,7 @@ def compute_motion(
from spikeinterface.sortingcomponents.peak_selection import select_peaks
from spikeinterface.sortingcomponents.peak_localization import localize_peaks, peak_localization_methods
from spikeinterface.core.node_pipeline import ExtractDenseWaveforms, run_node_pipeline
- from spikeinterface.sortingcomponents.motion.motion_estimation import estimate_motion, estimate_motion_methods
+ from spikeinterface.sortingcomponents.motion.motion_estimation import estimate_motion
# get preset params and update if necessary
detect_kwargs, select_kwargs, localize_peaks_kwargs, estimate_motion_kwargs = _update_motion_kwargs(
@@ -643,7 +642,6 @@ def load_motion_info(folder):
if (folder / "motion").is_dir():
motion = Motion.load(folder / "motion")
else:
-
is_legacy_format = True
required_files = ["spatial_bins.npy", "temporal_bins.npy", "motion.npy"]
for required_file in required_files:
@@ -651,7 +649,6 @@ def load_motion_info(folder):
is_legacy_format = False
if is_legacy_format:
-
warnings.warn("Trying to load Motion from the legacy format")
spatial_bins_um = np.load(folder / "spatial_bins.npy")
@@ -661,7 +658,6 @@ def load_motion_info(folder):
motion = Motion(displacement=displacement, temporal_bins_s=temporal_bins_s, spatial_bins_um=spatial_bins_um)
else:
-
warnings.warn("No `motion` object in folder. `motion_info` is loaded with `motion` equal to `None`.")
motion = None
diff --git a/src/spikeinterface/preprocessing/phase_shift.py b/src/spikeinterface/preprocessing/phase_shift.py
index 273e828da3..949f200f30 100644
--- a/src/spikeinterface/preprocessing/phase_shift.py
+++ b/src/spikeinterface/preprocessing/phase_shift.py
@@ -69,9 +69,9 @@ def __init__(
assert "inter_sample_shift" in recording.get_property_keys(), "'inter_sample_shift' is not a property!"
sample_shifts = recording.get_property("inter_sample_shift")
else:
- assert (
- len(inter_sample_shift) == recording.get_num_channels()
- ), "the 'inter_sample_shift' must be same size at the num_channels "
+ assert len(inter_sample_shift) == recording.get_num_channels(), (
+ "the 'inter_sample_shift' must be same size at the num_channels "
+ )
sample_shifts = np.asarray(inter_sample_shift)
dtype = np.dtype(recording.get_dtype() if dtype is None else dtype)
diff --git a/src/spikeinterface/preprocessing/pipeline.py b/src/spikeinterface/preprocessing/pipeline.py
index b75cae49f8..4ee81f3de0 100644
--- a/src/spikeinterface/preprocessing/pipeline.py
+++ b/src/spikeinterface/preprocessing/pipeline.py
@@ -5,7 +5,7 @@
from spikeinterface.core.core_tools import is_dict_extractor, is_path_remote
from spikeinterface.core.zarrextractors import super_zarr_open
from spikeinterface.core.zarr_tools import read_encoded_array
-from spikeinterface.preprocessing.preprocessing_classes import preprocessor_dict, _all_preprocesser_dict
+from spikeinterface.preprocessing.preprocessing_classes import preprocessor_dict
pp_names_to_functions = {preprocessor.__name__: preprocessor for preprocessor in preprocessor_dict.values()}
@@ -30,9 +30,9 @@ def __init__(self, preprocessor_list_or_dict):
preprocessor_list.append(step)
elif isinstance(preprocessor_list_or_dict, list):
preprocessor_list = preprocessor_list_or_dict
- assert all(
- isinstance(step, dict) and "name" in step for step in preprocessor_list
- ), "Each step in the preprocessor list must be a dict with 'name' key."
+ assert all(isinstance(step, dict) and "name" in step for step in preprocessor_list), (
+ "Each step in the preprocessor list must be a dict with 'name' key."
+ )
for step in preprocessor_list:
if "params" not in step:
@@ -321,7 +321,6 @@ def _make_pipeline_list_from_recording_dict(recording_dict):
preprocessing_list = []
for preprocessor in pipeline_dict_from_file:
-
preprocessor_class_name = preprocessor.split(".")[-1]
preprocessor_function = preprocessor_dict.get(preprocessor_class_name)
@@ -391,7 +390,6 @@ def _get_all_kwargs_and_values(my_pipeline):
all_kwargs_list = []
for preprocessor in my_pipeline.preprocessor_list:
-
preprocessor_name = preprocessor["name"].split(".")[-1]
pp_function = my_pipeline.function_names_to_functions[preprocessor["name"].split(".")[-1]]
signature = inspect.signature(pp_function)
@@ -407,7 +405,7 @@ def _get_all_kwargs_and_values(my_pipeline):
default_value = None
else:
default_value = default_value[-1]
- except:
+ except Exception:
default_value = None
preprocessor_index = my_pipeline.preprocessor_list.index(preprocessor)
diff --git a/src/spikeinterface/preprocessing/rectify.py b/src/spikeinterface/preprocessing/rectify.py
index 7bd91a16d9..1328e21dcf 100644
--- a/src/spikeinterface/preprocessing/rectify.py
+++ b/src/spikeinterface/preprocessing/rectify.py
@@ -6,7 +6,6 @@
class RectifyRecording(BasePreprocessor):
-
def __init__(self, recording):
BasePreprocessor.__init__(self, recording)
for parent_segment in recording.segments:
diff --git a/src/spikeinterface/preprocessing/remove_artifacts.py b/src/spikeinterface/preprocessing/remove_artifacts.py
index b20f1351b0..55584f3a13 100644
--- a/src/spikeinterface/preprocessing/remove_artifacts.py
+++ b/src/spikeinterface/preprocessing/remove_artifacts.py
@@ -125,9 +125,9 @@ def __init__(
# some checks
assert isinstance(list_triggers, list), "'list_triggers' must be a list (one per segment)"
assert len(list_triggers) == num_seg, "'list_triggers' must have the same length as the number of segments"
- assert all(
- isinstance(list_triggers[i], (list, np.ndarray)) for i in range(num_seg)
- ), "Each element of 'list_triggers' must be array-like"
+ assert all(isinstance(list_triggers[i], (list, np.ndarray)) for i in range(num_seg)), (
+ "Each element of 'list_triggers' must be array-like"
+ )
if list_labels is not None:
assert isinstance(list_labels, list), "'list_labels' must be a list (one per segment)"
@@ -163,9 +163,9 @@ def __init__(
for l in np.unique(labels):
assert l in artifacts.keys(), f"Artefacts are provided but label {l} has no value!"
else:
- assert (
- ms_before is not None and ms_after is not None
- ), f"ms_before/after should not be None for mode {mode}"
+ assert ms_before is not None and ms_after is not None, (
+ f"ms_before/after should not be None for mode {mode}"
+ )
sorting = NumpySorting.from_samples_and_labels(
list_triggers, list_labels, recording.get_sampling_frequency()
)
diff --git a/src/spikeinterface/preprocessing/resample.py b/src/spikeinterface/preprocessing/resample.py
index 10783062ed..6dd8c9c3b4 100644
--- a/src/spikeinterface/preprocessing/resample.py
+++ b/src/spikeinterface/preprocessing/resample.py
@@ -1,5 +1,4 @@
import numpy as np
-import warnings
from spikeinterface.core.core_tools import define_function_handling_dict_from_class
diff --git a/src/spikeinterface/preprocessing/tests/test_astype.py b/src/spikeinterface/preprocessing/tests/test_astype.py
index d1d1b11f43..88c80e414a 100644
--- a/src/spikeinterface/preprocessing/tests/test_astype.py
+++ b/src/spikeinterface/preprocessing/tests/test_astype.py
@@ -1,9 +1,4 @@
-import pytest
-from pathlib import Path
-import shutil
-
-from spikeinterface import set_global_tmp_folder, NumpyRecording
-from spikeinterface.core import generate_recording
+from spikeinterface import NumpyRecording
from spikeinterface.preprocessing import astype
diff --git a/src/spikeinterface/preprocessing/tests/test_common_reference.py b/src/spikeinterface/preprocessing/tests/test_common_reference.py
index 139213056f..d3559d862b 100644
--- a/src/spikeinterface/preprocessing/tests/test_common_reference.py
+++ b/src/spikeinterface/preprocessing/tests/test_common_reference.py
@@ -1,4 +1,3 @@
-import operator
import pytest
from spikeinterface.core import generate_recording, NumpyRecording
@@ -6,7 +5,6 @@
from spikeinterface.preprocessing import common_reference
import numpy as np
-from tqdm import trange
def _generate_test_recording():
@@ -244,7 +242,7 @@ def test_min_local_radius():
# remove closest channel to first channel
recording = recording.remove_channels(recording.channel_ids[1:5])
with pytest.warns(UserWarning):
- recording_local_car = common_reference(
+ _ = common_reference(
recording, reference="local", local_radius=(60, 150), operator="average", min_local_neighbors=5
)
diff --git a/src/spikeinterface/preprocessing/tests/test_detect_artifacts.py b/src/spikeinterface/preprocessing/tests/test_detect_artifacts.py
index 81f934300a..0f524af3b0 100644
--- a/src/spikeinterface/preprocessing/tests/test_detect_artifacts.py
+++ b/src/spikeinterface/preprocessing/tests/test_detect_artifacts.py
@@ -1,6 +1,6 @@
import numpy as np
-from spikeinterface.core import generate_recording, NumpyRecording
+from spikeinterface.core import NumpyRecording
from spikeinterface.preprocessing import (
detect_artifact_periods,
detect_saturation_periods,
@@ -41,7 +41,6 @@ def test_detect_artifact_by_envelope(debug_plots):
)
if debug_plots:
- import matplotlib
import matplotlib.pyplot as plt
plt.plot(envelope.get_traces(), color="r", lw=3)
@@ -151,7 +150,6 @@ def test_detect_saturation_periods(debug_plots):
offset = 0
if debug_plots:
- import matplotlib
import matplotlib.pyplot as plt
plt.plot(data_seg_1)
@@ -206,12 +204,12 @@ def test_detect_saturation_periods(debug_plots):
for seg_periods, seg_offset in zip([seg_1_periods, seg_2_periods], offsets):
slow_period_idx = np.argmin(np.abs(seg_periods["start_sample_index"] - start_slow_artifact))
slow_period = seg_periods[slow_period_idx]
- assert (
- slow_period["start_sample_index"] >= start_rising_sample + tolerance_samples
- ), "Slow artifact period starts in the rising phase"
- assert (
- slow_period["end_sample_index"] <= stop_falling_sample + seg_offset - tolerance_samples
- ), "Slow artifact period ends in the falling phase"
+ assert slow_period["start_sample_index"] >= start_rising_sample + tolerance_samples, (
+ "Slow artifact period starts in the rising phase"
+ )
+ assert slow_period["end_sample_index"] <= stop_falling_sample + seg_offset - tolerance_samples, (
+ "Slow artifact period ends in the falling phase"
+ )
# Just do a quick test that a threshold slightly over the sat value is not detected.
# In this case we only see the derivative threshold detection. We do not play around with this
diff --git a/src/spikeinterface/preprocessing/tests/test_detect_bad_channels.py b/src/spikeinterface/preprocessing/tests/test_detect_bad_channels.py
index b9c3b83a6f..4a0df49156 100644
--- a/src/spikeinterface/preprocessing/tests/test_detect_bad_channels.py
+++ b/src/spikeinterface/preprocessing/tests/test_detect_bad_channels.py
@@ -3,12 +3,9 @@
import importlib.util
-from spikeinterface import NumpyRecording, get_random_data_chunks
from probeinterface import generate_linear_probe
-from spikeinterface.generation import generate_recording
-
-from spikeinterface.core import generate_recording
+from spikeinterface.core import generate_recording, get_random_data_chunks, NumpyRecording
from spikeinterface.core.base import BaseExtractor
from spikeinterface.core.testing import check_recordings_equal
from spikeinterface.preprocessing import detect_bad_channels, highpass_filter, detect_and_remove_bad_channels
@@ -113,13 +110,13 @@ def test_detect_bad_channels_std_mad():
# Check that the number of segments is maintained after preprocessor
assert np.array_equal(rec2.get_num_segments(), rec.get_num_segments()), "wrong numbber of segments."
# Check that the size of the segments os maintained after preprocessor
- assert np.array_equal(
- *([r.get_num_frames(x) for x in range(rec.get_num_segments())] for r in [rec, rec2])
- ), "wrong length of resulting segments."
+ assert np.array_equal(*([r.get_num_frames(x) for x in range(rec.get_num_segments())] for r in [rec, rec2])), (
+ "wrong length of resulting segments."
+ )
# Check that locations are mantained
- assert np.array_equal(
- rec.get_channel_locations()[[0, 2, 3]], rec2.get_channel_locations()
- ), "wrong channels locations."
+ assert np.array_equal(rec.get_channel_locations()[[0, 2, 3]], rec2.get_channel_locations()), (
+ "wrong channels locations."
+ )
@pytest.mark.parametrize("pool_engine", ["thread", "process"])
diff --git a/src/spikeinterface/preprocessing/tests/test_filter.py b/src/spikeinterface/preprocessing/tests/test_filter.py
index 3b47d0eb1a..79d3a7b3ce 100644
--- a/src/spikeinterface/preprocessing/tests/test_filter.py
+++ b/src/spikeinterface/preprocessing/tests/test_filter.py
@@ -2,7 +2,6 @@
import numpy as np
from spikeinterface.core import generate_recording
-from spikeinterface import NumpyRecording, set_global_tmp_folder
from spikeinterface.preprocessing import filter, bandpass_filter, notch_filter, causal_filter
@@ -110,8 +109,8 @@ def test_causal_kwarg_error_raised(self, recording_and_data):
"""
recording, raw_data = recording_and_data
- with pytest.raises(BaseException) as e:
- filt_data = causal_filter(recording, direction="forward-backward")
+ with pytest.raises(BaseException):
+ _ = causal_filter(recording, direction="forward-backward")
def _run_iirfilter(self, options, recording):
"""
@@ -141,36 +140,33 @@ def _get_filter_options(self):
def test_filter(create_cache_folder):
+ from scipy.signal import iirfilter
+
rec = generate_recording()
rec = rec.save(folder=create_cache_folder / "test_filter_recording")
rec2 = bandpass_filter(rec, freq_min=300.0, freq_max=6000.0)
# compute by chunk
- rec2_cached0 = rec2.save(
- folder=create_cache_folder / "rec2_cached0", chunk_size=100000, verbose=False, progress_bar=True
- )
+ _ = rec2.save(folder=create_cache_folder / "rec2_cached0", chunk_size=100000, verbose=False, progress_bar=True)
- # compute by chunkf with joblib
+ # compute by chunk in parallel
rec2_cached1 = rec2.save(folder=create_cache_folder / "rec2_cached1", total_memory="10k", n_jobs=4, verbose=True)
# compute once
- rec2_cached2 = rec2.save(folder=create_cache_folder / "rec2_cached2", verbose=False)
+ _ = rec2.save(folder=create_cache_folder / "rec2_cached2", verbose=False)
trace0 = rec2.get_traces(segment_index=0)
trace1 = rec2_cached1.get_traces(segment_index=0)
# other filtering types
- rec3 = filter(rec, band=500.0, btype="highpass", filter_mode="ba", filter_order=2, margin_ms=5.0)
- rec4 = notch_filter(rec, freq=3000, q=30, margin_ms=5.0)
+ _ = filter(rec, band=500.0, btype="highpass", filter_mode="ba", filter_order=2, margin_ms=5.0)
+ _ = notch_filter(rec, freq=3000, q=30, margin_ms=5.0)
rec5 = causal_filter(rec, direction="forward")
rec6 = causal_filter(rec, direction="backward")
- # filter from coefficients
- from scipy.signal import iirfilter
-
coeff = iirfilter(8, [0.02, 0.4], rs=30, btype="band", analog=False, ftype="cheby2", output="sos")
- rec5 = filter(rec, coeff=coeff, filter_mode="sos", margin_ms=5.0)
+ rec5 = filter(rec, coeff=coeff, filter_mode="sos", margin_ms=50.0)
# compute by chunk
rec5_cached0 = rec5.save(
@@ -179,7 +175,7 @@ def test_filter(create_cache_folder):
trace50 = rec5.get_traces(segment_index=0)
trace51 = rec5_cached0.get_traces(segment_index=0)
-
+ np.testing.assert_array_almost_equal(trace50, trace51, decimal=4)
assert np.allclose(rec.get_times(0), rec2.get_times(0))
# reflect padding test
@@ -215,7 +211,7 @@ def test_filter_opencl():
rec_filtered = rec_filtered.save(chunk_size=1000, progress_bar=True, n_jobs=30)
rec2 = filter(rec, engine="opencl")
- rec2_cached0 = rec2.save(chunk_size=1000, verbose=False, progress_bar=True, n_jobs=1)
+ _ = rec2.save(chunk_size=1000, verbose=False, progress_bar=True, n_jobs=1)
# rec2_cached0 = rec2.save(chunk_size=1000,verbose=False, progress_bar=True, n_jobs=4)
# import matplotlib.pyplot as plt
diff --git a/src/spikeinterface/preprocessing/tests/test_filter_gaussian.py b/src/spikeinterface/preprocessing/tests/test_filter_gaussian.py
index f3da50671d..4cb822cf07 100644
--- a/src/spikeinterface/preprocessing/tests/test_filter_gaussian.py
+++ b/src/spikeinterface/preprocessing/tests/test_filter_gaussian.py
@@ -56,7 +56,6 @@ def test_bandpower(freq_min, freq_max, debug=False):
fs = 1000
T = 300
- t = np.arange(0, T, 1 / fs)
rng = np.random.default_rng()
x = rng.standard_normal(T * fs)
diff --git a/src/spikeinterface/preprocessing/tests/test_highpass_spatial_filter.py b/src/spikeinterface/preprocessing/tests/test_highpass_spatial_filter.py
index 89e8e36cf8..b4579451a1 100644
--- a/src/spikeinterface/preprocessing/tests/test_highpass_spatial_filter.py
+++ b/src/spikeinterface/preprocessing/tests/test_highpass_spatial_filter.py
@@ -88,8 +88,7 @@ def test_highpass_spatial_filter_synthetic_data(num_channels, ntr_pad, ntr_tap,
options = dict(lagc=lagc, ntr_pad=ntr_pad, ntr_tap=ntr_tap, butter_kwargs=butter_kwargs)
durations = [2, 2]
- rng = np.random.default_rng(seed=100)
- si_recording = generate_recording(num_channels=num_channels, durations=durations)
+ si_recording = generate_recording(num_channels=num_channels, durations=durations, seed=100)
_, si_highpass_spatial_filter = run_si_highpass_filter(si_recording, get_traces=False, **options)
frames = [(0, 500), (30000, 33000), (57000, 60000)]
diff --git a/src/spikeinterface/preprocessing/tests/test_motion.py b/src/spikeinterface/preprocessing/tests/test_motion.py
index 07dd810890..01dce124ac 100644
--- a/src/spikeinterface/preprocessing/tests/test_motion.py
+++ b/src/spikeinterface/preprocessing/tests/test_motion.py
@@ -10,6 +10,7 @@
compute_motion,
)
from spikeinterface.preprocessing.motion import _get_default_motion_params
+from spikeinterface.sortingcomponents.motion import InterpolateMotionRecording
def test_estimate_and_correct_motion(create_cache_folder):
@@ -21,6 +22,7 @@ def test_estimate_and_correct_motion(create_cache_folder):
shutil.rmtree(folder)
rec_corrected = correct_motion(rec, folder=folder, estimate_motion_kwargs={"win_step_um": 50, "win_scale_um": 100})
+ assert isinstance(rec_corrected, InterpolateMotionRecording)
# test reloading motion info
motion_info = load_motion_info(folder)
@@ -43,7 +45,7 @@ def test_get_motion_parameters_preset():
from pprint import pprint
p = _get_default_motion_params()
- # pprint(p)
+ assert isinstance(p, dict)
params = get_motion_parameters_preset("nonrigid_accurate")
params = get_motion_parameters_preset("dredge")
diff --git a/src/spikeinterface/preprocessing/tests/test_normalize_scale.py b/src/spikeinterface/preprocessing/tests/test_normalize_scale.py
index a304a18f18..58d6432ae5 100644
--- a/src/spikeinterface/preprocessing/tests/test_normalize_scale.py
+++ b/src/spikeinterface/preprocessing/tests/test_normalize_scale.py
@@ -93,8 +93,8 @@ def test_zscore_int():
zscore_recording = zscore(rec_int, dtype="int16", int_scale=256, mode="mean+std", seed=seed)
traces = zscore_recording.get_traces(segment_index=0)
trace_mean = np.mean(traces, axis=0)
- trace_std = np.std(traces, axis=0)
assert np.all(np.abs(trace_mean) < 1)
+ # trace_std = np.std(traces, axis=0)
# assert np.all(np.abs(trace_std - 256) < 1)
diff --git a/src/spikeinterface/preprocessing/tests/test_phase_shift.py b/src/spikeinterface/preprocessing/tests/test_phase_shift.py
index bd8a5b209c..12d4efdecf 100644
--- a/src/spikeinterface/preprocessing/tests/test_phase_shift.py
+++ b/src/spikeinterface/preprocessing/tests/test_phase_shift.py
@@ -20,7 +20,6 @@ def create_shifted_channel():
ratio = 10
sr = sr_h / ratio
- times = times_h[0::ratio]
delay_sample = 4
sig0 = sig_h[0::ratio]
sig1 = sig_h[delay_sample::ratio]
diff --git a/src/spikeinterface/preprocessing/tests/test_pipeline.py b/src/spikeinterface/preprocessing/tests/test_pipeline.py
index 1ea89ec749..9cd54ad9fc 100644
--- a/src/spikeinterface/preprocessing/tests/test_pipeline.py
+++ b/src/spikeinterface/preprocessing/tests/test_pipeline.py
@@ -6,8 +6,6 @@
from spikeinterface.preprocessing import (
apply_preprocessing_pipeline,
preprocessor_dict,
- bandpass_filter,
- common_reference,
whiten,
detect_and_remove_bad_channels,
bandpass_filter,
@@ -45,7 +43,6 @@ def test_pipeline_equiv_to_step():
for rec in [single_group_rec, rec_groups.split_by("group")]:
for _, pp_wrapper in preprocessor_dict.items():
-
pp_name = pp_wrapper.__name__
pp_class = pp_names_to_functions[pp_name]
diff --git a/src/spikeinterface/preprocessing/tests/test_preprocessing_tools.py b/src/spikeinterface/preprocessing/tests/test_preprocessing_tools.py
index db3df0b7ab..55d4b61037 100644
--- a/src/spikeinterface/preprocessing/tests/test_preprocessing_tools.py
+++ b/src/spikeinterface/preprocessing/tests/test_preprocessing_tools.py
@@ -1,5 +1,3 @@
-import pytest
-
import numpy as np
from spikeinterface.preprocessing import get_spatial_interpolation_kernel
@@ -13,7 +11,6 @@ def test_get_spatial_interpolation_kernel():
target_location[:, 1] = np.linspace(0, 130, 4)
for method in ("kriging", "idw", "nearest"):
-
kernel = get_spatial_interpolation_kernel(
source_location, target_location, method=method, force_extrapolate=False
)
diff --git a/src/spikeinterface/preprocessing/tests/test_remove_artifacts.py b/src/spikeinterface/preprocessing/tests/test_remove_artifacts.py
index 85ba61cdd4..716f173fbb 100644
--- a/src/spikeinterface/preprocessing/tests/test_remove_artifacts.py
+++ b/src/spikeinterface/preprocessing/tests/test_remove_artifacts.py
@@ -1,5 +1,3 @@
-import pytest
-
import numpy as np
from spikeinterface.core import generate_recording
diff --git a/src/spikeinterface/preprocessing/tests/test_resample.py b/src/spikeinterface/preprocessing/tests/test_resample.py
index de5f19def4..bfcd27f71e 100644
--- a/src/spikeinterface/preprocessing/tests/test_resample.py
+++ b/src/spikeinterface/preprocessing/tests/test_resample.py
@@ -143,7 +143,7 @@ def test_resample_freq_domain():
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=[10, 7])
xf, nyf = get_fft(parent_rec.get_traces().ravel(), parent_rec.get_sampling_frequency())
- _ = ax.plot(xf, nyf, color="k", alpha=0.8, label=f"original")
+ _ = ax.plot(xf, nyf, color="k", alpha=0.8, label="original")
for i, rec in enumerate(resamp_recs):
rs_rate = int(rec.get_sampling_frequency())
diff --git a/src/spikeinterface/preprocessing/tests/test_silence_periods.py b/src/spikeinterface/preprocessing/tests/test_silence_periods.py
index d3531f1a0f..fcc25a8b28 100644
--- a/src/spikeinterface/preprocessing/tests/test_silence_periods.py
+++ b/src/spikeinterface/preprocessing/tests/test_silence_periods.py
@@ -1,5 +1,3 @@
-import pytest
-
from spikeinterface.core import generate_recording
from spikeinterface.core import get_noise_levels
from spikeinterface.core.base import base_period_dtype
@@ -11,10 +9,7 @@
from pathlib import Path
-def test_silence(create_cache_folder):
-
- cache_folder = create_cache_folder
-
+def test_silence():
rec = generate_recording()
periods = np.array([(0, 0, 1000), (0, 5000, 6000)], dtype=base_period_dtype)
@@ -48,10 +43,7 @@ def test_silence(create_cache_folder):
assert not np.all(traces_mix[:-200] == 0)
-def test_silence_with_apodization(create_cache_folder):
-
- cache_folder = create_cache_folder
-
+def test_silence_with_apodization():
rec = generate_recording()
periods = np.array([(0, 0, 1000), (0, 5000, 6000)], dtype=base_period_dtype)
diff --git a/src/spikeinterface/preprocessing/tests/test_zero_padding.py b/src/spikeinterface/preprocessing/tests/test_zero_padding.py
index b6fcb00f03..724dc255f9 100644
--- a/src/spikeinterface/preprocessing/tests/test_zero_padding.py
+++ b/src/spikeinterface/preprocessing/tests/test_zero_padding.py
@@ -251,7 +251,6 @@ def test_trace_padded_recording_retrieve_traces_with_partial_padding(recording,
@pytest.mark.parametrize("padding_start, padding_end", [(5, 5), (0, 5), (5, 0), (0, 0)])
def test_trace_padded_recording_retrieve_only_start_padding(recording, padding_start, padding_end):
- num_samples = recording.get_num_samples()
num_channels = recording.get_num_channels()
padded_recording = TracePaddedRecording(
diff --git a/src/spikeinterface/preprocessing/tests/testing_tools.py b/src/spikeinterface/preprocessing/tests/testing_tools.py
index 2257039d43..244a421fe3 100644
--- a/src/spikeinterface/preprocessing/tests/testing_tools.py
+++ b/src/spikeinterface/preprocessing/tests/testing_tools.py
@@ -1,8 +1,2 @@
-import numpy as np
-
-from spikeinterface import NumpyRecording
-
-from probeinterface import generate_linear_probe
-
if __name__ == "__main__":
pass
diff --git a/src/spikeinterface/preprocessing/whiten.py b/src/spikeinterface/preprocessing/whiten.py
index d3fd699442..bbd30066a6 100644
--- a/src/spikeinterface/preprocessing/whiten.py
+++ b/src/spikeinterface/preprocessing/whiten.py
@@ -76,9 +76,9 @@ def __init__(
dtype_ = fix_dtype(recording, dtype)
if dtype_.kind == "i":
- assert (
- int_scale is not None
- ), "For recording with dtype=int you must set the output dtype to float OR set a int_scale"
+ assert int_scale is not None, (
+ "For recording with dtype=int you must set the output dtype to float OR set a int_scale"
+ )
if not apply_mean and regularize:
raise ValueError("`apply_mean` must be `True` if regularising. `assume_centered` is fixed to `True`.")
diff --git a/src/spikeinterface/preprocessing/zero_channel_pad.py b/src/spikeinterface/preprocessing/zero_channel_pad.py
index 639e5ccced..fdcce72866 100644
--- a/src/spikeinterface/preprocessing/zero_channel_pad.py
+++ b/src/spikeinterface/preprocessing/zero_channel_pad.py
@@ -129,7 +129,6 @@ def get_num_samples(self):
class ZeroChannelPaddedRecording(BaseRecording):
-
def __init__(self, recording: BaseRecording, num_channels: int, channel_mapping: list | None = None):
"""Pads a recording with channels that contain only zero.
@@ -147,11 +146,11 @@ def __init__(self, recording: BaseRecording, num_channels: int, channel_mapping:
BaseRecording.__init__(self, recording.get_sampling_frequency(), np.arange(num_channels), recording.get_dtype())
if channel_mapping is not None:
- assert (
- len(channel_mapping) == recording.get_num_channels()
- ), "The new mapping must be specified for all channels."
+ assert len(channel_mapping) == recording.get_num_channels(), (
+ "The new mapping must be specified for all channels."
+ )
assert max(channel_mapping) < num_channels, (
- "The new mapping cannot exceed total number of channels " "in the zero-chanenl-padded recording."
+ "The new mapping cannot exceed total number of channels in the zero-chanenl-padded recording."
)
else:
if recording.has_probe():
diff --git a/src/spikeinterface/sorters/basesorter.py b/src/spikeinterface/sorters/basesorter.py
index f25fe33e92..233de7ee46 100644
--- a/src/spikeinterface/sorters/basesorter.py
+++ b/src/spikeinterface/sorters/basesorter.py
@@ -195,7 +195,7 @@ def set_params_to_folder(
invalid_parameters = [k for k in new_params.keys() if k not in valid_parameters]
if invalid_parameters:
- error_msg = f"Invalid parameters: {invalid_parameters} \n" f"Valid parameters are: {valid_parameters}"
+ error_msg = f"Invalid parameters: {invalid_parameters} \nValid parameters are: {valid_parameters}"
raise ValueError(error_msg)
params.update(new_params)
@@ -278,7 +278,7 @@ def run_from_folder(cls, output_folder, raise_error, verbose):
t1 = time.perf_counter()
run_time = float(t1 - t0)
has_error = False
- except Exception as err:
+ except Exception:
has_error = True
run_time = None
log["error"] = True
diff --git a/src/spikeinterface/sorters/container_tools.py b/src/spikeinterface/sorters/container_tools.py
index a75ca57be7..df59f5b71b 100644
--- a/src/spikeinterface/sorters/container_tools.py
+++ b/src/spikeinterface/sorters/container_tools.py
@@ -102,7 +102,6 @@ def __init__(self, mode, container_image, volumes, py_user_base, extra_kwargs):
elif Path(sif_file).exists():
singularity_image = sif_file
else:
-
docker_image = Client.load("docker://" + container_image)
if docker_image and len(docker_image.tags) > 0:
tag = docker_image.tags[0]
@@ -116,7 +115,7 @@ def __init__(self, mode, container_image, volumes, py_user_base, extra_kwargs):
raise FileNotFoundError(f"Unable to locate container image {container_image}")
# bin options
- singularity_bind = ",".join([f'{volume_src}:{volume["bind"]}' for volume_src, volume in volumes.items()])
+ singularity_bind = ",".join([f"{volume_src}:{volume['bind']}" for volume_src, volume in volumes.items()])
options = ["--bind", singularity_bind]
# gpu options
@@ -278,6 +277,6 @@ def install_package_in_container(
raise ValueError(f"install_package_incontainer, wrong installation_mode={installation_mode}")
if isinstance(res_output, str) and "ERROR" in res_output.upper():
- warnings.warn(f"pip install of {package_name} in container may have failed. " f"pip output:\n{res_output}")
+ warnings.warn(f"pip install of {package_name} in container may have failed. pip output:\n{res_output}")
return res_output
diff --git a/src/spikeinterface/sorters/external/combinato.py b/src/spikeinterface/sorters/external/combinato.py
index 94fe33b70a..0d9457cfd8 100644
--- a/src/spikeinterface/sorters/external/combinato.py
+++ b/src/spikeinterface/sorters/external/combinato.py
@@ -52,7 +52,7 @@ class CombinatoSorter(BaseSorter):
}
_params_description = {
- "detect_sign": "Use -1 (negative) or 1 (positive) depending " "on the sign of the spikes in the recording",
+ "detect_sign": "Use -1 (negative) or 1 (positive) depending on the sign of the spikes in the recording",
"MaxClustersPerTemp": "How many clusters can be selected at one temperature",
"MinSpikesPerClusterMultiSelect": "How many spikes does a cluster need to be selected",
"RecursiveDepth": "How many clustering recursions should be run (1 do not recurse)",
@@ -125,7 +125,6 @@ def _setup_recording(cls, recording, sorter_output_folder, params, verbose):
# Generate h5 files in the dataset directory
chan_ids = recording.get_channel_ids()
assert len(chan_ids) == 1, "combinato is a single-channel recording"
- chid = chan_ids[0]
vcFile_h5 = str(sorter_output_folder / ("recording.h5"))
with h5py.File(vcFile_h5, mode="w") as f:
f.create_dataset("sr", data=[recording.get_sampling_frequency()], dtype="float32")
diff --git a/src/spikeinterface/sorters/external/dartsort.py b/src/spikeinterface/sorters/external/dartsort.py
index daad3ec555..8e66f7929b 100644
--- a/src/spikeinterface/sorters/external/dartsort.py
+++ b/src/spikeinterface/sorters/external/dartsort.py
@@ -1,4 +1,5 @@
from pathlib import Path
+import importlib.util
import numpy as np
@@ -44,14 +45,7 @@ def _dynamic_params(cls):
@classmethod
def is_installed(cls):
- try:
- import dartsort
-
- HAVE_DARTSORT = True
- except ImportError:
- HAVE_DARTSORT = False
-
- return HAVE_DARTSORT
+ return importlib.util.find_spec("dartsort") is not None
@staticmethod
def get_sorter_version():
diff --git a/src/spikeinterface/sorters/external/hdsort.py b/src/spikeinterface/sorters/external/hdsort.py
index 07d59332d2..ae4954785c 100644
--- a/src/spikeinterface/sorters/external/hdsort.py
+++ b/src/spikeinterface/sorters/external/hdsort.py
@@ -52,7 +52,7 @@ class HDSortSorter(BaseSorter):
_params_description = {
"detect_threshold": "Threshold for spike detection",
- "detect_sign": "Use -1 (negative) or 1 (positive) depending " "on the sign of the spikes in the recording",
+ "detect_sign": "Use -1 (negative) or 1 (positive) depending on the sign of the spikes in the recording",
"filter": "Enable or disable filter",
"parfor": "If True, the Matlab parfor is used",
"freq_min": "High-pass filter cutoff frequency",
@@ -248,7 +248,7 @@ def _get_result_from_folder(cls, sorter_output_folder):
def write_hdsort_input_format(cls, recording, save_path, chunk_memory="500M"):
try:
import h5py
- except:
+ except Exception:
raise Exception("To use HDSort, install h5py: pip install h5py")
# check if already in write format
@@ -294,7 +294,6 @@ def write_hdsort_input_format(cls, recording, save_path, chunk_memory="500M"):
mapping[i] = (ch, x[i], y[i], i)
ephys.create_dataset("mapping", data=mapping)
# save traces
- segment_index = 0
write_to_h5_dataset_format(
recording,
dataset_path="/ephys/signal",
diff --git a/src/spikeinterface/sorters/external/herdingspikes.py b/src/spikeinterface/sorters/external/herdingspikes.py
index 5f0bfa7dc1..c08907111d 100644
--- a/src/spikeinterface/sorters/external/herdingspikes.py
+++ b/src/spikeinterface/sorters/external/herdingspikes.py
@@ -128,9 +128,9 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
else:
lightning_api = False
- assert (
- lightning_api
- ), "HerdingSpikes version <0.4.1 is no longer supported. To upgrade, run:\n>>> pip install --upgrade herdingspikes"
+ assert lightning_api, (
+ "HerdingSpikes version <0.4.1 is no longer supported. To upgrade, run:\n>>> pip install --upgrade herdingspikes"
+ )
recording = cls.load_recording_from_folder(sorter_output_folder.parent, with_warnings=False)
diff --git a/src/spikeinterface/sorters/external/ironclust.py b/src/spikeinterface/sorters/external/ironclust.py
index e79324a0f8..ac0f0d05d5 100644
--- a/src/spikeinterface/sorters/external/ironclust.py
+++ b/src/spikeinterface/sorters/external/ironclust.py
@@ -161,8 +161,6 @@ def _check_apply_filter_in_params(cls, params):
@classmethod
def _setup_recording(cls, recording, sorter_output_folder, params, verbose):
- p = params
-
dataset_dir = sorter_output_folder / "ironclust_dataset"
# Generate three files in the dataset directory: raw.mda, geom.csv, params.json
MdaRecordingExtractor.write_recording(
diff --git a/src/spikeinterface/sorters/external/kilosort.py b/src/spikeinterface/sorters/external/kilosort.py
index 1933be38d9..e80e439b17 100644
--- a/src/spikeinterface/sorters/external/kilosort.py
+++ b/src/spikeinterface/sorters/external/kilosort.py
@@ -256,9 +256,9 @@ def _get_specific_options(cls, ops, params) -> dict:
ops["Th"] = params["Th"] # threshold for detecting spikes on template-filtered data ([6 12 12])
ops["lam"] = params["lam"] # large means amplitudes are forced around the mean ([10 30 30])
ops["nannealpasses"] = params["nannealpasses"] # should be less than nfullpasses (4)
- assert (
- ops["nannealpasses"] < ops["nfullpasses"]
- ), f"{ops['nannealpasses']=} should be less than {ops['nfullpasses']=}"
+ assert ops["nannealpasses"] < ops["nfullpasses"], (
+ f"{ops['nannealpasses']=} should be less than {ops['nfullpasses']=}"
+ )
ops["momentum"] = params["momentum"] # start with high momentum and anneal (1./[20 1000])
ops["shuffle_clusters"] = params["shuffle_clusters"] # allow merges and splits during optimization (1)
ops["mergeT"] = params["mergeT"] # upper threshold for merging (.1)
diff --git a/src/spikeinterface/sorters/external/kilosort2.py b/src/spikeinterface/sorters/external/kilosort2.py
index 6f4b0eec32..4ee92b5754 100644
--- a/src/spikeinterface/sorters/external/kilosort2.py
+++ b/src/spikeinterface/sorters/external/kilosort2.py
@@ -209,9 +209,9 @@ def _get_specific_options(cls, ops, params) -> dict:
ops["skip_kilosort_preprocessing"] = params["skip_kilosort_preprocessing"]
if params["skip_kilosort_preprocessing"]:
ops["fproc"] = ops["fbinary"]
- assert (
- params["scaleproc"] is not None
- ), "When skip_kilosort_preprocessing=True scaleproc must explicitly given"
+ assert params["scaleproc"] is not None, (
+ "When skip_kilosort_preprocessing=True scaleproc must explicitly given"
+ )
# int16 scaling of whitened data, when None then scaleproc is set to 200.
scaleproc = params["scaleproc"]
diff --git a/src/spikeinterface/sorters/external/kilosort2_5.py b/src/spikeinterface/sorters/external/kilosort2_5.py
index 06a1f07b11..23359796a1 100644
--- a/src/spikeinterface/sorters/external/kilosort2_5.py
+++ b/src/spikeinterface/sorters/external/kilosort2_5.py
@@ -232,9 +232,9 @@ def _get_specific_options(cls, ops, params) -> dict:
ops["skip_kilosort_preprocessing"] = params["skip_kilosort_preprocessing"]
if params["skip_kilosort_preprocessing"]:
ops["fproc"] = ops["fbinary"]
- assert (
- params["scaleproc"] is not None
- ), "When skip_kilosort_preprocessing=True scaleproc must explicitly given"
+ assert params["scaleproc"] is not None, (
+ "When skip_kilosort_preprocessing=True scaleproc must explicitly given"
+ )
# int16 scaling of whitened data, when None then scaleproc is set to 200.
scaleproc = params["scaleproc"]
diff --git a/src/spikeinterface/sorters/external/kilosort3.py b/src/spikeinterface/sorters/external/kilosort3.py
index 95cd145718..be405ae5fc 100644
--- a/src/spikeinterface/sorters/external/kilosort3.py
+++ b/src/spikeinterface/sorters/external/kilosort3.py
@@ -226,9 +226,9 @@ def _get_specific_options(cls, ops, params) -> dict:
ops["skip_kilosort_preprocessing"] = params["skip_kilosort_preprocessing"]
if params["skip_kilosort_preprocessing"]:
ops["fproc"] = ops["fbinary"]
- assert (
- params["scaleproc"] is not None
- ), "When skip_kilosort_preprocessing=True scaleproc must explicitly given"
+ assert params["scaleproc"] is not None, (
+ "When skip_kilosort_preprocessing=True scaleproc must explicitly given"
+ )
# int16 scaling of whitened data, when None then scaleproc is set to 200.
scaleproc = params["scaleproc"]
diff --git a/src/spikeinterface/sorters/external/kilosort4.py b/src/spikeinterface/sorters/external/kilosort4.py
index ea5e596b79..e52b084484 100644
--- a/src/spikeinterface/sorters/external/kilosort4.py
+++ b/src/spikeinterface/sorters/external/kilosort4.py
@@ -182,9 +182,7 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
if version.parse(cls.get_sorter_version()) < version.parse("4.0.16"):
raise RuntimeError(
- "Kilosort versions before 4.0.16 are not supported"
- "in SpikeInterface. "
- "Please upgrade Kilosort version."
+ "Kilosort versions before 4.0.16 are not supportedin SpikeInterface. Please upgrade Kilosort version."
)
# setup kilosort's console and file log handlers
@@ -212,7 +210,7 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
# find the stream handler
stream_handler = None
for handler in logger.handlers:
- if type(handler) == logging.StreamHandler:
+ if type(handler) is logging.StreamHandler:
stream_handler = handler
break
diff --git a/src/spikeinterface/sorters/external/kilosortbase.py b/src/spikeinterface/sorters/external/kilosortbase.py
index 15cbf4d3d0..68af4fa61e 100644
--- a/src/spikeinterface/sorters/external/kilosortbase.py
+++ b/src/spikeinterface/sorters/external/kilosortbase.py
@@ -226,9 +226,9 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
else:
tmp_files_to_remove = ()
else:
- assert isinstance(
- params["delete_tmp_files"], (tuple, list)
- ), "`delete_tmp_files` must be a `Bool`, `Tuple` or `List`."
+ assert isinstance(params["delete_tmp_files"], (tuple, list)), (
+ "`delete_tmp_files` must be a `Bool`, `Tuple` or `List`."
+ )
for name in params["delete_tmp_files"]:
assert name in all_tmp_files, f"{name} is not a valid option, must be one of: {all_tmp_files}"
diff --git a/src/spikeinterface/sorters/external/mountainsort4.py b/src/spikeinterface/sorters/external/mountainsort4.py
index f2a0e585c2..95d8fc2f04 100644
--- a/src/spikeinterface/sorters/external/mountainsort4.py
+++ b/src/spikeinterface/sorters/external/mountainsort4.py
@@ -30,7 +30,7 @@ class Mountainsort4Sorter(BaseSorter):
}
_params_description = {
- "detect_sign": "Use -1 (negative) or 1 (positive) depending " "on the sign of the spikes in the recording",
+ "detect_sign": "Use -1 (negative) or 1 (positive) depending on the sign of the spikes in the recording",
# Use -1, 0, or 1, depending on the sign of the spikes in the recording
"adjacency_radius": "Radius in um to build channel neighborhood "
"(Use -1 to include all channels in every neighborhood)",
@@ -126,7 +126,7 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
if p["tempdir"] is not None:
p["tempdir"] = str(p["tempdir"])
if verbose:
- print(f'Using temporary directory {p["tempdir"]}')
+ print(f"Using temporary directory {p['tempdir']}")
ms4_params.update(tempdir=p["tempdir"])
# Check location no more needed done in basesorter
diff --git a/src/spikeinterface/sorters/external/rt_sort.py b/src/spikeinterface/sorters/external/rt_sort.py
index 76ab5cc413..99f486c6c7 100644
--- a/src/spikeinterface/sorters/external/rt_sort.py
+++ b/src/spikeinterface/sorters/external/rt_sort.py
@@ -1,6 +1,5 @@
import importlib.util
import os
-import numpy as np
from ..basesorter import BaseSorter
@@ -116,7 +115,7 @@ class RTSortSorter(BaseSorter):
This implementation in SpikeInterface only implements RT-Sort's offline sorting.
For more information see https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0312438"""
- installation_mesg = f"""\nTo use RTSort run:\n
+ installation_mesg = """\nTo use RTSort run:\n
>>> pip install git+https://github.com/braingeneers/braindance#egg=braindance[rt-sort]
Additionally, install PyTorch (https://pytorch.org/get-started/locally/) with any version of CUDA as the compute platform.
diff --git a/src/spikeinterface/sorters/external/tests/test_combinato.py b/src/spikeinterface/sorters/external/tests/test_combinato.py
index 248cf9274d..304f523f18 100644
--- a/src/spikeinterface/sorters/external/tests/test_combinato.py
+++ b/src/spikeinterface/sorters/external/tests/test_combinato.py
@@ -1,6 +1,6 @@
from spikeinterface.sorters import CombinatoSorter
-import os, getpass
+import getpass
if getpass.getuser() == "samuel":
combinato_path = "/home/samuel/Documents/SpikeInterface/combinato/"
diff --git a/src/spikeinterface/sorters/external/tests/test_hdsort.py b/src/spikeinterface/sorters/external/tests/test_hdsort.py
index d8495339d3..0894a3655e 100644
--- a/src/spikeinterface/sorters/external/tests/test_hdsort.py
+++ b/src/spikeinterface/sorters/external/tests/test_hdsort.py
@@ -1,6 +1,6 @@
from spikeinterface.sorters import HDSortSorter
-import os, getpass
+import getpass
if getpass.getuser() == "samuel":
hdsort_path = "/home/samuel/Documents/SpikeInterface/HDsort/"
diff --git a/src/spikeinterface/sorters/external/tests/test_ironclust.py b/src/spikeinterface/sorters/external/tests/test_ironclust.py
index 54edae6976..7642bc8f7e 100644
--- a/src/spikeinterface/sorters/external/tests/test_ironclust.py
+++ b/src/spikeinterface/sorters/external/tests/test_ironclust.py
@@ -1,4 +1,5 @@
-import os, getpass
+import os
+import getpass
if getpass.getuser() == "samuel":
ironclust_path = "/home/samuel/Documents/SpikeInterface/ironclust/"
diff --git a/src/spikeinterface/sorters/external/tests/test_kilosort2_5.py b/src/spikeinterface/sorters/external/tests/test_kilosort2_5.py
index 58d9114930..8f7c7939a5 100644
--- a/src/spikeinterface/sorters/external/tests/test_kilosort2_5.py
+++ b/src/spikeinterface/sorters/external/tests/test_kilosort2_5.py
@@ -1,6 +1,6 @@
from spikeinterface.sorters import Kilosort2_5Sorter
-import os, getpass
+import getpass
if getpass.getuser() == "samuel":
kilosort2_5_path = "/home/samuel/Documents/SpikeInterface/Kilosort2.5"
diff --git a/src/spikeinterface/sorters/external/tests/test_singularity_containers_gpu.py b/src/spikeinterface/sorters/external/tests/test_singularity_containers_gpu.py
index eb238abdf4..aa3e683199 100644
--- a/src/spikeinterface/sorters/external/tests/test_singularity_containers_gpu.py
+++ b/src/spikeinterface/sorters/external/tests/test_singularity_containers_gpu.py
@@ -1,5 +1,4 @@
import os
-import shutil
import pytest
diff --git a/src/spikeinterface/sorters/external/tests/test_tridesclous.py b/src/spikeinterface/sorters/external/tests/test_tridesclous.py
index 95c663a20e..b00512879e 100644
--- a/src/spikeinterface/sorters/external/tests/test_tridesclous.py
+++ b/src/spikeinterface/sorters/external/tests/test_tridesclous.py
@@ -1,7 +1,6 @@
import unittest
import pytest
-from spikeinterface.extractors import toy_example
from spikeinterface.sorters import TridesclousSorter
from spikeinterface.sorters.tests.common_tests import SorterCommonTestSuite
diff --git a/src/spikeinterface/sorters/external/tests/test_waveclus.py b/src/spikeinterface/sorters/external/tests/test_waveclus.py
index 71af12d99f..4d3335a6dd 100644
--- a/src/spikeinterface/sorters/external/tests/test_waveclus.py
+++ b/src/spikeinterface/sorters/external/tests/test_waveclus.py
@@ -1,4 +1,5 @@
-import os, getpass
+import os
+import getpass
if getpass.getuser() == "samuel":
waveclus_path = "/home/samuel/Documents/SpikeInterface/wave_clus/"
diff --git a/src/spikeinterface/sorters/external/tridesclous.py b/src/spikeinterface/sorters/external/tridesclous.py
index 95a9f2ef43..47c5d90878 100644
--- a/src/spikeinterface/sorters/external/tridesclous.py
+++ b/src/spikeinterface/sorters/external/tridesclous.py
@@ -31,7 +31,7 @@ class TridesclousSorter(BaseSorter):
"freq_min": "High-pass filter cutoff frequency",
"freq_max": "Low-pass filter cutoff frequency",
"detect_threshold": "Threshold for spike detection",
- "detect_sign": "Use -1 (negative) or 1 (positive) depending " "on the sign of the spikes in the recording",
+ "detect_sign": "Use -1 (negative) or 1 (positive) depending on the sign of the spikes in the recording",
"common_ref_removal": "remove common reference with median",
}
diff --git a/src/spikeinterface/sorters/external/waveclus.py b/src/spikeinterface/sorters/external/waveclus.py
index 2d498616b7..df38dfc0f6 100644
--- a/src/spikeinterface/sorters/external/waveclus.py
+++ b/src/spikeinterface/sorters/external/waveclus.py
@@ -194,7 +194,7 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
"""
else:
source_dir = Path(__file__).parent
- shutil.copy(str(source_dir / f"waveclus_master.m"), str(sorter_output_folder))
+ shutil.copy(str(source_dir / "waveclus_master.m"), str(sorter_output_folder))
sorter_path = Path(cls.waveclus_path).absolute()
if "win" in sys.platform and sys.platform != "darwin":
@@ -290,7 +290,7 @@ def _generate_par_file(params, sorter_output_folder):
}
par_input = {}
for key, value in p.items():
- if type(value) == bool:
+ if type(value) is bool:
value = f"{value}".lower()
if key in par_renames:
key = par_renames[key]
diff --git a/src/spikeinterface/sorters/external/yass.py b/src/spikeinterface/sorters/external/yass.py
index 1a1b40b324..77373e8ad9 100644
--- a/src/spikeinterface/sorters/external/yass.py
+++ b/src/spikeinterface/sorters/external/yass.py
@@ -163,7 +163,7 @@ def _setup_recording(cls, recording, sorter_output_folder, params, verbose):
# to yaml
fname_config = sorter_output_folder / "config.yaml"
with open(fname_config, "w") as file:
- documents = yaml.dump(merge_params, file)
+ _ = yaml.dump(merge_params, file)
# RunNN training on existing
neural_nets_path = p["neural_nets_path"]
diff --git a/src/spikeinterface/sorters/internal/lupin.py b/src/spikeinterface/sorters/internal/lupin.py
index f672593510..b266b258ee 100644
--- a/src/spikeinterface/sorters/internal/lupin.py
+++ b/src/spikeinterface/sorters/internal/lupin.py
@@ -12,7 +12,7 @@
from spikeinterface.core.job_tools import fix_job_kwargs
-from spikeinterface.preprocessing import bandpass_filter, common_reference, zscore, whiten
+from spikeinterface.preprocessing import bandpass_filter, common_reference, whiten
from spikeinterface.core.base import minimum_spike_dtype
from spikeinterface.sortingcomponents.tools import cache_preprocessing, clean_cache_preprocessing
@@ -177,7 +177,6 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
# preprocessing
if params["apply_preprocessing"]:
if params["apply_motion_correction"]:
-
rec_for_motion = recording_raw
if params["preprocessing_dict"] is None:
rec_for_motion = bandpass_filter(
diff --git a/src/spikeinterface/sorters/internal/si_based.py b/src/spikeinterface/sorters/internal/si_based.py
index 3860e60fb5..64dc035085 100644
--- a/src/spikeinterface/sorters/internal/si_based.py
+++ b/src/spikeinterface/sorters/internal/si_based.py
@@ -1,4 +1,4 @@
-from spikeinterface.core import load, NumpyRecording
+from spikeinterface.core import load
from spikeinterface.sorters import BaseSorter
diff --git a/src/spikeinterface/sorters/internal/simplesorter.py b/src/spikeinterface/sorters/internal/simplesorter.py
index 0c7414171d..d0b89fe9fb 100644
--- a/src/spikeinterface/sorters/internal/simplesorter.py
+++ b/src/spikeinterface/sorters/internal/simplesorter.py
@@ -1,9 +1,8 @@
from .si_based import ComponentsBasedSorter
-from spikeinterface.core import BaseRecording, get_noise_levels, extract_waveforms, NumpySorting
+from spikeinterface.core import get_noise_levels, NumpySorting
from spikeinterface.core.job_tools import fix_job_kwargs
-from spikeinterface.sortingcomponents.tools import cache_preprocessing
-from spikeinterface.preprocessing import bandpass_filter, common_reference, zscore
+from spikeinterface.preprocessing import bandpass_filter, zscore
import numpy as np
diff --git a/src/spikeinterface/sorters/internal/spyking_circus2.py b/src/spikeinterface/sorters/internal/spyking_circus2.py
index 06b804b305..f62c9f6259 100644
--- a/src/spikeinterface/sorters/internal/spyking_circus2.py
+++ b/src/spikeinterface/sorters/internal/spyking_circus2.py
@@ -1,6 +1,7 @@
from .si_based import ComponentsBasedSorter
import shutil
+import importlib.util
import numpy as np
from spikeinterface.core import NumpySorting
@@ -90,8 +91,6 @@ class Spykingcircus2Sorter(ComponentsBasedSorter):
@classmethod
def is_installed(cls):
- import importlib.util
-
spykingcircus2_deps = ["scipy", "numba", "hdbscan"]
for package_name in spykingcircus2_deps:
@@ -107,10 +106,7 @@ def get_sorter_version(cls):
@classmethod
def _run_from_folder(cls, sorter_output_folder, params, verbose):
- try:
- import torch
- except ImportError:
- HAVE_TORCH = False
+ if importlib.util.find_spec("torch") is None:
print("spykingcircus2 could benefit from using torch. Consider installing it")
# this is imported only on demand because numba import are too heavy
@@ -231,7 +227,7 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
n_peaks_per_channel = selection_params.get("n_peaks_per_channel", 5000)
min_n_peaks = selection_params.get("min_n_peaks", 100000)
skip_peaks = not params["multi_units_only"] and selection_method == "uniform"
- skip_peaks = skip_peaks and not deterministic and not (matching_method is None)
+ skip_peaks = skip_peaks and not deterministic and matching_method is not None
max_n_peaks = n_peaks_per_channel * num_channels
n_peaks = max(min_n_peaks, max_n_peaks)
selection_params["n_peaks"] = n_peaks
@@ -407,7 +403,6 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
del more_outs
- before_clean_ids = templates.unit_ids.copy()
cleaning_kwargs["max_std_per_channel"] = max_std_per_channel
cleaning_kwargs["verbose"] = verbose
templates = clean_templates(templates, noise_levels=noise_levels, **cleaning_kwargs)
diff --git a/src/spikeinterface/sorters/internal/tests/test_lupin.py b/src/spikeinterface/sorters/internal/tests/test_lupin.py
index f838f9f4eb..fca6208bc7 100644
--- a/src/spikeinterface/sorters/internal/tests/test_lupin.py
+++ b/src/spikeinterface/sorters/internal/tests/test_lupin.py
@@ -1,10 +1,9 @@
import unittest
-import pytest
from spikeinterface.sorters.tests.common_tests import SorterCommonTestSuite
-from spikeinterface.sorters import LupinSorter, run_sorter
+from spikeinterface.sorters import LupinSorter
from pathlib import Path
diff --git a/src/spikeinterface/sorters/internal/tests/test_spykingcircus2.py b/src/spikeinterface/sorters/internal/tests/test_spykingcircus2.py
index 5188dd8329..7350809414 100644
--- a/src/spikeinterface/sorters/internal/tests/test_spykingcircus2.py
+++ b/src/spikeinterface/sorters/internal/tests/test_spykingcircus2.py
@@ -18,7 +18,7 @@ def test_with_numpy_gather(self):
sorter_params["matching"]["gather_mode"] = "npy"
- sorting = run_sorter(
+ _ = run_sorter(
sorter_name,
recording,
folder=output_folder,
diff --git a/src/spikeinterface/sorters/internal/tests/test_tridesclous2.py b/src/spikeinterface/sorters/internal/tests/test_tridesclous2.py
index 6431532b87..73d8e34a42 100644
--- a/src/spikeinterface/sorters/internal/tests/test_tridesclous2.py
+++ b/src/spikeinterface/sorters/internal/tests/test_tridesclous2.py
@@ -1,6 +1,5 @@
import unittest
-import pytest
from spikeinterface.sorters.tests.common_tests import SorterCommonTestSuite
@@ -26,7 +25,7 @@ def test_with_numpy_gather(self):
sorter_params["gather_mode"] = "npy"
- sorting = run_sorter(
+ _ = run_sorter(
sorter_name,
recording,
folder=output_folder,
diff --git a/src/spikeinterface/sorters/internal/tridesclous2.py b/src/spikeinterface/sorters/internal/tridesclous2.py
index 56a506b293..20d6c4e6e3 100644
--- a/src/spikeinterface/sorters/internal/tridesclous2.py
+++ b/src/spikeinterface/sorters/internal/tridesclous2.py
@@ -1,6 +1,3 @@
-import shutil
-import importlib
-
from .si_based import ComponentsBasedSorter
from copy import deepcopy
@@ -10,13 +7,12 @@
NumpySorting,
estimate_templates_with_accumulator,
Templates,
- compute_sparsity,
ms_to_samples,
)
from spikeinterface.core.job_tools import fix_job_kwargs
-from spikeinterface.preprocessing import bandpass_filter, common_reference, zscore, whiten
+from spikeinterface.preprocessing import bandpass_filter, common_reference, whiten
from spikeinterface.core.base import minimum_spike_dtype
from spikeinterface.sortingcomponents.tools import cache_preprocessing, clean_cache_preprocessing
@@ -142,7 +138,6 @@ def _run_from_folder(cls, sorter_output_folder, params, verbose):
# preprocessing
if params["apply_preprocessing"]:
if params["apply_motion_correction"]:
-
rec_for_motion = recording_raw
if params["preprocessing_dict"] is None:
rec_for_motion = bandpass_filter(
diff --git a/src/spikeinterface/sorters/launcher.py b/src/spikeinterface/sorters/launcher.py
index e1b5921746..8dc295e1fc 100644
--- a/src/spikeinterface/sorters/launcher.py
+++ b/src/spikeinterface/sorters/launcher.py
@@ -290,7 +290,7 @@ def run_sorter_by_property(
working_folder = Path(folder).absolute()
assert grouping_property in recording.get_property_keys(), (
- f"The 'grouping_property' {grouping_property} is not " f"a recording property!"
+ f"The 'grouping_property' {grouping_property} is not a recording property!"
)
recording_dict = recording.split_by(grouping_property)
diff --git a/src/spikeinterface/sorters/runsorter.py b/src/spikeinterface/sorters/runsorter.py
index 9b0e6855f5..c0923f0342 100644
--- a/src/spikeinterface/sorters/runsorter.py
+++ b/src/spikeinterface/sorters/runsorter.py
@@ -144,7 +144,6 @@ def run_sorter(
)
if isinstance(recording, dict):
-
all_kwargs = common_kwargs
all_kwargs.update(
dict(
@@ -186,8 +185,7 @@ def run_sorter(
if not has_singularity():
raise RuntimeError(
- "Singularity is not installed. Install singularity "
- "on this machine to run sorting with singularity."
+ "Singularity is not installed. Install singularity on this machine to run sorting with singularity."
)
if not has_spython():
@@ -482,9 +480,9 @@ def run_sorter_container(
print(f"installation_mode='auto' switching to installation_mode: '{installation_mode}'")
if installation_mode == "folder":
- assert (
- spikeinterface_folder_source is not None
- ), "for installation_mode='folder', spikeinterface_folder_source must be provided"
+ assert spikeinterface_folder_source is not None, (
+ "for installation_mode='folder', spikeinterface_folder_source must be provided"
+ )
host_folder_source = Path(spikeinterface_folder_source)
if installation_mode == "dev":
@@ -552,7 +550,7 @@ def run_sorter_container(
if need_si_install or installation_mode == "dev":
# update pip in container
- cmd = f"pip install --user --upgrade pip"
+ cmd = "pip install --user --upgrade pip"
res_output = container_client.run_command(cmd)
if installation_mode == "pypi":
@@ -678,7 +676,7 @@ def run_sorter_container(
if with_output:
try:
sorting = SorterClass.get_result_from_folder(folder)
- except Exception as e:
+ except Exception:
try:
sorting = load(in_container_sorting_folder)
except FileNotFoundError:
diff --git a/src/spikeinterface/sorters/sorterlist.py b/src/spikeinterface/sorters/sorterlist.py
index f536967b3b..71f16f1d6c 100644
--- a/src/spikeinterface/sorters/sorterlist.py
+++ b/src/spikeinterface/sorters/sorterlist.py
@@ -7,7 +7,7 @@
from .external.kilosort2 import Kilosort2Sorter
from .external.kilosort2_5 import Kilosort2_5Sorter
from .external.kilosort3 import Kilosort3Sorter
-from .external.kilosort4 import Kilosort4Sorter, read_kilosort4_motion
+from .external.kilosort4 import Kilosort4Sorter
from .external.pykilosort import PyKilosortSorter
from .external.klusta import KlustaSorter
from .external.mountainsort4 import Mountainsort4Sorter
diff --git a/src/spikeinterface/sorters/tests/test_container_tools.py b/src/spikeinterface/sorters/tests/test_container_tools.py
index 2f3b176cc5..9fa2a69974 100644
--- a/src/spikeinterface/sorters/tests/test_container_tools.py
+++ b/src/spikeinterface/sorters/tests/test_container_tools.py
@@ -101,24 +101,24 @@ def test_install_package_in_container():
container_client = ContainerClient(mode, container_image, volumes, py_user_base, extra_kwargs)
container_client.start()
- txt = container_client.run_command("pip install --user --upgrade pip")
+ _ = container_client.run_command("pip install --user --upgrade pip")
# # pypi installation
- txt = install_package_in_container(container_client, "neo", installation_mode="pypi", version="0.11.0")
+ _ = install_package_in_container(container_client, "neo", installation_mode="pypi", version="0.11.0")
# print(txt)
- txt = container_client.run_command("pip list")
+ _ = container_client.run_command("pip list")
# print(txt)
# # github installation
- txt = install_package_in_container(
+ _ = install_package_in_container(
container_client, "spikeinterface", extra="[full]", installation_mode="github", version="0.99.0"
)
# print(txt)
- txt = container_client.run_command("pip list")
+ _ = container_client.run_command("pip list")
# print(txt)
# folder installation
- txt = install_package_in_container(
+ _ = install_package_in_container(
container_client,
"spikeinterface",
extra="[full]",
@@ -127,7 +127,7 @@ def test_install_package_in_container():
)
# print(txt)
- txt = container_client.run_command("pip list")
+ _ = container_client.run_command("pip list")
# print(txt)
container_client.stop()
diff --git a/src/spikeinterface/sorters/tests/test_launcher.py b/src/spikeinterface/sorters/tests/test_launcher.py
index 6619431866..3e13fa0e24 100644
--- a/src/spikeinterface/sorters/tests/test_launcher.py
+++ b/src/spikeinterface/sorters/tests/test_launcher.py
@@ -16,7 +16,6 @@
def create_recordings(folder, NUM_RECORDINGS=2, base_seed=42):
recordings = []
for i in range(NUM_RECORDINGS):
-
recording, _ = generate_ground_truth_recording(num_channels=8, durations=[10.0], seed=base_seed + i)
recording = recording.save(folder=folder / f"rec_for_generate_recording_{i}", format="binary", overwrite=True)
diff --git a/src/spikeinterface/sorters/tests/test_runsorter_dependency_checks.py b/src/spikeinterface/sorters/tests/test_runsorter_dependency_checks.py
index 12ef8caafd..af164b3f2a 100644
--- a/src/spikeinterface/sorters/tests/test_runsorter_dependency_checks.py
+++ b/src/spikeinterface/sorters/tests/test_runsorter_dependency_checks.py
@@ -1,7 +1,7 @@
import pytest
import platform
from spikeinterface import generate_ground_truth_recording
-from spikeinterface.sorters.utils import has_spython, has_docker_python, has_docker, has_singularity
+from spikeinterface.sorters.utils import has_spython, has_docker_python
from spikeinterface.sorters import run_sorter
import sys
@@ -71,11 +71,11 @@ def uninstall_python_dependency(self, request):
try:
if dep_name == "spython":
- import spython
+ import spython # noqa: F401
else:
- import docker
+ import docker # noqa: F401
dependency_installed = True
- except:
+ except Exception:
dependency_installed = False
if dependency_installed:
@@ -120,7 +120,7 @@ def test_no_singularity_error_raised(self, recording, monkeypatch):
return False. Then, test the expected error is raised when the dependency
is not found.
"""
- monkeypatch.setattr(f"spikeinterface.sorters.runsorter.has_singularity", _monkeypatch_return_false)
+ monkeypatch.setattr("spikeinterface.sorters.runsorter.has_singularity", _monkeypatch_return_false)
with pytest.raises(RuntimeError) as e:
run_sorter("kilosort2_5", recording, singularity_image=True)
@@ -132,8 +132,8 @@ def test_no_spython_error_raised(self, recording, monkeypatch):
See `test_no_singularity_error_raised()`.
"""
# make sure singularity test returns true as that comes first
- monkeypatch.setattr(f"spikeinterface.sorters.runsorter.has_singularity", _monkeypatch_return_true)
- monkeypatch.setattr(f"spikeinterface.sorters.runsorter.has_spython", _monkeypatch_return_false)
+ monkeypatch.setattr("spikeinterface.sorters.runsorter.has_singularity", _monkeypatch_return_true)
+ monkeypatch.setattr("spikeinterface.sorters.runsorter.has_spython", _monkeypatch_return_false)
with pytest.raises(RuntimeError) as e:
run_sorter("kilosort2_5", recording, singularity_image=True)
@@ -144,7 +144,7 @@ def test_no_docker_error_raised(self, recording, monkeypatch):
"""
See `test_no_singularity_error_raised()`.
"""
- monkeypatch.setattr(f"spikeinterface.sorters.runsorter.has_docker", _monkeypatch_return_false)
+ monkeypatch.setattr("spikeinterface.sorters.runsorter.has_docker", _monkeypatch_return_false)
with pytest.raises(RuntimeError) as e:
run_sorter("kilosort2_5", recording, docker_image=True)
@@ -156,8 +156,8 @@ def test_as_no_docker_python_error_raised(self, recording, monkeypatch):
See `test_no_singularity_error_raised()`.
"""
# make sure docker test returns true as that comes first
- monkeypatch.setattr(f"spikeinterface.sorters.runsorter.has_docker", _monkeypatch_return_true)
- monkeypatch.setattr(f"spikeinterface.sorters.runsorter.has_docker_python", _monkeypatch_return_false)
+ monkeypatch.setattr("spikeinterface.sorters.runsorter.has_docker", _monkeypatch_return_true)
+ monkeypatch.setattr("spikeinterface.sorters.runsorter.has_docker_python", _monkeypatch_return_false)
with pytest.raises(RuntimeError) as e:
run_sorter("kilosort2_5", recording, docker_image=True)
diff --git a/src/spikeinterface/sorters/utils/misc.py b/src/spikeinterface/sorters/utils/misc.py
index 162c8f07c2..66e6710260 100644
--- a/src/spikeinterface/sorters/utils/misc.py
+++ b/src/spikeinterface/sorters/utils/misc.py
@@ -52,7 +52,7 @@ def get_git_commit(git_folder, shorten=True):
commit = check_output(["git", "rev-parse", "HEAD"], cwd=git_folder).decode("utf8").strip()
if shorten:
commit = commit[:12]
- except:
+ except Exception:
commit = None
return commit
diff --git a/src/spikeinterface/sorters/utils/shellscript.py b/src/spikeinterface/sorters/utils/shellscript.py
index abd2eaf0b1..5659466b78 100644
--- a/src/spikeinterface/sorters/utils/shellscript.py
+++ b/src/spikeinterface/sorters/utils/shellscript.py
@@ -106,7 +106,7 @@ def wait(self, timeout=None) -> int | None:
try:
retcode = self._process.wait(timeout=timeout)
return retcode
- except:
+ except Exception:
return None
def cleanup(self) -> None:
@@ -133,7 +133,7 @@ def stop(self) -> None:
try:
self._process.wait(timeout=0.02)
return
- except:
+ except Exception:
pass
def kill(self) -> None:
@@ -144,7 +144,7 @@ def kill(self) -> None:
self._process.send_signal(signal.SIGKILL)
try:
self._process.wait(timeout=1)
- except:
+ except Exception:
print("WARNING: unable to kill shell script.")
pass
@@ -157,7 +157,7 @@ def stopWithSignal(self, sig, timeout) -> bool:
try:
self._process.wait(timeout=timeout)
return True
- except:
+ except Exception:
return False
def elapsedTimeSinceStart(self) -> float | None:
@@ -208,7 +208,7 @@ def _rmdir_with_retries(dirname, num_retries, delay_between_tries=1):
try:
shutil.rmtree(dirname)
break
- except:
+ except Exception:
if retry_num < num_retries:
print(f"Retrying to remove directory: {dirname}")
time.sleep(delay_between_tries)
diff --git a/src/spikeinterface/sortingcomponents/clustering/cleaning_tools.py b/src/spikeinterface/sortingcomponents/clustering/cleaning_tools.py
index 4f10f51b73..6825b68a72 100644
--- a/src/spikeinterface/sortingcomponents/clustering/cleaning_tools.py
+++ b/src/spikeinterface/sortingcomponents/clustering/cleaning_tools.py
@@ -5,7 +5,6 @@
import numpy as np
from spikeinterface.core.job_tools import fix_job_kwargs
from spikeinterface.postprocessing import check_equal_template_with_distribution_overlap
-from spikeinterface.core import NumpySorting
def _split_waveforms(
@@ -50,7 +49,6 @@ def _split_waveforms(
if debug:
import matplotlib.pyplot as plt
- import umap
fig, ax = plt.subplots()
@@ -122,7 +120,6 @@ def _split_waveforms_nested(
# hdbscan on pca
clustering = hdbscan.hdbscan(local_feature, **hdbscan_params)
active_labels_with_noise = clustering[0]
- cluster_probability = clustering[2]
(persistent_clusters,) = np.nonzero(clustering[2] > probability_thr)
active_labels_with_noise[~np.isin(active_labels_with_noise, persistent_clusters)] = -1
@@ -229,9 +226,6 @@ def auto_split_clustering(
Internally used by PositionAndPCAClustering for the second step.
"""
- import sklearn.decomposition
- import hdbscan
-
split_peak_labels = -1 * np.ones(peak_labels.size, dtype=np.int64)
nb_clusters = 0
main_channels = {}
@@ -505,7 +499,6 @@ def remove_duplicates(
idx = np.argsort(channel_norms)[::-1]
explained_norms = np.cumsum(channel_norms[idx] / total_norm)
channel = np.searchsorted(explained_norms, sparsify_threshold)
- active_channels = np.sort(idx[:channel])
templates[t, :, idx[channel:]] = 0
from sklearn.metrics.pairwise import cosine_similarity
@@ -589,11 +582,9 @@ def detect_mixtures(templates, method_kwargs={}, job_kwargs={}, tmp_folder=None,
DEBUG = False
sub_recording = None # we only do a sub recording if we have data to iterate through
while keep_searching:
-
keep_searching = False
for i in list(set(range(nb_templates)).difference(ignore_inds)):
-
## Could be speed up by only computing the values for templates that are
## nearby
@@ -642,7 +633,6 @@ def detect_mixtures(templates, method_kwargs={}, job_kwargs={}, tmp_folder=None,
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2)
- from spikeinterface.widgets import plot_traces
# plot_traces(sub_recording, ax=axes[0])
axes[1].plot(templates_array[i].flatten(), label=f"{ref_norm}")
diff --git a/src/spikeinterface/sortingcomponents/clustering/graph_clustering.py b/src/spikeinterface/sortingcomponents/clustering/graph_clustering.py
index bea9cda7a2..197f5674ae 100644
--- a/src/spikeinterface/sortingcomponents/clustering/graph_clustering.py
+++ b/src/spikeinterface/sortingcomponents/clustering/graph_clustering.py
@@ -1,5 +1,3 @@
-from pathlib import Path
-
import numpy as np
@@ -72,7 +70,6 @@ def main_function(cls, recording, peaks, params, job_kwargs=dict()):
radius_um = peaks_svd["radius_um"]
motion = peaks_svd["motion"]
seed = params["seed"]
- verbose = params["verbose"]
clustering_kwargs = params["clusterer"].copy()
graph_kwargs = params["graph_kwargs"].copy()
diff --git a/src/spikeinterface/sortingcomponents/clustering/graph_tools.py b/src/spikeinterface/sortingcomponents/clustering/graph_tools.py
index a76adec994..df38fdca10 100644
--- a/src/spikeinterface/sortingcomponents/clustering/graph_tools.py
+++ b/src/spikeinterface/sortingcomponents/clustering/graph_tools.py
@@ -58,7 +58,6 @@ def create_graph_from_peak_features(
channel_locations = recording.get_channel_locations()
if bin_mode == "channels":
-
dims = ["xyz".index(i) for i in direction]
channel_locs = channel_locations[:, dims]
channel_distances = np.linalg.norm(channel_locs[:, np.newaxis] - channel_locs[np.newaxis, :], axis=2)
@@ -71,7 +70,6 @@ def create_graph_from_peak_features(
loop.append((local_chans, neighbors_indices, target_local_inds))
elif bin_mode == "vertical_bins":
-
assert len(direction) == 1
dim = "xyz".index(direction)
channel_depth = channel_locations[:, dim]
@@ -92,7 +90,6 @@ def create_graph_from_peak_features(
loop = []
for b in range(bins.size - 1):
-
# limits for peaks
l0, l1 = bins[b], bins[b + 1]
# mask = (peak_depths> l0) & (peak_depths<= l1)
diff --git a/src/spikeinterface/sortingcomponents/clustering/isosplit_isocut.py b/src/spikeinterface/sortingcomponents/clustering/isosplit_isocut.py
index c5dd6654ab..a6be2db181 100644
--- a/src/spikeinterface/sortingcomponents/clustering/isosplit_isocut.py
+++ b/src/spikeinterface/sortingcomponents/clustering/isosplit_isocut.py
@@ -42,7 +42,6 @@
if HAVE_NUMBA:
-
##########################
# isocut zone
@@ -284,7 +283,6 @@ def isosplit(
"""
if initial_labels is None:
-
if n_init >= X.shape[0]:
# protect against too high n_init compared to sample size
warnings.warn(f"isosplit : n_init {n_init} is too big compared to sample size {X.shape[0]}")
@@ -367,7 +365,6 @@ def isosplit(
break
if active_labels.size > 1:
-
# Find the pairs to compare on this iteration
# These will be closest pairs of active clusters that have not yet
# been compared in this pass
diff --git a/src/spikeinterface/sortingcomponents/clustering/iterative_isosplit.py b/src/spikeinterface/sortingcomponents/clustering/iterative_isosplit.py
index 002de2feeb..4ca8c3616a 100644
--- a/src/spikeinterface/sortingcomponents/clustering/iterative_isosplit.py
+++ b/src/spikeinterface/sortingcomponents/clustering/iterative_isosplit.py
@@ -271,7 +271,6 @@ def main_function(cls, recording, peaks, params, job_kwargs=dict()):
# templates_array = dense_templates.templates_array
if params["merge_from_features"] is not None:
-
merge_from_features_kwargs = params["merge_from_features"].copy()
merge_radius_um = merge_from_features_kwargs.pop("merge_radius_um")
diff --git a/src/spikeinterface/sortingcomponents/clustering/itersplit_tools.py b/src/spikeinterface/sortingcomponents/clustering/itersplit_tools.py
index d34ca8bb4e..5864ae9e68 100644
--- a/src/spikeinterface/sortingcomponents/clustering/itersplit_tools.py
+++ b/src/spikeinterface/sortingcomponents/clustering/itersplit_tools.py
@@ -1,5 +1,4 @@
import warnings
-import importlib.util
from multiprocessing import get_context
from threadpoolctl import threadpool_limits
from tqdm.auto import tqdm
@@ -10,11 +9,6 @@
from .tools import aggregate_sparse_features, FeaturesLoader
-if importlib.util.find_spec("numba") is not None:
- import numba
-else:
- pass
-# isocut requires numba
# important all DEBUG and matplotlib are left in the code intentionally
@@ -352,7 +346,6 @@ def split(
if final_features.shape[1] == 1:
final_features = np.hstack((final_features, np.zeros_like(final_features)))
- sl = slice(None, None, 100)
for k in np.unique(possible_labels):
mask = possible_labels == k
ax = axs[0]
@@ -364,7 +357,7 @@ def split(
ax.plot(flatten_wfs[mask].T, color=colors[k], alpha=0.1)
if k > -1:
ax.plot(np.median(flatten_wfs[mask].T, axis=1), color=colors[k], lw=2)
- ax.set_xlabel(f"PCA features")
+ ax.set_xlabel("PCA features")
ax = axs[3]
if n_pca_features == 1:
diff --git a/src/spikeinterface/sortingcomponents/clustering/main.py b/src/spikeinterface/sortingcomponents/clustering/main.py
index 46052fa5ae..c8b8a60a27 100644
--- a/src/spikeinterface/sortingcomponents/clustering/main.py
+++ b/src/spikeinterface/sortingcomponents/clustering/main.py
@@ -1,4 +1,4 @@
-from spikeinterface.core.job_tools import fix_job_kwargs, _shared_job_kwargs_doc
+from spikeinterface.core.job_tools import fix_job_kwargs
import copy
from ..tools import make_multi_method_doc
@@ -39,9 +39,9 @@ def find_clusters_from_peaks(
"""
job_kwargs = fix_job_kwargs(job_kwargs)
- assert (
- method in clustering_methods
- ), f"Method for clustering do not exists, should be in {list(clustering_methods.keys())}"
+ assert method in clustering_methods, (
+ f"Method for clustering do not exists, should be in {list(clustering_methods.keys())}"
+ )
method_class = clustering_methods[method]
params = copy.deepcopy(method_class._default_params.copy())
diff --git a/src/spikeinterface/sortingcomponents/clustering/merging_tools.py b/src/spikeinterface/sortingcomponents/clustering/merging_tools.py
index 9cc4bd18a3..1b9194d504 100644
--- a/src/spikeinterface/sortingcomponents/clustering/merging_tools.py
+++ b/src/spikeinterface/sortingcomponents/clustering/merging_tools.py
@@ -7,6 +7,7 @@
import numpy as np
from spikeinterface.core.job_tools import get_poolexecutor, fix_job_kwargs
+from .tools import aggregate_sparse_features, FeaturesLoader
numba_spec = importlib.util.find_spec("numba")
networkx_spec = importlib.util.find_spec("networkx")
@@ -20,7 +21,6 @@
else:
pass
-from .tools import aggregate_sparse_features, FeaturesLoader
DEBUG = False
@@ -45,10 +45,6 @@ def merge_peak_labels_from_features(
job_kwargs = fix_job_kwargs(job_kwargs)
- features = FeaturesLoader.from_dict_or_folder(features_dict_or_folder)
- # sparse_wfs = features["sparse_wfs"]
- # sparse_mask = features["sparse_mask"]
-
labels_set, pair_mask, pair_shift, pair_values = find_merge_pairs_from_features(
peaks,
peak_labels,
@@ -443,7 +439,6 @@ def merge(
is_merge = l0 >= l1
merge_value = l0 - l1
elif criteria == "distrib_overlap":
-
lim0 = min(np.min(feat0), np.min(feat1))
lim1 = max(np.max(feat0), np.max(feat1))
bin_size = (lim1 - lim0) / 200.0
diff --git a/src/spikeinterface/sortingcomponents/clustering/positions.py b/src/spikeinterface/sortingcomponents/clustering/positions.py
index b94f6607cb..93e57c27d1 100644
--- a/src/spikeinterface/sortingcomponents/clustering/positions.py
+++ b/src/spikeinterface/sortingcomponents/clustering/positions.py
@@ -1,5 +1,4 @@
# """Sorting components: clustering"""
-from pathlib import Path
import importlib.util
import numpy as np
diff --git a/src/spikeinterface/sortingcomponents/clustering/random_projections.py b/src/spikeinterface/sortingcomponents/clustering/random_projections.py
index cd451f4d07..24966fd348 100644
--- a/src/spikeinterface/sortingcomponents/clustering/random_projections.py
+++ b/src/spikeinterface/sortingcomponents/clustering/random_projections.py
@@ -4,13 +4,6 @@
import importlib
import numpy as np
-hdbscan_spec = importlib.util.find_spec("hdbscan")
-if hdbscan_spec is not None:
- HAVE_HDBSCAN = True
- import hdbscan
-else:
- HAVE_HDBSCAN = False
-
from spikeinterface.core.base import minimum_spike_dtype
from spikeinterface.core.core_tools import ms_to_samples
from spikeinterface.core.waveform_tools import estimate_templates
@@ -25,6 +18,14 @@
)
+hdbscan_spec = importlib.util.find_spec("hdbscan")
+if hdbscan_spec is not None:
+ HAVE_HDBSCAN = True
+ import hdbscan
+else:
+ HAVE_HDBSCAN = False
+
+
class RandomProjectionClustering:
"""
hdbscan clustering on peak_locations previously done by localize_peaks()
diff --git a/src/spikeinterface/sortingcomponents/clustering/tests/test_clustering.py b/src/spikeinterface/sortingcomponents/clustering/tests/test_clustering.py
index 35984f3732..081c6c02d3 100644
--- a/src/spikeinterface/sortingcomponents/clustering/tests/test_clustering.py
+++ b/src/spikeinterface/sortingcomponents/clustering/tests/test_clustering.py
@@ -107,7 +107,7 @@ def test_templates_from_svd(recording, peaks, job_kwargs):
peaks_svd, sparse_mask, svd_model = extract_peaks_svd(
recording, peaks, n_components=1, ms_before=1, ms_after=1, job_kwargs=job_kwargs
)
- templates = get_templates_from_peaks_and_svd(
+ _ = get_templates_from_peaks_and_svd(
recording,
peaks,
peaks["channel_index"],
diff --git a/src/spikeinterface/sortingcomponents/clustering/tests/test_isosplit_isocut.py b/src/spikeinterface/sortingcomponents/clustering/tests/test_isosplit_isocut.py
index 1b1deffc8a..7635b158b6 100644
--- a/src/spikeinterface/sortingcomponents/clustering/tests/test_isosplit_isocut.py
+++ b/src/spikeinterface/sortingcomponents/clustering/tests/test_isosplit_isocut.py
@@ -147,10 +147,10 @@ def test_isosplit():
# check that numba handle the 2 dtypes
data = data.astype("float64")
- labels = isosplit(data, isocut_threshold=2.0, n_init=40, seed=2205)
+ _ = isosplit(data, isocut_threshold=2.0, n_init=40, seed=2205)
data = data.astype("float32")
- labels = isosplit(data, isocut_threshold=2.0, n_init=40, seed=2205)
+ _ = isosplit(data, isocut_threshold=2.0, n_init=40, seed=2205)
# the beauty is that it discovers the number of clusters automatically, at least for this this seed :)
# assert np.unique(labels).size == 3
diff --git a/src/spikeinterface/sortingcomponents/clustering/tests/test_itersplit_tool.py b/src/spikeinterface/sortingcomponents/clustering/tests/test_itersplit_tool.py
index 35e2678d13..1476606ec5 100644
--- a/src/spikeinterface/sortingcomponents/clustering/tests/test_itersplit_tool.py
+++ b/src/spikeinterface/sortingcomponents/clustering/tests/test_itersplit_tool.py
@@ -1,8 +1,3 @@
-import pytest
-
-from spikeinterface.sortingcomponents.clustering.itersplit_tools import split_clusters
-
-
# TODO
def test_split():
pass
diff --git a/src/spikeinterface/sortingcomponents/clustering/tests/test_merging_tools.py b/src/spikeinterface/sortingcomponents/clustering/tests/test_merging_tools.py
index e462985450..77b1049b7b 100644
--- a/src/spikeinterface/sortingcomponents/clustering/tests/test_merging_tools.py
+++ b/src/spikeinterface/sortingcomponents/clustering/tests/test_merging_tools.py
@@ -1,11 +1,3 @@
-import pytest
-
-from spikeinterface.sortingcomponents.clustering.merging_tools import (
- merge_peak_labels_from_features,
- merge_peak_labels_from_templates,
-)
-
-
# TODO
def test_merge():
pass
diff --git a/src/spikeinterface/sortingcomponents/clustering/tools.py b/src/spikeinterface/sortingcomponents/clustering/tools.py
index 2fb05bbc6b..1df339400f 100644
--- a/src/spikeinterface/sortingcomponents/clustering/tools.py
+++ b/src/spikeinterface/sortingcomponents/clustering/tools.py
@@ -1,5 +1,4 @@
from pathlib import Path
-from typing import Any
import numpy as np
from spikeinterface.core import Templates, estimate_templates, fix_job_kwargs
diff --git a/src/spikeinterface/sortingcomponents/matching/base.py b/src/spikeinterface/sortingcomponents/matching/base.py
index 3288417173..e4efa41948 100644
--- a/src/spikeinterface/sortingcomponents/matching/base.py
+++ b/src/spikeinterface/sortingcomponents/matching/base.py
@@ -16,9 +16,9 @@ def __init__(self, recording, templates, return_output=True):
# TODO make a sharedmem of template here
# TODO maybe check that channel_id are the same with recording
- assert isinstance(
- templates, Templates
- ), f"The templates supplied is of type {type(templates)} and must be a Templates"
+ assert isinstance(templates, Templates), (
+ f"The templates supplied is of type {type(templates)} and must be a Templates"
+ )
self.templates = templates
self.recording = recording
PeakDetector.__init__(self, recording, return_output=return_output, parents=None)
diff --git a/src/spikeinterface/sortingcomponents/matching/circus.py b/src/spikeinterface/sortingcomponents/matching/circus.py
index cb133e435f..72706dd5f3 100644
--- a/src/spikeinterface/sortingcomponents/matching/circus.py
+++ b/src/spikeinterface/sortingcomponents/matching/circus.py
@@ -3,6 +3,9 @@
import numpy as np
import importlib.util
+from .base import BaseTemplateMatching
+
+
spike_dtype = [
("sample_index", "int64"),
("channel_index", "int64"),
@@ -23,8 +26,6 @@
else:
HAVE_TORCH = False
-from .base import BaseTemplateMatching
-
def compress_templates(
templates_array, approx_rank, remove_mean=False, return_new_templates=True
@@ -385,6 +386,7 @@ def compute_matching(self, traces, start_frame, end_frame, segment_index):
all_selections = np.empty((2, scalar_products.size), dtype=np.int32)
final_amplitudes = np.zeros(scalar_products.shape, dtype=np.float32)
num_selection = 0
+ selection = all_selections[:, :0] # empty until the first peak is picked
full_sps = scalar_products.copy()
@@ -406,7 +408,6 @@ def compute_matching(self, traces, start_frame, end_frame, segment_index):
do_loop = True
while do_loop:
-
best_cluster_inds = np.argmax(scalar_products, axis=0, keepdims=True)
products = np.take_along_axis(scalar_products, best_cluster_inds, axis=0)
@@ -419,7 +420,6 @@ def compute_matching(self, traces, start_frame, end_frame, segment_index):
break
for peak_index in peak_indices:
-
best_cluster_ind = best_cluster_inds[0, peak_index]
if num_selection > 0:
@@ -572,224 +572,3 @@ def __del__(self):
self.overlaps = None
self.shm.close()
self.shm = None
-
-
-class CircusPeeler(BaseTemplateMatching):
- """
- Greedy Template-matching ported from the Spyking Circus sorter
-
- https://elifesciences.org/articles/34518
-
- This is a Greedy Template Matching algorithm. The idea is to detect
- all the peaks (negative, positive or both) above a certain threshold
- Then, at every peak (plus or minus some jitter) we look if the signal
- can be explained with a scaled template.
- The amplitudes allowed, for every templates, are automatically adjusted
- in an optimal manner, to enhance the Matthew Correlation Coefficient
- between all spikes/templates in the waveformextractor. For speed and
- memory optimization, templates are automatically sparsified if the
- density of the matrix falls below a given threshold
-
- Parameters
- ----------
- peak_sign : str
- Sign of the peak (neg, pos, or both)
- exclude_sweep_ms : float
- The number of samples before/after to classify a peak (should be low)
- jitter : int
- The number of samples considered before/after every peak to search for
- matches
- detect_threshold : int
- The detection threshold
- max_amplitude : float
- Maximal amplitude allowed for every template
- min_amplitude : float
- Minimal amplitude allowed for every template
- use_sparse_matrix_threshold : float
- If density of the templates is below a given threshold, sparse matrix
- are used (memory efficient)
- sparse_kwargs : dict
- Parameters to extract a sparsity mask from the waveform_extractor, if not
- already sparse.
- -----
-
-
- """
-
- def __init__(
- self,
- recording,
- return_output=True,
- templates=None,
- peak_sign="neg",
- exclude_sweep_ms=0.8,
- jitter_ms=0.1,
- detect_threshold=5,
- noise_levels=None,
- max_amplitude=1.5,
- min_amplitude=0.5,
- use_sparse_matrix_threshold=0.25,
- ):
-
- BaseTemplateMatching.__init__(self, recording, templates, return_output=return_output)
- sklearn_spec = importlib.util.find_spec("sklearn") is not None
- if sklearn_spec is not None:
- HAVE_SKLEARN = True
- else:
- HAVE_SKLEARN = False
-
- assert HAVE_SKLEARN, "CircusPeeler needs sklearn to work"
-
- assert (use_sparse_matrix_threshold >= 0) and (
- use_sparse_matrix_threshold <= 1
- ), f"use_sparse_matrix_threshold should be in [0, 1]"
-
- self.num_channels = recording.get_num_channels()
- self.num_samples = templates.num_samples
- self.num_templates = len(templates.unit_ids)
-
- self.abs_threholds = noise_levels * detect_threshold
-
- self.use_sparse_matrix_threshold = use_sparse_matrix_threshold
- self._prepare_templates()
- self.overlaps = compute_overlaps(
- self.normed_templates,
- self.num_samples,
- self.num_channels,
- self.sparsities,
- )
-
- self.exclude_sweep_size = int(exclude_sweep_ms * recording.get_sampling_frequency() / 1000.0)
-
- self.nbefore = templates.nbefore
- self.nafter = templates.nafter
- self.patch_sizes = (templates.num_samples, self.num_channels)
- self.sym_patch = self.nbefore == self.nafter
- self.jitter = int(jitter_ms * recording.get_sampling_frequency() / 1000.0)
-
- self.amplitudes = np.zeros((self.num_templates, 2), dtype=np.float32)
- self.amplitudes[:, 0] = min_amplitude
- self.amplitudes[:, 1] = max_amplitude
-
- self.margin = max(self.nbefore, self.nafter) * 2
- self.peak_sign = peak_sign
-
- def _prepare_templates(self):
-
- from scipy.sparse import csr_matrix
-
- self.norms = np.zeros(self.num_templates, dtype=np.float32)
-
- all_units = self.templates.unit_ids
-
- sparsity = self.templates.sparsity.mask
-
- templates_array = self.templates.get_dense_templates()
- self.sparsities = {}
- self.normed_templates = {}
-
- for count, unit_id in enumerate(all_units):
- self.sparsities[count] = np.flatnonzero(sparsity[count])
- self.norms[count] = np.linalg.norm(templates_array[count])
- templates_array[count] /= self.norms[count]
- self.normed_templates[count] = templates_array[count][:, sparsity[count]]
-
- templates_array = templates_array.reshape(self.num_templates, -1)
-
- nnz = np.sum(templates_array != 0) / (self.num_templates * self.num_samples * self.num_channels)
- if nnz <= self.use_sparse_matrix_threshold:
- templates_array = csr_matrix(templates_array)
- print(f"Templates are automatically sparsified (sparsity level is {nnz})")
- self.is_dense = False
- else:
- self.is_dense = True
-
- self.circus_templates = templates_array
-
- def get_margin(self):
- return self.margin
-
- def compute_matching(self, traces, start_frame, end_frame, segment_index):
-
- neighbor_window = self.num_samples - 1
-
- peak_traces = traces[self.margin // 2 : -self.margin // 2, :]
- peak_sample_index, peak_chan_ind = DetectPeakByChannel.detect_peaks(
- peak_traces, self.peak_sign, self.abs_threholds, self.exclude_sweep_size
- )
- from sklearn.feature_extraction.image import extract_patches_2d
-
- if self.jitter > 0:
- jittered_peaks = peak_sample_index[:, np.newaxis] + np.arange(-self.jitter, self.jitter)
- jittered_channels = peak_chan_ind[:, np.newaxis] + np.zeros(2 * self.jitter)
- mask = (jittered_peaks > 0) & (jittered_peaks < len(peak_traces))
- jittered_peaks = jittered_peaks[mask]
- jittered_channels = jittered_channels[mask]
- peak_sample_index, unique_idx = np.unique(jittered_peaks, return_index=True)
- peak_chan_ind = jittered_channels[unique_idx]
- else:
- peak_sample_index, unique_idx = np.unique(peak_sample_index, return_index=True)
- peak_chan_ind = peak_chan_ind[unique_idx]
-
- num_peaks = len(peak_sample_index)
-
- if self.sym_patch:
- snippets = extract_patches_2d(traces, self.patch_sizes)[peak_sample_index]
- peak_sample_index += self.margin // 2
- else:
- peak_sample_index += self.margin // 2
- snippet_window = np.arange(-self.nbefore, self.nafter)
- snippets = traces[peak_sample_index[:, np.newaxis] + snippet_window]
-
- if num_peaks > 0:
- snippets = snippets.reshape(num_peaks, -1)
- scalar_products = self.circus_templates.dot(snippets.T)
- else:
- scalar_products = np.zeros((self.num_templates, 0), dtype=np.float32)
-
- num_spikes = 0
- spikes = np.empty(scalar_products.size, dtype=spike_dtype)
- idx_lookup = np.arange(scalar_products.size).reshape(self.num_templates, -1)
-
- min_sps = (self.amplitudes[:, 0] * self.norms)[:, np.newaxis]
- max_sps = (self.amplitudes[:, 1] * self.norms)[:, np.newaxis]
-
- is_valid = (scalar_products > min_sps) & (scalar_products < max_sps)
-
- cached_overlaps = {}
-
- while np.any(is_valid):
- best_amplitude_ind = scalar_products[is_valid].argmax()
- best_cluster_ind, peak_index = np.unravel_index(idx_lookup[is_valid][best_amplitude_ind], idx_lookup.shape)
-
- best_amplitude = scalar_products[best_cluster_ind, peak_index]
- best_peak_sample_index = peak_sample_index[peak_index]
- best_peak_chan_ind = peak_chan_ind[peak_index]
-
- peak_data = peak_sample_index - peak_sample_index[peak_index]
- is_valid_nn = np.searchsorted(peak_data, [-neighbor_window, neighbor_window + 1])
- idx_neighbor = peak_data[is_valid_nn[0] : is_valid_nn[1]] + neighbor_window
-
- if not best_cluster_ind in cached_overlaps.keys():
- cached_overlaps[best_cluster_ind] = self.overlaps[best_cluster_ind].toarray()
-
- to_add = -best_amplitude * cached_overlaps[best_cluster_ind][:, idx_neighbor]
-
- scalar_products[:, is_valid_nn[0] : is_valid_nn[1]] += to_add
- scalar_products[best_cluster_ind, is_valid_nn[0] : is_valid_nn[1]] = -np.inf
-
- spikes["sample_index"][num_spikes] = best_peak_sample_index
- spikes["channel_index"][num_spikes] = best_peak_chan_ind
- spikes["cluster_index"][num_spikes] = best_cluster_ind
- spikes["amplitude"][num_spikes] = best_amplitude
- num_spikes += 1
-
- is_valid = (scalar_products > min_sps) & (scalar_products < max_sps)
-
- spikes["amplitude"][:num_spikes] /= self.norms[spikes["cluster_index"][:num_spikes]]
-
- spikes = spikes[:num_spikes]
- order = np.argsort(spikes["sample_index"])
- spikes = spikes[order]
-
- return spikes
diff --git a/src/spikeinterface/sortingcomponents/matching/main.py b/src/spikeinterface/sortingcomponents/matching/main.py
index 0b054c0638..ec54f91bc7 100644
--- a/src/spikeinterface/sortingcomponents/matching/main.py
+++ b/src/spikeinterface/sortingcomponents/matching/main.py
@@ -1,7 +1,6 @@
import numpy as np
-import warnings
-from .method_list import *
+from .method_list import matching_methods
from spikeinterface.core.node_pipeline import run_node_pipeline
@@ -65,9 +64,6 @@ def find_spikes_from_templates(
# if method_class.full_convolution:
# Maybe we need to automatically adjust the temporal chunks given templates and n_processes
- if len(templates.unit_ids) == 0:
- return np.zeros(0, dtype=node0.get_dtype())
-
if method_class.need_noise_levels:
if "noise_levels" not in method_kwargs:
raise ValueError(f"find_spikes_from_templates() method {method} need noise_levels")
@@ -75,6 +71,9 @@ def find_spikes_from_templates(
node0 = method_class(recording, templates=templates, **method_kwargs)
nodes = [node0]
+ if len(templates.unit_ids) == 0:
+ return np.zeros(0, dtype=node0.get_dtype())
+
if pipeline_kwargs is None:
pipeline_kwargs = dict()
diff --git a/src/spikeinterface/sortingcomponents/matching/nearest.py b/src/spikeinterface/sortingcomponents/matching/nearest.py
index 7ca2c3ece4..5221f66e81 100644
--- a/src/spikeinterface/sortingcomponents/matching/nearest.py
+++ b/src/spikeinterface/sortingcomponents/matching/nearest.py
@@ -1,16 +1,13 @@
"""Sorting components: template matching."""
import numpy as np
-from spikeinterface.core.template_tools import get_template_extremum_channel
-from spikeinterface.core import get_noise_levels, get_channel_distances
-from spikeinterface.core.sparsity import compute_sparsity
+from spikeinterface.core import get_channel_distances
from .base import BaseTemplateMatching, _base_matching_dtype
class NearestTemplatesPeeler(BaseTemplateMatching):
-
name = "nearest"
need_noise_levels = True
# this is because numba
@@ -75,18 +72,6 @@ def __init__(
self.neighborhood_mask = np.ones((num_channels, num_templates), dtype=bool)
if support_radius_um is not None:
- if not templates.are_templates_sparse():
- from spikeinterface.core.sparsity import compute_sparsity
-
- sparsity = compute_sparsity(
- templates,
- method="radius",
- radius_um=sparsity_radius_um,
- peak_sign=self.peak_sign,
- )
- else:
- sparsity = templates.sparsity
-
channel_locations = recording.get_channel_locations()
channel_distances = np.linalg.norm(channel_locations[:, None] - channel_locations[np.newaxis, :], axis=2)
self.sparsity_support_mask = channel_distances <= self.support_radius_um
@@ -153,16 +138,18 @@ def compute_matching(self, traces, start_frame, end_frame, segment_index):
class NearestTemplatesSVDPeeler(NearestTemplatesPeeler):
-
name = "nearest-svd"
need_noise_levels = True
- params_doc = NearestTemplatesPeeler.params_doc + """
+ params_doc = (
+ NearestTemplatesPeeler.params_doc
+ + """
svd_model : The svd model used to project the waveforms
The radius to use to select neighbour channels for locally exclusive detection.
svd_radius_um : float
The radius in um of the local neighboorhood used, centered on every detected peaks, to compute
the distances with all the templates in the SVD space
"""
+ )
def __init__(
self,
diff --git a/src/spikeinterface/sortingcomponents/matching/tdc_peeler.py b/src/spikeinterface/sortingcomponents/matching/tdc_peeler.py
index cff99020fd..3101af0485 100644
--- a/src/spikeinterface/sortingcomponents/matching/tdc_peeler.py
+++ b/src/spikeinterface/sortingcomponents/matching/tdc_peeler.py
@@ -418,7 +418,6 @@ def compute_matching(self, traces, start_frame, end_frame, segment_index):
all_spikes = []
for start, stop, channel_motions in loop:
-
local_residuals = residuals[start:stop]
spikes_in_time_bin = []
@@ -782,7 +781,6 @@ def get_neighbors_spikes(sample_inds, chan_inds, delta_sample, near_chan_mask):
neighbors_spikes_inds = []
for i in range(sample_inds.size):
-
inds = np.flatnonzero(np.abs(sample_inds - sample_inds[i]) < delta_sample)
neighb = []
for ind in inds:
@@ -817,7 +815,6 @@ def fit_one_amplitude_with_neighbors(
amplitude = np.sum(template.flatten() * wf.flatten()) / template_norms[cluster_index]
else:
-
lim0 = min(start, np.min(neighbors_spikes["sample_index"]) - nbefore)
lim1 = max(stop, np.max(neighbors_spikes["sample_index"]) + nafter)
@@ -833,7 +830,6 @@ def fit_one_amplitude_with_neighbors(
num_spikes_to_fit = 1 + np.sum(mask_not_fitted)
x = np.zeros((lim1 - lim0, num_chans, num_spikes_to_fit), dtype="float32")
- wanted_channel_mask = chan_sparsity_mask
construct_prediction_sparse(
np.array([local_spike]),
x[:, :, 0],
diff --git a/src/spikeinterface/sortingcomponents/matching/tests/test_template_matching.py b/src/spikeinterface/sortingcomponents/matching/tests/test_template_matching.py
index 0fb3e6bc61..3fbf404907 100644
--- a/src/spikeinterface/sortingcomponents/matching/tests/test_template_matching.py
+++ b/src/spikeinterface/sortingcomponents/matching/tests/test_template_matching.py
@@ -1,8 +1,7 @@
import pytest
import numpy as np
-from pathlib import Path
-from spikeinterface import NumpySorting, create_sorting_analyzer, compute_sparsity, get_noise_levels
+from spikeinterface import create_sorting_analyzer, compute_sparsity, get_noise_levels
from spikeinterface.sortingcomponents.matching import find_spikes_from_templates
from spikeinterface.sortingcomponents.matching.method_list import matching_methods
@@ -90,28 +89,25 @@ def test_find_spikes_from_templates(method, sorting_analyzer):
# print(info)
# DEBUG = True
- DEBUG = False
+ # DEBUG = False
- if DEBUG:
- import matplotlib.pyplot as plt
- import spikeinterface.full as si
+ # if DEBUG:
+ # sorting_analyzer.compute("waveforms")
+ # sorting_analyzer.compute("templates")
- sorting_analyzer.compute("waveforms")
- sorting_analyzer.compute("templates")
+ # gt_sorting = sorting_analyzer.sorting
- gt_sorting = sorting_analyzer.sorting
+ # sorting = NumpySorting.from_samples_and_labels(
+ # spikes["sample_index"], spikes["cluster_index"], recording.sampling_frequency
+ # )
- sorting = NumpySorting.from_samples_and_labels(
- spikes["sample_index"], spikes["cluster_index"], recording.sampling_frequency
- )
+ # #metrics = si.compute_quality_metrics(sorting_analyzer, metric_names=["snr"])
- ##metrics = si.compute_quality_metrics(sorting_analyzer, metric_names=["snr"])
-
- # fig, ax = plt.subplots()
- # comp = si.compare_sorter_to_ground_truth(gt_sorting, sorting)
- # si.plot_agreement_matrix(comp, ax=ax)
- # ax.set_title(method)
- # plt.show()
+ # fig, ax = plt.subplots()
+ # comp = si.compare_sorter_to_ground_truth(gt_sorting, sorting)
+ # si.plot_agreement_matrix(comp, ax=ax)
+ # ax.set_title(method)
+ # plt.show()
if __name__ == "__main__":
diff --git a/src/spikeinterface/sortingcomponents/matching/tests/test_wobble.py b/src/spikeinterface/sortingcomponents/matching/tests/test_wobble.py
index 36d5452933..f3a7a2e4f9 100644
--- a/src/spikeinterface/sortingcomponents/matching/tests/test_wobble.py
+++ b/src/spikeinterface/sortingcomponents/matching/tests/test_wobble.py
@@ -1,6 +1,5 @@
from types import SimpleNamespace
-import pytest
import numpy as np
from spikeinterface.sortingcomponents.matching import wobble
@@ -326,7 +325,6 @@ def test_compute_scale_amplitudes():
rng = np.random.default_rng(seed)
num_spikes = rng.integers(0, 100)
norm_peaks = rng.random(num_spikes)
- num_jittered = rng.integers(1, 100)
peak_window_size = rng.integers(1, 100)
high_resolution_conv = rng.random((peak_window_size, num_spikes))
scale_min = rng.random() * 10
diff --git a/src/spikeinterface/sortingcomponents/matching/wobble.py b/src/spikeinterface/sortingcomponents/matching/wobble.py
index e9ee961c3e..9a42f3d9b3 100644
--- a/src/spikeinterface/sortingcomponents/matching/wobble.py
+++ b/src/spikeinterface/sortingcomponents/matching/wobble.py
@@ -171,9 +171,9 @@ def from_parameters_and_templates(cls, params, templates):
if params.template_indices2unit_indices is None: # Trivial grouping of templates = units
template_indices2unit_indices = np.arange(num_templates)
else:
- assert params.template_indices2unit_indices.shape == (
- templates.shape[0],
- ), "template_indices2unit_indices must have shape (num_templates,)"
+ assert params.template_indices2unit_indices.shape == (templates.shape[0],), (
+ "template_indices2unit_indices must have shape (num_templates,)"
+ )
template_indices2unit_indices = params.template_indices2unit_indices
unit_indices = np.unique(template_indices2unit_indices)
num_units = len(unit_indices)
diff --git a/src/spikeinterface/sortingcomponents/motion/decentralized.py b/src/spikeinterface/sortingcomponents/motion/decentralized.py
index 076d3658de..509841e6f6 100644
--- a/src/spikeinterface/sortingcomponents/motion/decentralized.py
+++ b/src/spikeinterface/sortingcomponents/motion/decentralized.py
@@ -3,7 +3,7 @@
from tqdm.auto import tqdm, trange
from spikeinterface.core.motion import Motion
-from .motion_utils import get_spatial_windows, get_spatial_bin_edges, make_2d_motion_histogram, scipy_conv1d
+from .motion_utils import get_spatial_windows, get_spatial_bin_edges, make_2d_motion_histogram
from .dredge import normxcorr1d
@@ -328,7 +328,7 @@ def compute_pairwise_displacement(
if conv_engine == "torch":
import torch
- assert conv_engine in ("torch", "numpy"), f"'conv_engine' must be 'torch' or 'numpy'"
+ assert conv_engine in ("torch", "numpy"), "'conv_engine' must be 'torch' or 'numpy'"
size = motion_hist.shape[0]
pairwise_displacement = np.zeros((size, size), dtype="float32")
@@ -509,7 +509,6 @@ def jac(p):
displacement = res.x
elif convergence_method == "lsqr_robust":
-
if sparse_mask is not None:
I, J = np.nonzero(sparse_mask > 0)
elif pairwise_displacement_weight is not None:
diff --git a/src/spikeinterface/sortingcomponents/motion/dredge.py b/src/spikeinterface/sortingcomponents/motion/dredge.py
index 6d9cc1afdf..b6a0529776 100644
--- a/src/spikeinterface/sortingcomponents/motion/dredge.py
+++ b/src/spikeinterface/sortingcomponents/motion/dredge.py
@@ -296,7 +296,6 @@ def dredge_ap(
threshold_kw = dict(bin_s=bin_s)
if batching_mode == "full":
-
displacement, extra = compute_displacement_full(
raster,
windows,
@@ -313,7 +312,6 @@ def dredge_ap(
)
elif batching_mode == "online":
-
# T_total is number of bin_s in recording
T_total = raster.shape[1]
T_chunk = max(1, int(np.ceil(chunk_len_s / bin_s)))
diff --git a/src/spikeinterface/sortingcomponents/motion/medicine.py b/src/spikeinterface/sortingcomponents/motion/medicine.py
index 8be18f7502..0cfc44f5a1 100644
--- a/src/spikeinterface/sortingcomponents/motion/medicine.py
+++ b/src/spikeinterface/sortingcomponents/motion/medicine.py
@@ -1,11 +1,7 @@
import numpy as np
-import tempfile
-import shutil
-from pathlib import Path
from spikeinterface.core.motion import Motion
-from spikeinterface.sortingcomponents.motion.motion_utils import get_spatial_windows
class MedicineRegistration:
diff --git a/src/spikeinterface/sortingcomponents/motion/motion_estimation.py b/src/spikeinterface/sortingcomponents/motion/motion_estimation.py
index 7e48ef146e..6f309281d7 100644
--- a/src/spikeinterface/sortingcomponents/motion/motion_estimation.py
+++ b/src/spikeinterface/sortingcomponents/motion/motion_estimation.py
@@ -1,5 +1,4 @@
import warnings
-import numpy as np
from spikeinterface.sortingcomponents.tools import make_multi_method_doc
diff --git a/src/spikeinterface/sortingcomponents/motion/motion_interpolation.py b/src/spikeinterface/sortingcomponents/motion/motion_interpolation.py
index 0eb63b8b6b..dc2b9ae2a2 100644
--- a/src/spikeinterface/sortingcomponents/motion/motion_interpolation.py
+++ b/src/spikeinterface/sortingcomponents/motion/motion_interpolation.py
@@ -359,8 +359,7 @@ def __init__(
channel_locations = recording.get_channel_locations()
assert channel_locations.ndim >= motion.dim, (
- f"'direction' {motion.direction} not available. "
- f"Channel locations have {channel_locations.ndim} dimensions."
+ f"'direction' {motion.direction} not available. Channel locations have {channel_locations.ndim} dimensions."
)
spatial_interpolation_kwargs = dict(
sigma_um=sigma_um, p=p, num_closest=num_closest, **spatial_interpolation_kwargs
diff --git a/src/spikeinterface/sortingcomponents/motion/motion_utils.py b/src/spikeinterface/sortingcomponents/motion/motion_utils.py
index c58322d2c6..ab08326c56 100644
--- a/src/spikeinterface/sortingcomponents/motion/motion_utils.py
+++ b/src/spikeinterface/sortingcomponents/motion/motion_utils.py
@@ -1,7 +1,6 @@
import warnings
import numpy as np
-from spikeinterface.core.core_tools import check_json
def get_spatial_windows(
@@ -58,8 +57,6 @@ def get_spatial_windows(
Here by default we use gaussian window.
"""
- n = spatial_bin_centers.size
-
if rigid:
# win_shape = 'rect' is forced
windows, window_centers = get_rigid_windows(spatial_bin_centers)
diff --git a/src/spikeinterface/sortingcomponents/motion/tests/test_drege.py b/src/spikeinterface/sortingcomponents/motion/tests/test_drege.py
index 8133c1fa6b..202ae63a64 100644
--- a/src/spikeinterface/sortingcomponents/motion/tests/test_drege.py
+++ b/src/spikeinterface/sortingcomponents/motion/tests/test_drege.py
@@ -1,6 +1,3 @@
-import pytest
-
-
def test_dredge_online_lfp():
pass
diff --git a/src/spikeinterface/sortingcomponents/motion/tests/test_medicine.py b/src/spikeinterface/sortingcomponents/motion/tests/test_medicine.py
index 4db1d8bfd7..cdbafa504b 100644
--- a/src/spikeinterface/sortingcomponents/motion/tests/test_medicine.py
+++ b/src/spikeinterface/sortingcomponents/motion/tests/test_medicine.py
@@ -1,9 +1,6 @@
import numpy as np
import pytest
-torch = pytest.importorskip("torch")
-medicine = pytest.importorskip("medicine")
-
from spikeinterface import get_noise_levels
from spikeinterface.core.node_pipeline import ExtractDenseWaveforms, run_node_pipeline
from spikeinterface.sortingcomponents.motion import estimate_motion
@@ -11,6 +8,10 @@
from spikeinterface.sortingcomponents.peak_localization.method_list import LocalizeCenterOfMass
from spikeinterface.sortingcomponents.tests.common import make_dataset
+
+torch = pytest.importorskip("torch")
+medicine = pytest.importorskip("medicine")
+
# Kept tiny so the model trains in a fraction of a second. Not representative of settings
# one would use for real motion estimation.
_FAST_TRAINING_KWARGS = dict(batch_size=32, training_steps=15, motion_noise_steps=5)
diff --git a/src/spikeinterface/sortingcomponents/motion/tests/test_motion_estimation.py b/src/spikeinterface/sortingcomponents/motion/tests/test_motion_estimation.py
index 1ba43e6a13..adff080792 100644
--- a/src/spikeinterface/sortingcomponents/motion/tests/test_motion_estimation.py
+++ b/src/spikeinterface/sortingcomponents/motion/tests/test_motion_estimation.py
@@ -6,7 +6,7 @@
from spikeinterface import get_noise_levels
from spikeinterface.core.node_pipeline import ExtractDenseWaveforms, run_node_pipeline
from spikeinterface.sortingcomponents.motion import estimate_motion
-from spikeinterface.sortingcomponents.peak_detection import detect_peaks, detect_peak_methods
+from spikeinterface.sortingcomponents.peak_detection import detect_peak_methods
from spikeinterface.sortingcomponents.peak_localization.method_list import LocalizeCenterOfMass
from spikeinterface.sortingcomponents.tests.common import make_dataset
diff --git a/src/spikeinterface/sortingcomponents/peak_detection/locally_exclusive.py b/src/spikeinterface/sortingcomponents/peak_detection/locally_exclusive.py
index bafb526a8c..d25007c02c 100644
--- a/src/spikeinterface/sortingcomponents/peak_detection/locally_exclusive.py
+++ b/src/spikeinterface/sortingcomponents/peak_detection/locally_exclusive.py
@@ -1,18 +1,18 @@
import numpy as np
import importlib.util
+from spikeinterface.core.node_pipeline import (
+ PeakDetector,
+)
+from spikeinterface.core.recording_tools import get_channel_distances
+from .by_channel import ByChannelTorchPeakDetector, ByChannelPeakDetector
+
numba_spec = importlib.util.find_spec("numba")
if numba_spec is not None:
HAVE_NUMBA = True
else:
HAVE_NUMBA = False
-from spikeinterface.core.node_pipeline import (
- PeakDetector,
-)
-from spikeinterface.core.recording_tools import get_channel_distances
-from .by_channel import ByChannelTorchPeakDetector
-
torch_spec = importlib.util.find_spec("torch")
if torch_spec is not None:
torch_nn_functional_spec = importlib.util.find_spec("torch.nn")
@@ -29,8 +29,6 @@
else:
HAVE_PYOPENCL = False
-from .by_channel import ByChannelPeakDetector
-
class LocallyExclusivePeakDetector(PeakDetector):
"""Detect peaks using the "locally exclusive" method."""
@@ -42,10 +40,13 @@ class LocallyExclusivePeakDetector(PeakDetector):
# this is because numba
need_first_call_before_pipeline = True
- params_doc = ByChannelPeakDetector.params_doc + """
+ params_doc = (
+ ByChannelPeakDetector.params_doc
+ + """
radius_um: float
The radius to use to select neighbour channels for locally exclusive detection.
"""
+ )
def __init__(
self,
@@ -148,7 +149,6 @@ def detect_peaks_numba_locally_exclusive_on_chunk(
keep_peak = np.ones(npeaks, dtype="bool")
next_start = 0
for i in range(npeaks):
-
if (samples_inds[i] < exclude_sweep_size + 1) or (
samples_inds[i] >= (num_samples - exclude_sweep_size - 1)
):
@@ -195,10 +195,13 @@ class LocallyExclusiveTorchPeakDetector(ByChannelTorchPeakDetector):
engine = "torch"
need_noise_levels = True
preferred_mp_context = "spawn"
- params_doc = ByChannelPeakDetector.params_doc + """
+ params_doc = (
+ ByChannelPeakDetector.params_doc
+ + """
radius_um: float
The radius to use to select neighbour channels for locally exclusive detection.
"""
+ )
def __init__(
self,
@@ -265,10 +268,13 @@ class LocallyExclusiveOpenCLPeakDetector(LocallyExclusivePeakDetector):
engine = "opencl"
preferred_mp_context = None
need_noise_levels = True
- params_doc = LocallyExclusiveTorchPeakDetector.params_doc + """
+ params_doc = (
+ LocallyExclusiveTorchPeakDetector.params_doc
+ + """
opencl_context_kwargs: None or dict
kwargs to create the opencl context
"""
+ )
def __init__(
self,
diff --git a/src/spikeinterface/sortingcomponents/peak_detection/main.py b/src/spikeinterface/sortingcomponents/peak_detection/main.py
index 4332acac0f..0fc554efea 100644
--- a/src/spikeinterface/sortingcomponents/peak_detection/main.py
+++ b/src/spikeinterface/sortingcomponents/peak_detection/main.py
@@ -2,7 +2,7 @@
from .method_list import detect_peak_methods
-from spikeinterface.core.job_tools import split_job_kwargs, fix_job_kwargs
+from spikeinterface.core.job_tools import fix_job_kwargs
from ..tools import make_multi_method_doc
diff --git a/src/spikeinterface/sortingcomponents/peak_detection/matched_filtering.py b/src/spikeinterface/sortingcomponents/peak_detection/matched_filtering.py
index a7ce981ed3..13849cf700 100644
--- a/src/spikeinterface/sortingcomponents/peak_detection/matched_filtering.py
+++ b/src/spikeinterface/sortingcomponents/peak_detection/matched_filtering.py
@@ -8,6 +8,7 @@
from spikeinterface.core.node_pipeline import PeakDetector
from spikeinterface.core.recording_tools import get_channel_distances, get_random_data_chunks
from spikeinterface.postprocessing.localization_tools import get_convolution_weights
+from .by_channel import ByChannelPeakDetector
numba_spec = importlib.util.find_spec("numba")
if numba_spec is not None:
@@ -15,8 +16,6 @@
else:
HAVE_NUMBA = False
-from .by_channel import ByChannelPeakDetector
-
class MatchedFilteringPeakDetector(PeakDetector):
"""Detect peaks using the 'matched_filtering' method."""
@@ -25,7 +24,9 @@ class MatchedFilteringPeakDetector(PeakDetector):
engine = "numba"
need_noise_levels = False
preferred_mp_context = None
- params_doc = ByChannelPeakDetector.params_doc + """
+ params_doc = (
+ ByChannelPeakDetector.params_doc
+ + """
radius_um : float
The radius to use to select neighbour channels for locally exclusive detection.
prototype : array
@@ -37,6 +38,7 @@ class MatchedFilteringPeakDetector(PeakDetector):
in order to know how to estimate the positions. One argument is mode that could
be either gaussian_2d (KS like) or exponential_3d (default)
"""
+ )
def __init__(
self,
diff --git a/src/spikeinterface/sortingcomponents/peak_detection/tests/test_peak_detection.py b/src/spikeinterface/sortingcomponents/peak_detection/tests/test_peak_detection.py
index 25b9d9515a..7f25299476 100644
--- a/src/spikeinterface/sortingcomponents/peak_detection/tests/test_peak_detection.py
+++ b/src/spikeinterface/sortingcomponents/peak_detection/tests/test_peak_detection.py
@@ -327,7 +327,7 @@ def test_detect_peaks_locally_exclusive(recording, job_kwargs, torch_job_kwargs)
assert np.isclose(np.array(len(peaks_local_numba)), np.array(len(peaks_local_torch)), rtol=0.1)
if HAVE_PYOPENCL:
- peaks_local_cl = detect_peaks(
+ _ = detect_peaks(
recording,
method="locally_exclusive_cl",
method_kwargs=dict(
diff --git a/src/spikeinterface/sortingcomponents/peak_localization/base.py b/src/spikeinterface/sortingcomponents/peak_localization/base.py
index 5e6a16fe4c..04d4307ffc 100644
--- a/src/spikeinterface/sortingcomponents/peak_localization/base.py
+++ b/src/spikeinterface/sortingcomponents/peak_localization/base.py
@@ -6,7 +6,6 @@
class LocalizeBase(PipelineNode):
-
def __init__(self, recording, parents, return_output=True, radius_um=75.0):
PipelineNode.__init__(self, recording, parents=parents, return_output=return_output)
self.recording = recording
diff --git a/src/spikeinterface/sortingcomponents/peak_localization/grid.py b/src/spikeinterface/sortingcomponents/peak_localization/grid.py
index c55b6b712e..94bcd38af2 100644
--- a/src/spikeinterface/sortingcomponents/peak_localization/grid.py
+++ b/src/spikeinterface/sortingcomponents/peak_localization/grid.py
@@ -4,7 +4,6 @@
from spikeinterface.core.node_pipeline import (
find_parent_of_type,
- PipelineNode,
WaveformsNode,
)
diff --git a/src/spikeinterface/sortingcomponents/peak_localization/main.py b/src/spikeinterface/sortingcomponents/peak_localization/main.py
index d75f4a8a55..1cb8d8629d 100644
--- a/src/spikeinterface/sortingcomponents/peak_localization/main.py
+++ b/src/spikeinterface/sortingcomponents/peak_localization/main.py
@@ -4,7 +4,7 @@
from .method_list import peak_localization_methods
from ..tools import make_multi_method_doc
-from spikeinterface.core.job_tools import split_job_kwargs, fix_job_kwargs
+from spikeinterface.core.job_tools import fix_job_kwargs
from spikeinterface.core.node_pipeline import (
@@ -30,9 +30,9 @@ def get_localization_pipeline_nodes(
seed=None,
):
- assert (
- method in peak_localization_methods
- ), f"Method {method} is not supported. Choose from {peak_localization_methods.keys()}"
+ assert method in peak_localization_methods, (
+ f"Method {method} is not supported. Choose from {peak_localization_methods.keys()}"
+ )
assert method_kwargs is not None
@@ -152,9 +152,9 @@ def localize_peaks(
job_kwargs = fix_job_kwargs(job_kwargs)
- assert (
- method in peak_localization_methods
- ), f"Method {method} is not supported. Choose from {peak_localization_methods.keys()}"
+ assert method in peak_localization_methods, (
+ f"Method {method} is not supported. Choose from {peak_localization_methods.keys()}"
+ )
peak_source = PeakRetriever(recording, peaks)
diff --git a/src/spikeinterface/sortingcomponents/peak_localization/tests/test_peak_localization.py b/src/spikeinterface/sortingcomponents/peak_localization/tests/test_peak_localization.py
index 9db0588f6d..15d0476e65 100644
--- a/src/spikeinterface/sortingcomponents/peak_localization/tests/test_peak_localization.py
+++ b/src/spikeinterface/sortingcomponents/peak_localization/tests/test_peak_localization.py
@@ -1,6 +1,3 @@
-import pytest
-import numpy as np
-
from spikeinterface.sortingcomponents.peak_detection import detect_peaks
from spikeinterface.sortingcomponents.peak_localization import localize_peaks
diff --git a/src/spikeinterface/sortingcomponents/peak_selection.py b/src/spikeinterface/sortingcomponents/peak_selection.py
index 018e627217..b260e7ef5e 100644
--- a/src/spikeinterface/sortingcomponents/peak_selection.py
+++ b/src/spikeinterface/sortingcomponents/peak_selection.py
@@ -288,7 +288,7 @@ def select_peak_indices(peaks, method, seed, **method_kwargs):
else:
raise NotImplementedError(
- f"The 'method' {method} does not exist for peaks selection." f" possible methods are {_possible_methods}"
+ f"The 'method' {method} does not exist for peaks selection. possible methods are {_possible_methods}"
)
selected_indices = np.concatenate(selected_indices)
diff --git a/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py b/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py
index e9d8f1987b..94db8bc510 100644
--- a/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py
+++ b/src/spikeinterface/sortingcomponents/tests/test_peak_selection.py
@@ -1,4 +1,3 @@
-import pytest
import numpy as np
@@ -52,37 +51,37 @@ def test_select_peaks():
]
for method in select_methods:
selected_peaks = select_peaks(peaks, method=method, **select_kwargs)
- assert (
- selected_peaks.size <= n_peaks
- ), "selected_peaks is not the right size when return_indices=False, select_per_channel=False"
+ assert selected_peaks.size <= n_peaks, (
+ "selected_peaks is not the right size when return_indices=False, select_per_channel=False"
+ )
selected_peaks = select_peaks(peaks, recording=recording, method=method, margin=(10, 10), **select_kwargs)
- assert (
- selected_peaks.size <= n_peaks
- ), "selected_peaks is not the right size when return_indices=False, select_per_channel=False"
+ assert selected_peaks.size <= n_peaks, (
+ "selected_peaks is not the right size when return_indices=False, select_per_channel=False"
+ )
selected_peaks = select_peaks(peaks, method=method, select_per_channel=True, **select_kwargs)
- assert selected_peaks.size <= (
- n_peaks * recording.get_num_channels()
- ), "selected_peaks is not the right size when return_indices=False, select_per_channel=True"
+ assert selected_peaks.size <= (n_peaks * recording.get_num_channels()), (
+ "selected_peaks is not the right size when return_indices=False, select_per_channel=True"
+ )
selected_peaks, selected_indices = select_peaks(peaks, method=method, return_indices=True, **select_kwargs)
- assert (
- selected_peaks.size <= n_peaks
- ), "selected_peaks is not the right size when return_indices=True, select_per_channel=False"
- assert np.all(
- selected_peaks == peaks[selected_indices]
- ), "selection_indices differ from selected_peaks when select_per_channel=False"
+ assert selected_peaks.size <= n_peaks, (
+ "selected_peaks is not the right size when return_indices=True, select_per_channel=False"
+ )
+ assert np.all(selected_peaks == peaks[selected_indices]), (
+ "selection_indices differ from selected_peaks when select_per_channel=False"
+ )
selected_peaks, selected_indices = select_peaks(
peaks, method=method, return_indices=True, select_per_channel=True, **select_kwargs
)
- assert selected_peaks.size <= (
- n_peaks * recording.get_num_channels()
- ), "selected_peaks is not the right size when return_indices=True, select_per_channel=True"
- assert np.all(
- selected_peaks == peaks[selected_indices]
- ), "selection_indices differ from selected_peaks when select_per_channel=True"
+ assert selected_peaks.size <= (n_peaks * recording.get_num_channels()), (
+ "selected_peaks is not the right size when return_indices=True, select_per_channel=True"
+ )
+ assert np.all(selected_peaks == peaks[selected_indices]), (
+ "selection_indices differ from selected_peaks when select_per_channel=True"
+ )
if __name__ == "__main__":
diff --git a/src/spikeinterface/sortingcomponents/waveforms/features_from_peaks.py b/src/spikeinterface/sortingcomponents/waveforms/features_from_peaks.py
index 0c7ffe7447..ec750d8c95 100644
--- a/src/spikeinterface/sortingcomponents/waveforms/features_from_peaks.py
+++ b/src/spikeinterface/sortingcomponents/waveforms/features_from_peaks.py
@@ -6,7 +6,6 @@
from spikeinterface.core import get_channel_distances
from spikeinterface.sortingcomponents.peak_localization.method_list import (
LocalizeCenterOfMass,
- LocalizeMonopolarTriangulation,
)
from spikeinterface.core.node_pipeline import (
run_node_pipeline,
@@ -70,9 +69,9 @@ def compute_features_from_peaks(
extract_dense_waveforms,
]
for feature_name in feature_list:
- assert (
- feature_name in _features_class.keys()
- ), f"Feature {feature_name} in 'feature_list' is not possible. Possible features are {list(_features_class.keys())}"
+ assert feature_name in _features_class.keys(), (
+ f"Feature {feature_name} in 'feature_list' is not possible. Possible features are {list(_features_class.keys())}"
+ )
Class = _features_class[feature_name]
params = feature_params.get(feature_name, {}).copy()
node = Class(recording, parents=[peak_retriever, extract_dense_waveforms], **params)
diff --git a/src/spikeinterface/sortingcomponents/waveforms/neural_network_denoiser.py b/src/spikeinterface/sortingcomponents/waveforms/neural_network_denoiser.py
index 7a889780b9..b5d6a45a03 100644
--- a/src/spikeinterface/sortingcomponents/waveforms/neural_network_denoiser.py
+++ b/src/spikeinterface/sortingcomponents/waveforms/neural_network_denoiser.py
@@ -82,9 +82,9 @@ def __init__(
self.denoiser, model_relative_path = self.load_model(
model_folder=model_folder, repo_id=repo_id, model_name=model_name, spike_size=spike_size
)
- except RuntimeError as e:
+ except RuntimeError:
raise ValueError(
- f"Failed to load model. Check consistency between waveform node shapes and model output layer"
+ "Failed to load model. Check consistency between waveform node shapes and model output layer"
)
self.assert_model_and_waveform_temporal_match(
@@ -122,7 +122,7 @@ def assert_model_and_waveform_temporal_match(
try:
filename = str(model_relative_path).replace(".pt", ".json")
json_file_path = hf_hub_download(repo_id=repo_id, filename=filename)
- except Exception as e:
+ except Exception:
warnings.warn(f"Could not download json file from repo {repo_id}. Model might misbehave")
if json_file_path is None or not Path(json_file_path).exists():
@@ -179,9 +179,9 @@ def load_model(
else:
if model_name is not None:
raise ValueError(f"Multiple models found in {model_folder}. Please specify model_name")
- assert (
- model_name is not None
- ), "If there are multiple .pt files in the repo, you need to specify the model_name"
+ assert model_name is not None, (
+ "If there are multiple .pt files in the repo, you need to specify the model_name"
+ )
filename = [f for f in pt_files if model_name in f]
if len(filename) == 0:
raise ValueError(f"Model {model_name} not found in repo {repo_id}")
@@ -199,9 +199,9 @@ def load_model(
if len(pt_files) == 1:
filename = pt_files[0]
else:
- assert (
- model_name is not None
- ), "If there are multiple .pt files in the repo, you need to specify the model_name"
+ assert model_name is not None, (
+ "If there are multiple .pt files in the repo, you need to specify the model_name"
+ )
filename = [f for f in pt_files if model_name in f]
if len(filename) == 0:
raise ValueError(f"Model {model_name} not found in repo {repo_id}")
diff --git a/src/spikeinterface/sortingcomponents/waveforms/tests/test_features_from_peaks.py b/src/spikeinterface/sortingcomponents/waveforms/tests/test_features_from_peaks.py
index 736b040a26..79f48932c5 100644
--- a/src/spikeinterface/sortingcomponents/waveforms/tests/test_features_from_peaks.py
+++ b/src/spikeinterface/sortingcomponents/waveforms/tests/test_features_from_peaks.py
@@ -1,5 +1,3 @@
-import pytest
-
from spikeinterface.sortingcomponents.waveforms.features_from_peaks import compute_features_from_peaks
from spikeinterface.core import get_noise_levels
from spikeinterface.sortingcomponents.peak_detection import detect_peaks
diff --git a/src/spikeinterface/sortingcomponents/waveforms/tests/test_hanning_filter.py b/src/spikeinterface/sortingcomponents/waveforms/tests/test_hanning_filter.py
index 1b006af429..83848881a1 100644
--- a/src/spikeinterface/sortingcomponents/waveforms/tests/test_hanning_filter.py
+++ b/src/spikeinterface/sortingcomponents/waveforms/tests/test_hanning_filter.py
@@ -1,6 +1,3 @@
-import pytest
-
-
from spikeinterface.sortingcomponents.waveforms.hanning_filter import HanningFilter
from spikeinterface.core.node_pipeline import (
diff --git a/src/spikeinterface/sortingcomponents/waveforms/tests/test_neural_network_denoiser.py b/src/spikeinterface/sortingcomponents/waveforms/tests/test_neural_network_denoiser.py
index b481a39ca6..d2cd517f86 100644
--- a/src/spikeinterface/sortingcomponents/waveforms/tests/test_neural_network_denoiser.py
+++ b/src/spikeinterface/sortingcomponents/waveforms/tests/test_neural_network_denoiser.py
@@ -83,7 +83,7 @@ def test_single_channel_yass_denoiser_wrong_shape(generated_recording_30khz, det
recording, parents=[peak_retriever], nbefore=nbefore, nafter=nafter, return_output=True
)
with pytest.raises(ValueError):
- yass_denoiser = SingleChannelDenoiser(
+ _ = SingleChannelDenoiser(
recording,
parents=[peak_retriever, waveform_extraction],
repo_id="spikeinterface/waveform_denoiser",
@@ -96,4 +96,4 @@ def test_single_channel_yass_denoiser_wrong_shape(generated_recording_30khz, det
model_name="yass_ibl",
)
with pytest.raises(ValueError):
- yass_denoiser = SingleChannelDenoiser(recording, parents=[peak_retriever, waveform_extraction], model=model)
+ _ = SingleChannelDenoiser(recording, parents=[peak_retriever, waveform_extraction], model=model)
diff --git a/src/spikeinterface/sortingcomponents/waveforms/tests/test_savgol_denoiser.py b/src/spikeinterface/sortingcomponents/waveforms/tests/test_savgol_denoiser.py
index 651b681078..fc2787a3d6 100644
--- a/src/spikeinterface/sortingcomponents/waveforms/tests/test_savgol_denoiser.py
+++ b/src/spikeinterface/sortingcomponents/waveforms/tests/test_savgol_denoiser.py
@@ -1,6 +1,3 @@
-import pytest
-
-
from spikeinterface.sortingcomponents.waveforms.savgol_denoiser import SavGolDenoiser
from spikeinterface.core.node_pipeline import (
diff --git a/src/spikeinterface/sortingcomponents/waveforms/tests/test_temporal_pca.py b/src/spikeinterface/sortingcomponents/waveforms/tests/test_temporal_pca.py
index dc01ab3431..e3d99a5e1d 100644
--- a/src/spikeinterface/sortingcomponents/waveforms/tests/test_temporal_pca.py
+++ b/src/spikeinterface/sortingcomponents/waveforms/tests/test_temporal_pca.py
@@ -180,9 +180,6 @@ def test_initialization_with_wrong_parents_failure(generated_recording, model_pa
recording = generated_recording
model_folder_path = model_path_of_trained_pca
dummy_parent = PipelineNode(recording)
- extract_waveforms = ExtractSparseWaveforms(
- recording=recording, ms_before=1, ms_after=1, radius_um=40, return_output=True
- )
match_error = f"TemporalPCA should have a single {WaveformsNode.__name__} in its parents"
diff --git a/src/spikeinterface/sortingcomponents/waveforms/waveform_thresholder.py b/src/spikeinterface/sortingcomponents/waveforms/waveform_thresholder.py
index ec223d0047..b6fb38350b 100644
--- a/src/spikeinterface/sortingcomponents/waveforms/waveform_thresholder.py
+++ b/src/spikeinterface/sortingcomponents/waveforms/waveform_thresholder.py
@@ -59,7 +59,7 @@ def __init__(
parents=parents,
)
assert feature in ["ptp", "mean", "energy", "peak_voltage"], (
- f"{feature} is not a valid feature" " must be one of 'ptp', 'mean', 'energy'," " or 'peak_voltage'"
+ f"{feature} is not a valid feature must be one of 'ptp', 'mean', 'energy', or 'peak_voltage'"
)
self.threshold = threshold
diff --git a/src/spikeinterface/widgets/all_amplitudes_distributions.py b/src/spikeinterface/widgets/all_amplitudes_distributions.py
index b3cf2cfc02..c4d3eb4b69 100644
--- a/src/spikeinterface/widgets/all_amplitudes_distributions.py
+++ b/src/spikeinterface/widgets/all_amplitudes_distributions.py
@@ -55,7 +55,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
diff --git a/src/spikeinterface/widgets/amplitudes.py b/src/spikeinterface/widgets/amplitudes.py
index 1983253299..6091214a66 100644
--- a/src/spikeinterface/widgets/amplitudes.py
+++ b/src/spikeinterface/widgets/amplitudes.py
@@ -159,7 +159,6 @@ def plot_figpack(self, data_plot, **backend_kwargs):
make_serializable,
handle_display_and_url,
import_figpack_or_sortingview,
- generate_unit_table_view,
)
use_sortingview = backend_kwargs.get("use_sortingview", False)
diff --git a/src/spikeinterface/widgets/autocorrelograms.py b/src/spikeinterface/widgets/autocorrelograms.py
index d83afeb259..1380d0119f 100644
--- a/src/spikeinterface/widgets/autocorrelograms.py
+++ b/src/spikeinterface/widgets/autocorrelograms.py
@@ -16,7 +16,6 @@ def __init__(self, *args, **kargs):
)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
@@ -46,7 +45,6 @@ def plot_figpack(self, data_plot, **backend_kwargs):
make_serializable,
handle_display_and_url,
import_figpack_or_sortingview,
- generate_unit_table_view,
)
use_sortingview = backend_kwargs.get("use_sortingview", False)
diff --git a/src/spikeinterface/widgets/base.py b/src/spikeinterface/widgets/base.py
index 646e46a7a7..e6d75222e5 100644
--- a/src/spikeinterface/widgets/base.py
+++ b/src/spikeinterface/widgets/base.py
@@ -1,10 +1,11 @@
-global default_backend_
-default_backend_ = "matplotlib"
-
from spikeinterface.core import SortingAnalyzer, BaseSorting
from spikeinterface.core.waveforms_extractor_backwards_compatibility import MockWaveformExtractor
+global default_backend_
+default_backend_ = "matplotlib"
+
+
def get_default_plotter_backend():
"""Return the default backend for spikeinterface widgets.
The default backend is "matplotlib" at init.
@@ -105,7 +106,7 @@ def check_backend(self, backend):
if backend is None:
backend = get_default_plotter_backend()
assert backend in self.get_possible_backends(), (
- f"{backend} backend not available! Available backends are: " f"{self.get_possible_backends()}"
+ f"{backend} backend not available! Available backends are: {self.get_possible_backends()}"
)
return backend
diff --git a/src/spikeinterface/widgets/bombcell_curation.py b/src/spikeinterface/widgets/bombcell_curation.py
index 38b4e6c751..3f06b88684 100644
--- a/src/spikeinterface/widgets/bombcell_curation.py
+++ b/src/spikeinterface/widgets/bombcell_curation.py
@@ -85,7 +85,6 @@ def _get_metrics_for_unit_label(self, unit_label, thresholds):
def plot_matplotlib(self, data_plot, **backend_kwargs):
import matplotlib.pyplot as plt
- import pandas as pd
dp = to_attr(data_plot)
metrics = dp.metrics
@@ -239,8 +238,7 @@ def plot_bombcell_unit_labeling_all(
dict
Dictionary with keys 'histograms', 'waveforms', 'upset' containing widget objects.
"""
- from pathlib import Path
- from spikeinterface.curation import bombcell_get_default_thresholds, save_bombcell_results
+ from spikeinterface.curation import bombcell_get_default_thresholds
if thresholds is None:
thresholds = bombcell_get_default_thresholds()
diff --git a/src/spikeinterface/widgets/collision.py b/src/spikeinterface/widgets/collision.py
index ce1f263cce..ad02f36b08 100644
--- a/src/spikeinterface/widgets/collision.py
+++ b/src/spikeinterface/widgets/collision.py
@@ -67,7 +67,6 @@ def __init__(
def plot_matplotlib(self, data_plot, **backend_kwargs):
import matplotlib.pyplot as plt
- import sklearn
import matplotlib
from .utils_matplotlib import make_mpl_figure
@@ -87,7 +86,6 @@ def plot_matplotlib(self, data_plot, **backend_kwargs):
template_inds = [all_unit_ids.index(u) for u in dp.unit_ids]
templates_array = dp.templates_array[template_inds, :, :].copy()
- flat_templates = templates_array.reshape(templates_array.shape[0], -1)
similarity_matrix, _ = compute_similarity_with_templates_array(
templates_array,
@@ -107,8 +105,6 @@ def plot_matplotlib(self, data_plot, **backend_kwargs):
fs = comp.sorting1.get_sampling_frequency()
lags = comp.bins / fs * 1000
- n = len(dp.unit_ids)
-
similarities, recall_scores, pair_names = comp.compute_collision_by_similarity(
similarity_matrix, unit_ids=dp.unit_ids, good_only=dp.good_only, min_accuracy=dp.min_accuracy
)
@@ -239,7 +235,6 @@ def __init__(
def plot_matplotlib(self, data_plot, **backend_kwargs):
import matplotlib.pyplot as plt
- import sklearn
import matplotlib
from .utils_matplotlib import make_mpl_figure
diff --git a/src/spikeinterface/widgets/comparison.py b/src/spikeinterface/widgets/comparison.py
index d111124522..2784cd09a2 100644
--- a/src/spikeinterface/widgets/comparison.py
+++ b/src/spikeinterface/widgets/comparison.py
@@ -27,7 +27,6 @@ def __init__(self, gt_comparison, count_text=True, unit_ticks=True, backend=None
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
@@ -108,7 +107,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
diff --git a/src/spikeinterface/widgets/crosscorrelograms.py b/src/spikeinterface/widgets/crosscorrelograms.py
index 438239ab88..ed818b7800 100644
--- a/src/spikeinterface/widgets/crosscorrelograms.py
+++ b/src/spikeinterface/widgets/crosscorrelograms.py
@@ -86,7 +86,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
@@ -131,7 +130,6 @@ def plot_figpack(self, data_plot, **backend_kwargs):
make_serializable,
handle_display_and_url,
import_figpack_or_sortingview,
- generate_unit_table_view,
)
use_sortingview = backend_kwargs.get("use_sortingview", False)
diff --git a/src/spikeinterface/widgets/drift_templates.py b/src/spikeinterface/widgets/drift_templates.py
index dda0371e52..297c24d287 100644
--- a/src/spikeinterface/widgets/drift_templates.py
+++ b/src/spikeinterface/widgets/drift_templates.py
@@ -69,7 +69,7 @@ def plot_ipywidgets(self, data_plot, **backend_kwargs):
max=arr.shape[0] - 1,
readout=False,
continuous_update=True,
- layout=widgets.Layout(width=f"100%"),
+ layout=widgets.Layout(width="100%"),
)
self.widget = widgets.AppLayout(
diff --git a/src/spikeinterface/widgets/isi_distribution.py b/src/spikeinterface/widgets/isi_distribution.py
index 65bda2341e..6e6c1e1cbd 100644
--- a/src/spikeinterface/widgets/isi_distribution.py
+++ b/src/spikeinterface/widgets/isi_distribution.py
@@ -1,5 +1,4 @@
import numpy as np
-from warnings import warn
from spikeinterface.core import SortingAnalyzer, BaseSorting
@@ -48,7 +47,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
diff --git a/src/spikeinterface/widgets/metrics.py b/src/spikeinterface/widgets/metrics.py
index 0631dc52c9..23317fdc4e 100644
--- a/src/spikeinterface/widgets/metrics.py
+++ b/src/spikeinterface/widgets/metrics.py
@@ -82,7 +82,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
@@ -376,9 +375,9 @@ def __init__(
for category, subdict in thresholds.items():
assert isinstance(subdict, dict), "Each category in thresholds should be a dict of metric thresholds."
for metric_name, thresh in subdict.items():
- assert isinstance(thresh, dict) and (
- "greater" in thresh or "less" in thresh
- ), "Each threshold entry should be a dict with 'greater' and/or 'less' keys."
+ assert isinstance(thresh, dict) and ("greater" in thresh or "less" in thresh), (
+ "Each threshold entry should be a dict with 'greater' and/or 'less' keys."
+ )
flat_thresholds[metric_name] = thresh
if metrics_to_plot is None:
diff --git a/src/spikeinterface/widgets/motion.py b/src/spikeinterface/widgets/motion.py
index a08c4b789a..4ac8c9b030 100644
--- a/src/spikeinterface/widgets/motion.py
+++ b/src/spikeinterface/widgets/motion.py
@@ -180,9 +180,9 @@ def __init__(
recording = None
sampling_frequency = sorting_analyzer.sampling_frequency
peaks = sorting_analyzer.sorting.to_spike_vector()
- assert sorting_analyzer.has_extension(
- "spike_locations"
- ), "The sorting analyzer must have the 'spike_locations' extension to use this function"
+ assert sorting_analyzer.has_extension("spike_locations"), (
+ "The sorting analyzer must have the 'spike_locations' extension to use this function"
+ )
peak_locations = sorting_analyzer.get_extension("spike_locations").get_data()
if color_amplitude:
assert sorting_analyzer.has_extension("spike_amplitudes"), (
@@ -348,9 +348,9 @@ def __init__(
raise ValueError(
"plot drift map : the Motion object is multi-segment you must provide segment_index=XX"
)
- assert recording.get_num_segments() == len(
- motion.displacement
- ), "The number of segments in the recording must be the same as the number of segments in the motion object"
+ assert recording.get_num_segments() == len(motion.displacement), (
+ "The number of segments in the recording must be the same as the number of segments in the motion object"
+ )
plot_data = dict(
sampling_frequency=motion_info["parameters"]["sampling_frequency"],
diff --git a/src/spikeinterface/widgets/multicomparison.py b/src/spikeinterface/widgets/multicomparison.py
index 38d1b28e54..b0878914f7 100644
--- a/src/spikeinterface/widgets/multicomparison.py
+++ b/src/spikeinterface/widgets/multicomparison.py
@@ -1,8 +1,6 @@
import numpy as np
-from warnings import warn
from .base import BaseWidget, to_attr
-from .utils import get_unit_colors
class MultiCompGraphWidget(BaseWidget):
@@ -228,7 +226,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.colors as mpl_colors
import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
diff --git a/src/spikeinterface/widgets/peak_activity.py b/src/spikeinterface/widgets/peak_activity.py
index f7582b4042..117df2073a 100644
--- a/src/spikeinterface/widgets/peak_activity.py
+++ b/src/spikeinterface/widgets/peak_activity.py
@@ -204,6 +204,6 @@ def _plot_one_bin(
artists = artists + (im,)
if with_color_bar:
- self.cbar = self.figure.colorbar(im, ax=self.ax, label=f"Peak rate (Hz)")
+ self.cbar = self.figure.colorbar(im, ax=self.ax, label="Peak rate (Hz)")
return artists
diff --git a/src/spikeinterface/widgets/peaks_on_probe.py b/src/spikeinterface/widgets/peaks_on_probe.py
index ea707c30ed..8f19b4a7eb 100644
--- a/src/spikeinterface/widgets/peaks_on_probe.py
+++ b/src/spikeinterface/widgets/peaks_on_probe.py
@@ -79,12 +79,10 @@ def plot_matplotlib(self, data_plot, **backend_kwargs):
dp.peaks,
dp.peak_locations,
)
- fs = dp.recording.get_sampling_frequency()
num_plots = len(peaks)
# Set the maximum time to the end time of the longest segment
if dp.time_range is None:
-
time_range = self._get_min_and_max_times_in_recording(dp.recording)
else:
time_range = dp.time_range
@@ -98,7 +96,6 @@ def plot_matplotlib(self, data_plot, **backend_kwargs):
# Plot each passed peaks / peak_locations over the probe on a separate subplot
for ax_idx, (peaks_to_plot, peak_locs_to_plot) in enumerate(zip(peaks, peak_locations)):
-
ax = self.axes[ax_idx]
plot_probe_map(dp.recording, ax=ax)
@@ -138,7 +135,7 @@ def plot_matplotlib(self, data_plot, **backend_kwargs):
ax.set_ylim(ylim[0], ylim[1])
- self.figure.suptitle(f"Peaks on Probe Plot")
+ self.figure.suptitle("Peaks on Probe Plot")
def _get_peaks_time_mask(self, recording, time_range, peaks_to_plot):
"""
@@ -152,7 +149,6 @@ def _get_peaks_time_mask(self, recording, time_range, peaks_to_plot):
time_mask = np.zeros(peaks_to_plot.size, dtype=bool)
for seg_idx in range(recording.get_num_segments()):
-
segment = recording.select_segments(seg_idx)
t_start_sample = segment.time_to_sample_index(time_range[0])
@@ -175,7 +171,6 @@ def _get_min_and_max_times_in_recording(self, recording):
t_starts = []
t_stops = []
for seg_idx in range(recording.get_num_segments()):
-
segment = recording.select_segments(seg_idx)
t_starts.append(segment.sample_index_to_time(0))
diff --git a/src/spikeinterface/widgets/potential_merges.py b/src/spikeinterface/widgets/potential_merges.py
index 370efa57eb..ce4e23e2f7 100644
--- a/src/spikeinterface/widgets/potential_merges.py
+++ b/src/spikeinterface/widgets/potential_merges.py
@@ -1,5 +1,4 @@
import numpy as np
-from warnings import warn
from .base import BaseWidget, default_backend_kwargs
diff --git a/src/spikeinterface/widgets/probe_map.py b/src/spikeinterface/widgets/probe_map.py
index 53f18af814..afc6224756 100644
--- a/src/spikeinterface/widgets/probe_map.py
+++ b/src/spikeinterface/widgets/probe_map.py
@@ -41,7 +41,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
from probeinterface.plotting import get_auto_lims, plot_probe
diff --git a/src/spikeinterface/widgets/rasters.py b/src/spikeinterface/widgets/rasters.py
index e302674845..eda75cef9e 100644
--- a/src/spikeinterface/widgets/rasters.py
+++ b/src/spikeinterface/widgets/rasters.py
@@ -1,10 +1,9 @@
import numpy as np
-from warnings import warn
from spikeinterface.core import SortingAnalyzer, BaseSorting
from spikeinterface.core.sorting_tools import get_segment_durations
-from .base import BaseWidget, to_attr, default_backend_kwargs
+from .base import BaseWidget, to_attr
from .utils import (
get_some_colors,
validate_segment_indices,
@@ -185,8 +184,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
- from matplotlib.colors import Normalize
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
@@ -267,10 +264,8 @@ def plot_matplotlib(self, data_plot, **backend_kwargs):
# Add segment boundary lines if provided and handle x limits
if dp.segment_start_stop_times is not None:
-
segment_times = np.array(list(dp.segment_start_stop_times.values()))
if len(segment_times) > 1:
-
segment_times = segment_times - dp.segment_time_offsets[:, None]
self._set_segment_time_ticks(scatter_ax, segment_times, dp.segment_time_offsets)
@@ -471,7 +466,7 @@ def __init__(
if isinstance(sorting_analyzer_or_sorting, SortingAnalyzer):
if not sorting_analyzer_or_sorting.has_extension("unit_locations"):
if sort_by_depth:
- raise AttributeError(f"'unit_locations' necessary for `sort_by_depth=True`")
+ raise AttributeError("'unit_locations' necessary for `sort_by_depth=True`")
else:
depths = sorting_analyzer_or_sorting.get_extension("unit_locations").get_data(outputs="numpy")
s_args_depths = np.argsort(depths[:, 1])
diff --git a/src/spikeinterface/widgets/spike_locations.py b/src/spikeinterface/widgets/spike_locations.py
index f589d86896..af2956522c 100644
--- a/src/spikeinterface/widgets/spike_locations.py
+++ b/src/spikeinterface/widgets/spike_locations.py
@@ -106,7 +106,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
from matplotlib.lines import Line2D
diff --git a/src/spikeinterface/widgets/spike_locations_by_time.py b/src/spikeinterface/widgets/spike_locations_by_time.py
index 5b35888852..c1f3b7d277 100644
--- a/src/spikeinterface/widgets/spike_locations_by_time.py
+++ b/src/spikeinterface/widgets/spike_locations_by_time.py
@@ -114,7 +114,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
@@ -167,7 +166,7 @@ def plot_matplotlib(self, data_plot, **backend_kwargs):
scatter_ax.set_xlim(0, dp.total_duration)
scatter_ax.set_xlabel("Times [s]")
- scatter_ax.set_ylabel(f"Location [um]")
+ scatter_ax.set_ylabel("Location [um]")
scatter_ax.spines["top"].set_visible(False)
scatter_ax.spines["right"].set_visible(False)
self.figure.subplots_adjust(bottom=0.1, top=0.9, left=0.1)
diff --git a/src/spikeinterface/widgets/spikes_on_traces.py b/src/spikeinterface/widgets/spikes_on_traces.py
index b28fe25e9d..86e1a26faf 100644
--- a/src/spikeinterface/widgets/spikes_on_traces.py
+++ b/src/spikeinterface/widgets/spikes_on_traces.py
@@ -1,5 +1,3 @@
-import warnings
-
import numpy as np
from .base import BaseWidget, to_attr
@@ -147,8 +145,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
- from .utils_matplotlib import make_mpl_figure
from matplotlib.patches import Ellipse
from matplotlib.lines import Line2D
@@ -237,7 +233,6 @@ def plot_matplotlib(self, data_plot, **backend_kwargs):
label_set = True
def plot_ipywidgets(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
import ipywidgets.widgets as widgets
from IPython.display import display
from .utils_ipywidgets import check_ipywidget_backend, UnitSelector
@@ -254,8 +249,6 @@ def plot_ipywidgets(self, data_plot, **backend_kwargs):
backend_kwargs_ts = backend_kwargs.copy()
backend_kwargs_ts["width_cm"] = ratios[1] * backend_kwargs_ts["width_cm"]
backend_kwargs_ts["display"] = False
- height_cm = backend_kwargs["height_cm"]
- width_cm = backend_kwargs["width_cm"]
# plot timeseries
self._traces_widget = TracesWidget(
diff --git a/src/spikeinterface/widgets/template_similarity.py b/src/spikeinterface/widgets/template_similarity.py
index 749afe0334..a9283d40b3 100644
--- a/src/spikeinterface/widgets/template_similarity.py
+++ b/src/spikeinterface/widgets/template_similarity.py
@@ -63,7 +63,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
diff --git a/src/spikeinterface/widgets/tests/test_widgets.py b/src/spikeinterface/widgets/tests/test_widgets.py
index 8ece826de9..fcac517d46 100644
--- a/src/spikeinterface/widgets/tests/test_widgets.py
+++ b/src/spikeinterface/widgets/tests/test_widgets.py
@@ -37,7 +37,6 @@
class TestWidgets(unittest.TestCase):
-
@classmethod
def setUpClass(cls):
@@ -759,7 +758,6 @@ def test_plot_bombcell_labels_upset(self):
if __name__ == "__main__":
# unittest.main()
- import matplotlib.pyplot as plt
TestWidgets.setUpClass()
mytest = TestWidgets()
diff --git a/src/spikeinterface/widgets/tests/test_widgets_utils.py b/src/spikeinterface/widgets/tests/test_widgets_utils.py
index c1905f3ac8..144fae8de9 100644
--- a/src/spikeinterface/widgets/tests/test_widgets_utils.py
+++ b/src/spikeinterface/widgets/tests/test_widgets_utils.py
@@ -5,24 +5,23 @@
get_some_colors,
validate_segment_indices,
)
-import numpy as np
def test_get_some_colors():
keys = ["a", "b", "c", "d"]
- colors = get_some_colors(keys, color_engine="auto")
+ _ = get_some_colors(keys, color_engine="auto")
# print(colors)
- colors = get_some_colors(keys, color_engine="distinctipy")
+ _ = get_some_colors(keys, color_engine="distinctipy")
# print(colors)
- colors = get_some_colors(keys, color_engine="matplotlib", shuffle=None)
+ _ = get_some_colors(keys, color_engine="matplotlib", shuffle=None)
# print(colors)
- colors = get_some_colors(keys, color_engine="matplotlib", shuffle=False)
- colors = get_some_colors(keys, color_engine="matplotlib", shuffle=True)
+ _ = get_some_colors(keys, color_engine="matplotlib", shuffle=False)
+ _ = get_some_colors(keys, color_engine="matplotlib", shuffle=True)
- colors = get_some_colors(keys, color_engine="colorsys")
+ _ = get_some_colors(keys, color_engine="colorsys")
# print(colors)
diff --git a/src/spikeinterface/widgets/traces.py b/src/spikeinterface/widgets/traces.py
index 62f221b6ca..8106e7e1d3 100644
--- a/src/spikeinterface/widgets/traces.py
+++ b/src/spikeinterface/widgets/traces.py
@@ -141,7 +141,7 @@ def __init__(
time_range = np.array(time_range, dtype=np.float64)
if time_range[1] > t_end:
warnings.warn(
- "You have selected a time after the end of the segment. The range will be clipped to " f"{t_end}"
+ f"You have selected a time after the end of the segment. The range will be clipped to {t_end}"
)
time_range[1] = t_end
@@ -209,9 +209,9 @@ def __init__(
if isinstance(clim, tuple):
clims = {layer_key: clim for layer_key in layer_keys}
elif isinstance(clim, dict):
- assert all(
- layer_key in clim for layer_key in layer_keys
- ), f"all recordings must be a key in `clim` if `clim` is a dict. Provide keys {layer_keys} in clim"
+ assert all(layer_key in clim for layer_key in layer_keys), (
+ f"all recordings must be a key in `clim` if `clim` is a dict. Provide keys {layer_keys} in clim"
+ )
clims = clim
else:
raise TypeError(f"'clim' can be None, tuple, or dict! Unsupported type {type(clim)}")
@@ -220,9 +220,9 @@ def __init__(
if events is not None:
num_segments = rec0.get_num_segments()
if num_segments > 1:
- assert (
- len(events) == num_segments
- ), f"events must be a list with the events for each of the {num_segments} segments"
+ assert len(events) == num_segments, (
+ f"events must be a list with the events for each of the {num_segments} segments"
+ )
evensts_w_dtype = events
else:
if isinstance(events, np.ndarray):
@@ -272,7 +272,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
from .utils_matplotlib import make_mpl_figure
@@ -283,7 +282,7 @@ def plot_matplotlib(self, data_plot, **backend_kwargs):
if self.cb is not None:
try:
self.cb.remove()
- except:
+ except Exception:
pass
ax = self.ax
@@ -618,7 +617,7 @@ def plot_figpack(self, data_plot, **backend_kwargs):
if not dp.order_channel_by_depth:
warnings.warn(
- "It is recommended to set 'order_channel_by_depth' to True " "when using the sortingview backend"
+ "It is recommended to set 'order_channel_by_depth' to True when using the sortingview backend"
)
tiled_layers = []
@@ -673,9 +672,9 @@ def _get_trace_list(recordings, channel_ids, segment_index, time_range=None, ret
rec0 = recordings[k0]
if return_in_uV:
- assert all(
- rec.has_scaleable_traces() for rec in recordings.values()
- ), "Some recording layers do not have scaled traces. Use `return_in_uV=False`"
+ assert all(rec.has_scaleable_traces() for rec in recordings.values()), (
+ "Some recording layers do not have scaled traces. Use `return_in_uV=False`"
+ )
assert time_range is not None or frame_range is not None, "You must provide either time_range or frame_range"
diff --git a/src/spikeinterface/widgets/unit_depths.py b/src/spikeinterface/widgets/unit_depths.py
index 6f6b24cc07..cd113cfca6 100644
--- a/src/spikeinterface/widgets/unit_depths.py
+++ b/src/spikeinterface/widgets/unit_depths.py
@@ -54,7 +54,6 @@ def __init__(self, sorting_analyzer, unit_colors=None, depth_axis=1, backend=Non
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
diff --git a/src/spikeinterface/widgets/unit_labels.py b/src/spikeinterface/widgets/unit_labels.py
index 348f0e3b8d..40a028ca8c 100644
--- a/src/spikeinterface/widgets/unit_labels.py
+++ b/src/spikeinterface/widgets/unit_labels.py
@@ -2,7 +2,6 @@
import numpy as np
-from spikeinterface.curation.curation_tools import is_threshold_disabled
from .base import BaseWidget, to_attr
@@ -38,9 +37,9 @@ def __init__(
self.check_extensions(sorting_analyzer, "templates")
if labels_order is not None:
assert len(labels_order) == len(np.unique(unit_labels)), "labels_order length must match unique unit types"
- assert all(
- [label in np.unique(unit_labels) for label in labels_order]
- ), "All labels in labels_order must be present in unit_labels"
+ assert all([label in np.unique(unit_labels) for label in labels_order]), (
+ "All labels in labels_order must be present in unit_labels"
+ )
else:
labels_order = np.unique(unit_labels)
plot_data = dict(
diff --git a/src/spikeinterface/widgets/unit_locations.py b/src/spikeinterface/widgets/unit_locations.py
index 7d88a523d4..4785f36251 100644
--- a/src/spikeinterface/widgets/unit_locations.py
+++ b/src/spikeinterface/widgets/unit_locations.py
@@ -109,7 +109,6 @@ def __init__(
BaseWidget.__init__(self, data_plot, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
from probeinterface.plotting import plot_probe
diff --git a/src/spikeinterface/widgets/unit_presence.py b/src/spikeinterface/widgets/unit_presence.py
index 72a9603544..0baf14914d 100644
--- a/src/spikeinterface/widgets/unit_presence.py
+++ b/src/spikeinterface/widgets/unit_presence.py
@@ -1,5 +1,4 @@
import numpy as np
-from warnings import warn
from spikeinterface.core import SortingAnalyzer, BaseSorting
from .base import BaseWidget, to_attr
@@ -55,7 +54,6 @@ def __init__(
BaseWidget.__init__(self, data_plot, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
diff --git a/src/spikeinterface/widgets/unit_probe_map.py b/src/spikeinterface/widgets/unit_probe_map.py
index 944331ad92..eb6a219295 100644
--- a/src/spikeinterface/widgets/unit_probe_map.py
+++ b/src/spikeinterface/widgets/unit_probe_map.py
@@ -59,7 +59,6 @@ def __init__(
BaseWidget.__init__(self, data_plot, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
from probeinterface.plotting import plot_probe
diff --git a/src/spikeinterface/widgets/unit_summary.py b/src/spikeinterface/widgets/unit_summary.py
index 821260eba7..e0ac78d66b 100644
--- a/src/spikeinterface/widgets/unit_summary.py
+++ b/src/spikeinterface/widgets/unit_summary.py
@@ -80,7 +80,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
diff --git a/src/spikeinterface/widgets/unit_valid_periods.py b/src/spikeinterface/widgets/unit_valid_periods.py
index 7c54e93fdc..5835497174 100644
--- a/src/spikeinterface/widgets/unit_valid_periods.py
+++ b/src/spikeinterface/widgets/unit_valid_periods.py
@@ -59,7 +59,6 @@ def __init__(
BaseWidget.__init__(self, data_plot, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
diff --git a/src/spikeinterface/widgets/unit_waveforms.py b/src/spikeinterface/widgets/unit_waveforms.py
index 5f9da5dc97..cfdd27b93e 100644
--- a/src/spikeinterface/widgets/unit_waveforms.py
+++ b/src/spikeinterface/widgets/unit_waveforms.py
@@ -6,7 +6,6 @@
from .utils import get_unit_colors
from spikeinterface.core import ChannelSparsity, SortingAnalyzer, Templates
-from spikeinterface.core.basesorting import BaseSorting
class UnitWaveformsWidget(BaseWidget):
@@ -236,7 +235,6 @@ def __init__(
BaseWidget.__init__(self, plot_data, backend=backend, **backend_kwargs)
def plot_matplotlib(self, data_plot, **backend_kwargs):
- import matplotlib.pyplot as plt
from .utils_matplotlib import make_mpl_figure
dp = to_attr(data_plot)
@@ -548,12 +546,12 @@ def _get_template_shadings(self, unit_ids, templates_percentile_shading):
if isinstance(templates_percentile_shading, (int, float)):
templates_percentile_shading = [templates_percentile_shading, 100 - templates_percentile_shading]
else:
- assert isinstance(
- templates_percentile_shading, (list, tuple)
- ), "'templates_percentile_shading' should be a float, a list/tuple of floats, or None!"
- assert (
- np.mod(len(templates_percentile_shading), 2) == 0
- ), "'templates_percentile_shading' should be a have an even number of elements."
+ assert isinstance(templates_percentile_shading, (list, tuple)), (
+ "'templates_percentile_shading' should be a float, a list/tuple of floats, or None!"
+ )
+ assert np.mod(len(templates_percentile_shading), 2) == 0, (
+ "'templates_percentile_shading' should be a have an even number of elements."
+ )
templates_shading = []
for percentile in templates_percentile_shading:
template_percentile = self.templates_ext.get_templates(
diff --git a/src/spikeinterface/widgets/utils.py b/src/spikeinterface/widgets/utils.py
index 82c35dafc0..824579179c 100644
--- a/src/spikeinterface/widgets/utils.py
+++ b/src/spikeinterface/widgets/utils.py
@@ -226,8 +226,8 @@ def array_to_image(
font = ImageFont.truetype("/usr/share/fonts/truetype/freefont/FreeMono.ttf", fontsize)
else:
font = ImageFont.truetype("arial.ttf", fontsize)
- except:
- print(f"Could not load font to use in scalebar. Scalebar will not be drawn.")
+ except Exception:
+ print("Could not load font to use in scalebar. Scalebar will not be drawn.")
font = None
if font is not None:
diff --git a/src/spikeinterface/widgets/utils_ipywidgets.py b/src/spikeinterface/widgets/utils_ipywidgets.py
index 25c67d36bd..7da6bec865 100644
--- a/src/spikeinterface/widgets/utils_ipywidgets.py
+++ b/src/spikeinterface/widgets/utils_ipywidgets.py
@@ -8,9 +8,9 @@ def check_ipywidget_backend():
import matplotlib
mpl_backend = matplotlib.get_backend()
- assert (
- "ipympl" in mpl_backend or "widget" in mpl_backend
- ), "To use the 'ipywidgets' backend, you have to set %matplotlib widget"
+ assert "ipympl" in mpl_backend or "widget" in mpl_backend, (
+ "To use the 'ipywidgets' backend, you have to set %matplotlib widget"
+ )
class TimeSlider(W.HBox):
@@ -80,7 +80,7 @@ def __init__(self, durations, sampling_frequency, frame_range, rec0=None, t_star
max=self.frame_limits[self.segment_index] - 1,
readout=False,
continuous_update=False,
- layout=W.Layout(width=f"70%"),
+ layout=W.Layout(width="70%"),
)
self.slider.observe(self.slider_moved, names="value", type="change")
@@ -184,7 +184,7 @@ def update_time(self, new_frame=None, new_time=None, update_slider=False, update
def time_label_changed(self, change=None):
try:
new_time = float(self.time_label.value)
- except:
+ except Exception:
new_time = None
if new_time is not None:
self.update_time(new_time=new_time, update_slider=True)
diff --git a/src/spikeinterface/widgets/widget_list.py b/src/spikeinterface/widgets/widget_list.py
index 6cd6bbfd23..988019fbac 100644
--- a/src/spikeinterface/widgets/widget_list.py
+++ b/src/spikeinterface/widgets/widget_list.py
@@ -38,7 +38,7 @@
from .collision import ComparisonCollisionBySimilarityWidget, StudyComparisonCollisionBySimilarityWidget
from .unit_labels import WaveformOverlayByLabelWidget
from .unit_valid_periods import ValidUnitPeriodsWidget
-from .bombcell_curation import BombcellUpsetPlotWidget, plot_bombcell_unit_labeling_all
+from .bombcell_curation import BombcellUpsetPlotWidget
widget_list = [
AgreementMatrixWidget,