nstat-toolbox 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. nstat_toolbox-0.4.1/PKG-INFO +278 -0
  2. nstat_toolbox-0.4.1/README.md +224 -0
  3. nstat_toolbox-0.4.1/nstat/ConfidenceInterval.py +5 -0
  4. nstat_toolbox-0.4.1/nstat/ConfigColl.py +5 -0
  5. nstat_toolbox-0.4.1/nstat/CovColl.py +5 -0
  6. nstat_toolbox-0.4.1/nstat/Covariate.py +5 -0
  7. nstat_toolbox-0.4.1/nstat/DecodingAlgorithms.py +5 -0
  8. nstat_toolbox-0.4.1/nstat/FitResSummary.py +5 -0
  9. nstat_toolbox-0.4.1/nstat/FitResult.py +5 -0
  10. nstat_toolbox-0.4.1/nstat/SignalObj.py +5 -0
  11. nstat_toolbox-0.4.1/nstat/TrialConfig.py +5 -0
  12. nstat_toolbox-0.4.1/nstat/__init__.py +139 -0
  13. nstat_toolbox-0.4.1/nstat/_spike_train_impl.py +727 -0
  14. nstat_toolbox-0.4.1/nstat/_trial_config_impl.py +369 -0
  15. nstat_toolbox-0.4.1/nstat/analysis.py +1411 -0
  16. nstat_toolbox-0.4.1/nstat/cif.py +1299 -0
  17. nstat_toolbox-0.4.1/nstat/class_fidelity.py +119 -0
  18. nstat_toolbox-0.4.1/nstat/compat/__init__.py +14 -0
  19. nstat_toolbox-0.4.1/nstat/compat/matlab/__init__.py +18 -0
  20. nstat_toolbox-0.4.1/nstat/confidence_interval.py +320 -0
  21. nstat_toolbox-0.4.1/nstat/core.py +2170 -0
  22. nstat_toolbox-0.4.1/nstat/data/__init__.py +1 -0
  23. nstat_toolbox-0.4.1/nstat/data/manifest.json +29 -0
  24. nstat_toolbox-0.4.1/nstat/data_manager.py +343 -0
  25. nstat_toolbox-0.4.1/nstat/datasets.py +102 -0
  26. nstat_toolbox-0.4.1/nstat/decoding.py +58 -0
  27. nstat_toolbox-0.4.1/nstat/decoding_algorithms.py +7941 -0
  28. nstat_toolbox-0.4.1/nstat/errors.py +41 -0
  29. nstat_toolbox-0.4.1/nstat/events.py +119 -0
  30. nstat_toolbox-0.4.1/nstat/extras/__init__.py +88 -0
  31. nstat_toolbox-0.4.1/nstat/extras/_lazy.py +102 -0
  32. nstat_toolbox-0.4.1/nstat/extras/decoding/__init__.py +23 -0
  33. nstat_toolbox-0.4.1/nstat/extras/decoding/clusterless_bridge.py +380 -0
  34. nstat_toolbox-0.4.1/nstat/extras/em/__init__.py +20 -0
  35. nstat_toolbox-0.4.1/nstat/extras/em/dynamax_bridge.py +1792 -0
  36. nstat_toolbox-0.4.1/nstat/extras/interop/__init__.py +20 -0
  37. nstat_toolbox-0.4.1/nstat/extras/interop/neo.py +129 -0
  38. nstat_toolbox-0.4.1/nstat/extras/interop/nwb.py +167 -0
  39. nstat_toolbox-0.4.1/nstat/extras/interop/pynapple.py +164 -0
  40. nstat_toolbox-0.4.1/nstat/extras/metrics/__init__.py +14 -0
  41. nstat_toolbox-0.4.1/nstat/extras/metrics/spike_distances.py +108 -0
  42. nstat_toolbox-0.4.1/nstat/extras/validation/__init__.py +16 -0
  43. nstat_toolbox-0.4.1/nstat/extras/validation/nemos_bridge.py +157 -0
  44. nstat_toolbox-0.4.1/nstat/extras/validation/pykalman_bridge.py +237 -0
  45. nstat_toolbox-0.4.1/nstat/extras/validation/statsmodels_bridge.py +163 -0
  46. nstat_toolbox-0.4.1/nstat/fit.py +2454 -0
  47. nstat_toolbox-0.4.1/nstat/glm.py +205 -0
  48. nstat_toolbox-0.4.1/nstat/history.py +332 -0
  49. nstat_toolbox-0.4.1/nstat/install.py +204 -0
  50. nstat_toolbox-0.4.1/nstat/linear_cif.py +480 -0
  51. nstat_toolbox-0.4.1/nstat/matlab_engine.py +444 -0
  52. nstat_toolbox-0.4.1/nstat/notebook_data.py +87 -0
  53. nstat_toolbox-0.4.1/nstat/notebook_fidelity_audit.py +167 -0
  54. nstat_toolbox-0.4.1/nstat/notebook_figures.py +120 -0
  55. nstat_toolbox-0.4.1/nstat/notebook_parity.py +179 -0
  56. nstat_toolbox-0.4.1/nstat/nspikeTrain.py +5 -0
  57. nstat_toolbox-0.4.1/nstat/nstColl.py +10 -0
  58. nstat_toolbox-0.4.1/nstat/nstat_install.py +12 -0
  59. nstat_toolbox-0.4.1/nstat/paper_example_catalog.py +122 -0
  60. nstat_toolbox-0.4.1/nstat/paper_examples.py +446 -0
  61. nstat_toolbox-0.4.1/nstat/paper_examples_full.py +794 -0
  62. nstat_toolbox-0.4.1/nstat/paper_figures.py +813 -0
  63. nstat_toolbox-0.4.1/nstat/paper_gallery.py +201 -0
  64. nstat_toolbox-0.4.1/nstat/parity_report.py +337 -0
  65. nstat_toolbox-0.4.1/nstat/plot_style.py +141 -0
  66. nstat_toolbox-0.4.1/nstat/signal.py +105 -0
  67. nstat_toolbox-0.4.1/nstat/simulation.py +102 -0
  68. nstat_toolbox-0.4.1/nstat/simulators.py +257 -0
  69. nstat_toolbox-0.4.1/nstat/simulink_fidelity.py +89 -0
  70. nstat_toolbox-0.4.1/nstat/spikes.py +37 -0
  71. nstat_toolbox-0.4.1/nstat/trial.py +2997 -0
  72. nstat_toolbox-0.4.1/nstat/zernike.py +118 -0
  73. nstat_toolbox-0.4.1/nstat_toolbox.egg-info/PKG-INFO +278 -0
  74. nstat_toolbox-0.4.1/nstat_toolbox.egg-info/SOURCES.txt +142 -0
  75. nstat_toolbox-0.4.1/nstat_toolbox.egg-info/dependency_links.txt +1 -0
  76. nstat_toolbox-0.4.1/nstat_toolbox.egg-info/entry_points.txt +3 -0
  77. nstat_toolbox-0.4.1/nstat_toolbox.egg-info/requires.txt +58 -0
  78. nstat_toolbox-0.4.1/nstat_toolbox.egg-info/top_level.txt +1 -0
  79. nstat_toolbox-0.4.1/pyproject.toml +126 -0
  80. nstat_toolbox-0.4.1/setup.cfg +4 -0
  81. nstat_toolbox-0.4.1/tests/test_analysis_pipeline.py +48 -0
  82. nstat_toolbox-0.4.1/tests/test_api_surface.py +46 -0
  83. nstat_toolbox-0.4.1/tests/test_audit_bug_fixes.py +139 -0
  84. nstat_toolbox-0.4.1/tests/test_ci_extras_functional.py +119 -0
  85. nstat_toolbox-0.4.1/tests/test_class_contracts.py +82 -0
  86. nstat_toolbox-0.4.1/tests/test_class_fidelity_audit.py +95 -0
  87. nstat_toolbox-0.4.1/tests/test_cleanroom_boundary.py +54 -0
  88. nstat_toolbox-0.4.1/tests/test_curriculum_parity.py +196 -0
  89. nstat_toolbox-0.4.1/tests/test_datasets.py +23 -0
  90. nstat_toolbox-0.4.1/tests/test_decoding_algorithms_fidelity.py +157 -0
  91. nstat_toolbox-0.4.1/tests/test_diff_against_matlab.py +146 -0
  92. nstat_toolbox-0.4.1/tests/test_docs_surface.py +64 -0
  93. nstat_toolbox-0.4.1/tests/test_example01_parity.py +418 -0
  94. nstat_toolbox-0.4.1/tests/test_example02_parity.py +512 -0
  95. nstat_toolbox-0.4.1/tests/test_example03_parity.py +661 -0
  96. nstat_toolbox-0.4.1/tests/test_example04_parity.py +469 -0
  97. nstat_toolbox-0.4.1/tests/test_example05_parity.py +421 -0
  98. nstat_toolbox-0.4.1/tests/test_expanded_coverage.py +508 -0
  99. nstat_toolbox-0.4.1/tests/test_extras_docs.py +178 -0
  100. nstat_toolbox-0.4.1/tests/test_extras_examples.py +120 -0
  101. nstat_toolbox-0.4.1/tests/test_fitresult_diagnostics.py +128 -0
  102. nstat_toolbox-0.4.1/tests/test_function_contracts.py +113 -0
  103. nstat_toolbox-0.4.1/tests/test_helpfile_freshness.py +172 -0
  104. nstat_toolbox-0.4.1/tests/test_install_and_compat.py +98 -0
  105. nstat_toolbox-0.4.1/tests/test_install_cli.py +70 -0
  106. nstat_toolbox-0.4.1/tests/test_intro_page.py +106 -0
  107. nstat_toolbox-0.4.1/tests/test_linear_cif.py +292 -0
  108. nstat_toolbox-0.4.1/tests/test_matlab_audit_xref.py +72 -0
  109. nstat_toolbox-0.4.1/tests/test_matlab_engine.py +229 -0
  110. nstat_toolbox-0.4.1/tests/test_matlab_gold_fixtures.py +1129 -0
  111. nstat_toolbox-0.4.1/tests/test_matlab_reference.py +73 -0
  112. nstat_toolbox-0.4.1/tests/test_matlab_symbol_surface.py +22 -0
  113. nstat_toolbox-0.4.1/tests/test_network_tutorial_builder.py +36 -0
  114. nstat_toolbox-0.4.1/tests/test_notebook_artifact_contracts.py +43 -0
  115. nstat_toolbox-0.4.1/tests/test_notebook_changed_topics.py +42 -0
  116. nstat_toolbox-0.4.1/tests/test_notebook_ci_groups.py +109 -0
  117. nstat_toolbox-0.4.1/tests/test_notebook_data.py +51 -0
  118. nstat_toolbox-0.4.1/tests/test_notebook_fidelity_audit.py +99 -0
  119. nstat_toolbox-0.4.1/tests/test_notebook_parity_notes.py +54 -0
  120. nstat_toolbox-0.4.1/tests/test_notebook_surface.py +62 -0
  121. nstat_toolbox-0.4.1/tests/test_nspiketrain_fidelity.py +105 -0
  122. nstat_toolbox-0.4.1/tests/test_paper_example_scripts.py +85 -0
  123. nstat_toolbox-0.4.1/tests/test_paper_figure_assets.py +52 -0
  124. nstat_toolbox-0.4.1/tests/test_paper_gallery_docs.py +69 -0
  125. nstat_toolbox-0.4.1/tests/test_parity_manifest.py +139 -0
  126. nstat_toolbox-0.4.1/tests/test_parity_report.py +41 -0
  127. nstat_toolbox-0.4.1/tests/test_population_time_rescale.py +133 -0
  128. nstat_toolbox-0.4.1/tests/test_pyproject_consistency.py +217 -0
  129. nstat_toolbox-0.4.1/tests/test_readme_examples_catalog.py +65 -0
  130. nstat_toolbox-0.4.1/tests/test_readme_links.py +227 -0
  131. nstat_toolbox-0.4.1/tests/test_readme_nstatpaperexamples.py +32 -0
  132. nstat_toolbox-0.4.1/tests/test_release_check.py +21 -0
  133. nstat_toolbox-0.4.1/tests/test_repo_layout.py +12 -0
  134. nstat_toolbox-0.4.1/tests/test_signalobj_fidelity.py +173 -0
  135. nstat_toolbox-0.4.1/tests/test_simulators_fidelity.py +44 -0
  136. nstat_toolbox-0.4.1/tests/test_simulink_fidelity_audit.py +110 -0
  137. nstat_toolbox-0.4.1/tests/test_time_rescale_oracle.py +196 -0
  138. nstat_toolbox-0.4.1/tests/test_time_rescale_vs_nstat.py +207 -0
  139. nstat_toolbox-0.4.1/tests/test_trial_fidelity.py +163 -0
  140. nstat_toolbox-0.4.1/tests/test_trial_plotting_surface.py +42 -0
  141. nstat_toolbox-0.4.1/tests/test_v030_methods.py +281 -0
  142. nstat_toolbox-0.4.1/tests/test_version_sync.py +119 -0
  143. nstat_toolbox-0.4.1/tests/test_workflow_fidelity.py +275 -0
  144. nstat_toolbox-0.4.1/tests/test_zernike.py +50 -0
@@ -0,0 +1,278 @@
1
+ Metadata-Version: 2.4
2
+ Name: nstat-toolbox
3
+ Version: 0.4.1
4
+ Summary: Python port of the nSTAT toolbox
5
+ Author: Cajigas Lab
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: numpy>=1.24
9
+ Requires-Dist: scipy>=1.10
10
+ Requires-Dist: matplotlib>=3.7
11
+ Requires-Dist: sympy>=1.13
12
+ Requires-Dist: PyYAML>=6.0
13
+ Requires-Dist: nbformat>=5.10
14
+ Requires-Dist: nbclient>=0.10
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=8.0; extra == "dev"
17
+ Requires-Dist: scikit-image>=0.22; extra == "dev"
18
+ Requires-Dist: sphinx>=8.0; extra == "dev"
19
+ Requires-Dist: sphinx-rtd-theme>=3.0; extra == "dev"
20
+ Requires-Dist: myst-parser>=4.0; extra == "dev"
21
+ Requires-Dist: packaging>=23.0; extra == "dev"
22
+ Provides-Extra: spikeinterface
23
+ Provides-Extra: neo
24
+ Requires-Dist: neo>=0.13; extra == "neo"
25
+ Requires-Dist: quantities>=0.15; extra == "neo"
26
+ Provides-Extra: nwb
27
+ Requires-Dist: pynwb>=2.8; extra == "nwb"
28
+ Provides-Extra: pynapple
29
+ Requires-Dist: pynapple>=0.7; extra == "pynapple"
30
+ Provides-Extra: metrics
31
+ Requires-Dist: pyspike>=0.8; extra == "metrics"
32
+ Provides-Extra: nemos
33
+ Requires-Dist: nemos>=0.2; extra == "nemos"
34
+ Provides-Extra: dynamax
35
+ Requires-Dist: dynamax>=0.1; extra == "dynamax"
36
+ Provides-Extra: test-parity
37
+ Requires-Dist: nemos>=0.2; extra == "test-parity"
38
+ Requires-Dist: pykalman>=0.11; extra == "test-parity"
39
+ Requires-Dist: statsmodels>=0.15; extra == "test-parity"
40
+ Requires-Dist: nitime>=0.12; extra == "test-parity"
41
+ Provides-Extra: clusterless
42
+ Requires-Dist: replay_trajectory_classification>=1.4; extra == "clusterless"
43
+ Provides-Extra: deep-learning
44
+ Provides-Extra: all-extras
45
+ Requires-Dist: neo>=0.13; extra == "all-extras"
46
+ Requires-Dist: quantities>=0.15; extra == "all-extras"
47
+ Requires-Dist: pynwb>=2.8; extra == "all-extras"
48
+ Requires-Dist: pynapple>=0.7; extra == "all-extras"
49
+ Requires-Dist: pyspike>=0.8; extra == "all-extras"
50
+ Requires-Dist: nemos>=0.2; extra == "all-extras"
51
+ Requires-Dist: pykalman>=0.11; extra == "all-extras"
52
+ Requires-Dist: statsmodels>=0.15; extra == "all-extras"
53
+ Requires-Dist: nitime>=0.12; extra == "all-extras"
54
+
55
+ # nSTAT-python
56
+
57
+ **Neural Spike Train Analysis Toolbox for Python**
58
+
59
+ [![test-and-build](https://github.com/cajigaslab/nSTAT-python/actions/workflows/ci.yml/badge.svg)](https://github.com/cajigaslab/nSTAT-python/actions/workflows/ci.yml)
60
+
61
+ > 📖 **New here?** Start with the
62
+ > [**5-minute intro**](https://cajigaslab.github.io/nSTAT-python/intro.html) —
63
+ > a friendly tour of the toolbox with runnable snippets, the
64
+ > `nstat.extras` opt-in bridges, and the paper-example gallery.
65
+
66
+ `nSTAT-python` is a Python port of the [nSTAT](https://github.com/cajigaslab/nSTAT)
67
+ open-source neural spike train analysis toolbox. It implements a range of models and
68
+ algorithms for neural spike train data analysis, with a focus on point-process
69
+ generalized linear models (GLMs), model fitting, model-order analysis, and adaptive
70
+ decoding. In addition to point-process algorithms, nSTAT also provides tools for
71
+ Gaussian signals — from correlation analysis to the Kalman filter — applicable to
72
+ continuous neural signals such as LFP, EEG, and ECoG.
73
+
74
+ One of nSTAT's key strengths is point-process generalized linear models for spike
75
+ train signals that provide a formal statistical framework for processing signals
76
+ recorded from ensembles of single neurons. It also has extensive support for model
77
+ fitting, model-order analysis, and adaptive decoding.
78
+
79
+ Although created with neural signal processing in mind, nSTAT can be used as a
80
+ generic tool for analyzing any types of discrete and continuous signals, and thus
81
+ has wide applicability.
82
+
83
+ Like all open-source projects, nSTAT will benefit from your involvement,
84
+ suggestions and contributions. This platform is intended as a repository for
85
+ extensions to the toolbox based on your code contributions as well as for flagging
86
+ and tracking open issues.
87
+
88
+ The current release can be installed from PyPI: `pip install nstat-toolbox`
89
+
90
+ Lab websites:
91
+ - Neuroscience Statistics Research Laboratory: https://www.neurostat.mit.edu
92
+ - RESToRe Lab: https://www.med.upenn.edu/cajigaslab/
93
+
94
+ ## How to install nSTAT
95
+
96
+ ```bash
97
+ python -m pip install nstat-toolbox
98
+ ```
99
+
100
+ From source:
101
+
102
+ ```bash
103
+ git clone git@github.com:cajigaslab/nSTAT-python.git
104
+ cd nSTAT-python
105
+ python -m pip install -e .[dev]
106
+ ```
107
+
108
+ Install the example dataset:
109
+
110
+ ```bash
111
+ nstat-install --download-example-data always
112
+ ```
113
+
114
+ Equivalent Python API:
115
+
116
+ ```python
117
+ from nstat.data_manager import ensure_example_data
118
+ data_dir = ensure_example_data(download=True)
119
+ ```
120
+
121
+ Quickstart:
122
+
123
+ ```bash
124
+ cd /path/to/nSTAT-python
125
+ pip install -e .[dev]
126
+ nstat-install --download-example-data always
127
+ pytest -q && python tools/paper_examples/build_gallery.py
128
+ ```
129
+
130
+ ## Paper Examples (Self-Contained)
131
+
132
+ Canonical source files:
133
+ - `examples/paper/*.py`
134
+ - `nstat/paper_examples_full.py`
135
+
136
+ Single command to regenerate the paper-example gallery metadata:
137
+
138
+ ```bash
139
+ python tools/paper_examples/build_gallery.py
140
+ ```
141
+
142
+ This writes `docs/paper_examples.md`, `docs/figures/manifest.json`, and
143
+ refreshes the canonical README paper-example table from
144
+ `examples/paper/manifest.yml`.
145
+
146
+ | Example | Thumbnail | What question it answers | Run command | Links |
147
+ |---|---|---|---|---|
148
+ | Example 01 | ![Example 01](docs/figures/example01/fig01_constant_mg_summary.png) | Do mEPSCs follow constant vs piecewise Poisson firing under Mg2+ washout? | `python examples/paper/example01_mepsc_poisson.py` | [Script](examples/paper/example01_mepsc_poisson.py) · [Figures](docs/figures/example01/) |
149
+ | Example 02 | ![Example 02](docs/figures/example02/fig01_data_overview.png) | How do explicit whisker stimulus and spike history improve thalamic GLM fits? | `python examples/paper/example02_whisker_stimulus_thalamus.py` | [Script](examples/paper/example02_whisker_stimulus_thalamus.py) · [Figures](docs/figures/example02/) |
150
+ | Example 03 | ![Example 03](docs/figures/example03/fig01_simulated_and_real_rasters.png) | How do PSTH and SSGLM capture within-trial and across-trial dynamics? | `python examples/paper/example03_psth_and_ssglm.py` | [Script](examples/paper/example03_psth_and_ssglm.py) · [Figures](docs/figures/example03/) |
151
+ | Example 04 | ![Example 04](docs/figures/example04/fig01_example_cells_path_overlay.png) | Which receptive-field basis (Gaussian vs Zernike) better fits place cells? | `python examples/paper/example04_place_cells_continuous_stimulus.py` | [Script](examples/paper/example04_place_cells_continuous_stimulus.py) · [Figures](docs/figures/example04/) |
152
+ | Example 05 | ![Example 05](docs/figures/example05/fig01_univariate_setup.png) | How well do adaptive/hybrid point-process filters decode stimulus and reach state? | `python examples/paper/example05_decoding_ppaf_pphf.py` | [Script](examples/paper/example05_decoding_ppaf_pphf.py) · [Figures](docs/figures/example05/) |
153
+
154
+ Expanded paper-example index and figure gallery:
155
+ - [docs/paper_examples.md](docs/paper_examples.md)
156
+
157
+ Plot style policy:
158
+
159
+ ```python
160
+ from nstat.plot_style import set_plot_style
161
+
162
+ # Modern readability-focused plots (default)
163
+ set_plot_style('modern')
164
+
165
+ # Legacy visual style for strict reproduction
166
+ set_plot_style('legacy')
167
+ ```
168
+
169
+ Rendered help documentation (GitHub Pages):
170
+ - https://cajigaslab.github.io/nSTAT-python/
171
+
172
+ For mathematical and programmatic details of the toolbox, see:
173
+
174
+ Cajigas I, Malik WQ, Brown EN. nSTAT: Open-source neural spike train analysis
175
+ toolbox for Matlab. Journal of Neuroscience Methods 211: 245–264, Nov. 2012.
176
+ - DOI: [10.1016/j.jneumeth.2012.08.009](https://doi.org/10.1016/j.jneumeth.2012.08.009)
177
+ - PubMed: [22981419](https://pubmed.ncbi.nlm.nih.gov/22981419/)
178
+
179
+ ## Paper-Aligned Toolbox Map
180
+
181
+ To keep terminology and workflows consistent with the 2012 toolbox paper,
182
+ the documentation includes a dedicated mapping page:
183
+ [docs/PaperOverview.md](docs/PaperOverview.md).
184
+
185
+ This page ties the Python toolbox to the paper's workflow categories:
186
+
187
+ - Class hierarchy and object model (`SignalObj`, `Covariate`, `Trial`,
188
+ `Analysis`, `FitResult`, `DecodingAlgorithms`)
189
+ - Fitting and assessment workflow (GLM fitting, diagnostics, summaries)
190
+ - Simulation workflow (conditional intensity and thinning examples)
191
+ - Decoding workflow (univariate/bivariate and history-aware decoding)
192
+ - Example-to-paper section mapping via `nSTATPaperExamples`
193
+
194
+ If you use nSTAT in your work, please remember to cite the above paper in any publications.
195
+ nSTAT is protected by the GPL v2 Open Source License.
196
+
197
+ The code repository for the Python port of nSTAT is hosted on GitHub at
198
+ https://github.com/cajigaslab/nSTAT-python.
199
+ The paper-example dataset is distributed separately from the Git repository:
200
+ - Figshare dataset DOI: https://doi.org/10.6084/m9.figshare.4834640.v3
201
+ - Paper DOI: https://doi.org/10.1016/j.jneumeth.2012.08.009
202
+
203
+ ## Code audit (2026-03-11)
204
+
205
+ The Python port was verified against the MATLAB reference through a comprehensive
206
+ 5-phase audit covering all 16 classes and 484 methods. **466 methods found in
207
+ Python, 6 nominal (MATLAB-infrastructure) gaps.** Full class-level and behavioral
208
+ parity verified.
209
+
210
+ **Python bugs fixed during the port:**
211
+
212
+ - `SignalObj.std()` used `ddof=0`; MATLAB uses `ddof=1` (N-1 normalization)
213
+ - `CovariateCollection.isCovPresent()` off-by-one in boundary check
214
+ - `SpikeTrainCollection.psthGLM()` was a stub; now wired to the full GLM path
215
+ - `SpikeTrainCollection.getNSTnames()` / `getUniqueNSTnames()` ignored the
216
+ `selectorArray` filter parameter
217
+ - `nspikeTrain.getNST()` missing resample check on retrieval
218
+
219
+ **MATLAB bugs discovered (13 total, filed as GitHub issues):**
220
+
221
+ - `FitResult.m` — KS test used `sampleRate` as bin width instead of
222
+ `1/sampleRate`, invalidating goodness-of-fit for any sampleRate != 1
223
+ - `CIF.m` — `symvar()` reordered variables alphabetically, causing silent
224
+ argument mismatch for non-alphabetical variable names
225
+ - `SignalObj.m` — `findPeaks('minima')` returned maxima; `findGlobalPeak('minima')`
226
+ crashed; handle aliasing mutated input signals in arithmetic
227
+ - `DecodingAlgorithms.m` — `isa(condNum,'nan')` always false; `ExplambdaDeltaCubed`
228
+ used `.^2` instead of `.^3`
229
+ - `Analysis.m` — Granger causality mask zeroed all columns instead of column `i`
230
+
231
+ See [parity/report.md](parity/report.md) for the full audit.
232
+
233
+ ## MATLAB Toolbox
234
+
235
+ The original MATLAB nSTAT toolbox lives in a separate repository:
236
+
237
+ - https://github.com/cajigaslab/nSTAT
238
+
239
+ That repository is MATLAB-focused and retains:
240
+
241
+ - Original MATLAB class/source files
242
+ - MATLAB helpfiles and help index (`helpfiles/helptoc.xml`)
243
+ - MATLAB example workflows, including `.mlx` examples
244
+
245
+ ## Related Python projects
246
+
247
+ > 📚 **Visual summary** with per-bridge cards, install matrix, and code snippets:
248
+ > [`extras_summary.html`](https://cajigaslab.github.io/nSTAT-python/extras_summary.html).
249
+ > **What's New** (per-iteration change summaries):
250
+ > [`whats_new.html`](https://cajigaslab.github.io/nSTAT-python/whats_new.html).
251
+
252
+ nstat ships **opt-in bridges** (`nstat.extras.*`) to libraries in the
253
+ modern Python systems-neuroscience stack. Install each via its
254
+ optional-dep group:
255
+
256
+ | Library | Use case | Bridge module | Install |
257
+ |---|---|---|---|
258
+ | [Neo](https://github.com/NeuralEnsemble/python-neo) | I/O for Spike2 / NEX / Blackrock / Plexon / TDT / NWB | `nstat.extras.interop.neo` | `pip install nstat-toolbox[neo]` |
259
+ | [pynapple](https://github.com/pynapple-org/pynapple) | Time-series + epoch math, NWB-native | `nstat.extras.interop.pynapple` | `pip install nstat-toolbox[pynapple]` |
260
+ | [pynwb](https://github.com/NeurodataWithoutBorders/pynwb) | BRAIN-Initiative NWB:N standard reader | `nstat.extras.interop.nwb` | `pip install nstat-toolbox[nwb]` |
261
+ | [NeMoS](https://github.com/flatironinstitute/nemos) | JAX Poisson-GLM (cross-validation reference) | `nstat.extras.validation.nemos_bridge` | `pip install nstat-toolbox[nemos]` |
262
+ | [pykalman](https://github.com/pykalman/pykalman) | Pure-NumPy Kalman (cross-validation reference) | `nstat.extras.validation.pykalman_bridge` | `pip install nstat-toolbox[test-parity]` |
263
+ | [statsmodels](https://www.statsmodels.org) | Poisson GLM (IRLS — tightest cross-validation oracle, ~1e-9 agreement) | `nstat.extras.validation.statsmodels_bridge` | `pip install nstat-toolbox[test-parity]` |
264
+ | [PySpike](https://github.com/mariomulansky/PySpike) | ISI / SPIKE-distance spike-train metrics | `nstat.extras.metrics.spike_distances` | `pip install nstat-toolbox[metrics]` |
265
+ | [Dynamax](https://github.com/probml/dynamax) | EM-trained linear-Gaussian state-space models (foundation for unported MATLAB `KF_EM` / `PP_EM` / `mPPCO_EM`) | `nstat.extras.em.dynamax_bridge` | `pip install nstat-toolbox[dynamax]` (pulls JAX ~200 MB) |
266
+
267
+ For ecosystem peers nstat does **not** wrap (spike sorting, calcium
268
+ imaging, deep-learning decoders), see
269
+ [`parity/integration_opportunities.md`](parity/integration_opportunities.md)
270
+ for the rationale and recommended alternatives:
271
+
272
+ - **[SpikeInterface](https://github.com/SpikeInterface/spikeinterface)** — spike sorting (nstat assumes pre-sorted data).
273
+ - **[Elephant](https://github.com/NeuralEnsemble/elephant)** — overlapping spike-train statistics; Neo-typed.
274
+ - **[ssqueezepy](https://github.com/OverLordGoldDragon/ssqueezepy)** — wavelet synchrosqueezing; planned `nstat.extras.spectral`.
275
+
276
+ Install every bridge at once: `pip install nstat-toolbox[all-extras]`
277
+ (does **not** include `[dynamax]` due to JAX install size — install
278
+ that group separately if you need EM-trained state-space models).
@@ -0,0 +1,224 @@
1
+ # nSTAT-python
2
+
3
+ **Neural Spike Train Analysis Toolbox for Python**
4
+
5
+ [![test-and-build](https://github.com/cajigaslab/nSTAT-python/actions/workflows/ci.yml/badge.svg)](https://github.com/cajigaslab/nSTAT-python/actions/workflows/ci.yml)
6
+
7
+ > 📖 **New here?** Start with the
8
+ > [**5-minute intro**](https://cajigaslab.github.io/nSTAT-python/intro.html) —
9
+ > a friendly tour of the toolbox with runnable snippets, the
10
+ > `nstat.extras` opt-in bridges, and the paper-example gallery.
11
+
12
+ `nSTAT-python` is a Python port of the [nSTAT](https://github.com/cajigaslab/nSTAT)
13
+ open-source neural spike train analysis toolbox. It implements a range of models and
14
+ algorithms for neural spike train data analysis, with a focus on point-process
15
+ generalized linear models (GLMs), model fitting, model-order analysis, and adaptive
16
+ decoding. In addition to point-process algorithms, nSTAT also provides tools for
17
+ Gaussian signals — from correlation analysis to the Kalman filter — applicable to
18
+ continuous neural signals such as LFP, EEG, and ECoG.
19
+
20
+ One of nSTAT's key strengths is point-process generalized linear models for spike
21
+ train signals that provide a formal statistical framework for processing signals
22
+ recorded from ensembles of single neurons. It also has extensive support for model
23
+ fitting, model-order analysis, and adaptive decoding.
24
+
25
+ Although created with neural signal processing in mind, nSTAT can be used as a
26
+ generic tool for analyzing any types of discrete and continuous signals, and thus
27
+ has wide applicability.
28
+
29
+ Like all open-source projects, nSTAT will benefit from your involvement,
30
+ suggestions and contributions. This platform is intended as a repository for
31
+ extensions to the toolbox based on your code contributions as well as for flagging
32
+ and tracking open issues.
33
+
34
+ The current release can be installed from PyPI: `pip install nstat-toolbox`
35
+
36
+ Lab websites:
37
+ - Neuroscience Statistics Research Laboratory: https://www.neurostat.mit.edu
38
+ - RESToRe Lab: https://www.med.upenn.edu/cajigaslab/
39
+
40
+ ## How to install nSTAT
41
+
42
+ ```bash
43
+ python -m pip install nstat-toolbox
44
+ ```
45
+
46
+ From source:
47
+
48
+ ```bash
49
+ git clone git@github.com:cajigaslab/nSTAT-python.git
50
+ cd nSTAT-python
51
+ python -m pip install -e .[dev]
52
+ ```
53
+
54
+ Install the example dataset:
55
+
56
+ ```bash
57
+ nstat-install --download-example-data always
58
+ ```
59
+
60
+ Equivalent Python API:
61
+
62
+ ```python
63
+ from nstat.data_manager import ensure_example_data
64
+ data_dir = ensure_example_data(download=True)
65
+ ```
66
+
67
+ Quickstart:
68
+
69
+ ```bash
70
+ cd /path/to/nSTAT-python
71
+ pip install -e .[dev]
72
+ nstat-install --download-example-data always
73
+ pytest -q && python tools/paper_examples/build_gallery.py
74
+ ```
75
+
76
+ ## Paper Examples (Self-Contained)
77
+
78
+ Canonical source files:
79
+ - `examples/paper/*.py`
80
+ - `nstat/paper_examples_full.py`
81
+
82
+ Single command to regenerate the paper-example gallery metadata:
83
+
84
+ ```bash
85
+ python tools/paper_examples/build_gallery.py
86
+ ```
87
+
88
+ This writes `docs/paper_examples.md`, `docs/figures/manifest.json`, and
89
+ refreshes the canonical README paper-example table from
90
+ `examples/paper/manifest.yml`.
91
+
92
+ | Example | Thumbnail | What question it answers | Run command | Links |
93
+ |---|---|---|---|---|
94
+ | Example 01 | ![Example 01](docs/figures/example01/fig01_constant_mg_summary.png) | Do mEPSCs follow constant vs piecewise Poisson firing under Mg2+ washout? | `python examples/paper/example01_mepsc_poisson.py` | [Script](examples/paper/example01_mepsc_poisson.py) · [Figures](docs/figures/example01/) |
95
+ | Example 02 | ![Example 02](docs/figures/example02/fig01_data_overview.png) | How do explicit whisker stimulus and spike history improve thalamic GLM fits? | `python examples/paper/example02_whisker_stimulus_thalamus.py` | [Script](examples/paper/example02_whisker_stimulus_thalamus.py) · [Figures](docs/figures/example02/) |
96
+ | Example 03 | ![Example 03](docs/figures/example03/fig01_simulated_and_real_rasters.png) | How do PSTH and SSGLM capture within-trial and across-trial dynamics? | `python examples/paper/example03_psth_and_ssglm.py` | [Script](examples/paper/example03_psth_and_ssglm.py) · [Figures](docs/figures/example03/) |
97
+ | Example 04 | ![Example 04](docs/figures/example04/fig01_example_cells_path_overlay.png) | Which receptive-field basis (Gaussian vs Zernike) better fits place cells? | `python examples/paper/example04_place_cells_continuous_stimulus.py` | [Script](examples/paper/example04_place_cells_continuous_stimulus.py) · [Figures](docs/figures/example04/) |
98
+ | Example 05 | ![Example 05](docs/figures/example05/fig01_univariate_setup.png) | How well do adaptive/hybrid point-process filters decode stimulus and reach state? | `python examples/paper/example05_decoding_ppaf_pphf.py` | [Script](examples/paper/example05_decoding_ppaf_pphf.py) · [Figures](docs/figures/example05/) |
99
+
100
+ Expanded paper-example index and figure gallery:
101
+ - [docs/paper_examples.md](docs/paper_examples.md)
102
+
103
+ Plot style policy:
104
+
105
+ ```python
106
+ from nstat.plot_style import set_plot_style
107
+
108
+ # Modern readability-focused plots (default)
109
+ set_plot_style('modern')
110
+
111
+ # Legacy visual style for strict reproduction
112
+ set_plot_style('legacy')
113
+ ```
114
+
115
+ Rendered help documentation (GitHub Pages):
116
+ - https://cajigaslab.github.io/nSTAT-python/
117
+
118
+ For mathematical and programmatic details of the toolbox, see:
119
+
120
+ Cajigas I, Malik WQ, Brown EN. nSTAT: Open-source neural spike train analysis
121
+ toolbox for Matlab. Journal of Neuroscience Methods 211: 245–264, Nov. 2012.
122
+ - DOI: [10.1016/j.jneumeth.2012.08.009](https://doi.org/10.1016/j.jneumeth.2012.08.009)
123
+ - PubMed: [22981419](https://pubmed.ncbi.nlm.nih.gov/22981419/)
124
+
125
+ ## Paper-Aligned Toolbox Map
126
+
127
+ To keep terminology and workflows consistent with the 2012 toolbox paper,
128
+ the documentation includes a dedicated mapping page:
129
+ [docs/PaperOverview.md](docs/PaperOverview.md).
130
+
131
+ This page ties the Python toolbox to the paper's workflow categories:
132
+
133
+ - Class hierarchy and object model (`SignalObj`, `Covariate`, `Trial`,
134
+ `Analysis`, `FitResult`, `DecodingAlgorithms`)
135
+ - Fitting and assessment workflow (GLM fitting, diagnostics, summaries)
136
+ - Simulation workflow (conditional intensity and thinning examples)
137
+ - Decoding workflow (univariate/bivariate and history-aware decoding)
138
+ - Example-to-paper section mapping via `nSTATPaperExamples`
139
+
140
+ If you use nSTAT in your work, please remember to cite the above paper in any publications.
141
+ nSTAT is protected by the GPL v2 Open Source License.
142
+
143
+ The code repository for the Python port of nSTAT is hosted on GitHub at
144
+ https://github.com/cajigaslab/nSTAT-python.
145
+ The paper-example dataset is distributed separately from the Git repository:
146
+ - Figshare dataset DOI: https://doi.org/10.6084/m9.figshare.4834640.v3
147
+ - Paper DOI: https://doi.org/10.1016/j.jneumeth.2012.08.009
148
+
149
+ ## Code audit (2026-03-11)
150
+
151
+ The Python port was verified against the MATLAB reference through a comprehensive
152
+ 5-phase audit covering all 16 classes and 484 methods. **466 methods found in
153
+ Python, 6 nominal (MATLAB-infrastructure) gaps.** Full class-level and behavioral
154
+ parity verified.
155
+
156
+ **Python bugs fixed during the port:**
157
+
158
+ - `SignalObj.std()` used `ddof=0`; MATLAB uses `ddof=1` (N-1 normalization)
159
+ - `CovariateCollection.isCovPresent()` off-by-one in boundary check
160
+ - `SpikeTrainCollection.psthGLM()` was a stub; now wired to the full GLM path
161
+ - `SpikeTrainCollection.getNSTnames()` / `getUniqueNSTnames()` ignored the
162
+ `selectorArray` filter parameter
163
+ - `nspikeTrain.getNST()` missing resample check on retrieval
164
+
165
+ **MATLAB bugs discovered (13 total, filed as GitHub issues):**
166
+
167
+ - `FitResult.m` — KS test used `sampleRate` as bin width instead of
168
+ `1/sampleRate`, invalidating goodness-of-fit for any sampleRate != 1
169
+ - `CIF.m` — `symvar()` reordered variables alphabetically, causing silent
170
+ argument mismatch for non-alphabetical variable names
171
+ - `SignalObj.m` — `findPeaks('minima')` returned maxima; `findGlobalPeak('minima')`
172
+ crashed; handle aliasing mutated input signals in arithmetic
173
+ - `DecodingAlgorithms.m` — `isa(condNum,'nan')` always false; `ExplambdaDeltaCubed`
174
+ used `.^2` instead of `.^3`
175
+ - `Analysis.m` — Granger causality mask zeroed all columns instead of column `i`
176
+
177
+ See [parity/report.md](parity/report.md) for the full audit.
178
+
179
+ ## MATLAB Toolbox
180
+
181
+ The original MATLAB nSTAT toolbox lives in a separate repository:
182
+
183
+ - https://github.com/cajigaslab/nSTAT
184
+
185
+ That repository is MATLAB-focused and retains:
186
+
187
+ - Original MATLAB class/source files
188
+ - MATLAB helpfiles and help index (`helpfiles/helptoc.xml`)
189
+ - MATLAB example workflows, including `.mlx` examples
190
+
191
+ ## Related Python projects
192
+
193
+ > 📚 **Visual summary** with per-bridge cards, install matrix, and code snippets:
194
+ > [`extras_summary.html`](https://cajigaslab.github.io/nSTAT-python/extras_summary.html).
195
+ > **What's New** (per-iteration change summaries):
196
+ > [`whats_new.html`](https://cajigaslab.github.io/nSTAT-python/whats_new.html).
197
+
198
+ nstat ships **opt-in bridges** (`nstat.extras.*`) to libraries in the
199
+ modern Python systems-neuroscience stack. Install each via its
200
+ optional-dep group:
201
+
202
+ | Library | Use case | Bridge module | Install |
203
+ |---|---|---|---|
204
+ | [Neo](https://github.com/NeuralEnsemble/python-neo) | I/O for Spike2 / NEX / Blackrock / Plexon / TDT / NWB | `nstat.extras.interop.neo` | `pip install nstat-toolbox[neo]` |
205
+ | [pynapple](https://github.com/pynapple-org/pynapple) | Time-series + epoch math, NWB-native | `nstat.extras.interop.pynapple` | `pip install nstat-toolbox[pynapple]` |
206
+ | [pynwb](https://github.com/NeurodataWithoutBorders/pynwb) | BRAIN-Initiative NWB:N standard reader | `nstat.extras.interop.nwb` | `pip install nstat-toolbox[nwb]` |
207
+ | [NeMoS](https://github.com/flatironinstitute/nemos) | JAX Poisson-GLM (cross-validation reference) | `nstat.extras.validation.nemos_bridge` | `pip install nstat-toolbox[nemos]` |
208
+ | [pykalman](https://github.com/pykalman/pykalman) | Pure-NumPy Kalman (cross-validation reference) | `nstat.extras.validation.pykalman_bridge` | `pip install nstat-toolbox[test-parity]` |
209
+ | [statsmodels](https://www.statsmodels.org) | Poisson GLM (IRLS — tightest cross-validation oracle, ~1e-9 agreement) | `nstat.extras.validation.statsmodels_bridge` | `pip install nstat-toolbox[test-parity]` |
210
+ | [PySpike](https://github.com/mariomulansky/PySpike) | ISI / SPIKE-distance spike-train metrics | `nstat.extras.metrics.spike_distances` | `pip install nstat-toolbox[metrics]` |
211
+ | [Dynamax](https://github.com/probml/dynamax) | EM-trained linear-Gaussian state-space models (foundation for unported MATLAB `KF_EM` / `PP_EM` / `mPPCO_EM`) | `nstat.extras.em.dynamax_bridge` | `pip install nstat-toolbox[dynamax]` (pulls JAX ~200 MB) |
212
+
213
+ For ecosystem peers nstat does **not** wrap (spike sorting, calcium
214
+ imaging, deep-learning decoders), see
215
+ [`parity/integration_opportunities.md`](parity/integration_opportunities.md)
216
+ for the rationale and recommended alternatives:
217
+
218
+ - **[SpikeInterface](https://github.com/SpikeInterface/spikeinterface)** — spike sorting (nstat assumes pre-sorted data).
219
+ - **[Elephant](https://github.com/NeuralEnsemble/elephant)** — overlapping spike-train statistics; Neo-typed.
220
+ - **[ssqueezepy](https://github.com/OverLordGoldDragon/ssqueezepy)** — wavelet synchrosqueezing; planned `nstat.extras.spectral`.
221
+
222
+ Install every bridge at once: `pip install nstat-toolbox[all-extras]`
223
+ (does **not** include `[dynamax]` due to JAX install size — install
224
+ that group separately if you need EM-trained state-space models).
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .confidence_interval import ConfidenceInterval
4
+
5
+ __all__ = ["ConfidenceInterval"]
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .trial import ConfigCollection as ConfigColl
4
+
5
+ __all__ = ["ConfigColl"]
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .trial import CovariateCollection as CovColl
4
+
5
+ __all__ = ["CovColl"]
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .core import Covariate
4
+
5
+ __all__ = ["Covariate"]
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .decoding_algorithms import DecodingAlgorithms
4
+
5
+ __all__ = ["DecodingAlgorithms"]
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .fit import FitResSummary
4
+
5
+ __all__ = ["FitResSummary"]
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .fit import FitResult
4
+
5
+ __all__ = ["FitResult"]
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .core import SignalObj
4
+
5
+ __all__ = ["SignalObj"]
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .trial import TrialConfig
4
+
5
+ __all__ = ["TrialConfig"]