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
- Multi-channel detection: spikes were detected using a combined signal across 40 channels
- Waveform extraction: each detected spike is captured as a (time × channel) snippet
- Autoencoder feature learning: a small autoencoder compressed each waveform snippet into a learned feature vector
- Clustering: spikes are grouped in the learned feature space (k-means clustering)
- Template construction: the cluster best matching the ground-truth neuron is averaged into a template.
- Template matching: the template is correlated against the full recording to find more matching spikes.
- 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 signaldetect_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 vectortrain_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 neurontemplate_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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56d4f83a694260a8ab98d8acb4e66c8a0bb81572976981e3a6a342cc83d78bce
|
|
| MD5 |
7724f33ec28e1d25583ef4bbfe31ea45
|
|
| BLAKE2b-256 |
fae71c413742ef72e6dd9e228c1859d1cc06c9fc381b634486be86b3499af65a
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
637b70cc2e327f757d695d861698bc3825fbc1a977ba5179a707d912c793666c
|
|
| MD5 |
126712a473150ec17c81cd5ac577b004
|
|
| BLAKE2b-256 |
688b1164d6a3071e04a995e17bbc00e16d8c4bdcba065d1a7aed03f28f5698e7
|