Skip to main content

spikecurate logo

spikecurate

author: steeve laquitaine - laquitainesteeve@gmail.com

tests regression docs

Curate sorted single-unit quality from SpikeInterface extractors, using a fractional-logistic classifier trained on SpikeInterface quality metrics.

Given a recording, a ground-truth sorting, a sorter's output, the sorter's own single-unit calls, and expert good/bad labels for a subset of those units, spikecurate engineers quality-metric features, trains a classifier of accurately- vs. poorly-sorted single units, and reports its cross-validated precision/recall.

Install

pip install -e .

Documentation

Full API reference (built with Sphinx from the docstrings in src/spikecurate/): https://steevelaquitaine.github.io/spikecurate/

Rebuilds automatically on every push to master (.github/workflows/docs.yml). To build it locally:

pip install -e .[docs]
sphinx-build -b html docs docs/_build/html

Demo notebook

demo/demo_03.ipynb walks through FractionalLogisticClassifier's API - train, crossval_evaluate, predict, score - using the real, already-engineered feature dataset checked into this repo at dataset/single_unit_quality_dataset.csv. No SpikeInterface extractors needed, just pandas + spikecurate:

pip install -e .
python -m ipykernel install --user --name spikecurate --display-name spikecurate
jupyter notebook demo/demo_03.ipynb

Usage

import spikecurate

result = spikecurate.run(
    recording=recording,          # spikeinterface RecordingExtractor
    sorting_true=sorting_true,    # spikeinterface ground-truth SortingExtractor
    sorting=sorting,              # spikeinterface SortingExtractor (e.g. Kilosort4)
    we_save_path="waveforms/single_units",
    single_unit_ids=single_unit_ids,   # e.g. sorting.unit_ids[sorting.get_property("KSLabel") == "good"]
    good_unit_ids=good_unit_ids,       # subset of single_unit_ids, >80% agreement with ground truth
    bad_unit_ids=bad_unit_ids,         # remaining subset of single_unit_ids
    predict_unit_ids=single_unit_ids[:10],  # units to classify with the trained model; defaults to all
    job_kwargs=dict(n_jobs=-1, progress_bar=True),
)

result["feature_correlations"]           # pd.DataFrame: feature correlation matrix
result["results"]["metric_stats"]        # median/std/95% CI precision & recall, cross-validated
result["model"]                          # FractionalLogisticClassifier, trained on the full dataset
result["predictions"]                    # DataFrame indexed by unit id: probability, predicted_label, predicted_quality

The classifier's own API

spikecurate.run is a convenience pipeline built on top of FractionalLogisticClassifier, which has a scikit-learn-flavored API and is usable standalone (e.g. to retrain/re-predict without redoing waveform extraction, or to classify units engineered outside spikecurate.run):

from spikecurate.model import FractionalLogisticClassifier

model = FractionalLogisticClassifier(predictors)   # predictors: result["data"]["predictors"]
model.crossval_evaluate(dataset)                    # cross-validated precision/recall (each fold trains its own fit)
model.train(dataset)                                 # fit on the full labeled dataset; returns self
model.predict(features)                              # DataFrame: probability, predicted_label, predicted_quality
model.score(dataset)                                 # precision/recall of the trained model against dataset's own labels

features passed to predict just needs unit id as its index and the columns in model.predictors - it doesn't need a quality_label column (that's the whole point: predicting labels for units you don't already have labels for).

Other pipeline stages are also usable standalone:

from spikecurate.features import load_dataset
from spikecurate.plotting import plot_precision_recall

Testing

  • tests/test_pipeline.py: end-to-end smoke test of spikecurate.run() against synthetic SpikeInterface data. Runs on every push/PR (.github/workflows/tests.yml).
  • tests/test_classification.py: pins the classifier's numeric output (crossval_evaluate, train+score, predict) against dataset/single_unit_quality_dataset.csv - the same real engineered dataset demo_03.ipynb walks through - so a future change to the model/crossval/predict code that silently changes results, not just one that crashes, gets caught. Needs no SpikeInterface extractors, so it's fast. Runs on every push to master (.github/workflows/regression.yml).

Citation

If you use this package, please consider citing:

Laquitaine, S., Imbeni, M., Tharayil, J., Isbister, J. B., & Reimann, M. W. (2024). Spike sorting biases and information loss in a detailed cortical model. bioRxiv. https://doi.org/10.1101/2024.12.04.626805

@article{laquitaine2024spikesorting,
  title   = {Spike sorting biases and information loss in a detailed cortical model},
  author  = {Laquitaine, Steeve and Imbeni, Milo and Tharayil, Joseph and Isbister, James B. and Reimann, Michael W.},
  journal = {bioRxiv},
  year    = {2024},
  doi     = {10.1101/2024.12.04.626805},
  url     = {https://www.biorxiv.org/content/10.1101/2024.12.04.626805v1}
}

License

GNU General Public License v3.0 - see LICENSE.

Notes

  • Requires a principal_components extension on the WaveformExtractor (computed automatically by spikecurate.run) - the silhouette quality metric depends on it.
  • good_unit_ids and bad_unit_ids must partition single_unit_ids exactly (every single unit gets exactly one label) - spikecurate.run will raise AssertionError otherwise.
  • features.load_dataset always returns dataset sorted by unit id (dataset.sort_index()). FractionalLogisticClassifier.crossval_evaluate's cross-validation splits train/test by row position (random.sample(range(n), n_train)), so for a given dataset and seeds, results are reproducible only if row order is pinned - passing an unsorted dataset (e.g. one you built yourself, in whatever order the sorting extractor's unit ids happened to come in) will still run, but won't reproduce the same split as the same content sorted differently.

Metadata

Release files for spikecurate 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spikecurate 0.1.0
File Size Uploaded Provenance Actions
spikecurate-0.1.0.tar.gz 28.3 kB Without provenance Details for spikecurate-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for spikecurate 0.1.0
File Interpreter ABI Platform Actions
spikecurate-0.1.0-py3-none-any.whl Python 3 none any Details for spikecurate-0.1.0-py3-none-any.whl

Total release size: 54.9 kB

Release files / spikecurate-0.1.0.tar.gz

Download URL spikecurate-0.1.0.tar.gz
Size 28.3 kB
Tags Source
SHA-256 checksum
How to use checksums
08c4a82809674f9600a33d9a770868ff8799b99052c2e2c46ab8384a3e5c862f
BLAKE2b-256 checksum
How to use checksums
ece6b3f5a67742087a89aa1af0679d64033a291e3156a1d266db287423192229
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.7

Release files / spikecurate-0.1.0-py3-none-any.whl

Download URL spikecurate-0.1.0-py3-none-any.whl
Size 26.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5c3733b78d6659b11920cd90d26c1c325611db8738b9c7ec95e0ec42f190d4dd
BLAKE2b-256 checksum
How to use checksums
d9aabc9e22442f8ffeaf464a479db055c74f72a63aa8799484dfa4a5a54d25c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.7

Security for spikecurate 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page