spectralbrain 0.0.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.
- spectralbrain-0.0.1/LICENSE +21 -0
- spectralbrain-0.0.1/Makefile +83 -0
- spectralbrain-0.0.1/PKG-INFO +102 -0
- spectralbrain-0.0.1/README.md +2 -0
- spectralbrain-0.0.1/RELEASE.md +196 -0
- spectralbrain-0.0.1/environment.yml +160 -0
- spectralbrain-0.0.1/pyproject.toml +246 -0
- spectralbrain-0.0.1/setup_uv.sh +132 -0
- spectralbrain-0.0.1/src/spectralbrain/__init__.py +142 -0
- spectralbrain-0.0.1/src/spectralbrain/backends/__init__.py +15 -0
- spectralbrain-0.0.1/src/spectralbrain/backends/cpu.py +928 -0
- spectralbrain-0.0.1/src/spectralbrain/backends/gpu.py +875 -0
- spectralbrain-0.0.1/src/spectralbrain/core/__init__.py +14 -0
- spectralbrain-0.0.1/src/spectralbrain/core/base.py +1026 -0
- spectralbrain-0.0.1/src/spectralbrain/core/meshes.py +1020 -0
- spectralbrain-0.0.1/src/spectralbrain/core/pointclouds.py +1201 -0
- spectralbrain-0.0.1/src/spectralbrain/io/__init__.py +35 -0
- spectralbrain-0.0.1/src/spectralbrain/io/export.py +333 -0
- spectralbrain-0.0.1/src/spectralbrain/io/gpu_preprocess.py +1458 -0
- spectralbrain-0.0.1/src/spectralbrain/io/loaders.py +825 -0
- spectralbrain-0.0.1/src/spectralbrain/io/parcellate.py +1026 -0
- spectralbrain-0.0.1/src/spectralbrain/io/preprocess.py +279 -0
- spectralbrain-0.0.1/src/spectralbrain/runtime.py +1033 -0
- spectralbrain-0.0.1/src/spectralbrain/spectral/__init__.py +27 -0
- spectralbrain-0.0.1/src/spectralbrain/spectral/anisotropic.py +360 -0
- spectralbrain-0.0.1/src/spectralbrain/spectral/collections.py +313 -0
- spectralbrain-0.0.1/src/spectralbrain/spectral/descriptors.py +767 -0
- spectralbrain-0.0.1/src/spectralbrain/spectral/distances.py +690 -0
- spectralbrain-0.0.1/src/spectralbrain/spectral/wavelets.py +364 -0
- spectralbrain-0.0.1/src/spectralbrain/statistics/__init__.py +38 -0
- spectralbrain-0.0.1/src/spectralbrain/statistics/analysis.py +1358 -0
- spectralbrain-0.0.1/src/spectralbrain/statistics/bayesian.py +935 -0
- spectralbrain-0.0.1/src/spectralbrain/statistics/eda.py +921 -0
- spectralbrain-0.0.1/src/spectralbrain/statistics/normative.py +859 -0
- spectralbrain-0.0.1/src/spectralbrain/statistics/surrogates.py +401 -0
- spectralbrain-0.0.1/src/spectralbrain/utils/__init__.py +19 -0
- spectralbrain-0.0.1/src/spectralbrain/utils/atlas.py +362 -0
- spectralbrain-0.0.1/src/spectralbrain/utils/datasets.py +329 -0
- spectralbrain-0.0.1/src/spectralbrain/utils/helpers.py +333 -0
- spectralbrain-0.0.1/src/spectralbrain/viz/__init__.py +67 -0
- spectralbrain-0.0.1/src/spectralbrain/viz/bayes.py +823 -0
- spectralbrain-0.0.1/src/spectralbrain/viz/brainplots.py +976 -0
- spectralbrain-0.0.1/src/spectralbrain/viz/geometry/__init__.py +62 -0
- spectralbrain-0.0.1/src/spectralbrain/viz/geometry/meshes.py +812 -0
- spectralbrain-0.0.1/src/spectralbrain/viz/geometry/points.py +849 -0
- spectralbrain-0.0.1/src/spectralbrain/viz/graphics.py +524 -0
- spectralbrain-0.0.1/src/spectralbrain/viz/hipp.py +728 -0
- spectralbrain-0.0.1/tests/__init__.py +0 -0
- spectralbrain-0.0.1/tests/test_smoke.py +90 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024–2026 Rodrigo Dalvit and SpectralBrain Contributors
|
|
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.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Makefile — SpectralBrain development shortcuts
|
|
2
|
+
# Usage: make <target>
|
|
3
|
+
#
|
|
4
|
+
# This Makefile wraps common uv/pytest/ruff commands so you don't have
|
|
5
|
+
# to remember the exact invocations. It's optional — you can always
|
|
6
|
+
# run the underlying commands directly.
|
|
7
|
+
|
|
8
|
+
.PHONY: help install install-full test lint format build clean \
|
|
9
|
+
publish-test publish docs check-version
|
|
10
|
+
|
|
11
|
+
# Default target: show available commands.
|
|
12
|
+
help:
|
|
13
|
+
@echo ""
|
|
14
|
+
@echo "SpectralBrain — development commands"
|
|
15
|
+
@echo "──────────────────────────────────────────────────"
|
|
16
|
+
@echo " make install Install core + dev dependencies"
|
|
17
|
+
@echo " make install-full Install everything (gpu, viz, bayesian, neuro)"
|
|
18
|
+
@echo " make test Run test suite"
|
|
19
|
+
@echo " make test-fast Run tests without slow markers"
|
|
20
|
+
@echo " make lint Check code style (ruff)"
|
|
21
|
+
@echo " make format Auto-format code (ruff)"
|
|
22
|
+
@echo " make build Build sdist + wheel"
|
|
23
|
+
@echo " make check-version Show current package version"
|
|
24
|
+
@echo " make publish-test Publish to TestPyPI (manual, for debugging)"
|
|
25
|
+
@echo " make clean Remove build artifacts"
|
|
26
|
+
@echo " make docs Build documentation"
|
|
27
|
+
@echo ""
|
|
28
|
+
|
|
29
|
+
# ── Installation ──────────────────────────────────────────────────────
|
|
30
|
+
install:
|
|
31
|
+
uv sync --group dev
|
|
32
|
+
|
|
33
|
+
install-full:
|
|
34
|
+
uv sync --all-extras --group dev
|
|
35
|
+
|
|
36
|
+
# ── Testing ───────────────────────────────────────────────────────────
|
|
37
|
+
test:
|
|
38
|
+
uv run pytest tests/ -v --tb=short
|
|
39
|
+
|
|
40
|
+
test-fast:
|
|
41
|
+
uv run pytest tests/ -v --tb=short -m "not slow"
|
|
42
|
+
|
|
43
|
+
test-cov:
|
|
44
|
+
uv run pytest tests/ --cov=spectralbrain --cov-report=html --cov-report=term-missing
|
|
45
|
+
@echo "Coverage report: htmlcov/index.html"
|
|
46
|
+
|
|
47
|
+
# ── Code quality ──────────────────────────────────────────────────────
|
|
48
|
+
lint:
|
|
49
|
+
uv run ruff check spectralbrain/ tests/
|
|
50
|
+
uv run ruff format --check spectralbrain/ tests/
|
|
51
|
+
|
|
52
|
+
format:
|
|
53
|
+
uv run ruff format spectralbrain/ tests/
|
|
54
|
+
uv run ruff check --fix spectralbrain/ tests/
|
|
55
|
+
|
|
56
|
+
typecheck:
|
|
57
|
+
uv run mypy spectralbrain/
|
|
58
|
+
|
|
59
|
+
# ── Build & release ───────────────────────────────────────────────────
|
|
60
|
+
build: clean
|
|
61
|
+
uv build
|
|
62
|
+
@echo ""
|
|
63
|
+
@echo "Built artifacts:"
|
|
64
|
+
@ls -lh dist/
|
|
65
|
+
|
|
66
|
+
check-version:
|
|
67
|
+
@uv run python -c "import spectralbrain; print(f'Version: {spectralbrain.__version__}')"
|
|
68
|
+
|
|
69
|
+
# Publish to TestPyPI using uv (for manual debugging; normally the
|
|
70
|
+
# GitHub Actions workflow handles this automatically).
|
|
71
|
+
publish-test: build
|
|
72
|
+
uv publish --publish-url https://test.pypi.org/legacy/ --trusted-publishing always
|
|
73
|
+
|
|
74
|
+
# ── Documentation ─────────────────────────────────────────────────────
|
|
75
|
+
docs:
|
|
76
|
+
uv run sphinx-build -b html docs/ docs/_build/html
|
|
77
|
+
@echo "Documentation: docs/_build/html/index.html"
|
|
78
|
+
|
|
79
|
+
# ── Cleanup ───────────────────────────────────────────────────────────
|
|
80
|
+
clean:
|
|
81
|
+
rm -rf dist/ build/ *.egg-info .pytest_cache .mypy_cache .ruff_cache htmlcov/
|
|
82
|
+
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
|
83
|
+
@echo "Cleaned build artifacts."
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: spectralbrain
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Spectral shape analysis for brain structures via the Laplace-Beltrami operator.
|
|
5
|
+
Project-URL: Homepage, https://github.com/spectralbrain/spectralbrain
|
|
6
|
+
Project-URL: Documentation, https://spectralbrain.readthedocs.io
|
|
7
|
+
Project-URL: Repository, https://github.com/spectralbrain/spectralbrain
|
|
8
|
+
Project-URL: Issues, https://github.com/spectralbrain/spectralbrain/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/spectralbrain/spectralbrain/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: Rodrigo Debona <r.debona@posgrad.ufsc.br>
|
|
11
|
+
Maintainer-email: Rodrigo Debona <r.debona@posgrad.ufsc.br>
|
|
12
|
+
License-Expression: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: HKS,ShapeDNA,WKS,brain,laplace-beltrami,morphometry,neuroimaging,neuroscience,shape-analysis,spectral-analysis
|
|
15
|
+
Classifier: Development Status :: 4 - Beta
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: <3.13,>=3.11
|
|
27
|
+
Requires-Dist: h5py>=3.10
|
|
28
|
+
Requires-Dist: lapy>=1.0
|
|
29
|
+
Requires-Dist: matplotlib>=3.8
|
|
30
|
+
Requires-Dist: nibabel>=5.2
|
|
31
|
+
Requires-Dist: numpy>=1.26
|
|
32
|
+
Requires-Dist: pandas>=2.2
|
|
33
|
+
Requires-Dist: pyvista>=0.44
|
|
34
|
+
Requires-Dist: rich>=13.7
|
|
35
|
+
Requires-Dist: scikit-learn>=1.4
|
|
36
|
+
Requires-Dist: scipy>=1.13
|
|
37
|
+
Requires-Dist: seaborn>=0.13
|
|
38
|
+
Requires-Dist: tqdm>=4.66
|
|
39
|
+
Requires-Dist: vtk>=9.3
|
|
40
|
+
Provides-Extra: bayesian
|
|
41
|
+
Requires-Dist: arviz>=0.18; extra == 'bayesian'
|
|
42
|
+
Requires-Dist: bambi>=0.14; extra == 'bayesian'
|
|
43
|
+
Requires-Dist: pymc>=5.16; extra == 'bayesian'
|
|
44
|
+
Provides-Extra: full
|
|
45
|
+
Requires-Dist: antspyx>=0.4; (platform_system != 'Windows') and extra == 'full'
|
|
46
|
+
Requires-Dist: arviz>=0.18; extra == 'full'
|
|
47
|
+
Requires-Dist: bambi>=0.14; extra == 'full'
|
|
48
|
+
Requires-Dist: brainspace>=0.1.16; extra == 'full'
|
|
49
|
+
Requires-Dist: cupy-cuda13x; (platform_system != 'Darwin') and extra == 'full'
|
|
50
|
+
Requires-Dist: dipy>=1.9; extra == 'full'
|
|
51
|
+
Requires-Dist: hippomaps; extra == 'full'
|
|
52
|
+
Requires-Dist: hippunfold-plot; extra == 'full'
|
|
53
|
+
Requires-Dist: ipywidgets>=8.1; extra == 'full'
|
|
54
|
+
Requires-Dist: jax[cuda13]; extra == 'full'
|
|
55
|
+
Requires-Dist: jupyterlab>=4.2; extra == 'full'
|
|
56
|
+
Requires-Dist: mne-connectivity>=0.7; extra == 'full'
|
|
57
|
+
Requires-Dist: mne>=1.7; extra == 'full'
|
|
58
|
+
Requires-Dist: nilearn>=0.13; extra == 'full'
|
|
59
|
+
Requires-Dist: open3d>=0.19; (python_version < '3.13') and extra == 'full'
|
|
60
|
+
Requires-Dist: pybids>=0.16; extra == 'full'
|
|
61
|
+
Requires-Dist: pymc>=5.16; extra == 'full'
|
|
62
|
+
Requires-Dist: scienceplots>=2.1; extra == 'full'
|
|
63
|
+
Requires-Dist: templateflow>=24.0; extra == 'full'
|
|
64
|
+
Requires-Dist: torch>=2.4; extra == 'full'
|
|
65
|
+
Requires-Dist: torchvision; extra == 'full'
|
|
66
|
+
Requires-Dist: trame-vtk; extra == 'full'
|
|
67
|
+
Requires-Dist: trame-vuetify; extra == 'full'
|
|
68
|
+
Requires-Dist: trame>=3.6; extra == 'full'
|
|
69
|
+
Requires-Dist: vedo>=2024.5; extra == 'full'
|
|
70
|
+
Requires-Dist: yabplot; (python_version == '3.11.*') and extra == 'full'
|
|
71
|
+
Provides-Extra: gpu
|
|
72
|
+
Requires-Dist: cupy-cuda13x; (platform_system != 'Darwin') and extra == 'gpu'
|
|
73
|
+
Requires-Dist: jax[cuda13]; extra == 'gpu'
|
|
74
|
+
Requires-Dist: torch>=2.4; extra == 'gpu'
|
|
75
|
+
Requires-Dist: torchvision; extra == 'gpu'
|
|
76
|
+
Provides-Extra: neuro
|
|
77
|
+
Requires-Dist: antspyx>=0.4; (platform_system != 'Windows') and extra == 'neuro'
|
|
78
|
+
Requires-Dist: brainspace>=0.1.16; extra == 'neuro'
|
|
79
|
+
Requires-Dist: dipy>=1.9; extra == 'neuro'
|
|
80
|
+
Requires-Dist: mne-connectivity>=0.7; extra == 'neuro'
|
|
81
|
+
Requires-Dist: mne>=1.7; extra == 'neuro'
|
|
82
|
+
Requires-Dist: nilearn>=0.13; extra == 'neuro'
|
|
83
|
+
Requires-Dist: pybids>=0.16; extra == 'neuro'
|
|
84
|
+
Requires-Dist: templateflow>=24.0; extra == 'neuro'
|
|
85
|
+
Provides-Extra: notebooks
|
|
86
|
+
Requires-Dist: ipywidgets>=8.1; extra == 'notebooks'
|
|
87
|
+
Requires-Dist: jupyterlab>=4.2; extra == 'notebooks'
|
|
88
|
+
Requires-Dist: trame-vtk; extra == 'notebooks'
|
|
89
|
+
Requires-Dist: trame-vuetify; extra == 'notebooks'
|
|
90
|
+
Requires-Dist: trame>=3.6; extra == 'notebooks'
|
|
91
|
+
Provides-Extra: viz
|
|
92
|
+
Requires-Dist: brainspace>=0.1.16; extra == 'viz'
|
|
93
|
+
Requires-Dist: hippomaps; extra == 'viz'
|
|
94
|
+
Requires-Dist: hippunfold-plot; extra == 'viz'
|
|
95
|
+
Requires-Dist: open3d>=0.19; (python_version < '3.13') and extra == 'viz'
|
|
96
|
+
Requires-Dist: scienceplots>=2.1; extra == 'viz'
|
|
97
|
+
Requires-Dist: vedo>=2024.5; extra == 'viz'
|
|
98
|
+
Requires-Dist: yabplot; (python_version == '3.11.*') and extra == 'viz'
|
|
99
|
+
Description-Content-Type: text/markdown
|
|
100
|
+
|
|
101
|
+
# spectralbrain
|
|
102
|
+
Input Agnostic Morfphometric Spectral Descriptors of Brain Structures Acquisition and Analysis.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Release Guide — SpectralBrain
|
|
2
|
+
|
|
3
|
+
This document walks through the complete release process: from bumping
|
|
4
|
+
the version to seeing `spectralbrain` live on PyPI. The workflow is
|
|
5
|
+
designed so that **creating a GitHub Release** is the only manual step;
|
|
6
|
+
everything else is automated.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## One-time setup (you only do this once)
|
|
11
|
+
|
|
12
|
+
### 1. Configure PyPI Trusted Publisher
|
|
13
|
+
|
|
14
|
+
The OIDC trusted publisher model eliminates API tokens entirely. PyPI
|
|
15
|
+
authenticates your GitHub Actions workflow via short-lived OIDC
|
|
16
|
+
credentials — nothing is stored as a secret.
|
|
17
|
+
|
|
18
|
+
Go to <https://pypi.org/manage/account/publishing/> and add a **pending
|
|
19
|
+
publisher** with these exact values:
|
|
20
|
+
|
|
21
|
+
| Field | Value |
|
|
22
|
+
|------------------|----------------------------------|
|
|
23
|
+
| PyPI project | `spectralbrain` |
|
|
24
|
+
| Owner | `<your-github-username-or-org>` |
|
|
25
|
+
| Repository | `spectralbrain` |
|
|
26
|
+
| Workflow name | `publish.yml` |
|
|
27
|
+
| Environment name | `pypi` |
|
|
28
|
+
|
|
29
|
+
Repeat the same process on **TestPyPI** at
|
|
30
|
+
<https://test.pypi.org/manage/account/publishing/>, using environment
|
|
31
|
+
name `testpypi`.
|
|
32
|
+
|
|
33
|
+
### 2. Create GitHub Environments
|
|
34
|
+
|
|
35
|
+
In your repository, go to **Settings → Environments** and create two
|
|
36
|
+
environments:
|
|
37
|
+
|
|
38
|
+
**`pypi`** — for production PyPI. Recommended protection rules:
|
|
39
|
+
|
|
40
|
+
- ✅ Required reviewers (add yourself) — this adds a manual approval
|
|
41
|
+
step before the package goes live.
|
|
42
|
+
- ✅ Allow only the `main` branch.
|
|
43
|
+
|
|
44
|
+
**`testpypi`** — for TestPyPI. You can skip protection rules here
|
|
45
|
+
since TestPyPI is a sandbox.
|
|
46
|
+
|
|
47
|
+
### 3. Verify CI is green
|
|
48
|
+
|
|
49
|
+
Push the `.github/workflows/ci.yml` and `.github/workflows/publish.yml`
|
|
50
|
+
files to your repository. The CI workflow should trigger on the next
|
|
51
|
+
push to `main` or any PR. Make sure it passes before attempting a
|
|
52
|
+
release.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Making a release
|
|
57
|
+
|
|
58
|
+
### Step 1 — Ensure `main` is clean
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git checkout main
|
|
62
|
+
git pull origin main
|
|
63
|
+
uv run pytest tests/ -v # all tests pass
|
|
64
|
+
uv run ruff check spectralbrain/ # no lint errors
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Step 2 — Create a git tag
|
|
68
|
+
|
|
69
|
+
SpectralBrain uses `hatch-vcs` for versioning: the version number is
|
|
70
|
+
derived from the most recent git tag. There is no version string to
|
|
71
|
+
edit manually in `pyproject.toml`.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Choose the next version following semantic versioning.
|
|
75
|
+
# Examples: v0.1.0, v0.2.0, v1.0.0, v1.0.1
|
|
76
|
+
git tag v0.1.0
|
|
77
|
+
git push origin v0.1.0
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Verify that `hatch-vcs` picks it up:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
uv run python -c "import spectralbrain; print(spectralbrain.__version__)"
|
|
84
|
+
# Should print: 0.1.0
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Step 3 — Create a GitHub Release
|
|
88
|
+
|
|
89
|
+
Go to your repo's **Releases** page → **Draft a new release**:
|
|
90
|
+
|
|
91
|
+
1. **Choose a tag**: select the tag you just pushed (e.g., `v0.1.0`).
|
|
92
|
+
2. **Release title**: `v0.1.0` (or a descriptive name).
|
|
93
|
+
3. **Description**: paste the relevant section of your CHANGELOG, or
|
|
94
|
+
click "Generate release notes" to auto-populate from merged PRs.
|
|
95
|
+
4. **Pre-release**: check this box for alpha/beta/rc versions.
|
|
96
|
+
5. Click **Publish release**.
|
|
97
|
+
|
|
98
|
+
### Step 4 — Watch the automation
|
|
99
|
+
|
|
100
|
+
Creating the release triggers `.github/workflows/publish.yml`. Go to
|
|
101
|
+
the **Actions** tab to watch the progress:
|
|
102
|
+
|
|
103
|
+
1. **Build** job: builds the sdist + wheel, verifies the version
|
|
104
|
+
matches the tag, uploads artifacts.
|
|
105
|
+
2. **Publish to TestPyPI** job: uploads to the TestPyPI sandbox
|
|
106
|
+
(automatic, no approval needed).
|
|
107
|
+
3. **Publish to PyPI** job: waits for your manual approval (if you
|
|
108
|
+
configured environment protection), then publishes.
|
|
109
|
+
|
|
110
|
+
The whole process takes about 2 minutes.
|
|
111
|
+
|
|
112
|
+
### Step 5 — Verify the release
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# From TestPyPI (should work immediately):
|
|
116
|
+
pip install --index-url https://test.pypi.org/simple/ \
|
|
117
|
+
--extra-index-url https://pypi.org/simple/ \
|
|
118
|
+
spectralbrain
|
|
119
|
+
|
|
120
|
+
# From production PyPI (after approval):
|
|
121
|
+
pip install spectralbrain
|
|
122
|
+
python -c "import spectralbrain; print(spectralbrain.__version__)"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## How versioning works
|
|
128
|
+
|
|
129
|
+
SpectralBrain uses **hatch-vcs**, which reads version information
|
|
130
|
+
from git tags automatically. The rules are:
|
|
131
|
+
|
|
132
|
+
| Git state | Resulting version |
|
|
133
|
+
|----------------------------------|--------------------------|
|
|
134
|
+
| Exactly on tag `v0.2.0` | `0.2.0` |
|
|
135
|
+
| 3 commits after `v0.2.0` | `0.2.1.dev3+g<hash>` |
|
|
136
|
+
| No tags at all | `0.1.0.dev0` (fallback) |
|
|
137
|
+
| Dirty working tree on `v0.2.0` | `0.2.1.dev0+dirty` |
|
|
138
|
+
|
|
139
|
+
This means you **never** need to edit a version string in a Python
|
|
140
|
+
file. The single source of truth is the git tag.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Releasing a patch / hotfix
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
git checkout main
|
|
148
|
+
# Make your fix, commit it.
|
|
149
|
+
git tag v0.1.1
|
|
150
|
+
git push origin main v0.1.1
|
|
151
|
+
# Create a GitHub Release for v0.1.1.
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Releasing a pre-release (alpha/beta/rc)
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
git tag v0.2.0a1 # alpha
|
|
160
|
+
git tag v0.2.0b1 # beta
|
|
161
|
+
git tag v0.2.0rc1 # release candidate
|
|
162
|
+
git push origin v0.2.0a1
|
|
163
|
+
# Create a GitHub Release and CHECK the "Pre-release" box.
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Pre-releases go through the same pipeline. PyPI will mark them as
|
|
167
|
+
pre-release, so `pip install spectralbrain` won't pick them up unless
|
|
168
|
+
the user opts in with `pip install --pre spectralbrain`.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Troubleshooting
|
|
173
|
+
|
|
174
|
+
**"Version mismatch" error in the build job**
|
|
175
|
+
This means `hatch-vcs` derived a version that doesn't match the
|
|
176
|
+
release tag. Usually caused by not fetching the full git history.
|
|
177
|
+
The workflow uses `fetch-depth: 0` to prevent this. If you're
|
|
178
|
+
running locally, make sure the tag is on the current commit:
|
|
179
|
+
`git describe --tags --dirty`.
|
|
180
|
+
|
|
181
|
+
**"Token exchange failed" in the publish job**
|
|
182
|
+
The OIDC handshake between GitHub and PyPI failed. Check that:
|
|
183
|
+
(a) the workflow filename in your trusted publisher config on PyPI
|
|
184
|
+
matches exactly (`publish.yml`), (b) the environment name matches
|
|
185
|
+
(`pypi`), and (c) the `id-token: write` permission is present.
|
|
186
|
+
|
|
187
|
+
**TestPyPI succeeds but PyPI fails**
|
|
188
|
+
If you're using environment protection rules, check the Actions tab —
|
|
189
|
+
the PyPI publish job may be waiting for manual approval. Click
|
|
190
|
+
"Review deployments" and approve it.
|
|
191
|
+
|
|
192
|
+
**Package installs but `import spectralbrain` fails**
|
|
193
|
+
Run `pip show spectralbrain` to check it's installed, then
|
|
194
|
+
`python -c "import spectralbrain; print(spectralbrain.__file__)"`.
|
|
195
|
+
If the version shows `0.1.0.dev0`, the git tag wasn't present at
|
|
196
|
+
build time. Rebuild with the tag on the commit.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# environment.yml — SpectralBrain + computational neuroscience workbench
|
|
2
|
+
#
|
|
3
|
+
# A single, robust conda environment pinned to Python 3.11 (required by
|
|
4
|
+
# yabplot and open3d). Uses conda-forge exclusively — do NOT mix with
|
|
5
|
+
# the 'defaults' or 'pytorch' channels to avoid ABI conflicts.
|
|
6
|
+
#
|
|
7
|
+
# Create: conda env create -f environment.yml
|
|
8
|
+
# Update: conda env update -f environment.yml --prune
|
|
9
|
+
# Lock: conda-lock lock -f environment.yml -p linux-64 -p osx-arm64
|
|
10
|
+
# Activate: conda activate spectralbrain
|
|
11
|
+
#
|
|
12
|
+
# For the SpectralBrain library itself in editable mode, after activating:
|
|
13
|
+
# pip install -e ".[full]"
|
|
14
|
+
# Or, for faster resolution:
|
|
15
|
+
# uv pip install -e ".[full]"
|
|
16
|
+
|
|
17
|
+
name: spectralbrain
|
|
18
|
+
channels:
|
|
19
|
+
- conda-forge
|
|
20
|
+
|
|
21
|
+
dependencies:
|
|
22
|
+
# ────────────────────────────────────────────────────────────────────
|
|
23
|
+
# Python — pinned to 3.11 (yabplot / open3d / hippunfold-plot ceiling)
|
|
24
|
+
# ────────────────────────────────────────────────────────────────────
|
|
25
|
+
- python=3.11
|
|
26
|
+
|
|
27
|
+
# ────────────────────────────────────────────────────────────────────
|
|
28
|
+
# Core scientific computing
|
|
29
|
+
# ────────────────────────────────────────────────────────────────────
|
|
30
|
+
- numpy>=2.0
|
|
31
|
+
- scipy>=1.13
|
|
32
|
+
- scikit-learn>=1.4
|
|
33
|
+
- pandas>=2.2
|
|
34
|
+
- statsmodels>=0.14
|
|
35
|
+
- pingouin>=0.5
|
|
36
|
+
- networkx>=3.2
|
|
37
|
+
- h5py>=3.10
|
|
38
|
+
- sympy>=1.12
|
|
39
|
+
|
|
40
|
+
# ────────────────────────────────────────────────────────────────────
|
|
41
|
+
# Neuroimaging — core I/O and analysis
|
|
42
|
+
# ────────────────────────────────────────────────────────────────────
|
|
43
|
+
- nibabel>=5.2
|
|
44
|
+
- nilearn>=0.10
|
|
45
|
+
- dipy>=1.9
|
|
46
|
+
- mne>=1.7
|
|
47
|
+
- mne-connectivity>=0.7
|
|
48
|
+
- pybids>=0.16
|
|
49
|
+
- templateflow>=24.0
|
|
50
|
+
- fslpy>=3.18
|
|
51
|
+
- datalad>=1.0
|
|
52
|
+
- brainspace>=0.1.10
|
|
53
|
+
|
|
54
|
+
# ────────────────────────────────────────────────────────────────────
|
|
55
|
+
# Spectral geometry and 3D surfaces
|
|
56
|
+
# ────────────────────────────────────────────────────────────────────
|
|
57
|
+
- lapy>=1.0
|
|
58
|
+
- trimesh>=4.0
|
|
59
|
+
- igl>=2.5 # libigl Python bindings
|
|
60
|
+
- pyglet>=2.0
|
|
61
|
+
- vtk>=9.3
|
|
62
|
+
- pyvista>=0.44
|
|
63
|
+
- pyvistaqt>=0.11
|
|
64
|
+
|
|
65
|
+
# ────────────────────────────────────────────────────────────────────
|
|
66
|
+
# 2D visualization
|
|
67
|
+
# ────────────────────────────────────────────────────────────────────
|
|
68
|
+
- matplotlib>=3.8
|
|
69
|
+
- seaborn>=0.13
|
|
70
|
+
- plotly>=5.18
|
|
71
|
+
- statannotations
|
|
72
|
+
- python-ternary
|
|
73
|
+
|
|
74
|
+
# ────────────────────────────────────────────────────────────────────
|
|
75
|
+
# 3D visualization
|
|
76
|
+
# ────────────────────────────────────────────────────────────────────
|
|
77
|
+
- vedo>=2024.5
|
|
78
|
+
|
|
79
|
+
# ────────────────────────────────────────────────────────────────────
|
|
80
|
+
# Deep learning (conda-forge CUDA builds — single source of truth)
|
|
81
|
+
# Comment out pytorch-cuda for CPU-only machines.
|
|
82
|
+
# ────────────────────────────────────────────────────────────────────
|
|
83
|
+
- pytorch>=2.4
|
|
84
|
+
- torchvision
|
|
85
|
+
- torchaudio
|
|
86
|
+
- pytorch-cuda=12.4 # ← remove this line for CPU-only environments
|
|
87
|
+
- lightning>=2.3
|
|
88
|
+
|
|
89
|
+
# ────────────────────────────────────────────────────────────────────
|
|
90
|
+
# Bayesian inference
|
|
91
|
+
# ────────────────────────────────────────────────────────────────────
|
|
92
|
+
- pymc>=5.16
|
|
93
|
+
- arviz>=0.18
|
|
94
|
+
- bambi>=0.14
|
|
95
|
+
- nutpie>=0.12 # Rust NUTS sampler — fastest on conda-forge
|
|
96
|
+
|
|
97
|
+
# ────────────────────────────────────────────────────────────────────
|
|
98
|
+
# Jupyter / interactive / Trame
|
|
99
|
+
# ────────────────────────────────────────────────────────────────────
|
|
100
|
+
- jupyterlab>=4.2
|
|
101
|
+
- ipywidgets>=8.1
|
|
102
|
+
- trame>=3.5
|
|
103
|
+
- trame-vtk
|
|
104
|
+
- trame-vuetify
|
|
105
|
+
- nodejs>=20
|
|
106
|
+
|
|
107
|
+
# ────────────────────────────────────────────────────────────────────
|
|
108
|
+
# Graph and network analysis
|
|
109
|
+
# ────────────────────────────────────────────────────────────────────
|
|
110
|
+
- networkx>=3.2
|
|
111
|
+
- python-igraph>=0.11
|
|
112
|
+
|
|
113
|
+
# ────────────────────────────────────────────────────────────────────
|
|
114
|
+
# Development and testing
|
|
115
|
+
# ────────────────────────────────────────────────────────────────────
|
|
116
|
+
- pytest>=8.0
|
|
117
|
+
- pytest-cov>=5.0
|
|
118
|
+
- ruff>=0.5
|
|
119
|
+
- pre-commit>=3.5
|
|
120
|
+
|
|
121
|
+
# ────────────────────────────────────────────────────────────────────
|
|
122
|
+
# Build toolchain (needed by some pip packages below)
|
|
123
|
+
# ────────────────────────────────────────────────────────────────────
|
|
124
|
+
- pip
|
|
125
|
+
- setuptools>=70
|
|
126
|
+
- wheel
|
|
127
|
+
- cython>=3.0
|
|
128
|
+
- cmake>=3.27
|
|
129
|
+
|
|
130
|
+
# ────────────────────────────────────────────────────────────────────
|
|
131
|
+
# pip-only / research-only packages (not on conda-forge or pip is
|
|
132
|
+
# the canonical install method)
|
|
133
|
+
# ────────────────────────────────────────────────────────────────────
|
|
134
|
+
- pip:
|
|
135
|
+
# 3D point cloud analysis
|
|
136
|
+
- open3d>=0.19
|
|
137
|
+
- meshplot
|
|
138
|
+
|
|
139
|
+
# Brain-specific visualization
|
|
140
|
+
- scienceplots>=2.1
|
|
141
|
+
- yabplot
|
|
142
|
+
- hippunfold-plot
|
|
143
|
+
- hippomaps
|
|
144
|
+
- enigmatoolbox
|
|
145
|
+
|
|
146
|
+
# ANTsPy (complex build; pip wheel is more reliable)
|
|
147
|
+
- antspyx>=0.4
|
|
148
|
+
|
|
149
|
+
# SuStaIn (disease progression modeling)
|
|
150
|
+
- git+https://github.com/ucl-pond/pySuStaIn.git
|
|
151
|
+
|
|
152
|
+
# SpectralBrain itself (editable install from local checkout)
|
|
153
|
+
# Uncomment after cloning the repo:
|
|
154
|
+
# - -e ".[full]"
|
|
155
|
+
|
|
156
|
+
variables:
|
|
157
|
+
# Prevent macOS OpenMP duplicate-runtime crash
|
|
158
|
+
KMP_DUPLICATE_LIB_OK: "TRUE"
|
|
159
|
+
# Force EGL for headless rendering (VTK 9.5+ PyPI wheel has EGL built-in)
|
|
160
|
+
PYOPENGL_PLATFORM: "egl"
|