Skill Tracer
Skills › Scientific Agent Skills › neuropixels-analysis

neuropixels-analysis

skill · 464 lines · MIT license · skills/neuropixels-analysis/SKILL.md

The facts

Its description

Analyzes Neuropixels extracellular recordings end-to-end with SpikeInterface. Covers loading SpikeGLX/Open Ephys/NWB data, preprocessing, drift/motion correction, Kilosort4 (and CPU) spike sorting, quality metrics, and unit curation (threshold-based, model-based UnitRefine, and AI-assisted visual review). Use when working with Neuropixels 1.0/2.0 recordings, spike sorting, or extracellular electrophysiology analysis.

The description the agent reads to decide when to use it.

From its settingsline 3

Runs scripts

python scripts/neuropixels_pipeline.py, scripts/compute_metrics.py, scripts/explore_recording.py, python scripts/explore_recording.py, scripts/preprocess_recording.py (first 5 of 14 lines)

Scripts the text names. Found by matching words, so treat them as pointers.

Found by matching wordsline 96 line 213 line 332 line 335 line 338

Files it mentions

references/PREPROCESSING.md, scripts/compute_metrics.py, references/AUTOMATED_CURATION.md, references/AI_CURATION.md, references/standard_workflow.md (first 5 of 14 lines)

Files the text names, such as ones to read or write. Found by matching words, so treat them as pointers.

Found by matching wordsline 121 line 213 line 214 line 270 line 378

Licence

MIT license, from the skill file

The terms its author shares it under, which let it be shown here.

From its settingsline 4 licence text

Other settings

compatibility: Requires Python 3.10+ with SpikeInterface, ProbeInterface, Neo, NumPy, SciPy, pandas, matplotlib, numba and scikit-learn. Optional sorters and models need separate dependencies and network access. metadata: name: ANTHROPIC_API_KEY

More settings at the top of the file, shown as written.

From its settingsline 5 line 6
Other files in this skill (18) Close

The text

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1---
2name: neuropixels-analysis
3description: Analyzes Neuropixels extracellular recordings end-to-end with SpikeInterface. Covers loading SpikeGLX/Open Ephys/NWB data, preprocessing, drift/motion correction, Kilosort4 (and CPU) spike sorting, quality metrics, and unit curation (threshold-based, model-based UnitRefine, and AI-assisted visual review). Use when working with Neuropixels 1.0/2.0 recordings, spike sorting, or extracellular electrophysiology analysis.
4license: MIT license
5compatibility: Requires Python 3.10+ with SpikeInterface, ProbeInterface, Neo, NumPy, SciPy, pandas, matplotlib, numba and scikit-learn. Optional sorters and models need separate dependencies and network access.
6metadata:
7 version: "2.6"
8 last-reviewed: "2026-10-01"
9 skill-author: K-Dense Inc.
10 openclaw:
11 primaryEnv: ANTHROPIC_API_KEY
12 envVars:
13 - name: ANTHROPIC_API_KEY
14 required: false
15 description: For optional Claude API calls.
16---
18# Neuropixels Data Analysis

Neuropixels Data Analysis

Raw lines 1 to 19
20## Overview
22Toolkit for analyzing Neuropixels high-density neural recordings using current best
23practices from [SpikeInterface](https://spikeinterface.readthedocs.io/), the Allen
24Institute, and the International Brain Laboratory (IBL). It covers the full workflow from
25raw data to reviewed, curated units. Targets SpikeInterface 0.105.0,
26ProbeInterface 0.4.0 and Neo 0.14.5 (reviewed 2026-10-01). Synthetic tests cover
27recording contracts, preprocessing, analyzers, metrics and exports; real acquisition
28files, native sorters, GPU execution and pretrained models remain illustrative.
30All examples use the real SpikeInterface API (`spikeinterface.full as si`) plus the
31companion curation module (`spikeinterface.curation as sc`). The skill ships runnable
32scripts in `scripts/` and a copy-and-edit template in `assets/` that implement this
33workflow directly on top of SpikeInterface — there is no separate package to install
34beyond the dependencies listed under [Installation](#installation).

Overview

Toolkit for analyzing Neuropixels high-density neural recordings using current best practices from SpikeInterface, the Allen Institute, and the International Brain Laboratory (IBL). It covers the full workflow from raw data to reviewed, curated units. Targets SpikeInterface 0.105.0, ProbeInterface 0.4.0 and Neo 0.14.5 (reviewed 2026-10-01). Synthetic tests cover recording contracts, preprocessing, analyzers, metrics and exports; real acquisition files, native sorters, GPU execution and pretrained models remain illustrative.

All examples use the real SpikeInterface API (spikeinterface.full as si) plus the companion curation module (spikeinterface.curation as sc). The skill ships runnable scripts in scripts/ and a copy-and-edit template in assets/ that implement this workflow directly on top of SpikeInterface — there is no separate package to install beyond the dependencies listed under Installation.

Raw lines 20 to 35
36## When to Use This Skill
38This skill should be used when:
39- Working with Neuropixels recordings (`.ap.bin`, `.lf.bin`, `.meta` files)
40- Loading data from SpikeGLX, Open Ephys, or NWB formats
41- Preprocessing neural recordings (filtering, common reference, bad-channel detection)
42- Detecting and correcting motion/drift
43- Running spike sorting (Kilosort4, SpykingCircus2, Mountainsort5, Tridesclous2)
44- Computing quality metrics (SNR, ISI violations, presence ratio, amplitude cutoff)
45- Curating units (threshold-based, model-based, or AI-assisted)
46- Creating visualizations and exporting to Phy or NWB

When to Use This Skill

This skill should be used when:

  • Working with Neuropixels recordings (.ap.bin, .lf.bin, .meta files)
  • Loading data from SpikeGLX, Open Ephys, or NWB formats
  • Preprocessing neural recordings (filtering, common reference, bad-channel detection)
  • Detecting and correcting motion/drift
  • Running spike sorting (Kilosort4, SpykingCircus2, Mountainsort5, Tridesclous2)
  • Computing quality metrics (SNR, ISI violations, presence ratio, amplitude cutoff)
  • Curating units (threshold-based, model-based, or AI-assisted)
  • Creating visualizations and exporting to Phy or NWB
Raw lines 36 to 47
48## Supported Hardware & Formats
50| Probe | Electrodes | Channels | Notes |
51|-------|-----------|----------|-------|
52| Neuropixels 1.0 | 960 | 384 | Use acquisition ADC timing metadata |
53| Neuropixels 2.0 (single) | 1280 | 384 | Verify part number and timing metadata |
54| Neuropixels 2.0 (4-shank) | 5120 | 384 | Multi-region recording |
56| Format | Extension | Reader |
57|--------|-----------|--------|
58| SpikeGLX | `.ap.bin`, `.lf.bin`, `.meta` | `si.read_spikeglx()` |
59| Open Ephys | `.continuous`, `.oebin` | `si.read_openephys()` |
60| NWB | `.nwb` | `si.read_nwb()` |

Supported Hardware & Formats

ProbeElectrodesChannelsNotes
Neuropixels 1.0960384Use acquisition ADC timing metadata
Neuropixels 2.0 (single)1280384Verify part number and timing metadata
Neuropixels 2.0 (4-shank)5120384Multi-region recording
FormatExtensionReader
SpikeGLX.ap.bin, .lf.bin, .metasi.read_spikeglx()
Open Ephys.continuous, .oebinsi.read_openephys()
NWB.nwbsi.read_nwb()
Raw lines 48 to 61
62## Quick Start
64### Import and configure parallel processing
66```python
67import spikeinterface.full as si
69# Global job kwargs are reused by all parallelizable steps
70si.set_global_job_kwargs(n_jobs=-1, chunk_duration="1s", progress_bar=True)
71```

Import and configure parallel processing

import spikeinterface.full as si

# Global job kwargs are reused by all parallelizable steps
si.set_global_job_kwargs(n_jobs=-1, chunk_duration="1s", progress_bar=True)
Raw lines 64 to 72
73### Loading data
75```python
76# Inspect available streams first
77stream_names, stream_ids = si.get_neo_streams("spikeglx", "/path/to/run_g0/")
78print(stream_names) # e.g. ['imec0.ap', 'imec0.lf', 'nidq']
80# SpikeGLX (most common) — select the AP stream by name
81recording = si.read_spikeglx("/path/to/run_g0/", stream_name="imec0.ap")
83# Open Ephys
84recording = si.read_openephys("/path/to/Record_Node_101/")
86# For quick iteration, slice the first 60 s
87fs = recording.get_sampling_frequency()
88recording_sub = recording.frame_slice(0, min(int(60 * fs), recording.get_num_samples()))
89```

Loading data

# Inspect available streams first
stream_names, stream_ids = si.get_neo_streams("spikeglx", "/path/to/run_g0/")
print(stream_names)  # e.g. ['imec0.ap', 'imec0.lf', 'nidq']

# SpikeGLX (most common) — select the AP stream by name
recording = si.read_spikeglx("/path/to/run_g0/", stream_name="imec0.ap")

# Open Ephys
recording = si.read_openephys("/path/to/Record_Node_101/")

# For quick iteration, slice the first 60 s
fs = recording.get_sampling_frequency()
recording_sub = recording.frame_slice(0, min(int(60 * fs), recording.get_num_samples()))
Raw lines 73 to 90
91### Full pipeline (bundled script)
93The repository ships an end-to-end pipeline built on SpikeInterface:
95```bash
96python scripts/neuropixels_pipeline.py /path/to/spikeglx/data output/ --sorter kilosort4 --curation allen
97```
99It performs load → preprocess → drift check → optional motion correction → sorting →
100postprocessing → quality metrics → curation → export. Phy and the report retain all
101units for review with curation labels; `sorting_curated/` contains selected good units. Read the steps below to run them
102interactively or customize the pipeline.

Full pipeline (bundled script)

The repository ships an end-to-end pipeline built on SpikeInterface:

python scripts/neuropixels_pipeline.py /path/to/spikeglx/data output/ --sorter kilosort4 --curation allen

It performs load → preprocess → drift check → optional motion correction → sorting → postprocessing → quality metrics → curation → export. Phy and the report retain all units for review with curation labels; sorting_curated/ contains selected good units. Read the steps below to run them interactively or customize the pipeline.

Raw lines 91 to 103
Runs code python scripts/neuropixels_pipeline.py :96
104## Standard Analysis Workflow

Standard Analysis Workflow

Raw lines 104 to 105
106### 1. Preprocessing
108Validate AP stream, calibration, channel order, probe geometry and segment boundaries
109first. This filter/reference chain is not full IBL destriping. Apply ADC timing
110correction only from valid acquisition metadata and reference each shank separately:
112```python
113rec = si.highpass_filter(recording, freq_min=400.0)
114bad_channel_ids, channel_labels = si.detect_bad_channels(rec)
115rec = rec.remove_channels(bad_channel_ids)
116rec = si.phase_shift(rec) # Requires valid inter_sample_shift property.
117rec = si.common_reference(rec, operator="median", reference="global") # Single shank only.
118```
120For multiple shanks, use the bundled `reference_by_shank` helper described in
121[PREPROCESSING.md](references/PREPROCESSING.md). Trace arrays are samples × channels;
122`get_traces(return_in_uV=True)` needs calibrated gain/offset. The bundled commands
123reject uncalibrated, empty or multisegment input instead of guessing.
125Cache preprocessed data when storage and repeated use justify it:
127```python
128rec = rec.save(folder="preprocessed/", format="binary")
129```

1. Preprocessing

Validate AP stream, calibration, channel order, probe geometry and segment boundaries first. This filter/reference chain is not full IBL destriping. Apply ADC timing correction only from valid acquisition metadata and reference each shank separately:

rec = si.highpass_filter(recording, freq_min=400.0)
bad_channel_ids, channel_labels = si.detect_bad_channels(rec)
rec = rec.remove_channels(bad_channel_ids)
rec = si.phase_shift(rec)  # Requires valid inter_sample_shift property.
rec = si.common_reference(rec, operator="median", reference="global")  # Single shank only.

For multiple shanks, use the bundled reference_by_shank helper described in PREPROCESSING.md. Trace arrays are samples × channels; get_traces(return_in_uV=True) needs calibrated gain/offset. The bundled commands reject uncalibrated, empty or multisegment input instead of guessing.

Cache preprocessed data when storage and repeated use justify it:

rec = rec.save(folder="preprocessed/", format="binary")
Raw lines 106 to 130
Reads a file references/PREPROCESSING.md :121
131### 2. Check and correct drift
133Always inspect drift before sorting:
135```python
136from spikeinterface.sortingcomponents.peak_detection import detect_peaks
137from spikeinterface.sortingcomponents.peak_localization import localize_peaks
139noise_levels = si.get_noise_levels(rec, return_in_uV=False)
140peaks = detect_peaks(rec, method='locally_exclusive', method_kwargs={'noise_levels': noise_levels, 'detect_threshold': 5, 'radius_um': 50.0})
141peak_locations = localize_peaks(rec, peaks, method="center_of_mass")
143# Visualize the drift raster
144si.plot_drift_raster_map(peaks=peaks, peak_locations=peak_locations,
145 recording=rec, clim=(-50, 50))
146```
148Apply correction if needed (presets: `rigid_fast`, `kilosort_like`,
149`nonrigid_accurate`, `nonrigid_fast_and_accurate`, `dredge`, `dredge_fast`, `medicine`):
151```python
152rec_corrected = si.correct_motion(rec, preset="nonrigid_fast_and_accurate", folder="motion/")
153```

2. Check and correct drift

Always inspect drift before sorting:

from spikeinterface.sortingcomponents.peak_detection import detect_peaks
from spikeinterface.sortingcomponents.peak_localization import localize_peaks

noise_levels = si.get_noise_levels(rec, return_in_uV=False)
peaks = detect_peaks(rec, method='locally_exclusive', method_kwargs={'noise_levels': noise_levels, 'detect_threshold': 5, 'radius_um': 50.0})
peak_locations = localize_peaks(rec, peaks, method="center_of_mass")

# Visualize the drift raster
si.plot_drift_raster_map(peaks=peaks, peak_locations=peak_locations,
                         recording=rec, clim=(-50, 50))

Apply correction if needed (presets: rigid_fast, kilosort_like, nonrigid_accurate, nonrigid_fast_and_accurate, dredge, dredge_fast, medicine):

rec_corrected = si.correct_motion(rec, preset="nonrigid_fast_and_accurate", folder="motion/")
Raw lines 131 to 154
155### 3. Spike sorting
157The calls below are illustrative until tested on the target recording and sorter.
158Choose one drift-correction stage: externally corrected input uses
159`do_correction=False` for Kilosort 2.5/3/4, or `apply_motion_correction=False`
160for Spykingcircus2. These flags match SpikeInterface 0.105.0; inspect sorter
161parameters when using another release. Uncorrected input can use sorter defaults.
162A spread of peak depths across neurons is not a temporal drift estimate. The bundled
163pipeline estimates/corrects motion when requested; inspect its saved motion output.
166```python
167# Kilosort4 (external install; CUDA recommended, CPU mode also supported)
168sorting = si.run_sorter("kilosort4", rec_corrected, folder="ks4_output", do_correction=False)
170# CPU alternatives (SC2/TDC2 need SI optional dependencies; MS5 needs mountainsort5)
171sorting = si.run_sorter("spykingcircus2", rec_corrected, folder="sc2_output", apply_motion_correction=False)
172sorting = si.run_sorter("tridesclous2", rec_corrected, folder="tdc2_output")
173sorting = si.run_sorter("mountainsort5", rec_corrected, folder="ms5_output")
175# External sorters can run in containers without local install
176sorting = si.run_sorter("kilosort2_5", rec_corrected, folder="ks25_output", docker_image=True, do_correction=False)
178print(si.installed_sorters())
179```
181> Note: `run_sorter` uses the `folder=` argument. The older `output_folder=` is deprecated.

3. Spike sorting

The calls below are illustrative until tested on the target recording and sorter. Choose one drift-correction stage: externally corrected input uses do_correction=False for Kilosort 2.5/3/4, or apply_motion_correction=False for Spykingcircus2. These flags match SpikeInterface 0.105.0; inspect sorter parameters when using another release. Uncorrected input can use sorter defaults. A spread of peak depths across neurons is not a temporal drift estimate. The bundled pipeline estimates/corrects motion when requested; inspect its saved motion output.

# Kilosort4 (external install; CUDA recommended, CPU mode also supported)
sorting = si.run_sorter("kilosort4", rec_corrected, folder="ks4_output", do_correction=False)

# CPU alternatives (SC2/TDC2 need SI optional dependencies; MS5 needs mountainsort5)
sorting = si.run_sorter("spykingcircus2", rec_corrected, folder="sc2_output", apply_motion_correction=False)
sorting = si.run_sorter("tridesclous2", rec_corrected, folder="tdc2_output")
sorting = si.run_sorter("mountainsort5", rec_corrected, folder="ms5_output")

# External sorters can run in containers without local install
sorting = si.run_sorter("kilosort2_5", rec_corrected, folder="ks25_output", docker_image=True, do_correction=False)

print(si.installed_sorters())
Note: run_sorter uses the folder= argument. The older output_folder= is deprecated.
Raw lines 155 to 182
183### 4. Postprocessing
185```python
186analyzer = si.create_sorting_analyzer(sorting, rec_corrected, sparse=True,
187 format="binary_folder", folder="analyzer/")
189analyzer.compute("random_spikes", method="uniform", max_spikes_per_unit=500)
190analyzer.compute("waveforms", ms_before=1.0, ms_after=2.0)
191analyzer.compute("templates", operators=["average", "std"])
192analyzer.compute("noise_levels")
193analyzer.compute("spike_amplitudes")
194analyzer.compute("amplitude_scalings")
195analyzer.compute("correlograms", window_ms=50.0, bin_ms=1.0)
196analyzer.compute("unit_locations", method="monopolar_triangulation")
197analyzer.compute("template_similarity")
199metric_names = ["firing_rate", "presence_ratio", "snr", "isi_violation", "amplitude_cutoff"]
200analyzer.compute("quality_metrics", metric_names=metric_names)
201metrics = analyzer.get_extension("quality_metrics").get_data()
202```

4. Postprocessing

analyzer = si.create_sorting_analyzer(sorting, rec_corrected, sparse=True,
                                      format="binary_folder", folder="analyzer/")

analyzer.compute("random_spikes", method="uniform", max_spikes_per_unit=500)
analyzer.compute("waveforms", ms_before=1.0, ms_after=2.0)
analyzer.compute("templates", operators=["average", "std"])
analyzer.compute("noise_levels")
analyzer.compute("spike_amplitudes")
analyzer.compute("amplitude_scalings")
analyzer.compute("correlograms", window_ms=50.0, bin_ms=1.0)
analyzer.compute("unit_locations", method="monopolar_triangulation")
analyzer.compute("template_similarity")

metric_names = ["firing_rate", "presence_ratio", "snr", "isi_violation", "amplitude_cutoff"]
analyzer.compute("quality_metrics", metric_names=metric_names)
metrics = analyzer.get_extension("quality_metrics").get_data()
Raw lines 183 to 203
204### 5. Curation by metric thresholds
206```python
207# Example screen, not a guarantee of single-neuron isolation.
208query = "(amplitude_cutoff < 0.1) & (isi_violations_ratio < 0.5) & (presence_ratio > 0.9)"
209good_unit_ids = metrics.query(query).index.values
210```
212For reusable local screening with `allen` / legacy `ibl` / `strict` presets, use the
214[references/AUTOMATED_CURATION.md](references/AUTOMATED_CURATION.md) for details and the
215Bombcell / UnitMatch tools. The legacy `ibl` preset is not the IBL classifier.
216Missing/nonfinite metrics remain `unsorted`, and boundary values fail the strict
217thresholds. All bundled entry points now use the same screening criteria.

5. Curation by metric thresholds

# Example screen, not a guarantee of single-neuron isolation.
query = "(amplitude_cutoff < 0.1) & (isi_violations_ratio < 0.5) & (presence_ratio > 0.9)"
good_unit_ids = metrics.query(query).index.values

For reusable local screening with allen / legacy ibl / strict presets, use the bundled scripts/compute_metrics.py. See references/AUTOMATED_CURATION.md for details and the Bombcell / UnitMatch tools. The legacy ibl preset is not the IBL classifier. Missing/nonfinite metrics remain unsorted, and boundary values fail the strict thresholds. All bundled entry points now use the same screening criteria.

Raw lines 204 to 218
219### 6. Model-based curation (UnitRefine)
221SpikeInterface can apply pretrained machine-learning classifiers from Hugging Face via the
222`spikeinterface.curation` module. The UnitRefine models were trained on real Neuropixels
223data (V1, SC, ALM). The public model metadata currently requests SI 0.102.0 and
224scikit-learn 1.4.2, with empty metric-parameter metadata; compatibility with this
2250.105.0 environment is untested. Inspect model requirements/features first:
227```python
228import spikeinterface.curation as sc
230# 1) noise vs neural
231noise_labels = sc.model_based_label_units(
232 sorting_analyzer=analyzer,
233 repo_id="SpikeInterface/UnitRefine_noise_neural_classifier",
234 trust_model=True,
235 enforce_metric_params=True,
237neural = analyzer.remove_units(noise_labels[noise_labels["prediction"] == "noise"].index)
239# 2) single-unit (sua) vs multi-unit (mua) on the surviving units
240sua_mua_labels = sc.model_based_label_units(
241 sorting_analyzer=neural,
242 repo_id="SpikeInterface/UnitRefine_sua_mua_classifier",
243 trust_model=True,
244 enforce_metric_params=True,
246```
248Each call returns a DataFrame with `prediction` and `probability` (confidence) per unit.
249`trust_model=True` (or an explicit `trusted=[...]` list) is required to load the `.skops`
250model — only load models from sources you trust. Parameter enforcement cannot
251validate training settings absent from model metadata. Models trained on other brain
252areas/datasets may not transfer; validate against a manually labelled subset.

6. Model-based curation (UnitRefine)

SpikeInterface can apply pretrained machine-learning classifiers from Hugging Face via the spikeinterface.curation module. The UnitRefine models were trained on real Neuropixels data (V1, SC, ALM). The public model metadata currently requests SI 0.102.0 and scikit-learn 1.4.2, with empty metric-parameter metadata; compatibility with this 0.105.0 environment is untested. Inspect model requirements/features first:

import spikeinterface.curation as sc

# 1) noise vs neural
noise_labels = sc.model_based_label_units(
    sorting_analyzer=analyzer,
    repo_id="SpikeInterface/UnitRefine_noise_neural_classifier",
    trust_model=True,
    enforce_metric_params=True,
)
neural = analyzer.remove_units(noise_labels[noise_labels["prediction"] == "noise"].index)

# 2) single-unit (sua) vs multi-unit (mua) on the surviving units
sua_mua_labels = sc.model_based_label_units(
    sorting_analyzer=neural,
    repo_id="SpikeInterface/UnitRefine_sua_mua_classifier",
    trust_model=True,
    enforce_metric_params=True,
)

Each call returns a DataFrame with prediction and probability (confidence) per unit. trust_model=True (or an explicit trusted=[...] list) is required to load the .skops model — only load models from sources you trust. Parameter enforcement cannot validate training settings absent from model metadata. Models trained on other brain areas/datasets may not transfer; validate against a manually labelled subset.

Raw lines 219 to 253
254### 7. AI-assisted curation (for uncertain units)
256When running inside an agent such as Cursor or Claude Code, the agent can directly inspect
257waveform/correlogram plots and suggest review questions — no API setup required. Generate plots
258and ask the agent to assess isolation quality.
260For programmatic vision-model access, **read API keys from the environment — never hardcode
261credentials in analysis scripts** (they leak into version control and logs):
263```python
264import os
265from anthropic import Anthropic
267client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"]) # set this in your shell, not in code
268```
270See [references/AI_CURATION.md](references/AI_CURATION.md) for the full pattern (rendering a
271unit summary image, building the prompt, and retaining the response as advisory evidence).

7. AI-assisted curation (for uncertain units)

When running inside an agent such as Cursor or Claude Code, the agent can directly inspect waveform/correlogram plots and suggest review questions — no API setup required. Generate plots and ask the agent to assess isolation quality.

For programmatic vision-model access, read API keys from the environment — never hardcode credentials in analysis scripts (they leak into version control and logs):

import os
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])  # set this in your shell, not in code

See references/AI_CURATION.md for the full pattern (rendering a unit summary image, building the prompt, and retaining the response as advisory evidence).

Raw lines 254 to 272
Reads a file references/AI_CURATION.md :270
273### 8. Export results
275```python
276# Keep only good units, then export
277analyzer_clean = analyzer.select_units(good_unit_ids, folder="analyzer_clean/", format="binary_folder")
279# Phy for manual review
280si.export_to_phy(analyzer_clean, output_folder="phy_export/",
281 compute_pc_features=True, compute_amplitudes=True)
283# Figures report
284si.export_report(analyzer_clean, "report/", format="png")
286# Metrics table
287metrics.to_csv("quality_metrics.csv")
288```
290SpikeInterface 0.105.0 has no `export_to_nwb` exporter. Use the source-specific
291[NeuroConv NWBConverter workflow](https://neuroconv.readthedocs.io/en/main/user_guide/nwbconverter.html),
292with session metadata, electrodes, calibration and aligned unit times; validate
293the resulting NWB file. This optional conversion was not executed here.
295SpikeInterface 0.105.0 has an observed `read_phy` bug for exported nonnumeric
296unit IDs (`np.isnan` TypeError). Phy export preserves `cluster_si_unit_ids.tsv`;
297keep that mapping and use a validated importer/fixed release for string-ID
298readback. Numeric-ID Phy export/reload was tested on synthetic data.

8. Export results

# Keep only good units, then export
analyzer_clean = analyzer.select_units(good_unit_ids, folder="analyzer_clean/", format="binary_folder")

# Phy for manual review
si.export_to_phy(analyzer_clean, output_folder="phy_export/",
                 compute_pc_features=True, compute_amplitudes=True)

# Figures report
si.export_report(analyzer_clean, "report/", format="png")

# Metrics table
metrics.to_csv("quality_metrics.csv")

SpikeInterface 0.105.0 has no export_to_nwb exporter. Use the source-specific NeuroConv NWBConverter workflow, with session metadata, electrodes, calibration and aligned unit times; validate the resulting NWB file. This optional conversion was not executed here.

SpikeInterface 0.105.0 has an observed read_phy bug for exported nonnumeric unit IDs (np.isnan TypeError). Phy export preserves cluster_si_unit_ids.tsv; keep that mapping and use a validated importer/fixed release for string-ID readback. Numeric-ID Phy export/reload was tested on synthetic data.

Raw lines 273 to 299
300## Common Pitfalls and Best Practices
3021. **Inspect drift** before and after correction; no universal displacement cutoff proves quality.
3032. **Use acquisition timing metadata** for ADC phase correction; do not assume NP2 needs none.
3043. **Budget disk space** before caching with `rec.save(folder=...)`; retain original data.
3054. **Check sorter requirements**; Kilosort4 supports CPU but CUDA is recommended at this scale.
3065. **Review uncertain units** — automated/model-based curation is a starting point, not a verdict.
3076. **Combine approaches** — thresholds for clear cases, model/AI for borderline units.
3087. **Document thresholds and model repo IDs** for reproducibility.
3098. **Export to Phy** for critical experiments — human oversight is valuable.

Common Pitfalls and Best Practices

  1. Inspect drift before and after correction; no universal displacement cutoff proves quality.
  2. Use acquisition timing metadata for ADC phase correction; do not assume NP2 needs none.
  3. Budget disk space before caching with rec.save(folder=...); retain original data.
  4. Check sorter requirements; Kilosort4 supports CPU but CUDA is recommended at this scale.
  5. Review uncertain units — automated/model-based curation is a starting point, not a verdict.
  6. Combine approaches — thresholds for clear cases, model/AI for borderline units.
  7. Document thresholds and model repo IDs for reproducibility.
  8. Export to Phy for critical experiments — human oversight is valuable.
Raw lines 300 to 310
311## Key Parameters to Adjust

Key Parameters to Adjust

Raw lines 311 to 312
313### Preprocessing
314- `freq_min`: highpass cutoff (300–400 Hz typical)
315- `detect_bad_channels`: returns `(bad_channel_ids, channel_labels)`

Preprocessing

  • freq_min: highpass cutoff (300–400 Hz typical)
  • detect_bad_channels: returns (bad_channel_ids, channel_labels)
Raw lines 313 to 316
317### Motion Correction
318- `preset`: `nonrigid_fast_and_accurate` (balanced), `nonrigid_accurate` (severe drift), `dredge` (validate on the experiment)

Motion Correction

  • preset: nonrigid_fast_and_accurate (balanced), nonrigid_accurate (severe drift), dredge (validate on the experiment)
Raw lines 317 to 319
320### Spike Sorting (Kilosort4)
321- `batch_size`: samples per batch (60000 default)
322- `nblocks`: drift blocks (increase for long, drifty recordings)
323- `Th_universal` / `Th_learned`: detection thresholds (lower = more spikes)

Spike Sorting (Kilosort4)

  • batch_size: samples per batch (60000 default)
  • nblocks: drift blocks (increase for long, drifty recordings)
  • Th_universal / Th_learned: detection thresholds (lower = more spikes)
Raw lines 320 to 324
325### Quality Metrics
326- `snr`: signal-to-noise cutoff (3–5 typical)
327- `isi_violations_ratio`: refractory violations (0.01–0.5)
328- `presence_ratio`: recording coverage (0.5–0.95)

Quality Metrics

  • snr: signal-to-noise cutoff (3–5 typical)
  • isi_violations_ratio: refractory violations (0.01–0.5)
  • presence_ratio: recording coverage (0.5–0.95)
Raw lines 325 to 329
330## Bundled Resources

Bundled Resources

Raw lines 330 to 331
332### scripts/explore_recording.py
333Quick inspection of a recording (streams, channels, duration, bad channels):
334```bash
335python scripts/explore_recording.py /path/to/data
336```

scripts/explore_recording.py

Quick inspection of a recording (streams, channels, duration, bad channels):

python scripts/explore_recording.py /path/to/data
Raw lines 332 to 337
Runs code scripts/explore_recording.py :332
Runs code python scripts/explore_recording.py :335
338### scripts/preprocess_recording.py
339Automated preprocessing:
340```bash
341python scripts/preprocess_recording.py /path/to/data --output preprocessed/
342```

scripts/preprocess_recording.py

Automated preprocessing:

python scripts/preprocess_recording.py /path/to/data --output preprocessed/
Raw lines 338 to 343
Runs code scripts/preprocess_recording.py :338
Runs code python scripts/preprocess_recording.py :341
344### scripts/run_sorting.py
345Run spike sorting:
346```bash
347python scripts/run_sorting.py preprocessed/ --sorter kilosort4 --output sorting/
348```

scripts/run_sorting.py

Run spike sorting:

python scripts/run_sorting.py preprocessed/ --sorter kilosort4 --output sorting/
Raw lines 344 to 349
Runs code scripts/run_sorting.py :344
Runs code python scripts/run_sorting.py :347
350### scripts/compute_metrics.py
351Compute quality metrics and apply curation:
352```bash
353python scripts/compute_metrics.py sorting/ preprocessed/ --output metrics/ --curation allen
354```

scripts/compute_metrics.py

Compute quality metrics and apply curation:

python scripts/compute_metrics.py sorting/ preprocessed/ --output metrics/ --curation allen
Raw lines 350 to 355
Runs code scripts/compute_metrics.py :350
Runs code python scripts/compute_metrics.py :353
356### scripts/export_to_phy.py
357Export to Phy for manual curation:
358```bash
359python scripts/export_to_phy.py metrics/analyzer --output phy_export/
360```

scripts/export_to_phy.py

Export to Phy for manual curation:

python scripts/export_to_phy.py metrics/analyzer --output phy_export/
Raw lines 356 to 361
Runs code scripts/export_to_phy.py :356
Runs code python scripts/export_to_phy.py :359
362### scripts/neuropixels_pipeline.py
363Complete end-to-end pipeline (see [Quick Start](#full-pipeline-bundled-script)).

scripts/neuropixels_pipeline.py

Complete end-to-end pipeline (see Quick Start).

Raw lines 362 to 364
Runs code scripts/neuropixels_pipeline.py :362
365### assets/analysis_template.py
366Complete, editable analysis template. Copy and customize:
367```bash
368cp assets/analysis_template.py my_analysis.py
369# Copy scripts/ alongside it as neuropixels_scripts/ (template helper path)
370# Edit the PARAMETERS section, then run
371python my_analysis.py
372```

assets/analysis_template.py

Complete, editable analysis template. Copy and customize:

cp assets/analysis_template.py my_analysis.py
# Copy scripts/ alongside it as neuropixels_scripts/ (template helper path)
# Edit the PARAMETERS section, then run
python my_analysis.py
Raw lines 365 to 373
Runs code python my_analysis.py :371
374## Detailed Reference Guides
376| Topic | Reference |
377|-------|-----------|
378| Full workflow | [references/standard_workflow.md](references/standard_workflow.md) |
379| API reference (SpikeInterface) | [references/api_reference.md](references/api_reference.md) |
380| Plotting guide | [references/plotting_guide.md](references/plotting_guide.md) |
381| Preprocessing | [references/PREPROCESSING.md](references/PREPROCESSING.md) |
382| Spike sorting | [references/SPIKE_SORTING.md](references/SPIKE_SORTING.md) |
383| Motion correction | [references/MOTION_CORRECTION.md](references/MOTION_CORRECTION.md) |
384| Quality metrics | [references/QUALITY_METRICS.md](references/QUALITY_METRICS.md) |
385| Automated & model-based curation | [references/AUTOMATED_CURATION.md](references/AUTOMATED_CURATION.md) |
386| AI-assisted curation | [references/AI_CURATION.md](references/AI_CURATION.md) |
387| Waveform analysis | [references/ANALYSIS.md](references/ANALYSIS.md) |

Detailed Reference Guides

TopicReference
Full workflowreferences/standard_workflow.md
API reference (SpikeInterface)references/api_reference.md
Plotting guidereferences/plotting_guide.md
Preprocessingreferences/PREPROCESSING.md
Spike sortingreferences/SPIKE_SORTING.md
Motion correctionreferences/MOTION_CORRECTION.md
Quality metricsreferences/QUALITY_METRICS.md
Automated & model-based curationreferences/AUTOMATED_CURATION.md
AI-assisted curationreferences/AI_CURATION.md
Waveform analysisreferences/ANALYSIS.md
Raw lines 374 to 388
389## Installation
391Requires Python ≥ 3.10. Using [uv](https://docs.astral.sh/uv/) is recommended.
393```bash
394# Core packages (SpikeInterface bundles the curation/model tooling)
395uv pip install "spikeinterface==0.105.0" "probeinterface==0.4.0" "neo==0.14.5" numpy scipy pandas matplotlib numba scikit-learn
397# Spike sorters
398uv pip install kilosort # Separate environment; follow upstream PyTorch/CUDA setup
399# Spykingcircus2/Tridesclous2: install SI sorting extras in the chosen sorter environment
400uv pip install mountainsort5 # Mountainsort5 (CPU)
402# Model-based curation (UnitRefine) downloads from Hugging Face
403uv pip install "huggingface_hub" skops
405# Optional: AI-assisted visual curation
406uv pip install anthropic
408# Optional: IBL tools and Bombcell
409uv pip install ibl-neuropixel ibllib bombcell
410```
412The tested core environment used Python 3.13 and the pins above; native sorters,
413models and optional tool installations were not executed. Pin and record their
414versions separately. SpikeInterface 0.105.0 still requires `zarr>=2.18,<3`.

Installation

Requires Python ≥ 3.10. Using uv is recommended.

# Core packages (SpikeInterface bundles the curation/model tooling)
uv pip install "spikeinterface==0.105.0" "probeinterface==0.4.0" "neo==0.14.5" numpy scipy pandas matplotlib numba scikit-learn

# Spike sorters
uv pip install kilosort          # Separate environment; follow upstream PyTorch/CUDA setup
# Spykingcircus2/Tridesclous2: install SI sorting extras in the chosen sorter environment
uv pip install mountainsort5     # Mountainsort5 (CPU)

# Model-based curation (UnitRefine) downloads from Hugging Face
uv pip install "huggingface_hub" skops

# Optional: AI-assisted visual curation
uv pip install anthropic

# Optional: IBL tools and Bombcell
uv pip install ibl-neuropixel ibllib bombcell

The tested core environment used Python 3.13 and the pins above; native sorters, models and optional tool installations were not executed. Pin and record their versions separately. SpikeInterface 0.105.0 still requires zarr>=2.18,<3.

Raw lines 389 to 415
416## Project Structure
418```
419project/
420├── raw_data/
421│ └── recording_g0/
422│ └── recording_g0_imec0/
423│ ├── recording_g0_t0.imec0.ap.bin
424│ └── recording_g0_t0.imec0.ap.meta
425├── preprocessed/ # Saved preprocessed recording
426├── motion/ # Motion estimation results
427├── sorting_output/ # Spike sorter output
428├── analyzer/ # SortingAnalyzer (waveforms, metrics)
429├── phy_export/ # For manual curation
430├── ai_curation/ # AI analysis reports
431└── results/
432 ├── quality_metrics.csv
433 ├── curation_labels.json
434 └── output.nwb
435```

Project Structure

project/
├── raw_data/
│   └── recording_g0/
│       └── recording_g0_imec0/
│           ├── recording_g0_t0.imec0.ap.bin
│           └── recording_g0_t0.imec0.ap.meta
├── preprocessed/           # Saved preprocessed recording
├── motion/                 # Motion estimation results
├── sorting_output/         # Spike sorter output
├── analyzer/               # SortingAnalyzer (waveforms, metrics)
├── phy_export/             # For manual curation
├── ai_curation/            # AI analysis reports
└── results/
    ├── quality_metrics.csv
    ├── curation_labels.json
    └── output.nwb
Raw lines 416 to 436
437## Additional Resources
439- **SpikeInterface Docs**: https://spikeinterface.readthedocs.io/
440- **Neuropixels Tutorial**: https://spikeinterface.readthedocs.io/en/stable/how_to/analyze_neuropixels.html
441- **Model-based Curation Tutorial**: https://spikeinterface.readthedocs.io/en/stable/tutorials/curation/plot_1_automated_curation.html
442- **UnitRefine Models (Hugging Face)**: https://huggingface.co/SpikeInterface
443- **Kilosort4 GitHub**: https://github.com/MouseLand/Kilosort
444- **IBL Neuropixel Tools**: https://github.com/int-brain-lab/ibl-neuropixel
445- **Allen Institute ecephys**: https://github.com/AllenInstitute/ecephys_spike_sorting
446- **Bombcell (Automated QC)**: https://github.com/Julie-Fabre/bombcell
447- **Awesome Neuropixels**: https://github.com/Julie-Fabre/awesome_neuropixels

Additional Resources

  • SpikeInterface Docs: https://spikeinterface.readthedocs.io/
  • Neuropixels Tutorial: https://spikeinterface.readthedocs.io/en/stable/how_to/analyze_neuropixels.html
  • Model-based Curation Tutorial: https://spikeinterface.readthedocs.io/en/stable/tutorials/curation/plot_1_automated_curation.html
  • UnitRefine Models (Hugging Face): https://huggingface.co/SpikeInterface
  • Kilosort4 GitHub: https://github.com/MouseLand/Kilosort
  • IBL Neuropixel Tools: https://github.com/int-brain-lab/ibl-neuropixel
  • Allen Institute ecephys: https://github.com/AllenInstitute/ecephys_spike_sorting
  • Bombcell (Automated QC): https://github.com/Julie-Fabre/bombcell
  • Awesome Neuropixels: https://github.com/Julie-Fabre/awesome_neuropixels
Raw lines 437 to 448
Boilerplate, lines 449 to 464. The same text appears in 125 other files here. Close
449## Citing Scientific Agent Skills
451This skill is part of Scientific Agent Skills by K-Dense. If it materially contributed to a
452manuscript, report, presentation, or code release, add the paper to the references or
453software section and tell the user you did so:
455> Kassis, T., Agarwal, V., He, Y., Patel, D., & Brueckner, A. M. (2026). Scientific Agent
456> Skills: A Library of Procedural Knowledge for Research Agents. arXiv:2609.00065.
457> https://doi.org/10.48550/arXiv.2609.00065
459Always cite the current version. The DOI and https://arxiv.org/abs/2609.00065 resolve to the
460latest arXiv version, so never append a version suffix such as `v1`. When network access is
461available, fetch https://arxiv.org/abs/2609.00065 (or
462http://export.arxiv.org/api/query?id_list=2609.00065) before writing the reference and take
463the author list, year, and version from that record. If the record lists a journal reference
464or publisher DOI, cite the published version instead.

From K-Dense-AI/scientific-agent-skills at 5f2bc03, 2026-10-26. Not read by a model yet. Summary and techniques by Claude Opus 5.5 on 2026-11-06.