Skip to main content

A closed-loop spike sorting pipeline with autoencoder feature learning

Project description

pulse-sort

A closed loop spike sorting pipeline built on in-vivo Neuropixel recordings which includes multi-channel detection, an autoencoder, and iterations to make the pipeline close-looped. I built this project to extend my original project with a basic single-channel pipeline: fund-spike-sort.

Data

In this project I used real in-vivo data from the Kampff Lab ground-truth dataset (cell c37). This data came from a 384-channel Neuropixel recording, giving 601 ground-truth spikes from a sample cortical neuron.

Pipeline

  1. Multi-channel detection: spikes were detected using a combined signal across 40 channels
  2. Waveform extraction: each detected spike is captured as a (time × channel) snippet
  3. Autoencoder feature learning: a small autoencoder compressed each waveform snippet into a learned feature vector
  4. Clustering: spikes are grouped in the learned feature space (k-means clustering)
  5. Template construction: the cluster best matching the ground-truth neuron is averaged into a template.
  6. Template matching: the template is correlated against the full recording to find more matching spikes.
  7. Iterative refinement: the template is repeatedly rebuilt from its own matches, and fed back into the next round of matching.

Installation

git clone git@github.com:rrajmanna/pulse-sort.git
cd pulse-sort
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Usage

Each stage of the pipeline is in src/ as a function, which I ran step by step in the notebooks under notebooks/.

Detection (src/detection.py)

  • bandpass_filter: isolates the frequency range where spikes are (300-6000 Hz)
  • combined_signal: merges multiple channels into one detection signal
  • detect_spikes: locates spike times using thresholds

Waveform extraction (src/waveforms.py)

  • extract_waveforms: builds multi-channel (time × channel) snippet around each detected spike

Feature learning (src/autoencoder.py)

  • WaveformAutoencoder: an autoencoder that compresses waveform snippets into a learned feature vector
  • train_autoencoder: trains the autoencoder on extracted waveforms

I chose a latent dimension of 8 after checking 2-32 dimensions and comparing reconstruction loss:

Clustering and templates (src/templates.py)

  • build_template: averages a cluster's waveforms into a template for one neuron
  • template_match: correlates a template against the recording to find matching spikes

Iterative refinement (src/refine.py)

  • iterative_refine: iteratively rebuilds the template from its own best matches

I tested many refinement methods like naive rebuild, top-K selection, fixed candidate pool, and the final anchored approach which I kept in the code. All of them converged, but none of them improved on single-pass template matching for this dataset (limitation).

Results

Autoencoder features outperformed PCA at the same dimensions:

Method Best cluster purity
PCA (8 components) 53.9%
Autoencoder (8 latent dims) 64.5%

Spatial template for the neuron:

Precision/recall by pipeline stage:

Method Precision Recall
Raw multi-channel detection 13.5% 59.9%
Autoencoder + clustering 64.5% 39.9%
Template matching (0.6) 37.4% 42.6%

Acknowledgments

Ground-truth data from the Kampff Lab paired recordings dataset. Built with PyTorch, scikit-learn, NumPy, and SciPy.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pulse_sort-0.1.0.tar.gz (4.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pulse_sort-0.1.0-py3-none-any.whl (4.1 kB view details)

Uploaded Python 3

File details

Details for the file pulse_sort-0.1.0.tar.gz.

File metadata

  • Download URL: pulse_sort-0.1.0.tar.gz
  • Upload date:
  • Size: 4.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for pulse_sort-0.1.0.tar.gz
Algorithm Hash digest
SHA256 56d4f83a694260a8ab98d8acb4e66c8a0bb81572976981e3a6a342cc83d78bce
MD5 7724f33ec28e1d25583ef4bbfe31ea45
BLAKE2b-256 fae71c413742ef72e6dd9e228c1859d1cc06c9fc381b634486be86b3499af65a

See more details on using hashes here.

File details

Details for the file pulse_sort-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pulse_sort-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 4.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for pulse_sort-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 637b70cc2e327f757d695d861698bc3825fbc1a977ba5179a707d912c793666c
MD5 126712a473150ec17c81cd5ac577b004
BLAKE2b-256 688b1164d6a3071e04a995e17bbc00e16d8c4bdcba065d1a7aed03f28f5698e7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page