p-brain 3.0.0__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.
- p_brain-3.0.0/LICENSE +21 -0
- p_brain-3.0.0/PKG-INFO +596 -0
- p_brain-3.0.0/README.md +519 -0
- p_brain-3.0.0/p_brain.egg-info/PKG-INFO +596 -0
- p_brain-3.0.0/p_brain.egg-info/SOURCES.txt +132 -0
- p_brain-3.0.0/p_brain.egg-info/dependency_links.txt +1 -0
- p_brain-3.0.0/p_brain.egg-info/entry_points.txt +2 -0
- p_brain-3.0.0/p_brain.egg-info/requires.txt +40 -0
- p_brain-3.0.0/p_brain.egg-info/top_level.txt +1 -0
- p_brain-3.0.0/pbrain/__init__.py +48 -0
- p_brain-3.0.0/pbrain/__main__.py +6 -0
- p_brain-3.0.0/pbrain/_console.py +35 -0
- p_brain-3.0.0/pbrain/_paths.py +34 -0
- p_brain-3.0.0/pbrain/aggregation/__init__.py +10 -0
- p_brain-3.0.0/pbrain/aggregation/base.py +62 -0
- p_brain-3.0.0/pbrain/aggregation/median_curve.py +257 -0
- p_brain-3.0.0/pbrain/aggregation/parcel.py +124 -0
- p_brain-3.0.0/pbrain/aggregation/region.py +122 -0
- p_brain-3.0.0/pbrain/aggregation/slice_wise.py +101 -0
- p_brain-3.0.0/pbrain/aggregation/voxelwise.py +83 -0
- p_brain-3.0.0/pbrain/aif/__init__.py +10 -0
- p_brain-3.0.0/pbrain/aif/_backshift.py +156 -0
- p_brain-3.0.0/pbrain/aif/base.py +74 -0
- p_brain-3.0.0/pbrain/aif/cnn.py +610 -0
- p_brain-3.0.0/pbrain/aif/cnn_sss_shifted.py +121 -0
- p_brain-3.0.0/pbrain/aif/curve_file.py +105 -0
- p_brain-3.0.0/pbrain/aif/deterministic.py +138 -0
- p_brain-3.0.0/pbrain/aif/from_file.py +87 -0
- p_brain-3.0.0/pbrain/aif/manual.py +334 -0
- p_brain-3.0.0/pbrain/aif/ranker.py +178 -0
- p_brain-3.0.0/pbrain/cli/__init__.py +1 -0
- p_brain-3.0.0/pbrain/cli/__main__.py +145 -0
- p_brain-3.0.0/pbrain/cli/_config_file.py +108 -0
- p_brain-3.0.0/pbrain/cli/_deps.py +106 -0
- p_brain-3.0.0/pbrain/cli/_fetch.py +164 -0
- p_brain-3.0.0/pbrain/cli/_setup.py +136 -0
- p_brain-3.0.0/pbrain/cli/cohort.py +220 -0
- p_brain-3.0.0/pbrain/cli/run.py +398 -0
- p_brain-3.0.0/pbrain/core/__init__.py +30 -0
- p_brain-3.0.0/pbrain/core/config.py +94 -0
- p_brain-3.0.0/pbrain/core/devices.py +141 -0
- p_brain-3.0.0/pbrain/core/discovery.py +92 -0
- p_brain-3.0.0/pbrain/core/logs.py +77 -0
- p_brain-3.0.0/pbrain/core/manifest.py +72 -0
- p_brain-3.0.0/pbrain/core/path_scheme.py +66 -0
- p_brain-3.0.0/pbrain/core/pipeline.py +176 -0
- p_brain-3.0.0/pbrain/core/plugin.py +36 -0
- p_brain-3.0.0/pbrain/core/qc.py +166 -0
- p_brain-3.0.0/pbrain/core/stage.py +69 -0
- p_brain-3.0.0/pbrain/demo/__init__.py +8 -0
- p_brain-3.0.0/pbrain/demo/__main__.py +452 -0
- p_brain-3.0.0/pbrain/diagnostics/__init__.py +10 -0
- p_brain-3.0.0/pbrain/diagnostics/_generic.py +135 -0
- p_brain-3.0.0/pbrain/diagnostics/base.py +51 -0
- p_brain-3.0.0/pbrain/diagnostics/conversion.py +116 -0
- p_brain-3.0.0/pbrain/diagnostics/montage.py +221 -0
- p_brain-3.0.0/pbrain/diagnostics/patlak.py +166 -0
- p_brain-3.0.0/pbrain/diagnostics/tikhonov.py +278 -0
- p_brain-3.0.0/pbrain/diagnostics/tikhonov_bayes.py +179 -0
- p_brain-3.0.0/pbrain/diffusion/__init__.py +15 -0
- p_brain-3.0.0/pbrain/diffusion/base.py +102 -0
- p_brain-3.0.0/pbrain/diffusion/csd.py +128 -0
- p_brain-3.0.0/pbrain/diffusion/dki.py +101 -0
- p_brain-3.0.0/pbrain/diffusion/dki_micro.py +113 -0
- p_brain-3.0.0/pbrain/diffusion/dti.py +92 -0
- p_brain-3.0.0/pbrain/diffusion/fwdti.py +88 -0
- p_brain-3.0.0/pbrain/diffusion/noddi.py +118 -0
- p_brain-3.0.0/pbrain/diffusion/rsi.py +159 -0
- p_brain-3.0.0/pbrain/diffusion/tractography.py +203 -0
- p_brain-3.0.0/pbrain/io/__init__.py +1 -0
- p_brain-3.0.0/pbrain/io/ir_assembly.py +388 -0
- p_brain-3.0.0/pbrain/io/loaders/__init__.py +31 -0
- p_brain-3.0.0/pbrain/io/loaders/base.py +62 -0
- p_brain-3.0.0/pbrain/io/loaders/dicom.py +116 -0
- p_brain-3.0.0/pbrain/io/loaders/dwi.py +182 -0
- p_brain-3.0.0/pbrain/io/loaders/nifti.py +113 -0
- p_brain-3.0.0/pbrain/io/loaders/parrec.py +164 -0
- p_brain-3.0.0/pbrain/io/path_schemes/__init__.py +10 -0
- p_brain-3.0.0/pbrain/io/path_schemes/base.py +5 -0
- p_brain-3.0.0/pbrain/io/path_schemes/bids_like.py +131 -0
- p_brain-3.0.0/pbrain/io/path_schemes/legacy.py +103 -0
- p_brain-3.0.0/pbrain/io/subject_discovery.py +130 -0
- p_brain-3.0.0/pbrain/models/__init__.py +17 -0
- p_brain-3.0.0/pbrain/models/_baseline_shift.py +359 -0
- p_brain-3.0.0/pbrain/models/_patlak_tools.py +528 -0
- p_brain-3.0.0/pbrain/models/base.py +168 -0
- p_brain-3.0.0/pbrain/models/extended_tofts.py +366 -0
- p_brain-3.0.0/pbrain/models/patlak.py +475 -0
- p_brain-3.0.0/pbrain/models/patlak_legacy.py +59 -0
- p_brain-3.0.0/pbrain/models/tikhonov.py +1046 -0
- p_brain-3.0.0/pbrain/models/tikhonov_bayes.py +93 -0
- p_brain-3.0.0/pbrain/models/tikhonov_legacy.py +60 -0
- p_brain-3.0.0/pbrain/normalisation/__init__.py +10 -0
- p_brain-3.0.0/pbrain/normalisation/base.py +37 -0
- p_brain-3.0.0/pbrain/normalisation/baseline_p95.py +90 -0
- p_brain-3.0.0/pbrain/normalisation/identity.py +55 -0
- p_brain-3.0.0/pbrain/normalisation/legacy_shift.py +260 -0
- p_brain-3.0.0/pbrain/signal_to_conc/__init__.py +10 -0
- p_brain-3.0.0/pbrain/signal_to_conc/base.py +41 -0
- p_brain-3.0.0/pbrain/signal_to_conc/baseline.py +113 -0
- p_brain-3.0.0/pbrain/signal_to_conc/saturation_recovery.py +117 -0
- p_brain-3.0.0/pbrain/signal_to_conc/spgr.py +95 -0
- p_brain-3.0.0/pbrain/signal_to_conc/vfa_spgr.py +75 -0
- p_brain-3.0.0/pbrain/stages/__init__.py +92 -0
- p_brain-3.0.0/pbrain/stages/_builtin.py +1195 -0
- p_brain-3.0.0/pbrain/stages/_diagnostics.py +306 -0
- p_brain-3.0.0/pbrain/t1_m0/__init__.py +10 -0
- p_brain-3.0.0/pbrain/t1_m0/base.py +56 -0
- p_brain-3.0.0/pbrain/t1_m0/inversion_recovery.py +315 -0
- p_brain-3.0.0/pbrain/t1_m0/preloaded.py +77 -0
- p_brain-3.0.0/pbrain/t1_m0/vfa_spgr.py +98 -0
- p_brain-3.0.0/pbrain/tissue_roi/__init__.py +10 -0
- p_brain-3.0.0/pbrain/tissue_roi/base.py +67 -0
- p_brain-3.0.0/pbrain/tissue_roi/command.py +113 -0
- p_brain-3.0.0/pbrain/tissue_roi/fastsurfer.py +38 -0
- p_brain-3.0.0/pbrain/tissue_roi/manual.py +38 -0
- p_brain-3.0.0/pbrain/tissue_roi/preloaded.py +202 -0
- p_brain-3.0.0/pbrain/tissue_roi/synthseg.py +248 -0
- p_brain-3.0.0/pbrain/tissue_roi/voxelwise.py +69 -0
- p_brain-3.0.0/pyproject.toml +82 -0
- p_brain-3.0.0/setup.cfg +4 -0
- p_brain-3.0.0/tests/test_pbrain_aggregation.py +101 -0
- p_brain-3.0.0/tests/test_pbrain_aif.py +152 -0
- p_brain-3.0.0/tests/test_pbrain_cnr_qc.py +142 -0
- p_brain-3.0.0/tests/test_pbrain_contracts.py +124 -0
- p_brain-3.0.0/tests/test_pbrain_loaders.py +168 -0
- p_brain-3.0.0/tests/test_pbrain_models_parity.py +221 -0
- p_brain-3.0.0/tests/test_pbrain_normalisation.py +80 -0
- p_brain-3.0.0/tests/test_pbrain_path_schemes.py +47 -0
- p_brain-3.0.0/tests/test_pbrain_patlak_vectorised.py +236 -0
- p_brain-3.0.0/tests/test_pbrain_signal_to_conc.py +47 -0
- p_brain-3.0.0/tests/test_pbrain_stages_qc.py +190 -0
- p_brain-3.0.0/tests/test_pbrain_t1m0.py +57 -0
- p_brain-3.0.0/tests/test_pbrain_tractography.py +99 -0
p_brain-3.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Edis Devin Tireli
|
|
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.
|
p_brain-3.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: p-brain
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: A modular, cross-platform framework for automated DCE-MRI and diffusion MRI research.
|
|
5
|
+
Author-email: Edis Devin Tireli <aizibuzi@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2023 Edis Devin Tireli
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/edtireli/p-brain
|
|
29
|
+
Project-URL: Repository, https://github.com/edtireli/p-brain
|
|
30
|
+
Project-URL: Issues, https://github.com/edtireli/p-brain/issues
|
|
31
|
+
Keywords: MRI,DCE-MRI,diffusion,pharmacokinetics,neuroimaging,Patlak,Tikhonov
|
|
32
|
+
Classifier: Development Status :: 4 - Beta
|
|
33
|
+
Classifier: Intended Audience :: Science/Research
|
|
34
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
35
|
+
Classifier: Operating System :: OS Independent
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
40
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
41
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
42
|
+
Requires-Python: >=3.10
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
License-File: LICENSE
|
|
45
|
+
Requires-Dist: numpy>=1.24
|
|
46
|
+
Requires-Dist: scipy>=1.10
|
|
47
|
+
Requires-Dist: matplotlib>=3.7
|
|
48
|
+
Requires-Dist: nibabel>=5.0
|
|
49
|
+
Provides-Extra: cnn
|
|
50
|
+
Requires-Dist: tensorflow>=2.13; extra == "cnn"
|
|
51
|
+
Provides-Extra: diffusion
|
|
52
|
+
Requires-Dist: dipy>=1.7; extra == "diffusion"
|
|
53
|
+
Provides-Extra: noddi
|
|
54
|
+
Requires-Dist: dmri-amico>=2.0; extra == "noddi"
|
|
55
|
+
Provides-Extra: dicom
|
|
56
|
+
Requires-Dist: pydicom>=2.4; extra == "dicom"
|
|
57
|
+
Provides-Extra: yaml
|
|
58
|
+
Requires-Dist: pyyaml>=6.0; extra == "yaml"
|
|
59
|
+
Provides-Extra: torch
|
|
60
|
+
Requires-Dist: torch>=2.0; extra == "torch"
|
|
61
|
+
Provides-Extra: dev
|
|
62
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
63
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
64
|
+
Provides-Extra: docs
|
|
65
|
+
Requires-Dist: mkdocs>=1.5; extra == "docs"
|
|
66
|
+
Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
|
|
67
|
+
Requires-Dist: mkdocs-material>=9.0; extra == "docs"
|
|
68
|
+
Provides-Extra: all
|
|
69
|
+
Requires-Dist: tensorflow>=2.13; extra == "all"
|
|
70
|
+
Requires-Dist: dipy>=1.7; extra == "all"
|
|
71
|
+
Requires-Dist: dmri-amico>=2.0; extra == "all"
|
|
72
|
+
Requires-Dist: pydicom>=2.4; extra == "all"
|
|
73
|
+
Requires-Dist: pyyaml>=6.0; extra == "all"
|
|
74
|
+
Requires-Dist: pytest>=7.0; extra == "all"
|
|
75
|
+
Requires-Dist: pytest-cov>=4.0; extra == "all"
|
|
76
|
+
Dynamic: license-file
|
|
77
|
+
|
|
78
|
+
# _p_-Brain — a modular framework for automated DCE-MRI & diffusion research
|
|
79
|
+
|
|
80
|
+
[](https://github.com/edtireli/p-brain/actions/workflows/ci.yml)
|
|
81
|
+
[](https://www.python.org/)
|
|
82
|
+
[](LICENSE)
|
|
83
|
+
[](#install)
|
|
84
|
+
|
|
85
|
+
<img width="2500" height="549" alt="pbrainplatform_banner" src="https://github.com/user-attachments/assets/e0c55c26-5c31-468f-9380-3b045e3a495c" />
|
|
86
|
+
|
|
87
|
+
**_p_-Brain is a cross-platform Python command-line tool.** Install it with
|
|
88
|
+
`pip` on Linux, macOS, or Windows (Python 3.10–3.12), point `pbrain run` at a
|
|
89
|
+
subject's scans, and it produces the full derivatives tree — no notebook, no
|
|
90
|
+
GUI, no server required. The CLI is the product; an optional macOS desktop app
|
|
91
|
+
is just one front-end on top of it (see [below](#optional-macos-app)).
|
|
92
|
+
|
|
93
|
+
_p_-Brain takes raw dynamic-contrast-enhanced (and diffusion) MRI through the
|
|
94
|
+
whole analysis — T1/M0 mapping, arterial-input-function extraction,
|
|
95
|
+
signal-to-concentration conversion, tissue parcellation, pharmacokinetic and
|
|
96
|
+
diffusion modelling — and produces standardised voxel-, tissue-, and
|
|
97
|
+
parcel-level results, fully automatically.
|
|
98
|
+
|
|
99
|
+
It is two things at once. **As shipped it is a validated, ready-to-run
|
|
100
|
+
pipeline** you can point at real scanner data today and get publication-grade
|
|
101
|
+
maps (Ki, CBF, MTT, CTH, FA, …). And it is a **template you extend**: each step
|
|
102
|
+
is a self-contained plug-in, so adding your own kinetic model — or a different
|
|
103
|
+
AIF, segmentation backend, or whole stage — is a single file and **no changes
|
|
104
|
+
to the core**. Drop a model into `pbrain/models/`, call it with `--models
|
|
105
|
+
yourmodel`, and it is run on every subject, aggregated to every anatomical
|
|
106
|
+
level, written as NIfTI/CSV/JSON, and given diagnostics automatically.
|
|
107
|
+
|
|
108
|
+
The aim is to let groups stop re-implementing the same plumbing: use it as-is,
|
|
109
|
+
modify what you need, and extend it to go beyond — while everyone's outputs
|
|
110
|
+
stay directly comparable.
|
|
111
|
+
|
|
112
|
+
> If you use _p_-Brain in your research, please **cite our paper** (Tireli et
|
|
113
|
+
> al.; see [Citation](#citation)).
|
|
114
|
+
|
|
115
|
+
> **Author:** Edis Devin Tireli, M.Sc., Ph.D. student
|
|
116
|
+
> **Affiliations:** Functional Imaging Unit, Copenhagen University Hospital – Rigshospitalet; Department of Neuroscience and Department of Clinical Medicine, University of Copenhagen.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Contents
|
|
121
|
+
|
|
122
|
+
1. [Why a framework](#why-a-framework) — the idea, and how the pieces fit
|
|
123
|
+
2. [Install](#install)
|
|
124
|
+
3. [How to run](#how-to-run) — first steps, the flags explained, quick start
|
|
125
|
+
4. [Add your own model — it's one file](#add-your-own) — the headline feature
|
|
126
|
+
5. [Config files](#config-files)
|
|
127
|
+
6. [Models](#models) — what's shipped, defaults, and every option
|
|
128
|
+
7. [Diffusion & connectomics](#diffusion)
|
|
129
|
+
8. [Outputs](#outputs) — the standardised result tree
|
|
130
|
+
9. [Representative output](#representative-output)
|
|
131
|
+
10. [Demo](#demo) · [Repository structure](#repository-structure) · [Citation](#citation)
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Why a framework
|
|
136
|
+
|
|
137
|
+
DCE-MRI analysis is a chain of stages — fit T1, find the artery, convert signal
|
|
138
|
+
to contrast concentration, segment tissue, fit a kinetic model, summarise. In
|
|
139
|
+
most labs each of these is bespoke code, so results are hard to compare and a
|
|
140
|
+
new model means re-plumbing the whole pipeline.
|
|
141
|
+
|
|
142
|
+
_p_-Brain makes each stage a **plug-in**: a single file that declares what it
|
|
143
|
+
needs and what it produces, discovered automatically at runtime. The
|
|
144
|
+
orchestrator wires the stages together by those declarations — so:
|
|
145
|
+
|
|
146
|
+
- **adding a method changes one file, never the core;**
|
|
147
|
+
- **every model is run, aggregated, and reported the same way**, giving
|
|
148
|
+
standardised, directly-comparable outputs across groups;
|
|
149
|
+
- you can **swap any step** (a different AIF, your lab's segmentation tool, a
|
|
150
|
+
new deconvolution) by name on the command line.
|
|
151
|
+
|
|
152
|
+
There are 12 such plug-points. The full contract and copy-paste templates live
|
|
153
|
+
in **[`docs/ADDING_PLUGINS.md`](docs/ADDING_PLUGINS.md)**; the design rationale
|
|
154
|
+
in **[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)**. Read those two when you
|
|
155
|
+
want to extend the framework — the rest of this README gets you running first.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Install
|
|
160
|
+
|
|
161
|
+
_p_-Brain is a normal `pip`-installable Python package. It runs on **Linux,
|
|
162
|
+
macOS, and Windows** with **Python 3.10–3.12**.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
pip install p-brain # core install — installs the `pbrain` command
|
|
166
|
+
pbrain --help
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
That gives you the `pbrain` command (and `python -m pbrain`) plus the light core
|
|
170
|
+
dependencies — `numpy, scipy, matplotlib, nibabel`. Everything heavier is an
|
|
171
|
+
**opt-in extra**, installed only if you select a plug-in that needs it:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
pip install "p-brain[cnn]" # TensorFlow — CNN arterial-input-function (default AIF)
|
|
175
|
+
pip install "p-brain[diffusion]" # dipy — the diffusion track (DTI/DKI/CSD/…)
|
|
176
|
+
pip install "p-brain[dicom]" # pydicom — DICOM input (see DICOM input below)
|
|
177
|
+
pip install "p-brain[all]" # everything in one go
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The default AIF (`cnn_sss_shifted`) needs the CNN extra **and** its trained
|
|
181
|
+
`.keras` weights (~1.2 GB), archived on Zenodo. Download them once — they cache
|
|
182
|
+
under `~/.p-brain/AI` and every later run finds them automatically:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pbrain setup # interactive: installs extras + offers to fetch weights & data
|
|
186
|
+
pbrain fetch-weights # just the CNN weights (Zenodo 10.5281/zenodo.15697443)
|
|
187
|
+
pbrain fetch-data # the example subject sub-01 (Zenodo 10.5281/zenodo.20826857)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
To run weights-free, pick a model-free AIF (`--aif deterministic`, or `from_file`
|
|
191
|
+
/ `manual` for your own ROIs/curves), or try `python -m pbrain.demo`, which needs
|
|
192
|
+
no weights or data at all.
|
|
193
|
+
|
|
194
|
+
**From source** (for development or the bleeding edge):
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
git clone https://github.com/edtireli/p-brain.git
|
|
198
|
+
cd p-brain
|
|
199
|
+
pip install -e ".[dev]" # editable install + test tooling
|
|
200
|
+
pytest -q # run the test suite
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Check your environment.** `python -m pbrain check-deps` verifies the
|
|
204
|
+
third-party Python deps and offers to install any that are missing;
|
|
205
|
+
`python -m pbrain setup` additionally inspects external tooling (`dcm2niix`,
|
|
206
|
+
optionally FreeSurfer for segmentation, GPU support) and walks you through it.
|
|
207
|
+
|
|
208
|
+
### DICOM input
|
|
209
|
+
|
|
210
|
+
_p_-Brain reads **NIfTI** (`.nii` / `.nii.gz`) and **Philips PAR/REC** natively.
|
|
211
|
+
**DICOM** is supported through [`dcm2niix`](https://github.com/rordenlab/dcm2niix),
|
|
212
|
+
the standard, well-validated DICOM→NIfTI converter: point `--dce` / `--ir` /
|
|
213
|
+
`--dwi` at a DICOM file or a folder of DICOMs and _p_-Brain calls `dcm2niix`
|
|
214
|
+
under the hood, picking up the reconstructed NIfTI (and, for diffusion, the
|
|
215
|
+
`.bval` / `.bvec` gradient tables it writes).
|
|
216
|
+
|
|
217
|
+
Install `dcm2niix` from its own channel — it is a compiled binary, not a pip
|
|
218
|
+
package:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
conda install -c conda-forge dcm2niix # any OS (recommended)
|
|
222
|
+
brew install dcm2niix # macOS
|
|
223
|
+
sudo apt install dcm2niix # Debian / Ubuntu
|
|
224
|
+
# Windows: download the release .zip from the dcm2niix GitHub and add it to PATH
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`pip install "p-brain[dicom]"` adds `pydicom` for header inspection;
|
|
228
|
+
`dcm2niix` must be on your `PATH` for the actual conversion. Run
|
|
229
|
+
`python -m pbrain check-deps` to confirm it is found.
|
|
230
|
+
|
|
231
|
+
### Optional macOS app
|
|
232
|
+
|
|
233
|
+
A native macOS desktop app wraps this CLI in a point-and-click GUI for users who
|
|
234
|
+
prefer not to touch a terminal. It is **entirely optional** — the Python CLI
|
|
235
|
+
above is the product and the canonical interface; the app simply drives it.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## How to run
|
|
240
|
+
|
|
241
|
+
A run takes one subject's raw data and produces its full derivatives tree.
|
|
242
|
+
The first three steps:
|
|
243
|
+
|
|
244
|
+
1. **Point at your data.** `--dce` is the 4-D DCE series (NIfTI, PAR/REC, or
|
|
245
|
+
DICOM — converted automatically). `--ir` is the inversion-recovery series
|
|
246
|
+
used to fit T1/M0; `--dwi` is an optional diffusion scan. Each of `--dce`,
|
|
247
|
+
`--t1`, `--ir` accepts a **full path, a filename, a protocol-name substring,
|
|
248
|
+
or `auto`** — so you can write `--dce hperf --t1 auto --ir auto` once and
|
|
249
|
+
reuse it across subjects whose scan numbers differ (raw PAR/REC are matched
|
|
250
|
+
by their Philips `Protocol name`; `--ir auto` assembles the `TI_*` series).
|
|
251
|
+
2. **Choose your methods.** `--models patlak,tikhonov` selects the kinetic
|
|
252
|
+
models; `--aif`, `--tissue-roi`, `--t1m0` select how each upstream step is
|
|
253
|
+
done. Sensible defaults mean you can omit most of them.
|
|
254
|
+
3. **Choose your output levels.** `--aggregations voxelwise,region,parcel`
|
|
255
|
+
controls whether you get whole-brain maps, tissue-class summaries, and/or
|
|
256
|
+
per-parcel tables.
|
|
257
|
+
|
|
258
|
+
### The flags, explained
|
|
259
|
+
|
|
260
|
+
| flag | meaning | default |
|
|
261
|
+
|---|---|---|
|
|
262
|
+
| `--subject-dir` | where the derivatives tree is written | (required) |
|
|
263
|
+
| `--dce` | 4-D DCE series (NIfTI / PAR-REC / DICOM) | (required) |
|
|
264
|
+
| `--ir` | inversion-recovery series for the T1/M0 fit | — |
|
|
265
|
+
| `--dwi` | diffusion series (for the diffusion track) | — |
|
|
266
|
+
| `--t1m0` | how T1 & M0 are obtained (`inversion_recovery`, `vfa_spgr`, …) | `inversion_recovery` |
|
|
267
|
+
| `--aif` | arterial-input-function method | `cnn_sss_shifted` |
|
|
268
|
+
| `--tissue-roi` | parcellation source (`synthseg`, `fastsurfer`, `command`, `preloaded`, …) | `voxelwise` |
|
|
269
|
+
| `--models` | comma-list of kinetic models to run | `patlak,tikhonov` |
|
|
270
|
+
| `--diffusion` | comma-list of diffusion models, or `default`/`all` | (auto when `--dwi` given) |
|
|
271
|
+
| `--aggregations` | output levels: `voxelwise,region,parcel,slice_wise` | `voxelwise,parcel,region` |
|
|
272
|
+
| `--device` | `cpu` / `mps` / `cuda` / `auto` | `cpu` |
|
|
273
|
+
| `--config` | read all of the above from a `.toml`/`.yaml` file | — |
|
|
274
|
+
|
|
275
|
+
Two niceties: runs are **resumable** (a finished stage is skipped on re-run;
|
|
276
|
+
`--force` recomputes), and every output carries **provenance** (the `pbrain`
|
|
277
|
+
version and exact options that made it). Use `--quiet` / `--verbose` /
|
|
278
|
+
`--log-file` to control logging.
|
|
279
|
+
|
|
280
|
+
### Quick start
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
# Minimal: DCE + IR, the default models, all output levels
|
|
284
|
+
python -m pbrain run \
|
|
285
|
+
--subject-dir /data/sub-01 \
|
|
286
|
+
--dce dce.nii.gz --ir ir.nii.gz \
|
|
287
|
+
--models patlak,tikhonov \
|
|
288
|
+
--aggregations voxelwise,parcel,region
|
|
289
|
+
|
|
290
|
+
# With diffusion (FA/MD + tractography) in the same command
|
|
291
|
+
python -m pbrain run \
|
|
292
|
+
--subject-dir /data/sub-01 \
|
|
293
|
+
--dce dce.nii.gz --ir ir.nii.gz --dwi dwi.nii.gz \
|
|
294
|
+
--models patlak,tikhonov --diffusion default
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**See what's available** — every plug-in, its inputs/outputs, its diagnostic:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
python -m pbrain list # all plug-points at a glance
|
|
301
|
+
python -m pbrain list models # one plug-point in detail
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Run a whole cohort** — parallel, resumable, error-isolated:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# ── one flag, raw scanner data: point --cohort at a folder of subjects ──
|
|
308
|
+
# Each sub-directory is a subject of raw Philips PAR/REC. Inputs are
|
|
309
|
+
# auto-discovered by protocol name (DCE = hperf*; the TI_* saturation-recovery
|
|
310
|
+
# series is assembled into an IR; a 3-D T1 anatomical for SynthSeg), then the
|
|
311
|
+
# full pipeline runs with ALL kinetic models at tissue (region) + parcel level.
|
|
312
|
+
# No config needed. Add --force for a fresh re-run. Pass several roots to run
|
|
313
|
+
# patients + controls + follow-ups in one go.
|
|
314
|
+
python -m pbrain run-cohort --cohort /data/patients /data/controls --workers 4 --force
|
|
315
|
+
|
|
316
|
+
# pick models / levels, or skip known-bad subjects:
|
|
317
|
+
python -m pbrain run-cohort --cohort /data/patients --workers 4 \
|
|
318
|
+
--models tikhonov,inverse_gaussian --aggregations region,parcel \
|
|
319
|
+
--exclude 20221003x1 # --voxelwise to fit per-voxel (slower)
|
|
320
|
+
|
|
321
|
+
# ── config mode, pre-converted NIfTI cohorts: inputs from a shared config ──
|
|
322
|
+
python -m pbrain run-cohort --config study.toml --data-dir /data --workers 8
|
|
323
|
+
python -m pbrain run-cohort --config study.toml --subjects-glob '/data/sub-*' --workers 8
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
`--cohort` is the one-flag "do the whole study" path: it resolves each subject's
|
|
327
|
+
DCE / IR / T1 itself (scan numbers vary between subjects, so they can't be
|
|
328
|
+
templated by name) and fits every model at the parcel level by default
|
|
329
|
+
(average-then-fit — exactly the resolution these models support, and tractable
|
|
330
|
+
across hundreds of subjects). Use `--config` mode when inputs are already
|
|
331
|
+
NIfTI and named consistently.
|
|
332
|
+
|
|
333
|
+
**Override any option** with `--opt <plug-point>.<plugin>.<key>=<value>`, e.g.
|
|
334
|
+
`--opt models.tikhonov.lambda_selection=evidence`. Every knob is documented
|
|
335
|
+
under [Models](#models).
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Add your own
|
|
340
|
+
|
|
341
|
+
> **Step-by-step guide:** [`docs/ADDING_PLUGINS.md`](docs/ADDING_PLUGINS.md) —
|
|
342
|
+
> templates for models, AIF methods, segmentation backends, diffusion models,
|
|
343
|
+
> and whole pipeline stages. Start there.
|
|
344
|
+
|
|
345
|
+
A new kinetic model is one file and no core changes. You write the maths; the
|
|
346
|
+
framework runs it on every voxel/curve, aggregates the result to tissue classes
|
|
347
|
+
and parcels, writes NIfTI + CSV + JSON, and renders fit diagnostics.
|
|
348
|
+
|
|
349
|
+
`pbrain/models/two_cxm.py`:
|
|
350
|
+
|
|
351
|
+
```python
|
|
352
|
+
from dataclasses import dataclass
|
|
353
|
+
from typing import Any, ClassVar
|
|
354
|
+
import numpy as np
|
|
355
|
+
from .base import CurveInputs, ModelResult
|
|
356
|
+
|
|
357
|
+
@dataclass(frozen=True, slots=True)
|
|
358
|
+
class TwoCXM:
|
|
359
|
+
key: ClassVar[str] = "two_cxm" # the name you call it by
|
|
360
|
+
name: ClassVar[str] = "Two-compartment exchange model"
|
|
361
|
+
description: ClassVar[str] = "Fp, PS, vp, ve via 2CXM least-squares."
|
|
362
|
+
outputs: ClassVar[tuple] = ("fp", "ps", "vp", "ve")
|
|
363
|
+
units: ClassVar[dict] = {"fp": "mL/100g/min", "ps": "mL/100g/min",
|
|
364
|
+
"vp": "fraction", "ve": "fraction"}
|
|
365
|
+
|
|
366
|
+
def fit(self, inputs: CurveInputs, **opts: Any) -> ModelResult:
|
|
367
|
+
... # your maths → fp, ps, vp, ve
|
|
368
|
+
return ModelResult(maps={"fp": fp, "ps": ps, "vp": vp, "ve": ve},
|
|
369
|
+
units=dict(self.units))
|
|
370
|
+
|
|
371
|
+
PLUGIN = TwoCXM()
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
That's the entire integration. Now:
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
python -m pbrain run --models two_cxm,patlak ...
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
runs your model alongside Patlak, produces `fp/ps/vp/ve` maps, aggregates each
|
|
381
|
+
to region and parcel level, and draws per-tissue fit plots — automatically.
|
|
382
|
+
|
|
383
|
+
The **step-by-step guide** for this and the other 11 plug-points (AIF methods,
|
|
384
|
+
segmentation backends, diffusion models, whole stages) is
|
|
385
|
+
**[`docs/ADDING_PLUGINS.md`](docs/ADDING_PLUGINS.md)** — start there.
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## Config files
|
|
390
|
+
|
|
391
|
+
For reproducibility, put the whole run in a versioned file —
|
|
392
|
+
`pbrain run --config study.toml` (CLI flags still override it):
|
|
393
|
+
|
|
394
|
+
```toml
|
|
395
|
+
subject_dir = "/data/sub-01"
|
|
396
|
+
|
|
397
|
+
[inputs]
|
|
398
|
+
dce = "dce.nii.gz"
|
|
399
|
+
ir = "ir.nii.gz"
|
|
400
|
+
dwi = "dwi.nii.gz"
|
|
401
|
+
|
|
402
|
+
[pipeline]
|
|
403
|
+
t1m0 = "inversion_recovery"
|
|
404
|
+
aif = "cnn_sss_shifted"
|
|
405
|
+
tissue_roi = "synthseg"
|
|
406
|
+
models = ["patlak", "tikhonov"]
|
|
407
|
+
diffusion = "default"
|
|
408
|
+
aggregations = ["region", "parcel"]
|
|
409
|
+
|
|
410
|
+
[acquisition]
|
|
411
|
+
flip_angle_deg = 30.0
|
|
412
|
+
tr_s = 0.01118
|
|
413
|
+
|
|
414
|
+
[options] # same keys as --opt
|
|
415
|
+
"models.tikhonov.lambda_selection" = "evidence"
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
TOML works out of the box; YAML needs `pip install pyyaml`.
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Models
|
|
423
|
+
|
|
424
|
+
Set any option with `--opt models.<key>.<opt>=<value>` (or in a config file).
|
|
425
|
+
Defaults are what you get without setting anything.
|
|
426
|
+
|
|
427
|
+
**`patlak`** — blood–brain-barrier influx **Ki** and blood volume **vp** from
|
|
428
|
+
the Patlak graphical analysis.
|
|
429
|
+
|
|
430
|
+
| option | default | what it does |
|
|
431
|
+
|---|---|---|
|
|
432
|
+
| `regression` | `huber` | slope fit: `huber` (robust to leverage points) or `ols`. |
|
|
433
|
+
| `tail_mode` | `smart` | which late points enter the fit: `smart` (curvature-detected linear tail) or `legacy` (fixed upper-2⁄3 window). |
|
|
434
|
+
| `aif_min_fraction` | `0.05` | drop AIF samples below this fraction of the peak (avoids a near-zero AIF blowing Ki up). |
|
|
435
|
+
|
|
436
|
+
**`tikhonov`** — **CBF, MTT, CTH** by regularised deconvolution of the residue
|
|
437
|
+
function.
|
|
438
|
+
|
|
439
|
+
| option | default | what it does |
|
|
440
|
+
|---|---|---|
|
|
441
|
+
| `lambda_selection` | `gcv` | regularisation strength: `gcv` (cross-validation), `lcurve`, or `evidence` (marginal likelihood — most robust on smooth curves). |
|
|
442
|
+
| `lambda_spacing` | `log` | λ grid spacing (`log`/`linear`). |
|
|
443
|
+
| `n_lambdas` | `121` | number of λ values searched. |
|
|
444
|
+
| `mtt_cth_method` | `residue_integral` | MTT/CTH from the residue integral or the central-volume theorem. |
|
|
445
|
+
|
|
446
|
+
**`extended_tofts`** — **Ktrans, ve, vp, kep** by constrained
|
|
447
|
+
Levenberg–Marquardt (no tuning needed for the default fit).
|
|
448
|
+
|
|
449
|
+
You are meant to add to this list — see [Add your own](#add-your-own).
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## Diffusion
|
|
454
|
+
|
|
455
|
+
Give a diffusion scan with `--dwi` (NIfTI, PAR/REC, or DICOM — converted
|
|
456
|
+
automatically, gradients extracted) and the diffusion track runs in native DWI
|
|
457
|
+
space and resamples to your parcellation. Select models with `--diffusion`
|
|
458
|
+
(`dti`, a comma-list, `default` = shell-aware, or `all`); options via
|
|
459
|
+
`--opt diffusion.<key>.<opt>=<value>`.
|
|
460
|
+
|
|
461
|
+
### Which model, when
|
|
462
|
+
|
|
463
|
+
- **`dti`** — the workhorse: **FA, MD, AD, RD** (+ colour-FA). Any DWI with a
|
|
464
|
+
b0 and one shell. **Start here for FA/MD.**
|
|
465
|
+
- **`dki`** — adds mean/axial/radial **kurtosis** and KFA. Needs ≥ 2 shells.
|
|
466
|
+
- **`dki_micro`** — WMTI microstructure (axonal water fraction, tortuosity) and
|
|
467
|
+
**μFA**. Multi-shell.
|
|
468
|
+
- **`fwdti`** — **free-water elimination**: tissue FA/MD with CSF/oedema removed
|
|
469
|
+
+ the free-water fraction. Multi-shell.
|
|
470
|
+
- **`csd`** — constrained spherical deconvolution: fibre orientations for
|
|
471
|
+
tractography + GFA. Multi-shell preferred.
|
|
472
|
+
- **`rsi`** — restriction-spectrum fractions (restricted/hindered/free); needs a
|
|
473
|
+
high-b shell.
|
|
474
|
+
- **`noddi`** — neurite density / orientation dispersion; needs AMICO + high-b.
|
|
475
|
+
|
|
476
|
+
### Connectomics (tractography → connectome)
|
|
477
|
+
|
|
478
|
+
With a fibre-orientation model (`csd` by default, or the `dti` tensor) the
|
|
479
|
+
diffusion track can run **tractography** and build a **structural connectome**
|
|
480
|
+
between parcels:
|
|
481
|
+
|
|
482
|
+
```bash
|
|
483
|
+
python -m pbrain run --dwi dwi.nii.gz --diffusion csd --connectome ...
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
This writes the streamlines (`.tck`, openable in MRtrix/TrackVis and rendered
|
|
487
|
+
as a track-density NIfTI for 3-D exploration) and a parcel × parcel connectivity
|
|
488
|
+
matrix (CSV/JSON) under `09_diffusion/`.
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## Outputs
|
|
493
|
+
|
|
494
|
+
A BIDS-like derivatives tree under `<subject-dir>/derivatives/`, numbered for
|
|
495
|
+
natural sort order:
|
|
496
|
+
|
|
497
|
+
```
|
|
498
|
+
00_diagnostics/ fit plots + whole-brain map montages
|
|
499
|
+
01_load/ loaded DCE/IR/DWI (+ timing)
|
|
500
|
+
02_t1m0/ T1 map + M0 map (t1_map.nii.gz, m0_map.nii.gz)
|
|
501
|
+
03_aif/ arterial input function
|
|
502
|
+
04_tissue_roi/ parcellation + tissue region map
|
|
503
|
+
05_signal_to_conc/ 4-D contrast concentration (concentration.nii.gz)
|
|
504
|
+
<converter>/diagnostics/ conversion QC plot (conversion_qc.png)
|
|
505
|
+
06_normalisation/ normalised curves
|
|
506
|
+
07_kinetic/<model>/ per model:
|
|
507
|
+
voxelwise/ whole-brain maps (nii.gz)
|
|
508
|
+
region/ parcel/ tissue & parcel summaries (nii.gz + csv + json)
|
|
509
|
+
diagnostics/{voxel,tissue,parcel,montage}/ fit plots & map montages
|
|
510
|
+
08_summary/ run summary + QC
|
|
511
|
+
09_diffusion/<model>/ FA/MD/… maps, + tractography & connectome
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Every model output exists as **nii.gz, csv, and json** at the region/parcel
|
|
515
|
+
levels. The T1 map, M0 map, and the **4-D concentration volume** are written as
|
|
516
|
+
NIfTI so you can use them directly. Each stage writes a `manifest.json` with its
|
|
517
|
+
provenance and a QC block (physiological-range flags). Per-model diagnostics —
|
|
518
|
+
the same fit plots shown in the paper — render every run.
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## Representative output
|
|
523
|
+
|
|
524
|
+
Whole-brain parameter maps for one subject, masked to the brain segmentation
|
|
525
|
+
(see the paper for the full set and quantitative validation):
|
|
526
|
+
|
|
527
|
+
**Ki — blood–brain-barrier influx (Patlak)**
|
|
528
|
+

|
|
529
|
+
|
|
530
|
+
**CBF — cerebral blood flow (Tikhonov deconvolution)**
|
|
531
|
+

|
|
532
|
+
|
|
533
|
+
**FA — fractional anisotropy (DTI)**
|
|
534
|
+

|
|
535
|
+
|
|
536
|
+
These montages are produced by the pipeline itself (the `diagnostics` stage),
|
|
537
|
+
with data-adaptive slice layout and brain-segmentation masking. Every map is
|
|
538
|
+
also aggregated to tissue classes and DKT parcels.
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
## Demo
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
python -m pbrain.demo --clean
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Synthesises a small phantom (no patient data), runs the **entire** pipeline
|
|
549
|
+
end-to-end, and writes parameter-map montages to `demo/maps/` — a self-contained
|
|
550
|
+
way to see the output format and confirm your install works.
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## Repository structure
|
|
555
|
+
|
|
556
|
+
```
|
|
557
|
+
pbrain/ the framework — everything lives here
|
|
558
|
+
core/ Plugin/Stage contracts, discovery, Config, Pipeline, logging, QC
|
|
559
|
+
io/ loaders (nifti/parrec/dicom/dwi) + output path schemes
|
|
560
|
+
t1_m0/ aif/ tissue_roi/ signal_to_conc/ normalisation/ upstream stages
|
|
561
|
+
models/ kinetic models diffusion/ diffusion models
|
|
562
|
+
aggregation/ voxel/region/parcel/slice rollups
|
|
563
|
+
diagnostics/ per-model fit plots + the montage generator
|
|
564
|
+
stages/ the pipeline steps (a discoverable, topologically-ordered plug-point)
|
|
565
|
+
cli/ demo/
|
|
566
|
+
docs/ ADDING_PLUGINS.md · ARCHITECTURE.md · mkdocs API reference
|
|
567
|
+
tests/ the test suite validation/ cohort runners
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
## Documentation
|
|
573
|
+
|
|
574
|
+
- **API reference** — a rendered reference generated from the package
|
|
575
|
+
docstrings (every public class, the plug-in contracts, the kinetic and
|
|
576
|
+
diffusion models, the pipeline stages, and the QC functions). Build it
|
|
577
|
+
locally with:
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
pip install "p-brain[docs]"
|
|
581
|
+
mkdocs build # → ./site/ (or `mkdocs serve` for a live preview)
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Entry points: [`docs/index.md`](docs/index.md) and the contributor
|
|
585
|
+
[architecture overview](docs/architecture-overview.md).
|
|
586
|
+
- **Extending the framework** —
|
|
587
|
+
[`docs/ADDING_PLUGINS.md`](docs/ADDING_PLUGINS.md) (copy-paste templates)
|
|
588
|
+
and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) (full design rationale
|
|
589
|
+
and output layout).
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## Citation
|
|
594
|
+
|
|
595
|
+
If _p_-Brain contributes to your work, please cite the accompanying paper
|
|
596
|
+
(Tireli et al.) and this repository. See [`LICENSE`](LICENSE) for terms.
|