junifer 0.0.3.dev188__py3-none-any.whl → 0.0.4__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.
- junifer/_version.py +14 -2
- junifer/api/cli.py +162 -17
- junifer/api/functions.py +87 -419
- junifer/api/parser.py +24 -0
- junifer/api/queue_context/__init__.py +8 -0
- junifer/api/queue_context/gnu_parallel_local_adapter.py +258 -0
- junifer/api/queue_context/htcondor_adapter.py +365 -0
- junifer/api/queue_context/queue_context_adapter.py +60 -0
- junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +192 -0
- junifer/api/queue_context/tests/test_htcondor_adapter.py +257 -0
- junifer/api/res/afni/run_afni_docker.sh +6 -6
- junifer/api/res/ants/ResampleImage +3 -0
- junifer/api/res/ants/antsApplyTransforms +3 -0
- junifer/api/res/ants/antsApplyTransformsToPoints +3 -0
- junifer/api/res/ants/run_ants_docker.sh +39 -0
- junifer/api/res/fsl/applywarp +3 -0
- junifer/api/res/fsl/flirt +3 -0
- junifer/api/res/fsl/img2imgcoord +3 -0
- junifer/api/res/fsl/run_fsl_docker.sh +39 -0
- junifer/api/res/fsl/std2imgcoord +3 -0
- junifer/api/res/run_conda.sh +4 -4
- junifer/api/res/run_venv.sh +22 -0
- junifer/api/tests/data/partly_cloudy_agg_mean_tian.yml +16 -0
- junifer/api/tests/test_api_utils.py +21 -3
- junifer/api/tests/test_cli.py +232 -9
- junifer/api/tests/test_functions.py +211 -439
- junifer/api/tests/test_parser.py +1 -1
- junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +6 -1
- junifer/configs/juseless/datagrabbers/camcan_vbm.py +6 -1
- junifer/configs/juseless/datagrabbers/ixi_vbm.py +6 -1
- junifer/configs/juseless/datagrabbers/tests/test_ucla.py +8 -8
- junifer/configs/juseless/datagrabbers/ucla.py +44 -26
- junifer/configs/juseless/datagrabbers/ukb_vbm.py +6 -1
- junifer/data/VOIs/meta/AutobiographicalMemory_VOIs.txt +23 -0
- junifer/data/VOIs/meta/Power2013_MNI_VOIs.tsv +264 -0
- junifer/data/__init__.py +4 -0
- junifer/data/coordinates.py +298 -31
- junifer/data/masks.py +360 -28
- junifer/data/parcellations.py +621 -188
- junifer/data/template_spaces.py +190 -0
- junifer/data/tests/test_coordinates.py +34 -3
- junifer/data/tests/test_data_utils.py +1 -0
- junifer/data/tests/test_masks.py +202 -86
- junifer/data/tests/test_parcellations.py +266 -55
- junifer/data/tests/test_template_spaces.py +104 -0
- junifer/data/utils.py +4 -2
- junifer/datagrabber/__init__.py +1 -0
- junifer/datagrabber/aomic/id1000.py +111 -70
- junifer/datagrabber/aomic/piop1.py +116 -53
- junifer/datagrabber/aomic/piop2.py +116 -53
- junifer/datagrabber/aomic/tests/test_id1000.py +27 -27
- junifer/datagrabber/aomic/tests/test_piop1.py +27 -27
- junifer/datagrabber/aomic/tests/test_piop2.py +27 -27
- junifer/datagrabber/base.py +62 -10
- junifer/datagrabber/datalad_base.py +0 -2
- junifer/datagrabber/dmcc13_benchmark.py +372 -0
- junifer/datagrabber/hcp1200/datalad_hcp1200.py +5 -0
- junifer/datagrabber/hcp1200/hcp1200.py +30 -13
- junifer/datagrabber/pattern.py +133 -27
- junifer/datagrabber/pattern_datalad.py +111 -13
- junifer/datagrabber/tests/test_base.py +57 -6
- junifer/datagrabber/tests/test_datagrabber_utils.py +204 -76
- junifer/datagrabber/tests/test_datalad_base.py +0 -6
- junifer/datagrabber/tests/test_dmcc13_benchmark.py +256 -0
- junifer/datagrabber/tests/test_multiple.py +43 -10
- junifer/datagrabber/tests/test_pattern.py +125 -178
- junifer/datagrabber/tests/test_pattern_datalad.py +44 -25
- junifer/datagrabber/utils.py +151 -16
- junifer/datareader/default.py +36 -10
- junifer/external/nilearn/junifer_nifti_spheres_masker.py +6 -0
- junifer/markers/base.py +25 -16
- junifer/markers/collection.py +35 -16
- junifer/markers/complexity/__init__.py +27 -0
- junifer/markers/complexity/complexity_base.py +149 -0
- junifer/markers/complexity/hurst_exponent.py +136 -0
- junifer/markers/complexity/multiscale_entropy_auc.py +140 -0
- junifer/markers/complexity/perm_entropy.py +132 -0
- junifer/markers/complexity/range_entropy.py +136 -0
- junifer/markers/complexity/range_entropy_auc.py +145 -0
- junifer/markers/complexity/sample_entropy.py +134 -0
- junifer/markers/complexity/tests/test_complexity_base.py +19 -0
- junifer/markers/complexity/tests/test_hurst_exponent.py +69 -0
- junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +68 -0
- junifer/markers/complexity/tests/test_perm_entropy.py +68 -0
- junifer/markers/complexity/tests/test_range_entropy.py +69 -0
- junifer/markers/complexity/tests/test_range_entropy_auc.py +69 -0
- junifer/markers/complexity/tests/test_sample_entropy.py +68 -0
- junifer/markers/complexity/tests/test_weighted_perm_entropy.py +68 -0
- junifer/markers/complexity/weighted_perm_entropy.py +133 -0
- junifer/markers/falff/_afni_falff.py +153 -0
- junifer/markers/falff/_junifer_falff.py +142 -0
- junifer/markers/falff/falff_base.py +91 -84
- junifer/markers/falff/falff_parcels.py +61 -45
- junifer/markers/falff/falff_spheres.py +64 -48
- junifer/markers/falff/tests/test_falff_parcels.py +89 -121
- junifer/markers/falff/tests/test_falff_spheres.py +92 -127
- junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +1 -0
- junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +1 -0
- junifer/markers/functional_connectivity/functional_connectivity_base.py +1 -0
- junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +46 -44
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +34 -39
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +40 -52
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +62 -70
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +99 -85
- junifer/markers/parcel_aggregation.py +60 -38
- junifer/markers/reho/_afni_reho.py +192 -0
- junifer/markers/reho/_junifer_reho.py +281 -0
- junifer/markers/reho/reho_base.py +69 -34
- junifer/markers/reho/reho_parcels.py +26 -16
- junifer/markers/reho/reho_spheres.py +23 -9
- junifer/markers/reho/tests/test_reho_parcels.py +93 -92
- junifer/markers/reho/tests/test_reho_spheres.py +88 -86
- junifer/markers/sphere_aggregation.py +54 -9
- junifer/markers/temporal_snr/temporal_snr_base.py +1 -0
- junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +38 -37
- junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +34 -38
- junifer/markers/tests/test_collection.py +43 -42
- junifer/markers/tests/test_ets_rss.py +29 -37
- junifer/markers/tests/test_parcel_aggregation.py +587 -468
- junifer/markers/tests/test_sphere_aggregation.py +209 -157
- junifer/markers/utils.py +2 -40
- junifer/onthefly/read_transform.py +13 -6
- junifer/pipeline/__init__.py +1 -0
- junifer/pipeline/pipeline_step_mixin.py +105 -41
- junifer/pipeline/registry.py +17 -0
- junifer/pipeline/singleton.py +45 -0
- junifer/pipeline/tests/test_pipeline_step_mixin.py +139 -51
- junifer/pipeline/tests/test_update_meta_mixin.py +1 -0
- junifer/pipeline/tests/test_workdir_manager.py +104 -0
- junifer/pipeline/update_meta_mixin.py +8 -2
- junifer/pipeline/utils.py +154 -15
- junifer/pipeline/workdir_manager.py +246 -0
- junifer/preprocess/__init__.py +3 -0
- junifer/preprocess/ants/__init__.py +4 -0
- junifer/preprocess/ants/ants_apply_transforms_warper.py +185 -0
- junifer/preprocess/ants/tests/test_ants_apply_transforms_warper.py +56 -0
- junifer/preprocess/base.py +96 -69
- junifer/preprocess/bold_warper.py +265 -0
- junifer/preprocess/confounds/fmriprep_confound_remover.py +91 -134
- junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +106 -111
- junifer/preprocess/fsl/__init__.py +4 -0
- junifer/preprocess/fsl/apply_warper.py +179 -0
- junifer/preprocess/fsl/tests/test_apply_warper.py +45 -0
- junifer/preprocess/tests/test_bold_warper.py +159 -0
- junifer/preprocess/tests/test_preprocess_base.py +6 -6
- junifer/preprocess/warping/__init__.py +6 -0
- junifer/preprocess/warping/_ants_warper.py +167 -0
- junifer/preprocess/warping/_fsl_warper.py +109 -0
- junifer/preprocess/warping/space_warper.py +213 -0
- junifer/preprocess/warping/tests/test_space_warper.py +198 -0
- junifer/stats.py +18 -4
- junifer/storage/base.py +9 -1
- junifer/storage/hdf5.py +8 -3
- junifer/storage/pandas_base.py +2 -1
- junifer/storage/sqlite.py +1 -0
- junifer/storage/tests/test_hdf5.py +2 -1
- junifer/storage/tests/test_sqlite.py +8 -8
- junifer/storage/tests/test_utils.py +6 -6
- junifer/storage/utils.py +1 -0
- junifer/testing/datagrabbers.py +11 -7
- junifer/testing/utils.py +1 -0
- junifer/tests/test_stats.py +2 -0
- junifer/utils/__init__.py +1 -0
- junifer/utils/helpers.py +53 -0
- junifer/utils/logging.py +14 -3
- junifer/utils/tests/test_helpers.py +35 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/METADATA +59 -28
- junifer-0.0.4.dist-info/RECORD +257 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/WHEEL +1 -1
- junifer/markers/falff/falff_estimator.py +0 -334
- junifer/markers/falff/tests/test_falff_estimator.py +0 -238
- junifer/markers/reho/reho_estimator.py +0 -515
- junifer/markers/reho/tests/test_reho_estimator.py +0 -260
- junifer-0.0.3.dev188.dist-info/RECORD +0 -199
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/top_level.txt +0 -0
@@ -11,22 +11,30 @@ from typing import List
|
|
11
11
|
import nibabel as nib
|
12
12
|
import numpy as np
|
13
13
|
import pytest
|
14
|
-
from nilearn.image import new_img_like
|
14
|
+
from nilearn.image import new_img_like, resample_to_img
|
15
15
|
from numpy.testing import assert_array_almost_equal, assert_array_equal
|
16
16
|
|
17
17
|
from junifer.data.parcellations import (
|
18
18
|
_retrieve_aicha,
|
19
|
+
_retrieve_brainnetome,
|
19
20
|
_retrieve_parcellation,
|
20
21
|
_retrieve_schaefer,
|
21
22
|
_retrieve_shen,
|
22
23
|
_retrieve_suit,
|
23
24
|
_retrieve_tian,
|
24
25
|
_retrieve_yan,
|
26
|
+
get_parcellation,
|
25
27
|
list_parcellations,
|
26
28
|
load_parcellation,
|
27
29
|
merge_parcellations,
|
28
30
|
register_parcellation,
|
29
31
|
)
|
32
|
+
from junifer.datareader import DefaultDataReader
|
33
|
+
from junifer.pipeline.utils import _check_ants
|
34
|
+
from junifer.testing.datagrabbers import (
|
35
|
+
OasisVBMTestingDataGrabber,
|
36
|
+
PartlyCloudyTestingDataGrabber,
|
37
|
+
)
|
30
38
|
|
31
39
|
|
32
40
|
def test_register_parcellation_built_in_check() -> None:
|
@@ -36,6 +44,7 @@ def test_register_parcellation_built_in_check() -> None:
|
|
36
44
|
name="SUITxSUIT",
|
37
45
|
parcellation_path="testparc.nii.gz",
|
38
46
|
parcels_labels=["1", "2", "3"],
|
47
|
+
space="SUIT",
|
39
48
|
overwrite=True,
|
40
49
|
)
|
41
50
|
|
@@ -53,6 +62,7 @@ def test_register_parcellation_already_registered() -> None:
|
|
53
62
|
name="testparc",
|
54
63
|
parcellation_path="testparc.nii.gz",
|
55
64
|
parcels_labels=["1", "2", "3"],
|
65
|
+
space="MNI152Lin",
|
56
66
|
)
|
57
67
|
assert (
|
58
68
|
load_parcellation("testparc", path_only=True)[2].name
|
@@ -65,11 +75,13 @@ def test_register_parcellation_already_registered() -> None:
|
|
65
75
|
name="testparc",
|
66
76
|
parcellation_path="testparc.nii.gz",
|
67
77
|
parcels_labels=["1", "2", "3"],
|
78
|
+
space="MNI152Lin",
|
68
79
|
)
|
69
80
|
register_parcellation(
|
70
81
|
name="testparc",
|
71
82
|
parcellation_path="testparc2.nii.gz",
|
72
83
|
parcels_labels=["1", "2", "3"],
|
84
|
+
space="MNI152Lin",
|
73
85
|
overwrite=True,
|
74
86
|
)
|
75
87
|
|
@@ -86,18 +98,23 @@ def test_parcellation_wrong_labels_values(tmp_path: Path) -> None:
|
|
86
98
|
----------
|
87
99
|
tmp_path : pathlib.Path
|
88
100
|
The path to the test directory.
|
101
|
+
|
89
102
|
"""
|
90
|
-
schaefer, labels, schaefer_path = load_parcellation("Schaefer100x7")
|
103
|
+
schaefer, labels, schaefer_path, _ = load_parcellation("Schaefer100x7")
|
91
104
|
assert schaefer is not None
|
92
105
|
|
93
106
|
# Test wrong number of labels
|
94
|
-
register_parcellation(
|
107
|
+
register_parcellation(
|
108
|
+
"WrongLabels", schaefer_path, labels[:10], "MNI152Lin"
|
109
|
+
)
|
95
110
|
|
96
111
|
with pytest.raises(ValueError, match=r"has 100 parcels but 10"):
|
97
112
|
load_parcellation("WrongLabels")
|
98
113
|
|
99
114
|
# Test wrong number of labels
|
100
|
-
register_parcellation(
|
115
|
+
register_parcellation(
|
116
|
+
"WrongLabels2", schaefer_path, [*labels, "wrong"], "MNI152Lin"
|
117
|
+
)
|
101
118
|
|
102
119
|
with pytest.raises(ValueError, match=r"has 100 parcels but 101"):
|
103
120
|
load_parcellation("WrongLabels2")
|
@@ -108,7 +125,9 @@ def test_parcellation_wrong_labels_values(tmp_path: Path) -> None:
|
|
108
125
|
new_schaefer_img = new_img_like(schaefer, schaefer_data)
|
109
126
|
nib.save(new_schaefer_img, new_schaefer_path)
|
110
127
|
|
111
|
-
register_parcellation(
|
128
|
+
register_parcellation(
|
129
|
+
"WrongValues", new_schaefer_path, labels[:-1], "MNI152Lin"
|
130
|
+
)
|
112
131
|
with pytest.raises(ValueError, match=r"the range [0, 99]"):
|
113
132
|
load_parcellation("WrongValues")
|
114
133
|
|
@@ -118,23 +137,44 @@ def test_parcellation_wrong_labels_values(tmp_path: Path) -> None:
|
|
118
137
|
new_schaefer_img = new_img_like(schaefer, schaefer_data)
|
119
138
|
nib.save(new_schaefer_img, new_schaefer_path)
|
120
139
|
|
121
|
-
register_parcellation(
|
140
|
+
register_parcellation(
|
141
|
+
"WrongValues2", new_schaefer_path, labels, "MNI152Lin"
|
142
|
+
)
|
122
143
|
with pytest.raises(ValueError, match=r"the range [0, 100]"):
|
123
144
|
load_parcellation("WrongValues2")
|
124
145
|
|
125
146
|
|
126
147
|
@pytest.mark.parametrize(
|
127
|
-
"name, parcellation_path, parcels_labels, overwrite",
|
148
|
+
"name, parcellation_path, parcels_labels, space, overwrite",
|
128
149
|
[
|
129
|
-
(
|
130
|
-
|
131
|
-
|
150
|
+
(
|
151
|
+
"testparc_1",
|
152
|
+
"testparc_1.nii.gz",
|
153
|
+
["1", "2", "3"],
|
154
|
+
"MNI152Lin",
|
155
|
+
True,
|
156
|
+
),
|
157
|
+
(
|
158
|
+
"testparc_2",
|
159
|
+
"testparc_2.nii.gz",
|
160
|
+
["1", "2", "6"],
|
161
|
+
"MNI152Lin",
|
162
|
+
True,
|
163
|
+
),
|
164
|
+
(
|
165
|
+
"testparc_3",
|
166
|
+
Path("testparc_3.nii.gz"),
|
167
|
+
["1", "2", "6"],
|
168
|
+
"MNI152Lin",
|
169
|
+
True,
|
170
|
+
),
|
132
171
|
],
|
133
172
|
)
|
134
173
|
def test_register_parcellation(
|
135
174
|
name: str,
|
136
175
|
parcellation_path: str,
|
137
176
|
parcels_labels: List[str],
|
177
|
+
space: str,
|
138
178
|
overwrite: bool,
|
139
179
|
) -> None:
|
140
180
|
"""Test parcellation registration.
|
@@ -147,6 +187,8 @@ def test_register_parcellation(
|
|
147
187
|
The parametrized parcellation path.
|
148
188
|
parcels_labels : list of str
|
149
189
|
The parametrized parcellation labels.
|
190
|
+
space : str
|
191
|
+
The parametrized parcellation space.
|
150
192
|
overwrite : bool
|
151
193
|
The parametrized parcellation overwrite value.
|
152
194
|
|
@@ -156,16 +198,20 @@ def test_register_parcellation(
|
|
156
198
|
name=name,
|
157
199
|
parcellation_path=parcellation_path,
|
158
200
|
parcels_labels=parcels_labels,
|
201
|
+
space=space,
|
159
202
|
overwrite=overwrite,
|
160
203
|
)
|
161
204
|
# List available parcellation and check registration
|
162
205
|
parcellations = list_parcellations()
|
163
206
|
assert name in parcellations
|
164
207
|
# Load registered parcellation
|
165
|
-
_, lbl, fname = load_parcellation(
|
208
|
+
_, lbl, fname, parcellation_space = load_parcellation(
|
209
|
+
name=name, path_only=True
|
210
|
+
)
|
166
211
|
# Check values for registered parcellation
|
167
212
|
assert lbl == parcels_labels
|
168
213
|
assert fname.name == f"{name}.nii.gz"
|
214
|
+
assert parcellation_space == space
|
169
215
|
|
170
216
|
|
171
217
|
@pytest.mark.parametrize(
|
@@ -281,7 +327,7 @@ def test_schaefer(
|
|
281
327
|
f"{int(resolution)}mm.nii.gz"
|
282
328
|
)
|
283
329
|
# Load parcellation
|
284
|
-
img, label, img_path = load_parcellation(
|
330
|
+
img, label, img_path, space = load_parcellation(
|
285
331
|
name=parcellation_name,
|
286
332
|
parcellations_dir=tmp_path,
|
287
333
|
resolution=resolution,
|
@@ -289,6 +335,7 @@ def test_schaefer(
|
|
289
335
|
assert img is not None
|
290
336
|
assert img_path.name == parcellation_file
|
291
337
|
assert len(label) == n_rois
|
338
|
+
assert space == "MNI152NLin6Asym"
|
292
339
|
assert_array_equal(
|
293
340
|
img.header["pixdim"][1:4], 3 * [resolution] # type: ignore
|
294
341
|
)
|
@@ -331,29 +378,32 @@ def test_retrieve_schaefer_incorrect_yeo_networks(tmp_path: Path) -> None:
|
|
331
378
|
|
332
379
|
|
333
380
|
@pytest.mark.parametrize(
|
334
|
-
"space",
|
335
|
-
["SUIT", "MNI"],
|
381
|
+
"space_key, space",
|
382
|
+
[("SUIT", "SUIT"), ("MNI", "MNI152NLin6Asym")],
|
336
383
|
)
|
337
|
-
def test_suit(tmp_path: Path, space: str) -> None:
|
384
|
+
def test_suit(tmp_path: Path, space_key: str, space: str) -> None:
|
338
385
|
"""Test SUIT parcellation.
|
339
386
|
|
340
387
|
Parameters
|
341
388
|
----------
|
342
389
|
tmp_path : pathlib.Path
|
343
390
|
The path to the test directory.
|
391
|
+
space_key : str
|
392
|
+
The parametrized space values for the key.
|
344
393
|
space : str
|
345
394
|
The parametrized space values.
|
346
395
|
|
347
396
|
"""
|
348
397
|
parcellations = list_parcellations()
|
349
|
-
assert f"SUITx{
|
398
|
+
assert f"SUITx{space_key}" in parcellations
|
350
399
|
# Load parcellation
|
351
|
-
img, label, img_path = load_parcellation(
|
352
|
-
name=f"SUITx{
|
400
|
+
img, label, img_path, parcellation_space = load_parcellation(
|
401
|
+
name=f"SUITx{space_key}",
|
353
402
|
parcellations_dir=tmp_path,
|
354
403
|
)
|
355
404
|
assert img is not None
|
356
|
-
assert img_path.name == f"SUIT_{
|
405
|
+
assert img_path.name == f"SUIT_{space_key}Space_1mm.nii"
|
406
|
+
assert parcellation_space == space
|
357
407
|
assert len(label) == 34
|
358
408
|
assert_array_equal(img.header["pixdim"][1:4], [1, 1, 1]) # type: ignore
|
359
409
|
|
@@ -397,16 +447,17 @@ def test_tian_3T_6thgeneration(
|
|
397
447
|
assert "TianxS3x3TxMNI6thgeneration" in parcellations
|
398
448
|
assert "TianxS4x3TxMNI6thgeneration" in parcellations
|
399
449
|
# Load parcellation
|
400
|
-
img, lbl, fname = load_parcellation(
|
450
|
+
img, lbl, fname, parcellation_space_1 = load_parcellation(
|
401
451
|
name=f"TianxS{scale}x3TxMNI6thgeneration", parcellations_dir=tmp_path
|
402
452
|
)
|
403
453
|
fname1 = f"Tian_Subcortex_S{scale}_3T_1mm.nii.gz"
|
404
454
|
assert img is not None
|
405
455
|
assert fname.name == fname1
|
456
|
+
assert parcellation_space_1 == "MNI152NLin6Asym"
|
406
457
|
assert len(lbl) == n_label
|
407
458
|
assert_array_equal(img.header["pixdim"][1:4], [1, 1, 1]) # type: ignore
|
408
459
|
# Load parcellation
|
409
|
-
img, lbl, fname = load_parcellation(
|
460
|
+
img, lbl, fname, parcellation_space_2 = load_parcellation(
|
410
461
|
name=f"TianxS{scale}x3TxMNI6thgeneration",
|
411
462
|
parcellations_dir=tmp_path,
|
412
463
|
resolution=2,
|
@@ -414,6 +465,7 @@ def test_tian_3T_6thgeneration(
|
|
414
465
|
fname1 = f"Tian_Subcortex_S{scale}_3T.nii.gz"
|
415
466
|
assert img is not None
|
416
467
|
assert fname.name == fname1
|
468
|
+
assert parcellation_space_2 == "MNI152NLin6Asym"
|
417
469
|
assert len(lbl) == n_label
|
418
470
|
assert_array_equal(img.header["pixdim"][1:4], [2, 2, 2]) # type: ignore
|
419
471
|
|
@@ -442,13 +494,14 @@ def test_tian_3T_nonlinear2009cAsym(
|
|
442
494
|
assert "TianxS3x3TxMNInonlinear2009cAsym" in parcellations
|
443
495
|
assert "TianxS4x3TxMNInonlinear2009cAsym" in parcellations
|
444
496
|
# Load parcellation
|
445
|
-
img, lbl, fname = load_parcellation(
|
497
|
+
img, lbl, fname, space = load_parcellation(
|
446
498
|
name=f"TianxS{scale}x3TxMNInonlinear2009cAsym",
|
447
499
|
parcellations_dir=tmp_path,
|
448
500
|
)
|
449
501
|
fname1 = f"Tian_Subcortex_S{scale}_3T_2009cAsym.nii.gz"
|
450
502
|
assert img is not None
|
451
503
|
assert fname.name == fname1
|
504
|
+
assert space == "MNI152NLin2009cAsym"
|
452
505
|
assert len(lbl) == n_label
|
453
506
|
assert_array_equal(img.header["pixdim"][1:4], [2, 2, 2]) # type: ignore
|
454
507
|
|
@@ -477,12 +530,13 @@ def test_tian_7T_6thgeneration(
|
|
477
530
|
assert "TianxS3x7TxMNI6thgeneration" in parcellations
|
478
531
|
assert "TianxS4x7TxMNI6thgeneration" in parcellations
|
479
532
|
# Load parcellation
|
480
|
-
img, lbl, fname = load_parcellation(
|
533
|
+
img, lbl, fname, space = load_parcellation(
|
481
534
|
name=f"TianxS{scale}x7TxMNI6thgeneration", parcellations_dir=tmp_path
|
482
535
|
)
|
483
536
|
fname1 = f"Tian_Subcortex_S{scale}_7T.nii.gz"
|
484
537
|
assert img is not None
|
485
538
|
assert fname.name == fname1
|
539
|
+
assert space == "MNI152NLin6Asym"
|
486
540
|
assert len(lbl) == n_label
|
487
541
|
assert_array_almost_equal(
|
488
542
|
img.header["pixdim"][1:4], [1.6, 1.6, 1.6] # type: ignore
|
@@ -503,13 +557,13 @@ def test_retrieve_tian_incorrect_space(tmp_path: Path) -> None:
|
|
503
557
|
parcellations_dir=tmp_path, resolution=1, scale=1, space="wrong"
|
504
558
|
)
|
505
559
|
|
506
|
-
with pytest.raises(ValueError, match=r"
|
560
|
+
with pytest.raises(ValueError, match=r"MNI152NLin6Asym"):
|
507
561
|
_retrieve_tian(
|
508
562
|
parcellations_dir=tmp_path,
|
509
563
|
resolution=1,
|
510
564
|
scale=1,
|
511
565
|
magneticfield="7T",
|
512
|
-
space="
|
566
|
+
space="MNI152NLin2009cAsym",
|
513
567
|
)
|
514
568
|
|
515
569
|
|
@@ -545,7 +599,7 @@ def test_retrieve_tian_incorrect_scale(tmp_path: Path) -> None:
|
|
545
599
|
parcellations_dir=tmp_path,
|
546
600
|
resolution=1,
|
547
601
|
scale=5,
|
548
|
-
space="
|
602
|
+
space="MNI152NLin6Asym",
|
549
603
|
)
|
550
604
|
|
551
605
|
|
@@ -564,11 +618,12 @@ def test_aicha(tmp_path: Path, version: int) -> None:
|
|
564
618
|
parcellations = list_parcellations()
|
565
619
|
assert f"AICHA_v{version}" in parcellations
|
566
620
|
# Load parcellation
|
567
|
-
img, label, img_path = load_parcellation(
|
621
|
+
img, label, img_path, space = load_parcellation(
|
568
622
|
name=f"AICHA_v{version}", parcellations_dir=tmp_path
|
569
623
|
)
|
570
624
|
assert img is not None
|
571
625
|
assert img_path.name == "AICHA.nii"
|
626
|
+
assert space == "IXI549Space"
|
572
627
|
assert len(label) == 384
|
573
628
|
assert_array_equal(img.header["pixdim"][1:4], [2, 2, 2]) # type: ignore
|
574
629
|
|
@@ -632,13 +687,14 @@ def test_shen(
|
|
632
687
|
parcellations = list_parcellations()
|
633
688
|
assert f"Shen_{year}_{n_rois}" in parcellations
|
634
689
|
# Load parcellation
|
635
|
-
img, label, img_path = load_parcellation(
|
690
|
+
img, label, img_path, space = load_parcellation(
|
636
691
|
name=f"Shen_{year}_{n_rois}",
|
637
692
|
parcellations_dir=tmp_path,
|
638
693
|
resolution=resolution,
|
639
694
|
)
|
640
695
|
assert img is not None
|
641
696
|
assert img_name in img_path.name
|
697
|
+
assert space == "MNI152NLin2009cAsym"
|
642
698
|
assert len(label) == n_labels
|
643
699
|
assert_array_equal(
|
644
700
|
img.header["pixdim"][1:4], 3 * [resolution] # type: ignore
|
@@ -827,13 +883,14 @@ def test_yan(
|
|
827
883
|
f"{int(resolution)}mm.nii.gz"
|
828
884
|
)
|
829
885
|
# Load parcellation
|
830
|
-
img, label, img_path = load_parcellation(
|
886
|
+
img, label, img_path, space = load_parcellation(
|
831
887
|
name=parcellation_name, # type: ignore
|
832
888
|
parcellations_dir=tmp_path,
|
833
889
|
resolution=resolution,
|
834
890
|
)
|
835
891
|
assert img is not None
|
836
892
|
assert img_path.name == parcellation_file # type: ignore
|
893
|
+
assert space == "MNI152NLin6Asym"
|
837
894
|
assert len(label) == n_rois
|
838
895
|
assert_array_equal(
|
839
896
|
img.header["pixdim"][1:4], 3 * [resolution] # type: ignore
|
@@ -921,13 +978,84 @@ def test_retrieve_yan_incorrect_kong_networks(tmp_path: Path) -> None:
|
|
921
978
|
)
|
922
979
|
|
923
980
|
|
981
|
+
@pytest.mark.parametrize(
|
982
|
+
"resolution, threshold",
|
983
|
+
[
|
984
|
+
(1.0, 0),
|
985
|
+
(1.0, 25),
|
986
|
+
(1.0, 50),
|
987
|
+
(1.25, 0),
|
988
|
+
(1.25, 25),
|
989
|
+
(1.25, 50),
|
990
|
+
(2, 0),
|
991
|
+
(2, 25),
|
992
|
+
(2, 50),
|
993
|
+
],
|
994
|
+
)
|
995
|
+
def test_brainnetome(
|
996
|
+
tmp_path: Path,
|
997
|
+
resolution: float,
|
998
|
+
threshold: int,
|
999
|
+
) -> None:
|
1000
|
+
"""Test Brainnetome parcellation.
|
1001
|
+
|
1002
|
+
Parameters
|
1003
|
+
----------
|
1004
|
+
tmp_path : pathlib.Path
|
1005
|
+
The path to the test directory.
|
1006
|
+
resolution : float
|
1007
|
+
The parametrized resolution values.
|
1008
|
+
threshold : int
|
1009
|
+
The parametrized threshold values.
|
1010
|
+
|
1011
|
+
"""
|
1012
|
+
parcellations = list_parcellations()
|
1013
|
+
parcellation_name = f"Brainnetome_thr{threshold}"
|
1014
|
+
assert parcellation_name in parcellations
|
1015
|
+
|
1016
|
+
# Fix resolution
|
1017
|
+
if resolution in [1.0, 2.0]:
|
1018
|
+
resolution = int(resolution)
|
1019
|
+
|
1020
|
+
parcellation_file = f"BNA-maxprob-thr{threshold}-{resolution}mm.nii.gz"
|
1021
|
+
# Load parcellation
|
1022
|
+
img, label, img_path, space = load_parcellation(
|
1023
|
+
name=parcellation_name,
|
1024
|
+
parcellations_dir=tmp_path,
|
1025
|
+
resolution=resolution,
|
1026
|
+
)
|
1027
|
+
assert img is not None
|
1028
|
+
assert img_path.name == parcellation_file
|
1029
|
+
assert space == "MNI152NLin6Asym"
|
1030
|
+
assert len(label) == 246
|
1031
|
+
assert_array_equal(
|
1032
|
+
img.header["pixdim"][1:4], 3 * [resolution] # type: ignore
|
1033
|
+
)
|
1034
|
+
|
1035
|
+
|
1036
|
+
def test_retrieve_brainnetome_incorrect_threshold(tmp_path: Path) -> None:
|
1037
|
+
"""Test retrieve Brainnetome with incorrect threshold.
|
1038
|
+
|
1039
|
+
Parameters
|
1040
|
+
----------
|
1041
|
+
tmp_path : pathlib.Path
|
1042
|
+
The path to the test directory.
|
1043
|
+
|
1044
|
+
"""
|
1045
|
+
with pytest.raises(ValueError, match="The parameter `threshold`"):
|
1046
|
+
_retrieve_brainnetome(
|
1047
|
+
parcellations_dir=tmp_path,
|
1048
|
+
threshold=100,
|
1049
|
+
)
|
1050
|
+
|
1051
|
+
|
924
1052
|
def test_merge_parcellations() -> None:
|
925
1053
|
"""Test merging parcellations."""
|
926
1054
|
# load some parcellations for testing
|
927
|
-
schaefer_parcellation, schaefer_labels, _ = load_parcellation(
|
1055
|
+
schaefer_parcellation, schaefer_labels, _, _ = load_parcellation(
|
928
1056
|
"Schaefer100x17"
|
929
1057
|
)
|
930
|
-
tian_parcellation, tian_labels, _ = load_parcellation(
|
1058
|
+
tian_parcellation, tian_labels, _, _ = load_parcellation(
|
931
1059
|
"TianxS2x3TxMNInonlinear2009cAsym"
|
932
1060
|
)
|
933
1061
|
# prepare the list of the actual parcellations
|
@@ -960,7 +1088,7 @@ def test_merge_parcellations_3D_multiple_non_overlapping(
|
|
960
1088
|
|
961
1089
|
"""
|
962
1090
|
# Get the testing parcellation
|
963
|
-
parcellation, labels, _ = load_parcellation("Schaefer100x7")
|
1091
|
+
parcellation, labels, _, _ = load_parcellation("Schaefer100x7")
|
964
1092
|
|
965
1093
|
assert parcellation is not None
|
966
1094
|
|
@@ -981,7 +1109,7 @@ def test_merge_parcellations_3D_multiple_non_overlapping(
|
|
981
1109
|
names = ["high", "low"]
|
982
1110
|
labels_lists = [labels1, labels2]
|
983
1111
|
|
984
|
-
merged_parc,
|
1112
|
+
merged_parc, _ = merge_parcellations(
|
985
1113
|
parcellation_list, names, labels_lists
|
986
1114
|
)
|
987
1115
|
|
@@ -991,18 +1119,11 @@ def test_merge_parcellations_3D_multiple_non_overlapping(
|
|
991
1119
|
assert len(np.unique(parc_data)) == 101 # 100 + 1 because background 0
|
992
1120
|
|
993
1121
|
|
994
|
-
def test_merge_parcellations_3D_multiple_overlapping(
|
995
|
-
"""Test merge_parcellations with multiple overlapping parcellations.
|
996
|
-
|
997
|
-
Parameters
|
998
|
-
----------
|
999
|
-
tmp_path : pathlib.Path
|
1000
|
-
The path to the test directory.
|
1001
|
-
|
1002
|
-
"""
|
1122
|
+
def test_merge_parcellations_3D_multiple_overlapping() -> None:
|
1123
|
+
"""Test merge_parcellations with multiple overlapping parcellations."""
|
1003
1124
|
|
1004
1125
|
# Get the testing parcellation
|
1005
|
-
parcellation, labels, _ = load_parcellation("Schaefer100x7")
|
1126
|
+
parcellation, labels, _, _ = load_parcellation("Schaefer100x7")
|
1006
1127
|
|
1007
1128
|
assert parcellation is not None
|
1008
1129
|
|
@@ -1035,20 +1156,11 @@ def test_merge_parcellations_3D_multiple_overlapping(tmp_path: Path) -> None:
|
|
1035
1156
|
assert len(np.unique(parc_data)) == 101 # 100 + 1 because background 0
|
1036
1157
|
|
1037
1158
|
|
1038
|
-
def test_merge_parcellations_3D_multiple_duplicated_labels(
|
1039
|
-
|
1040
|
-
) -> None:
|
1041
|
-
"""Test merge_parcellations with two parcellations with duplicated labels.
|
1042
|
-
|
1043
|
-
Parameters
|
1044
|
-
----------
|
1045
|
-
tmp_path : pathlib.Path
|
1046
|
-
The path to the test directory.
|
1047
|
-
|
1048
|
-
"""
|
1159
|
+
def test_merge_parcellations_3D_multiple_duplicated_labels() -> None:
|
1160
|
+
"""Test merge_parcellations with duplicated labels."""
|
1049
1161
|
|
1050
1162
|
# Get the testing parcellation
|
1051
|
-
parcellation, labels, _ = load_parcellation("Schaefer100x7")
|
1163
|
+
parcellation, labels, _, _ = load_parcellation("Schaefer100x7")
|
1052
1164
|
|
1053
1165
|
assert parcellation is not None
|
1054
1166
|
|
@@ -1078,3 +1190,102 @@ def test_merge_parcellations_3D_multiple_duplicated_labels(
|
|
1078
1190
|
assert_array_equal(parc_data, merged_parc.get_fdata())
|
1079
1191
|
assert len(labels) == 100
|
1080
1192
|
assert len(np.unique(parc_data)) == 101 # 100 + 1 because background 0
|
1193
|
+
|
1194
|
+
|
1195
|
+
def test_get_parcellation_single() -> None:
|
1196
|
+
"""Test tailored single parcellation fetch."""
|
1197
|
+
with PartlyCloudyTestingDataGrabber() as dg:
|
1198
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
1199
|
+
bold = element_data["BOLD"]
|
1200
|
+
bold_img = bold["data"]
|
1201
|
+
# Get tailored parcellation
|
1202
|
+
tailored_parcellation, tailored_labels = get_parcellation(
|
1203
|
+
parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
|
1204
|
+
target_data=bold,
|
1205
|
+
)
|
1206
|
+
# Check shape and affine with original element data
|
1207
|
+
assert tailored_parcellation.shape == bold_img.shape[:3]
|
1208
|
+
assert_array_equal(tailored_parcellation.affine, bold_img.affine)
|
1209
|
+
# Get raw parcellation
|
1210
|
+
raw_parcellation, raw_labels, _, _ = load_parcellation(
|
1211
|
+
"TianxS1x3TxMNInonlinear2009cAsym",
|
1212
|
+
resolution=1.5,
|
1213
|
+
)
|
1214
|
+
resampled_raw_parcellation = resample_to_img(
|
1215
|
+
source_img=raw_parcellation,
|
1216
|
+
target_img=bold_img,
|
1217
|
+
interpolation="nearest",
|
1218
|
+
copy=True,
|
1219
|
+
)
|
1220
|
+
# Check resampled data with tailored data
|
1221
|
+
assert_array_equal(
|
1222
|
+
tailored_parcellation.get_fdata(),
|
1223
|
+
resampled_raw_parcellation.get_fdata(),
|
1224
|
+
)
|
1225
|
+
assert tailored_labels == raw_labels
|
1226
|
+
|
1227
|
+
|
1228
|
+
def test_get_parcellation_multi_same_space() -> None:
|
1229
|
+
"""Test tailored multi parcellation fetch in same space."""
|
1230
|
+
with PartlyCloudyTestingDataGrabber() as dg:
|
1231
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
1232
|
+
bold = element_data["BOLD"]
|
1233
|
+
bold_img = bold["data"]
|
1234
|
+
# Get tailored parcellation
|
1235
|
+
tailored_parcellation, tailored_labels = get_parcellation(
|
1236
|
+
parcellation=[
|
1237
|
+
"Shen_2015_268",
|
1238
|
+
"TianxS1x3TxMNInonlinear2009cAsym",
|
1239
|
+
],
|
1240
|
+
target_data=bold,
|
1241
|
+
)
|
1242
|
+
# Check shape and affine with original element data
|
1243
|
+
assert tailored_parcellation.shape == bold_img.shape[:3]
|
1244
|
+
assert_array_equal(tailored_parcellation.affine, bold_img.affine)
|
1245
|
+
# Get raw parcellations
|
1246
|
+
raw_parcellations = []
|
1247
|
+
raw_labels = []
|
1248
|
+
parcellations_names = [
|
1249
|
+
"Shen_2015_268",
|
1250
|
+
"TianxS1x3TxMNInonlinear2009cAsym",
|
1251
|
+
]
|
1252
|
+
for name in parcellations_names:
|
1253
|
+
img, labels, _, _ = load_parcellation(name=name, resolution=1.5)
|
1254
|
+
# Resample raw parcellations
|
1255
|
+
resampled_img = resample_to_img(
|
1256
|
+
source_img=img,
|
1257
|
+
target_img=bold_img,
|
1258
|
+
interpolation="nearest",
|
1259
|
+
copy=True,
|
1260
|
+
)
|
1261
|
+
raw_parcellations.append(resampled_img)
|
1262
|
+
raw_labels.append(labels)
|
1263
|
+
# Merge resampled parcellations
|
1264
|
+
merged_resampled_parcellations, merged_labels = merge_parcellations(
|
1265
|
+
parcellations_list=raw_parcellations,
|
1266
|
+
parcellations_names=parcellations_names,
|
1267
|
+
labels_lists=raw_labels,
|
1268
|
+
)
|
1269
|
+
# Check resampled data with tailored data
|
1270
|
+
assert_array_equal(
|
1271
|
+
tailored_parcellation.get_fdata(),
|
1272
|
+
merged_resampled_parcellations.get_fdata(),
|
1273
|
+
)
|
1274
|
+
assert tailored_labels == merged_labels
|
1275
|
+
|
1276
|
+
|
1277
|
+
@pytest.mark.skipif(
|
1278
|
+
_check_ants() is False, reason="requires ANTs to be in PATH"
|
1279
|
+
)
|
1280
|
+
def test_get_parcellation_multi_different_space() -> None:
|
1281
|
+
"""Test tailored multi parcellation fetch in different space."""
|
1282
|
+
with OasisVBMTestingDataGrabber() as dg:
|
1283
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
1284
|
+
# Get tailored parcellation
|
1285
|
+
get_parcellation(
|
1286
|
+
parcellation=[
|
1287
|
+
"Schaefer100x7",
|
1288
|
+
"TianxS1x3TxMNInonlinear2009cAsym",
|
1289
|
+
],
|
1290
|
+
target_data=element_data["VBM_GM"],
|
1291
|
+
)
|