nltools 0.6.0.dev0__py3-none-any.whl
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.
- nltools/__init__.py +55 -0
- nltools/algorithms/__init__.py +90 -0
- nltools/algorithms/alignment/__init__.py +21 -0
- nltools/algorithms/alignment/procrustes.py +565 -0
- nltools/algorithms/alignment/srm.py +758 -0
- nltools/algorithms/backends.py +1059 -0
- nltools/algorithms/corrections.py +177 -0
- nltools/algorithms/decoding.py +327 -0
- nltools/algorithms/inference/__init__.py +50 -0
- nltools/algorithms/inference/bootstrap.py +1386 -0
- nltools/algorithms/inference/correlation.py +373 -0
- nltools/algorithms/inference/intersubject.py +422 -0
- nltools/algorithms/inference/isc.py +1554 -0
- nltools/algorithms/inference/matrix.py +602 -0
- nltools/algorithms/inference/one_sample.py +288 -0
- nltools/algorithms/inference/random.py +122 -0
- nltools/algorithms/inference/timeseries.py +347 -0
- nltools/algorithms/inference/two_sample.py +212 -0
- nltools/algorithms/inference/utils.py +58 -0
- nltools/algorithms/inference/validation.py +282 -0
- nltools/algorithms/neighborhoods.py +207 -0
- nltools/algorithms/outliers.py +308 -0
- nltools/algorithms/regression.py +83 -0
- nltools/algorithms/signal.py +303 -0
- nltools/algorithms/similarity.py +234 -0
- nltools/algorithms/validation.py +151 -0
- nltools/cross_validation.py +72 -0
- nltools/data/__init__.py +30 -0
- nltools/data/adjacency/__init__.py +875 -0
- nltools/data/adjacency/io.py +111 -0
- nltools/data/adjacency/modeling.py +569 -0
- nltools/data/adjacency/plotting.py +174 -0
- nltools/data/adjacency/state.py +349 -0
- nltools/data/adjacency/stats.py +596 -0
- nltools/data/adjacency/utils.py +79 -0
- nltools/data/atlases/__init__.py +23 -0
- nltools/data/atlases/labeling.py +158 -0
- nltools/data/atlases/loading.py +76 -0
- nltools/data/atlases/registry.py +96 -0
- nltools/data/atlases/reporting.py +456 -0
- nltools/data/braindata/__init__.py +2170 -0
- nltools/data/braindata/analysis.py +1381 -0
- nltools/data/braindata/bootstrap.py +398 -0
- nltools/data/braindata/io.py +896 -0
- nltools/data/braindata/modeling.py +594 -0
- nltools/data/braindata/plotting.py +501 -0
- nltools/data/braindata/prediction.py +1250 -0
- nltools/data/braindata/utils.py +348 -0
- nltools/data/braindata/validation.py +197 -0
- nltools/data/braindata/viewer.js +266 -0
- nltools/data/braindata/viewer.py +770 -0
- nltools/data/combine.py +27 -0
- nltools/data/designmatrix/__init__.py +1032 -0
- nltools/data/designmatrix/append.py +518 -0
- nltools/data/designmatrix/diagnostics.py +248 -0
- nltools/data/designmatrix/io.py +356 -0
- nltools/data/designmatrix/plotting.py +291 -0
- nltools/data/designmatrix/regressors.py +463 -0
- nltools/data/designmatrix/transforms.py +200 -0
- nltools/data/designmatrix/utils.py +350 -0
- nltools/data/ownership.py +129 -0
- nltools/data/results.py +291 -0
- nltools/data/roc/__init__.py +398 -0
- nltools/data/simulator/__init__.py +927 -0
- nltools/data/simulator/haxby.py +124 -0
- nltools/data/validation.py +83 -0
- nltools/datasets.py +218 -0
- nltools/io/__init__.py +10 -0
- nltools/io/events.py +67 -0
- nltools/io/h5.py +246 -0
- nltools/mask.py +403 -0
- nltools/models/__init__.py +11 -0
- nltools/models/glm.py +543 -0
- nltools/models/results.py +49 -0
- nltools/models/ridge.py +1303 -0
- nltools/models/validation.py +26 -0
- nltools/plotting/__init__.py +32 -0
- nltools/plotting/adjacency.py +421 -0
- nltools/plotting/brain.py +669 -0
- nltools/plotting/decomposition.py +111 -0
- nltools/plotting/prediction.py +110 -0
- nltools/resources/covariates_example.csv +161 -0
- nltools/resources/onsets_example.csv +40 -0
- nltools/templates/__init__.py +51 -0
- nltools/templates/config.py +144 -0
- nltools/templates/fetch.py +260 -0
- nltools/templates/matching.py +183 -0
- nltools/templates/paths.py +106 -0
- nltools/templates/registry.py +25 -0
- nltools/utils.py +230 -0
- nltools/version.py +13 -0
- nltools-0.6.0.dev0.dist-info/METADATA +95 -0
- nltools-0.6.0.dev0.dist-info/RECORD +95 -0
- nltools-0.6.0.dev0.dist-info/WHEEL +4 -0
- nltools-0.6.0.dev0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Static registry of supported MNI templates."""
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
TemplateName = Literal["default", "nilearn", "fmriprep"]
|
|
6
|
+
"""Which MNI template a brain space is built from."""
|
|
7
|
+
|
|
8
|
+
Resolution = Literal[1, 2, 3]
|
|
9
|
+
"""Voxel size of a template, in millimetres."""
|
|
10
|
+
|
|
11
|
+
VERSION_MAP: dict[str, str] = {
|
|
12
|
+
"default": "fsl",
|
|
13
|
+
"nilearn": "a",
|
|
14
|
+
"fmriprep": "c",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
VERSION_TO_TEMPLATE: dict[str, str] = {v: k for k, v in VERSION_MAP.items()}
|
|
18
|
+
|
|
19
|
+
SUPPORTED_RESOLUTIONS: dict[str, list[int]] = {
|
|
20
|
+
"default": [2, 3],
|
|
21
|
+
"nilearn": [1, 2, 3],
|
|
22
|
+
"fmriprep": [1, 2],
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
TEMPLATE_PRIORITY: list[str] = ["default", "nilearn", "fmriprep"]
|
nltools/utils.py
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"""Cross-cutting utilities used across the nltools package."""
|
|
2
|
+
|
|
3
|
+
__all__ = ["DesignMatrixWarning", "ResamplingWarning"]
|
|
4
|
+
|
|
5
|
+
import contextlib
|
|
6
|
+
import inspect
|
|
7
|
+
import re
|
|
8
|
+
from os.path import dirname, join, sep as pathsep
|
|
9
|
+
|
|
10
|
+
import polars as pl
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# ---------------------------------------------------------------------------
|
|
14
|
+
# polars compatibility
|
|
15
|
+
# ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _polars_version_tuple(text: str) -> tuple[int, ...]:
|
|
19
|
+
"""Read the leading `(major, minor, patch)` numbers out of a version string.
|
|
20
|
+
|
|
21
|
+
polars ships a beta of every minor release and reports it in a dashed form
|
|
22
|
+
(`'1.36.0-beta.2'`), so splitting on `'.'` and calling `int` on the pieces
|
|
23
|
+
raises. Only the numeric prefix matters for a feature check.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
text (str): A version string, e.g. `'1.33.1'` or `'1.36.0-beta.2'`.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
tuple[int, ...]: Up to three leading integers, e.g. `(1, 36, 0)`.
|
|
30
|
+
"""
|
|
31
|
+
return tuple(int(part) for part in re.findall(r"\d+", text)[:3])
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# polars 1.42.1 renamed the classic equal-height horizontal concat to
|
|
35
|
+
# ``horizontal_extend`` and deprecated the old ``horizontal`` spelling, which
|
|
36
|
+
# will start padding to the tallest frame in the next breaking release. Below
|
|
37
|
+
# 1.42.1 only ``horizontal`` exists. Every nltools call site concatenates
|
|
38
|
+
# frames of equal height, so the two names are interchangeable there, and
|
|
39
|
+
# picking by version lets the package run on the polars 1.33.1 that Pyodide
|
|
40
|
+
# bundles as well as on current releases.
|
|
41
|
+
_HORIZONTAL_CONCAT = (
|
|
42
|
+
"horizontal_extend"
|
|
43
|
+
if _polars_version_tuple(pl.__version__) >= (1, 42, 1)
|
|
44
|
+
else "horizontal"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
# Warnings: attribution and library-wide categories
|
|
50
|
+
# ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
_PACKAGE_DIR = dirname(__file__) + pathsep
|
|
53
|
+
_TESTS_DIR = join(_PACKAGE_DIR, "tests") + pathsep
|
|
54
|
+
# ``@_coalesced_gc()`` (a contextmanager used as a decorator) wraps facade
|
|
55
|
+
# methods in a stdlib contextlib frame; it is nltools plumbing, not user code.
|
|
56
|
+
_PLUMBING_FILES = frozenset({contextlib.__file__})
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _is_library_frame(filename: str) -> bool:
|
|
60
|
+
if filename in _PLUMBING_FILES:
|
|
61
|
+
return True
|
|
62
|
+
return filename.startswith(_PACKAGE_DIR) and not filename.startswith(_TESTS_DIR)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _find_stack_level() -> int:
|
|
66
|
+
"""Return the ``stacklevel`` that attributes a warning to the caller's code.
|
|
67
|
+
|
|
68
|
+
Walks up from the caller until the first frame outside the nltools package
|
|
69
|
+
(``nltools/tests/`` counts as outside: tests are the library's users; the
|
|
70
|
+
stdlib ``contextlib`` frame that ``@_coalesced_gc()`` inserts counts as
|
|
71
|
+
inside), so a ``warnings.warn`` deep inside a facade lands on the user's
|
|
72
|
+
line rather than on nltools internals — the same pattern nilearn and pandas
|
|
73
|
+
use. Every ``warnings.warn`` in the library passes
|
|
74
|
+
``stacklevel=_find_stack_level()``; a source-scan test enforces it.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
int: Value for the ``stacklevel`` argument of ``warnings.warn``.
|
|
78
|
+
|
|
79
|
+
Examples:
|
|
80
|
+
```python
|
|
81
|
+
warnings.warn("message", UserWarning, stacklevel=_find_stack_level())
|
|
82
|
+
```
|
|
83
|
+
"""
|
|
84
|
+
frame = inspect.currentframe()
|
|
85
|
+
level = 0
|
|
86
|
+
try:
|
|
87
|
+
while frame is not None and _is_library_frame(inspect.getfile(frame)):
|
|
88
|
+
frame = frame.f_back
|
|
89
|
+
level += 1
|
|
90
|
+
finally:
|
|
91
|
+
del frame
|
|
92
|
+
return level
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class ResamplingWarning(UserWarning):
|
|
96
|
+
"""Data is (or will be) resampled to a different space than it arrived in.
|
|
97
|
+
|
|
98
|
+
Raised when a data image does not match the mask/template it is loaded
|
|
99
|
+
against — a detected template at another resolution, or a mask in a
|
|
100
|
+
different space — and nltools resamples to reconcile them. Subclasses
|
|
101
|
+
``UserWarning`` so it participates in default filtering while staying
|
|
102
|
+
individually silenceable:
|
|
103
|
+
``warnings.filterwarnings("ignore", category=ResamplingWarning)``.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class DesignMatrixWarning(UserWarning):
|
|
108
|
+
"""A ``DesignMatrix`` operation was skipped, or the design itself is suspect.
|
|
109
|
+
|
|
110
|
+
Raised by regressor builders (``add_poly``, ``add_dct_basis``,
|
|
111
|
+
``convolve``) when the requested columns already exist and are skipped,
|
|
112
|
+
and by ``BrainData.fit()`` when the design it receives is rank deficient.
|
|
113
|
+
Subclasses ``UserWarning`` so it participates in default filtering while
|
|
114
|
+
staying individually silenceable:
|
|
115
|
+
``warnings.filterwarnings("ignore", category=DesignMatrixWarning)``.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# ---------------------------------------------------------------------------
|
|
120
|
+
# Cross-cutting helpers (used by multiple subsystems)
|
|
121
|
+
# ---------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _attempt_to_import(dependency, fromlist=None):
|
|
125
|
+
"""Attempt to import an optional dependency, returning None if unavailable.
|
|
126
|
+
|
|
127
|
+
This function is used to handle optional dependencies gracefully. If the
|
|
128
|
+
import fails, the function returns None rather than raising an error,
|
|
129
|
+
allowing the calling code to check and handle missing dependencies.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
dependency (str): The module name to import (e.g. `'torch'`, `'cupy'`).
|
|
133
|
+
fromlist (list[str], optional): Names to import from the module (passed to
|
|
134
|
+
`__import__`).
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
ModuleType | None: The imported module, or None if the import failed.
|
|
138
|
+
|
|
139
|
+
Examples:
|
|
140
|
+
```python
|
|
141
|
+
torch = _attempt_to_import("torch")
|
|
142
|
+
if torch is not None:
|
|
143
|
+
... # use torch
|
|
144
|
+
```
|
|
145
|
+
"""
|
|
146
|
+
try:
|
|
147
|
+
mod = __import__(dependency, fromlist=fromlist)
|
|
148
|
+
except ImportError:
|
|
149
|
+
mod = None
|
|
150
|
+
return mod
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# ---------------------------------------------------------------------------
|
|
154
|
+
# Progress bars — the single library-wide mechanism
|
|
155
|
+
# ---------------------------------------------------------------------------
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class _NullProgressBar:
|
|
159
|
+
"""No-op stand-in for `tqdm` used when `progress_bar=False`.
|
|
160
|
+
|
|
161
|
+
Supports the subset of the tqdm interface nltools relies on, so call sites
|
|
162
|
+
that drive a bar manually need no branching.
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
def update(self, n: int = 1) -> None:
|
|
166
|
+
pass
|
|
167
|
+
|
|
168
|
+
def close(self) -> None:
|
|
169
|
+
pass
|
|
170
|
+
|
|
171
|
+
def __enter__(self) -> "_NullProgressBar":
|
|
172
|
+
return self
|
|
173
|
+
|
|
174
|
+
def __exit__(self, *exc_info) -> bool:
|
|
175
|
+
return False
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def _maybe_tqdm(iterable, *, progress_bar: bool, **tqdm_kwargs):
|
|
179
|
+
"""Wrap `iterable` in a tqdm progress bar only when `progress_bar` is True.
|
|
180
|
+
|
|
181
|
+
tqdm writes to stderr, so an unconditional bar makes functions noisy when
|
|
182
|
+
called in a loop (a 100-iteration calibration study would emit 100 bars).
|
|
183
|
+
Importing tqdm lazily also keeps it off the import path when unused. Uses
|
|
184
|
+
`tqdm.auto`, so notebooks get widget bars and terminals get text bars.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
iterable (Iterable): The iterable to wrap.
|
|
188
|
+
progress_bar (bool): Whether to display a progress bar.
|
|
189
|
+
**tqdm_kwargs (dict): Forwarded to `tqdm` (e.g. `desc`, `unit`, `total`).
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
Iterable: The original iterable, or a `tqdm`-wrapped version of it.
|
|
193
|
+
|
|
194
|
+
Examples:
|
|
195
|
+
```python
|
|
196
|
+
for i in _maybe_tqdm(range(n_permute), progress_bar=progress_bar,
|
|
197
|
+
desc="CPU parallel perms", unit="perm"):
|
|
198
|
+
...
|
|
199
|
+
```
|
|
200
|
+
"""
|
|
201
|
+
if not progress_bar:
|
|
202
|
+
return iterable
|
|
203
|
+
|
|
204
|
+
from tqdm.auto import tqdm
|
|
205
|
+
|
|
206
|
+
return tqdm(iterable, **tqdm_kwargs)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _make_progress_bar(*, progress_bar: bool, **tqdm_kwargs):
|
|
210
|
+
"""Build a progress bar, or a no-op stand-in when `progress_bar` is False.
|
|
211
|
+
|
|
212
|
+
Use this for call sites that drive the bar manually via `.update()` rather
|
|
213
|
+
than by iteration. Uses `tqdm.auto`, so notebooks get widget bars and
|
|
214
|
+
terminals get text bars.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
progress_bar (bool): Whether to display a progress bar.
|
|
218
|
+
**tqdm_kwargs (dict): Forwarded to `tqdm` (e.g. `total`, `desc`, `unit`).
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
tqdm | _NullProgressBar: A `tqdm` instance, or a `_NullProgressBar` exposing
|
|
222
|
+
the same subset of its interface (`update`, `close`, and the
|
|
223
|
+
context-manager protocol).
|
|
224
|
+
"""
|
|
225
|
+
if not progress_bar:
|
|
226
|
+
return _NullProgressBar()
|
|
227
|
+
|
|
228
|
+
from tqdm.auto import tqdm
|
|
229
|
+
|
|
230
|
+
return tqdm(**tqdm_kwargs)
|
nltools/version.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Expose the installed nltools version. Single source of truth: pyproject.toml.
|
|
2
|
+
|
|
3
|
+
`__version__` is read from the installed package metadata (populated by hatchling
|
|
4
|
+
from the `version` field in pyproject.toml), so the release bump in pyproject.toml
|
|
5
|
+
flows through automatically — there is no version string to keep in sync here.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
__version__ = version("nltools")
|
|
12
|
+
except PackageNotFoundError: # running from a source tree without an install
|
|
13
|
+
__version__ = "0.0.0+unknown"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: nltools
|
|
3
|
+
Version: 0.6.0.dev0
|
|
4
|
+
Summary: A Python package to analyze neuroimaging data
|
|
5
|
+
Project-URL: Homepage, https://nltools.org
|
|
6
|
+
Author-email: "Luke J. Chang" <luke.j.chang@dartmouth.edu>, Eshin Jolly <eshin.jolly@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: analysis,machine-learning,neuroimaging,preprocessing
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Requires-Python: >=3.11
|
|
17
|
+
Requires-Dist: anywidget>=0.9
|
|
18
|
+
Requires-Dist: h5py>=3.13
|
|
19
|
+
Requires-Dist: himalaya<0.5,>=0.4.11
|
|
20
|
+
Requires-Dist: huggingface-hub>=0.30
|
|
21
|
+
Requires-Dist: joblib>=1.5.3
|
|
22
|
+
Requires-Dist: matplotlib>=3.8.0
|
|
23
|
+
Requires-Dist: nibabel>=5.2.0
|
|
24
|
+
Requires-Dist: nilearn>=0.14.1
|
|
25
|
+
Requires-Dist: numpy>=2.0.2
|
|
26
|
+
Requires-Dist: pandas>=2.3.0
|
|
27
|
+
Requires-Dist: polars>=1.33.1
|
|
28
|
+
Requires-Dist: pynv>=0.3
|
|
29
|
+
Requires-Dist: scikit-learn>=1.8
|
|
30
|
+
Requires-Dist: scipy>=1.11.1
|
|
31
|
+
Requires-Dist: seaborn>=0.13.2
|
|
32
|
+
Requires-Dist: tqdm>=4.67.1
|
|
33
|
+
Provides-Extra: all
|
|
34
|
+
Requires-Dist: h5py>=3.13; extra == 'all'
|
|
35
|
+
Requires-Dist: ipywidgets>=8.1.7; extra == 'all'
|
|
36
|
+
Requires-Dist: networkx>=3.5; extra == 'all'
|
|
37
|
+
Provides-Extra: graph
|
|
38
|
+
Requires-Dist: networkx>=3.5; extra == 'graph'
|
|
39
|
+
Provides-Extra: h5
|
|
40
|
+
Requires-Dist: h5py>=3.13; extra == 'h5'
|
|
41
|
+
Provides-Extra: interactive-plots
|
|
42
|
+
Requires-Dist: ipywidgets>=8.1.7; extra == 'interactive-plots'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
[](https://pypi.org/project/nltools/)
|
|
46
|
+
[](https://github.com/cosanlab/nltools/actions/workflows/ci.yml)
|
|
47
|
+
[](https://codecov.io/gh/cosanlab/nltools)
|
|
48
|
+
[](https://doi.org/10.5281/zenodo.2229813)
|
|
49
|
+

|
|
50
|
+

|
|
51
|
+
|
|
52
|
+
# NLTools
|
|
53
|
+
|
|
54
|
+
Python toolbox for analyzing neuroimaging data, with a focus on multivariate analyses. It grew out of Tor Wager's object-oriented Matlab [CANlab core tools](http://wagerlab.colorado.edu/tools) and builds on [nilearn](https://nilearn.github.io) and [scikit-learn](https://scikit-learn.org). Requires Python 3.11+.
|
|
55
|
+
|
|
56
|
+
## Documentation
|
|
57
|
+
|
|
58
|
+
Documentation and tutorials are available at https://nltools.org
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
With [uv](https://docs.astral.sh/uv/) (recommended, for use in a project):
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
uv add nltools
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or with pip:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
pip install nltools
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Development
|
|
75
|
+
|
|
76
|
+
`uv` manages the whole workflow — it creates the virtual environment, installs core and development dependencies, and installs `nltools` into it in editable mode.
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
git clone https://github.com/cosanlab/nltools
|
|
80
|
+
cd nltools
|
|
81
|
+
uv sync
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Common tasks (run via [poe](https://poethepoet.natn.io/), all prefixed with `uv run`):
|
|
85
|
+
|
|
86
|
+
| Command | What it does |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `uv run poe lint` | Fix, format, and type-check (ruff + ty) |
|
|
89
|
+
| `uv run poe test` | Run the fast test suite in parallel |
|
|
90
|
+
| `uv run pytest -k test_name` | Run a specific test |
|
|
91
|
+
| `uv run poe docs-serve` | Live-preview the docs site at localhost:8000 (executes tutorials via the cache) |
|
|
92
|
+
| `uv run poe docs-build` | Full docs build (API reference + executed tutorials) |
|
|
93
|
+
| `uv run poe tutorials` | Run every tutorial notebook end-to-end |
|
|
94
|
+
| `uv build` | Build the package locally |
|
|
95
|
+
| `uv add/remove [--dev] pkg` | Add or remove a (dev) dependency |
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
nltools/__init__.py,sha256=7IItMeSyhfkcIOH2u8V_VRGGhR16uV2UbvbBu_QML2k,1324
|
|
2
|
+
nltools/cross_validation.py,sha256=NrqqK8b76GL__HI8IgUTIDISh0Zva8qUUlT-qAVomNw,3163
|
|
3
|
+
nltools/datasets.py,sha256=9794fWKoo6hveVLExN9PGNEzOqBkyr97JtADzlIISR0,7760
|
|
4
|
+
nltools/mask.py,sha256=I8dqgLIzmfwhYxpbVFapd8uCE-xREXi37vp8PRJ6c-A,15017
|
|
5
|
+
nltools/utils.py,sha256=cOUsYg-uUqrUTlMEEtmureJhPnGU8Mz1x9pd-97RuQ0,8246
|
|
6
|
+
nltools/version.py,sha256=7BHvDy32PQzzL-GoAWoixl-vXAxQ_l0_EhxyKbQ9A50,549
|
|
7
|
+
nltools/algorithms/__init__.py,sha256=2LS8wVPYlQIyCMr7fgCnrKfezMkAG540gSoUaPN_b3c,2865
|
|
8
|
+
nltools/algorithms/backends.py,sha256=DVK-IvWbDKVt4J0CXlZXAtEcKQFA5RI7aXiPgXovrXg,40110
|
|
9
|
+
nltools/algorithms/corrections.py,sha256=A7UhdMtHFlp307oLKCcV5MOitPKQJAW4qjVxl64LnOE,6350
|
|
10
|
+
nltools/algorithms/decoding.py,sha256=xP-ITRkI1El_7cEB1k2MxZ4GFBGk3nrAu9qwuMwTNZM,13018
|
|
11
|
+
nltools/algorithms/neighborhoods.py,sha256=csCgyfAO6b3Ho3AobrtzrKRmrFp5fL8pVlEV6HqhFeM,6549
|
|
12
|
+
nltools/algorithms/outliers.py,sha256=sffoulDgvo2tbaDcidDVAnJyDTxI68WKQuetly6S_Yg,12339
|
|
13
|
+
nltools/algorithms/regression.py,sha256=1Ln6P9RY-Aib2hdFRmTDSMCGUGkngKDoqDR08POVAUM,3013
|
|
14
|
+
nltools/algorithms/signal.py,sha256=j8YUe0J9QihpscTDPV2fR0qUE8p-YK5mVakwpvpf82c,10705
|
|
15
|
+
nltools/algorithms/similarity.py,sha256=31hRio7A3W55dBqrMOGFjmzZ6rwBSAH66tB_o-WtOs4,8442
|
|
16
|
+
nltools/algorithms/validation.py,sha256=XgGq9Ir5S3khLgn4zGVMkvlvhKOd6azHVLziMktJYy0,6091
|
|
17
|
+
nltools/algorithms/alignment/__init__.py,sha256=WgAQFbOZ8Woy3SMhItHpqxVaiUlO2-RPEP0MHgwnE0Y,773
|
|
18
|
+
nltools/algorithms/alignment/procrustes.py,sha256=qJs6hhoJbIvyY_vV2aYhoKhxFOd4kGiile9KW5MsZd8,23844
|
|
19
|
+
nltools/algorithms/alignment/srm.py,sha256=sUIb9jpZQOyjkRnUI1rfwRa0my4HtWhliazl2nq0_zI,30188
|
|
20
|
+
nltools/algorithms/inference/__init__.py,sha256=W0_HFffImX232hGljm5TYTkl3IUy2JbStZdHgtKVfbg,2070
|
|
21
|
+
nltools/algorithms/inference/bootstrap.py,sha256=Ck30DzzB_qV3dOnGIHGENUBSI4x_qWEyEDFu5c_VrZc,53134
|
|
22
|
+
nltools/algorithms/inference/correlation.py,sha256=OUlKAc3vdiFBo2phdOs1VLfloal2lsMv2xAVKG3krrA,13508
|
|
23
|
+
nltools/algorithms/inference/intersubject.py,sha256=itroP7KsndATd8SYhCN9UYitER_60X8ns_bZjoxhRDg,17695
|
|
24
|
+
nltools/algorithms/inference/isc.py,sha256=dWTiSxpDrvwtGdljbzhSJLaPUbJ-vGHIJLeAEzMs3rM,62575
|
|
25
|
+
nltools/algorithms/inference/matrix.py,sha256=PVwi6ZoQetyQAXIQ0au-N5qQNIeLFq_VabgOQxJpQGQ,22116
|
|
26
|
+
nltools/algorithms/inference/one_sample.py,sha256=DCwapMcIppYykauqMCiJY3hD2B_z1-A8jTQ5aaerPUs,10977
|
|
27
|
+
nltools/algorithms/inference/random.py,sha256=dzYM3HIcjnkATzksPExHW7md5ujuqqID9nTfnCPMhTQ,4026
|
|
28
|
+
nltools/algorithms/inference/timeseries.py,sha256=4wEGUqfEOqCAbnMuixc-bqfBKSGEwEM0eFy-v7_3BqY,13411
|
|
29
|
+
nltools/algorithms/inference/two_sample.py,sha256=bWp5KG-x0aQdODZJbNsWUs5JwVoCG3AASASM0h48LZc,7933
|
|
30
|
+
nltools/algorithms/inference/utils.py,sha256=YjX0a57F_20XpFLeD4JqAiVv9CZ2MSOBnMYijx5Do0E,2598
|
|
31
|
+
nltools/algorithms/inference/validation.py,sha256=K3X5zIdM-qfzFU4p-LWIDiE_QiXca8hsWDKGoT4rtDw,9124
|
|
32
|
+
nltools/data/__init__.py,sha256=iIQRTD8fUxXjTrqqBO6WiEo7sQLus92WidRXPcksY90,917
|
|
33
|
+
nltools/data/combine.py,sha256=3jbaWh3luHiBMRoasBAopHgD1OKoUfmFi3dkLPvfTmU,820
|
|
34
|
+
nltools/data/ownership.py,sha256=jXW-0XbEQxPH8pyuif3IE7rh3l79GhnVSKDKdwKWh4I,4640
|
|
35
|
+
nltools/data/results.py,sha256=TiaIzPV7xHwzY6xUezVg0-hTIt1D74orYPkIALi1CNg,13090
|
|
36
|
+
nltools/data/validation.py,sha256=pbO9nhVZmj5V9wBZbVjzMFrce1eMJDwHF3hNFh1Yf8o,3091
|
|
37
|
+
nltools/data/adjacency/__init__.py,sha256=zIsI6yK03jKEQgymjtMOTufFvLpgK-c0csf_k4zplr8,34643
|
|
38
|
+
nltools/data/adjacency/io.py,sha256=2iuENnU8TYl3QG2GEef-Jm4QrE0SOlmmGQ0EXZorAvU,3809
|
|
39
|
+
nltools/data/adjacency/modeling.py,sha256=gvD5kjuDAIOnFgbfAvwS1HFl2DZmQpRGJpR5DzkZMyQ,22772
|
|
40
|
+
nltools/data/adjacency/plotting.py,sha256=dAtPQvSrzk3LHz3HEYwOXmzioHKDD3pNeapytJJwSrA,6084
|
|
41
|
+
nltools/data/adjacency/state.py,sha256=ZJkjkELXyIOKUth40yBR1-Tx9aTWWCRWHybPQmYNj44,13067
|
|
42
|
+
nltools/data/adjacency/stats.py,sha256=W2fHDncIEbSHGp2UC7HwA68jT0v6MURxd5unrPjGTKY,21808
|
|
43
|
+
nltools/data/adjacency/utils.py,sha256=xMG1JFdZ9bkijmYfqxuK4jnPQqgC_ZdU5YxXuFCOXOc,2532
|
|
44
|
+
nltools/data/atlases/__init__.py,sha256=U7-5bbv-vBI0Nxj3XfpGCDAIOTKfq3NkeS7ddZ5LEKc,1083
|
|
45
|
+
nltools/data/atlases/labeling.py,sha256=ywFHAR4dS4RPOZRN-wGFUhpKG08Rt11Lp3TK9USKbgs,5310
|
|
46
|
+
nltools/data/atlases/loading.py,sha256=YHyPy4AbWz2ay6ZQEhvP7lUkLXLqKU8OY5VOc3LIcEE,2388
|
|
47
|
+
nltools/data/atlases/registry.py,sha256=pURNm3n_evGN5M-eYOVeyDvnsdO8SPscw_6OWCofZCQ,3191
|
|
48
|
+
nltools/data/atlases/reporting.py,sha256=-6s8WSb5HBzIe9K1p2Bahux1zCpGcwUjxiQFpzvzXRk,16712
|
|
49
|
+
nltools/data/braindata/__init__.py,sha256=4V90OOVk5thNZMN93s05EFjtiQeywWge_fTuH5G2qOY,91595
|
|
50
|
+
nltools/data/braindata/analysis.py,sha256=vWQqvVbMhUAunhKTU0mIaBn86rZgGDYNOprKwKggUPU,51232
|
|
51
|
+
nltools/data/braindata/bootstrap.py,sha256=-HZsFkeObUv8_JkV7fVwuPLHOxC6I5OSAjsL6_A8sb4,14900
|
|
52
|
+
nltools/data/braindata/io.py,sha256=arClhB8NJdBajXMD-ELpwhYrWjNFmaKS6I19HN2B4zk,33464
|
|
53
|
+
nltools/data/braindata/modeling.py,sha256=LYFOdAVh6JK5u4P3tKnq_Zpmej4eydiAYKZ9__sDFsQ,24065
|
|
54
|
+
nltools/data/braindata/plotting.py,sha256=-8irLFfTVDjWKXi8V-ZlQ6gzcdNS-ahOfhKHhGHgDYw,19552
|
|
55
|
+
nltools/data/braindata/prediction.py,sha256=Mnbybz59Gm8xrBG-ox8M7I_7pExw27VMjoqVslXNDP4,49208
|
|
56
|
+
nltools/data/braindata/utils.py,sha256=qMm2jrxYiVDlN2f2exuwC5ygGWH_HaQjURywSEdYDNU,12567
|
|
57
|
+
nltools/data/braindata/validation.py,sha256=xktJf2trblOXdIcr0ISRgbaZ0IVs-NPIBGzRd6oZ4yA,6417
|
|
58
|
+
nltools/data/braindata/viewer.js,sha256=o8zMONQSJGSI6CqOcQpQhTqvK_OfG3rh0ggBE9yeYqs,10555
|
|
59
|
+
nltools/data/braindata/viewer.py,sha256=D80RTnrDYxEmDwPXi16FpmD9UVspQqaAKE7FmxPNBio,30639
|
|
60
|
+
nltools/data/designmatrix/__init__.py,sha256=THr9Ouibck41o8NNv_SKbr7dyp4zk97lucLd06QeTig,42699
|
|
61
|
+
nltools/data/designmatrix/append.py,sha256=Ax_NAnxGZ6UNbFi0D5c-t1vA76MemMTNyv8WSY4uBWc,20360
|
|
62
|
+
nltools/data/designmatrix/diagnostics.py,sha256=M8iBCkkrxZwaKK8WoaODSGxyhlKE0erEkkkf6_1evQg,8945
|
|
63
|
+
nltools/data/designmatrix/io.py,sha256=74Z1DF8OSB_feEEyYkSzs7U7iYWTbqj4PBeBQJDNZVw,12906
|
|
64
|
+
nltools/data/designmatrix/plotting.py,sha256=3hwJVrkJLjsj_ftIt-LqkdvW8tmiX4bfLYrwUETDVDU,9384
|
|
65
|
+
nltools/data/designmatrix/regressors.py,sha256=Q4QNt87nRk8-oGoznqdyYhBCwQGIbemqNYi521KTTeE,18326
|
|
66
|
+
nltools/data/designmatrix/transforms.py,sha256=EEXWaY0OJWl5vrt-tYNG09dmlvjM6fdz4YtFLVKGBGs,7203
|
|
67
|
+
nltools/data/designmatrix/utils.py,sha256=MatdEj_CqhYSuNQirez1lhHqiHNTU6A-rC0eH00nSV4,12831
|
|
68
|
+
nltools/data/roc/__init__.py,sha256=CfguSwm36akUbJQVrUyxPaJqZOgs_heex1bG6AHbSgM,19013
|
|
69
|
+
nltools/data/simulator/__init__.py,sha256=RPvakdFqrbIfpm4EKJn4bAZU_s34cc7X0cIXSPOnAlY,37568
|
|
70
|
+
nltools/data/simulator/haxby.py,sha256=AbfY1d_4YgEdy4MCiBzKJgETeM7bFdSz7XK_R9meWWs,4605
|
|
71
|
+
nltools/io/__init__.py,sha256=oZ5oki0-YZwcTRU0kp9oc2eSCy38o5YRoDQdNi3LgZ8,305
|
|
72
|
+
nltools/io/events.py,sha256=WEm8uLdDsEvzK4Cbb1lG7wBbe86BUJIlUAZHaNnZ8eo,2200
|
|
73
|
+
nltools/io/h5.py,sha256=fOdGjRvnL0nUo_2WxEbBuzLAxxT62WDL8NL5TdU1O3U,9111
|
|
74
|
+
nltools/models/__init__.py,sha256=-Vu2zF2s8UPRRzea9zOu-HJBjfzrHrAxf2knio2fdjA,394
|
|
75
|
+
nltools/models/glm.py,sha256=E8e0OwZvkZBK08GQCO0R8OkJJ46KlzYZ0P62ePUg0ew,22939
|
|
76
|
+
nltools/models/results.py,sha256=dgALr-Ovs9GkfOeXB2Xzs9vQua4vYoqwijMhOh7M_00,1759
|
|
77
|
+
nltools/models/ridge.py,sha256=3zLNwryD3hmsg_qKTkhM3hkoZ0FgYlGrVKy-xvCT-cA,52538
|
|
78
|
+
nltools/models/validation.py,sha256=RQ5xVzJZSWeIqqy47pNAEdtoYLdIbsK8wnOY0W-v_wc,856
|
|
79
|
+
nltools/plotting/__init__.py,sha256=TDVc_sNA-SV9FNGULuOZDw2AdXvsu-kKd8I5TxXdIck,1037
|
|
80
|
+
nltools/plotting/adjacency.py,sha256=AfOOvsyMe7AokKDvJminpFJeEC1BYnUgsEPMd-NyEMk,15123
|
|
81
|
+
nltools/plotting/brain.py,sha256=zq49_w0jHsBriMww3cPwiCCFWu0AJueKCW6u4vOHoGU,22882
|
|
82
|
+
nltools/plotting/decomposition.py,sha256=618Bj_Fo9Nggg4a0YHReyuPl2VaHCK6x4PL83GYr-Xo,3980
|
|
83
|
+
nltools/plotting/prediction.py,sha256=cCwwR8ndfVraMWuNfakp26linmXqe9kmoZUvr_vMI9w,3913
|
|
84
|
+
nltools/resources/covariates_example.csv,sha256=_TIH5ioewGMSOWuPjTTNUErY-IEGYOUCEr-YK8UCiaU,60230
|
|
85
|
+
nltools/resources/onsets_example.csv,sha256=efDlmnfCA5G66uCqYwnwrqMUbzPuoORBO-874EllDPc,1160
|
|
86
|
+
nltools/templates/__init__.py,sha256=83wgbjDTShcuT0Naq4n3ppPvlX7cRNznhHT9i1xPAt4,1422
|
|
87
|
+
nltools/templates/config.py,sha256=qFgQ6xrzpIkVcSp8cW2cjYzHNpudIKHKBhG-J6kJMGw,4567
|
|
88
|
+
nltools/templates/fetch.py,sha256=i3U7B7E-wCwEtL9P3uh4TZWnM6fG1vIANJs8cl0Nnlk,9479
|
|
89
|
+
nltools/templates/matching.py,sha256=4v4lsEiminAi3_yTiBoQfdTkC8UohnCEaMqGSLPbIDk,6540
|
|
90
|
+
nltools/templates/paths.py,sha256=STnUDeLa7Nvs1A-k-B8RmiejOQPh-VJGNs-8RQMA0Do,3796
|
|
91
|
+
nltools/templates/registry.py,sha256=zjDQMqUXEDzMj0YZ1-7Pfv6HnA7VSMAfwStSYEe6OsY,636
|
|
92
|
+
nltools-0.6.0.dev0.dist-info/METADATA,sha256=umDZvW8YhYWDBFix8VsidV_6nTSycSoCdlcO4J2Xc-0,3735
|
|
93
|
+
nltools-0.6.0.dev0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
94
|
+
nltools-0.6.0.dev0.dist-info/licenses/LICENSE,sha256=ZOQ5Dr2VC_ZzSEVTTnkfqCA60sJ9LE2dfV6f-5uHXH0,1108
|
|
95
|
+
nltools-0.6.0.dev0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015-2026 Cosan Lab & SciMinds Research Studio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|