Jump to: Quickstart · Concepts learning track · Tutorials and notebooks · Paper examples · nstat.extras helpfiles · Reference · Ecosystem · Citation
📖 New here? Start with the 5-minute intro — a friendly tour of the toolbox with runnable snippets, the
nstat.extrasopt-in bridges, and the paper-example gallery.🎓 Learning the science? The Concepts & Background guide teaches microelectrode recordings, the LFP, point-process GLMs, goodness-of-fit, and decoding — with figures, runnable examples, and cited literature.
🛠 Other ways in: the runnable
00_getting_started.ipynbnotebook; six end-to-end tutorial scripts inexamples/tutorials/; the five paper examples inexamples/paper/; and the reference notebooks innotebooks/.
nSTAT-python is the Python port of the
nSTAT toolbox
(Cajigas, Malik & Brown 2012).
It implements point-process generalized linear models (GLMs) with stimulus,
history, and ensemble terms; the
time-rescaling KS test
for goodness-of-fit (per-neuron and population-level via
population_time_rescale, Tao et al. 2018);
adaptive decoding (PPAF / PPHF / Kalman / EM); and continuous-signal analysis
for LFP / EEG / ECoG (multitaper spectra, spectrograms, Kalman filtering). An
opt-in nstat.extras namespace adds bridges to
Dynamax (EM-trained state-space models), replay_trajectory_classification
(clusterless decoding), Neo / pynapple / pynwb (data I/O), and
validation oracles.
Although designed for neural signal processing, nSTAT works as a generic toolkit for analyzing any discrete or continuous time series. From the lab: Neuroscience Statistics Research Laboratory and RESToRe Lab.
Quickstart
python -m pip install nstat-toolbox
nstat-install --download-example-data always # ~150 MB figshare dataset
import numpy as np
from nstat import nspikeTrain
times = np.sort(np.random.default_rng(0).uniform(0, 1, 100))
st = nspikeTrain(times, name="neuron1", sampleRate=1000,
minTime=0.0, maxTime=1.0)
print(f"{st.n_spikes} spikes")
From source (development install):
git clone git@github.com:cajigaslab/nSTAT-python.git
cd nSTAT-python
python -m pip install -e .[dev]
nstat-install --download-example-data always
pytest -q && python tools/paper_examples/build_gallery.py
The example dataset is also reachable from Python:
from nstat.data_manager import ensure_example_data
data_dir = ensure_example_data(download=True)
Performance — Numba opt-in (v0.5.6+)
For the two hot per-step filter paths, an opt-in Numba JIT closes the last performance gaps vs. MATLAB:
python -m pip install nstat-toolbox[numba]
Once Numba is installed, DecodingAlgorithms.PPDecodeFilterLinear and
DecodingAlgorithms.kalman_filter route through JIT'd kernels
transparently — 14× and 20× faster than MATLAB respectively on the
maintainer's M2 Max baseline. Default install is unchanged; the JIT
path is dual-mode tested in CI to preserve bit-equivalence against
the gold-fixture suite.
docs/parity/runbook.md documents the 10-path performance baseline
and the workflow for re-timing after a code change.
Concepts learning track
A 15-page didactic track that teaches the neuroscience and statistics behind the API. Each page builds intuition first, then shows the matching nSTAT objects and a runnable snippet, and cites the primary literature. The concepts index hosts the full path; the table below is the direct map.
| # | Page | What you'll learn |
|---|---|---|
| 1 | Microelectrode recordings: spikes & the LFP | What an electrode measures; the broadband → spikes + LFP split; single vs multi-unit; spike sorting. |
| 2 | Spike trains & point-process GLMs | Spike trains as point processes, the conditional intensity function, log-link GLMs with stimulus + history + ensemble terms. |
| 3 | The LFP & spectral analysis | Multitaper power spectra, spectrograms, the time–bandwidth trade-off, Kalman filtering. |
| 4 | Goodness-of-fit & decoding | Time-rescaling KS, population GOF, PPAF / PPHF decoding, clusterless decoding from waveform features. |
| 5 | State-space models & EM | The across-trial SSGLM (forward–backward smoother); EM-trained latent state-space models with multi-restart selection. |
| 6 | Network connectivity | Ensemble GLM coupling, cross-correlograms, Granger; why correlation is not connection (the common-input trap). |
| 7 | Uncertainty & confidence intervals | Fisher information, CIs on coefficients and firing rates, credible bands on a decode. |
| 8 | Rhythmic firing & the clinical microelectrode | Tremor cells modelled as a periodic-covariate GLM; the beta-band biomarker that guides adaptive DBS. |
| 9 | Population geometry | A PCA sketch of population activity; neural manifolds; pointers to GPFA and dimensionality reduction. |
| 10 | From filters to deep learning | What carries over from the PPAF to RNN / LSTM / transformer decoders, and what changes. |
| 11 | Further study | Topics nSTAT does not implement, with primary references for each. |
| 12 | Pitfalls & FAQ | Common mistakes that quietly invalidate an analysis — bin width, multiple comparisons, missing history, multitaper choices, reproducibility & seeds. |
| 13 | Self-check | Per-topic quizzes plus cross-cutting synthesis questions; answers collapsible. |
| 14 | Glossary | Plain-language definitions of every term, with HTML anchors for deep-linking from any page. |
| 15 | Annotated bibliography | Every cited reference with a one-line note on why it matters for nSTAT users. |
Every topical page opens with a "Glossary jumps" box that deep-links into the glossary entries it uses.
Tutorials and notebooks
Runnable, end-to-end lessons organized by depth:
| File | What you'll do |
|---|---|
notebooks/00_getting_started.ipynb |
The executable mirror of the 5-minute intro: build a spike train, fit a GLM, run the KS test, decode a stimulus with the PPAF — all in one notebook. |
examples/tutorials/encoding_to_goodness_of_fit.py |
Encoding → GLM → time-rescaling KS, with a correct-vs-wrong model contrast. |
examples/tutorials/model_comparison.py |
AIC / BIC + KS contrasts on nested GLMs, with Fisher-information confidence intervals on every coefficient. |
examples/tutorials/decoding_ppaf.py |
Decode a hidden stimulus from a population with the point-process adaptive filter; RMSE drops with population size. |
examples/tutorials/network_coupling.py |
Recover known asymmetric excite/inhibit wiring from two simulated neurons via the cross-correlogram and a coupling GLM. |
examples/tutorials/clinical_microelectrode_walkthrough.py |
A simulated tremor cell: encode → KS check → beta-band spectrum → PPAF phase decode. |
examples/tutorials/place_cell_walkthrough.py |
Capstone on real hippocampal place-cell data: encode → check → decode, with the honest lesson that a model can decode well yet still fail goodness-of-fit. |
examples/tutorials/Tutorial_MicroelectrodeToDecoding.ipynb |
Notebook-format guided tour spanning microelectrode signals → spikes → multitaper spectra → GLM → GOF → decoding. |
Reference notebooks (MATLAB-help ports) live under
notebooks/ and the
"By concept" crosswalk
in the Example Index maps each concepts page to the notebooks that
demonstrate it.
🖼 Browse rendered notebook figures on GitHub:
docs/notebook_galleries/— every notebook'sFigureTrackeroutput, regenerated bymake regen-notebook-galleriesand drift-checked in CI. Each gallery links back to its source.ipynb.
Paper examples
The five canonical examples from Cajigas, Malik & Brown (2012), each reproduced as a self-contained Python script with a generated figure gallery.
Regenerate the gallery metadata after editing any paper-example script:
python tools/paper_examples/build_gallery.py
| Example | Thumbnail | What question it answers | Run command | Links |
|---|---|---|---|---|
| Example 01 | Do mEPSCs follow constant vs piecewise Poisson firing under Mg2+ washout? | python examples/paper/example01_mepsc_poisson.py |
Script · Figures | |
| Example 02 | How do explicit whisker stimulus and spike history improve thalamic GLM fits? | python examples/paper/example02_whisker_stimulus_thalamus.py |
Script · Figures | |
| Example 03 | How do PSTH and SSGLM capture within-trial and across-trial dynamics? | python examples/paper/example03_psth_and_ssglm.py |
Script · Figures | |
| Example 04 | Which receptive-field basis (Gaussian vs Zernike) better fits place cells? | python examples/paper/example04_place_cells_continuous_stimulus.py |
Script · Figures | |
| Example 05 | How well do adaptive/hybrid point-process filters decode stimulus and reach state? | python examples/paper/example05_decoding_ppaf_pphf.py |
Script · Figures | |
| Example 06 | How does a tensor-product B-spline Poisson GLM recover a known 2-D place field, and how do its rate and second-order diagnostics compare to an LGCP? | python examples/paper/example06_place_fields_glm_basis.py |
Script · Figures | |
| Example 07 | Can the Bartlett spectrum and wave-peak detector recover the speed and direction of a known planar wave embedded in a multivariate Hawkes triggering matrix? | python examples/paper/example07_spatiotemporal_hawkes_waves.py |
Script · Figures | |
| Example 08 | Does a B-spline Poisson GLM trained on real hippocampal place cells produce a held-out spatial pair-correlation inside the inhomogeneous global-rank envelope, and a population rescaled-time ACF inside the Bartlett band? | python examples/paper/example08_real_place_cells.py |
Script · Figures |
Expanded paper-example index and figure gallery: docs/paper_examples.md.
The figshare paper dataset is distributed separately from the Git repository:
DOI 10.6084/m9.figshare.4834640.v3
(nstat-install --download-example-data always fetches it; NSTAT_OFFLINE=1
forces offline mode).
Plot-style policy (modern readability vs strict-reproduction legacy):
from nstat.plot_style import set_plot_style
set_plot_style('modern') # default
set_plot_style('legacy') # strict paper reproduction
nstat.extras helpfiles
Opt-in bridges (nstat.extras.*) to libraries in the modern Python
systems-neuroscience stack. Each has a dedicated narrative helpfile under
docs/extras/ covering install, intended use, gotchas, and
runnable snippets. Install via the optional-dep group; install the lightweight
groups at once with pip install nstat-toolbox[all-extras] (this is not every
group: latents, numba, clusterless, spatial-gp, hawkes, dpp and
dynamax are excluded by design — install them individually).
| Bridge | What it does | Helpfile | Optional dep |
|---|---|---|---|
nstat.extras.em.dynamax_bridge |
Dynamax-trained (JAX) linear-Gaussian / point-process / hybrid state-space EM — an opt-in alternative to the native MATLAB-mirror DecodingAlgorithms.KF_EM / PP_EM / PPLFP_EM (mPPCO_EM). Held-out predictive log-likelihood + multi-restart selection (canonical-gauge identifiability). |
em_dynamax | [dynamax] (pulls JAX ~200 MB) |
nstat.extras.decoding.clusterless_bridge |
Clusterless marked point-process decoding (no spike sorting) + trajectory-type classification — the modern descendant of nSTAT's PPAF / PPHF filters (Denovellis et al. 2021). | decoding_clusterless | [clusterless] (pulls JAX ~200 MB) |
nstat.extras.spatial |
Spatial / spatiotemporal point processes: LGCP rate maps with credible bands (Laplace), inhomogeneous second-order goodness-of-fit (g/K/L, F/G/J, global-rank envelope), and the discrete-time-rescaling KS correction (Haslinger-Pipa-Brown 2010). Spatiotemporal tier: space-time kernel intensity + Kronecker-Laplace LGCP with credible bands, space-time inhomogeneous K/pair-correlation + global-rank envelope, space-time Hawkes/ETAS branching EM, LGCP-background Cox-Hawkes, and a modulated-renewal (conditional-ISI) CIF. Pure NumPy/SciPy core; optional Hawkes/DPP/GP bridges. |
spatial_point_processes | core: none; [spatial-gp] / [hawkes] / [dpp] (optional) |
nstat.extras.interop.neo |
Vendor-format I/O via Neo — Spike2 / NEX / Blackrock / Plexon / TDT / NWB. | interop_neo | [neo] |
nstat.extras.interop.nwb |
BRAIN-Initiative NWB:N standard reader via pynwb. | interop_nwb | [nwb] |
nstat.extras.interop.pynapple |
Time-series + epoch math via pynapple, NWB-native. | interop_pynapple | [pynapple] |
nstat.extras.validation.nemos_bridge |
JAX Poisson-GLM cross-validation oracle via NeMoS. | validation_nemos | [nemos] |
nstat.extras.validation.pykalman_bridge |
Pure-NumPy Kalman cross-validation reference via pykalman. | validation_pykalman | [test-parity] |
nstat.extras.validation.statsmodels_bridge |
Poisson GLM IRLS cross-validation oracle (~1e-9 agreement) via statsmodels. | validation_statsmodels | [test-parity] |
nstat.extras.metrics.spike_distances |
ISI / SPIKE-distance spike-train metrics via PySpike. | metrics_spike_distances | [metrics] |
The interactive extras_summary.html
landing page has the same content as bigger cards with code snippets.
Reference
Full rendered documentation is on GitHub Pages:
| Page | What you'll find |
|---|---|
| 5-minute intro | The friendly, illustrated tour with runnable snippets |
| API reference | Every public symbol, auto-generated from NumPy-style docstrings |
| Class definitions | Method catalog for each MATLAB-faithful core class |
| Paper-aligned toolbox map | Crosswalk between the 2012 paper's workflow categories (object model, fitting/assessment, simulation, decoding) and the Python API |
nstat.extras summary |
Per-bridge cards with install commands, status, and runnable snippets |
| Example Index | Visual gallery of every runnable example, including a "By concept" crosswalk back to the concepts pages |
| What's New | Per-release change summaries |
RELEASE_NOTES.md |
Full changelog (start here when upgrading) |
| Methods roadmap | What's queued for upcoming releases |
RELEASE_READINESS.md |
Release procedure for maintainers; note that pushing a v* tag triggers the PyPI publish workflow (publish.yml) |
| Parity audit | MATLAB ↔ Python class & method parity verification |
Ecosystem
The MATLAB reference toolbox lives in a separate repository:
github.com/cajigaslab/nSTAT. It retains
the original MATLAB classes, the helpfiles/helptoc.xml index, and the
.mlx example workflows.
For ecosystem peers nSTAT does not wrap (spike sorting, calcium imaging,
deep-learning decoders), recommended alternatives — with rationale in
parity/integration_opportunities.md:
- SpikeInterface — spike sorting (nSTAT consumes pre-sorted data).
- Elephant — overlapping spike-train statistics; Neo-typed.
- ssqueezepy — wavelet synchrosqueezing; planned
nstat.extras.spectral.
nSTAT will benefit from your involvement. Open issues / PRs at github.com/cajigaslab/nSTAT-python.
Citation
If you use nSTAT in your work, please cite the toolbox paper:
Cajigas I, Malik WQ, Brown EN. nSTAT: Open-source neural spike train analysis toolbox for Matlab. Journal of Neuroscience Methods 211: 245–264, Nov. 2012. doi:10.1016/j.jneumeth.2012.08.009 · PMID 22981419
Method references for every page in the concepts track are in the annotated bibliography. The paper-example dataset has its own figshare DOI. nSTAT-python is distributed under the GPL-2.0 license.
Metadata
Release files for nstat-toolbox 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| nstat_toolbox-0.6.0.tar.gz | 768.8 kB | With provenance | Details for nstat_toolbox-0.6.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| nstat_toolbox-0.6.0-py3-none-any.whl | Python 3 | none | any | Details for nstat_toolbox-0.6.0-py3-none-any.whl |
Total release size: 1.4 MB
Release files / nstat_toolbox-0.6.0.tar.gz
| Download URL | nstat_toolbox-0.6.0.tar.gz |
|---|---|
| Size | 768.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e8d81df68150fd04b4bf51ce6e1f1fbd19a2ac96ed6eed7151032ebc797b799b
|
|
BLAKE2b-256 checksum How to use checksums |
dd1dfb173dbf83ea528f20e1a826216137793f4fe77737b33bc8a08113991b38
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency logRelease files / nstat_toolbox-0.6.0-py3-none-any.whl
| Download URL | nstat_toolbox-0.6.0-py3-none-any.whl |
|---|---|
| Size | 588.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a5a418b42773c0cd82f401d1baaa53717cb287eb0494f2012571fc2e679fb402
|
|
BLAKE2b-256 checksum How to use checksums |
5f17c61a1cd072a922257039906a344ab3e85504af7d5813c873feede669a84d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency logSecurity for nstat-toolbox 0.6.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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for nstat_toolbox-0.6.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency logA 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.