Back to Claude Scientific Skills

API Reference (SpikeInterface)

skills/neuropixels-analysis/references/api_reference.md

2.46.07.2 KB
Original Source

API Reference (SpikeInterface)

Quick reference for the SpikeInterface functions used throughout this skill. Import with:

python
import spikeinterface.full as si
import spikeinterface.curation as sc
import spikeinterface.widgets as sw

All examples target SpikeInterface ≥ 0.104. Set global parallelization once:

python
si.set_global_job_kwargs(n_jobs=-1, chunk_duration="1s", progress_bar=True)

Loading

Inspect streams

python
stream_names, stream_ids = si.get_neo_streams("spikeglx", "/path/to/run_g0/")
# stream_names -> ['imec0.ap', 'imec0.lf', 'nidq']

Readers

python
si.read_spikeglx(folder_path, stream_name="imec0.ap", load_sync_channel=False)
si.read_openephys(folder_path, stream_name=None)
si.read_nwb(file_path)

Prefer stream_name (a value from get_neo_streams) over stream_id.

Recording introspection

python
recording.get_num_channels()
recording.get_total_duration()        # seconds
recording.get_sampling_frequency()    # Hz
recording.get_channel_locations()
recording.get_probe()
recording.frame_slice(start_frame, end_frame)

Preprocessing

python
si.highpass_filter(recording, freq_min=400.0)
si.bandpass_filter(recording, freq_min=300.0, freq_max=6000.0)
si.phase_shift(recording)                                  # ADC phase correction (NP 1.0)
si.detect_bad_channels(recording)                          # -> (bad_channel_ids, channel_labels)
recording.remove_channels(bad_channel_ids)
si.common_reference(recording, operator="median", reference="global")
si.highpass_spatial_filter(recording)                      # IBL-style destriping
si.get_noise_levels(recording, return_in_uV=False)
recording.save(folder="preprocessed/", format="binary")

detect_bad_channels returns a 2-tuple; always unpack both values.

Drift detection and motion correction

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

peaks = detect_peaks(rec, method="locally_exclusive", noise_levels=noise_levels,
                     detect_threshold=5, radius_um=50.0)
peak_locations = localize_peaks(rec, peaks, method="center_of_mass")

# One-call correction with a preset
rec_corrected = si.correct_motion(rec, preset="nonrigid_fast_and_accurate", folder="motion/")

Presets: rigid_fast, kilosort_like, nonrigid_accurate, nonrigid_fast_and_accurate (recommended default), dredge, dredge_fast.

Spike sorting

python
si.installed_sorters()
si.available_sorters()
si.get_default_sorter_params("kilosort4")

sorting = si.run_sorter(
    "kilosort4",            # sorter name
    recording,
    folder="ks4_output",   # NOT output_folder (deprecated)
    verbose=True,
    # sorter-specific kwargs, e.g. Th_universal=9, Th_learned=8, nblocks=5, batch_size=60000
)

# Containerized external sorters (no local install needed)
si.run_sorter("kilosort2_5", recording, folder="ks25/", docker_image=True)

# Read a sorter folder back
sorting = si.read_sorter_folder("ks4_output")

Sorting introspection:

python
sorting.unit_ids
sorting.get_total_num_spikes()
sorting.get_unit_spike_train(unit_id)
sorting.select_units(unit_ids)
sorting.to_spike_vector()

Postprocessing: SortingAnalyzer

python
analyzer = si.create_sorting_analyzer(
    sorting, recording,
    sparse=True,
    format="binary_folder",   # or "memory" / "zarr"
    folder="analyzer/",
)

# Extensions (order matters: random_spikes -> waveforms -> templates -> ...)
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("correlograms", window_ms=50.0, bin_ms=1.0)
analyzer.compute("unit_locations", method="monopolar_triangulation")
analyzer.compute("spike_locations", method="center_of_mass")
analyzer.compute("template_similarity")
analyzer.compute("principal_components", n_components=5, mode="by_channel_local")

# Or compute several at once
analyzer.compute(["random_spikes", "waveforms", "templates", "noise_levels"])

# Access extension data
analyzer.get_extension("quality_metrics").get_data()
analyzer.get_extension("templates").get_unit_template(unit_id, operator="average")

# Persist / reload / subset
si.load_sorting_analyzer("analyzer/")
analyzer.select_units(unit_ids, folder="analyzer_clean/", format="binary_folder")
analyzer.remove_units(unit_ids)

Quality metrics

python
metric_names = ["firing_rate", "presence_ratio", "snr", "isi_violation",
                "amplitude_cutoff", "amplitude_cv", "sliding_rp_violation"]
analyzer.compute("quality_metrics", metric_names=metric_names)
metrics = analyzer.get_extension("quality_metrics").get_data()

# Equivalent standalone helper
metrics = si.compute_quality_metrics(analyzer, metric_names=metric_names)

Common columns: snr, firing_rate, presence_ratio, amplitude_cutoff, isi_violations_ratio, isi_violations_count. PCA-based metrics (isolation_distance, l_ratio, d_prime, nn_hit_rate) require analyzer.compute("principal_components") first.

Curation

Threshold-based

python
query = "(amplitude_cutoff < 0.1) & (isi_violations_ratio < 0.5) & (presence_ratio > 0.9)"
good_unit_ids = metrics.query(query).index.values
clean = sorting.select_units(good_unit_ids)

Model-based (UnitRefine / Hugging Face)

python
import spikeinterface.curation as sc

labels = sc.model_based_label_units(
    sorting_analyzer=analyzer,
    repo_id="SpikeInterface/UnitRefine_noise_neural_classifier",
    trust_model=True,
)
# labels -> DataFrame with 'prediction' and 'probability' columns

# Load a model object explicitly (e.g. to inspect feature_names_in_)
model, model_info = sc.load_model(repo_id="SpikeInterface/toy_tetrode_model", trusted=["numpy.dtype"])

Manual edits

python
from spikeinterface.curation import CurationSorting
cur = CurationSorting(sorting)
cur.remove_units(noise_unit_ids)
sorting_curated = cur.sorting

Visualization (widgets)

python
sw.plot_probe_map(recording, with_channel_ids=True)
sw.plot_traces({"filtered": rec1, "cmr": rec2}, backend="matplotlib", clim=(-50, 50))
si.plot_drift_raster_map(peaks=peaks, peak_locations=peak_locations, recording=rec, clim=(-50, 50))
sw.plot_unit_waveforms(analyzer, unit_ids=[0])
sw.plot_unit_templates(analyzer, unit_ids=[0, 1, 2])
sw.plot_autocorrelograms(analyzer, unit_ids=[0])
sw.plot_amplitudes(analyzer, unit_ids=[0], plot_histograms=True)
sw.plot_unit_locations(analyzer)
si.plot_sorting_summary(analyzer, backend="sortingview")  # web-based viewer

See plotting_guide.md for publication-quality figure recipes.

Export

python
si.export_to_phy(analyzer, output_folder="phy_export/",
                 compute_pc_features=True, compute_amplitudes=True, copy_binary=True)
si.export_report(analyzer, "report/", format="png")

from spikeinterface.exporters import export_to_nwb
export_to_nwb(analyzer, "output.nwb")

si.read_phy("phy_export/")   # load Phy curation back

Note: export_to_phy / export_report take output_folder — this is correct and distinct from run_sorter/create_sorting_analyzer, which take folder.