junifer 0.0.3.dev186__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.dev186.dist-info → junifer-0.0.4.dist-info}/METADATA +59 -28
- junifer-0.0.4.dist-info/RECORD +257 -0
- {junifer-0.0.3.dev186.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.dev186.dist-info/RECORD +0 -199
- {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/top_level.txt +0 -0
@@ -3,6 +3,9 @@
|
|
3
3
|
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
|
4
4
|
# License: AGPL
|
5
5
|
|
6
|
+
from contextlib import nullcontext
|
7
|
+
from typing import ContextManager, Dict, List, Union
|
8
|
+
|
6
9
|
import pytest
|
7
10
|
|
8
11
|
from junifer.datagrabber.utils import (
|
@@ -12,79 +15,204 @@ from junifer.datagrabber.utils import (
|
|
12
15
|
)
|
13
16
|
|
14
17
|
|
15
|
-
|
16
|
-
"
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
with
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
18
|
+
@pytest.mark.parametrize(
|
19
|
+
"types, expect",
|
20
|
+
[
|
21
|
+
("wrong", pytest.raises(TypeError, match="must be a list")),
|
22
|
+
([1], pytest.raises(TypeError, match="must be a list of strings")),
|
23
|
+
(["T1w", "BOLD"], nullcontext()),
|
24
|
+
],
|
25
|
+
)
|
26
|
+
def test_validate_types(
|
27
|
+
types: Union[str, List[str], List[int]],
|
28
|
+
expect: ContextManager,
|
29
|
+
) -> None:
|
30
|
+
"""Test validation of types.
|
31
|
+
|
32
|
+
Parameters
|
33
|
+
----------
|
34
|
+
types : str, list of int or str
|
35
|
+
The parametrized data types to validate.
|
36
|
+
expect : typing.ContextManager
|
37
|
+
The parametrized ContextManager object.
|
38
|
+
|
39
|
+
"""
|
40
|
+
with expect:
|
41
|
+
validate_types(types) # type: ignore
|
42
|
+
|
43
|
+
|
44
|
+
@pytest.mark.parametrize(
|
45
|
+
"replacements, patterns, expect",
|
46
|
+
[
|
47
|
+
(
|
48
|
+
"wrong",
|
49
|
+
"also wrong",
|
50
|
+
pytest.raises(TypeError, match="must be a list"),
|
51
|
+
),
|
52
|
+
(
|
53
|
+
[1],
|
54
|
+
{
|
55
|
+
"T1w": {"pattern": "{subject}/anat/{subject}_T1w.nii.gz"},
|
56
|
+
"BOLD": {
|
57
|
+
"pattern": "{subject}/func/{subject}_task-rest_bold.nii.gz"
|
58
|
+
},
|
59
|
+
},
|
60
|
+
pytest.raises(TypeError, match="must be a list of strings"),
|
61
|
+
),
|
62
|
+
(
|
63
|
+
["session"],
|
64
|
+
{
|
65
|
+
"T1w": {"pattern": "{subject}/anat/{subject}_T1w.nii.gz"},
|
66
|
+
"BOLD": {
|
67
|
+
"pattern": "{subject}/func/{subject}_task-rest_bold.nii.gz"
|
68
|
+
},
|
69
|
+
},
|
70
|
+
pytest.raises(ValueError, match="is not part of"),
|
71
|
+
),
|
72
|
+
(
|
73
|
+
["subject", "session"],
|
74
|
+
{
|
75
|
+
"T1w": {"pattern": "{subject}/anat/_T1w.nii.gz"},
|
76
|
+
"BOLD": {"pattern": "{session}/func/_task-rest_bold.nii.gz"},
|
77
|
+
},
|
78
|
+
pytest.raises(ValueError, match="At least one pattern"),
|
79
|
+
),
|
80
|
+
(
|
81
|
+
["subject"],
|
82
|
+
{
|
83
|
+
"T1w": {"pattern": "{subject}/anat/{subject}_T1w.nii.gz"},
|
84
|
+
"BOLD": {
|
85
|
+
"pattern": "{subject}/func/{subject}_task-rest_bold.nii.gz"
|
86
|
+
},
|
87
|
+
},
|
88
|
+
nullcontext(),
|
89
|
+
),
|
90
|
+
],
|
91
|
+
)
|
92
|
+
def test_validate_replacements(
|
93
|
+
replacements: Union[str, List[str], List[int]],
|
94
|
+
patterns: Union[str, Dict[str, Dict[str, str]]],
|
95
|
+
expect: ContextManager,
|
96
|
+
) -> None:
|
97
|
+
"""Test validation of replacements.
|
98
|
+
|
99
|
+
Parameters
|
100
|
+
----------
|
101
|
+
replacements : str, list of str or int
|
102
|
+
The parametrized pattern replacements to validate.
|
103
|
+
patterns : str, dict
|
104
|
+
The parametrized patterns to validate against.
|
105
|
+
expect : typing.ContextManager
|
106
|
+
The parametrized ContextManager object.
|
107
|
+
|
108
|
+
"""
|
109
|
+
with expect:
|
110
|
+
validate_replacements(replacements=replacements, patterns=patterns) # type: ignore
|
111
|
+
|
112
|
+
|
113
|
+
@pytest.mark.parametrize(
|
114
|
+
"types, patterns, expect",
|
115
|
+
[
|
116
|
+
(
|
117
|
+
["T1w", "BOLD"],
|
118
|
+
"wrong",
|
119
|
+
pytest.raises(TypeError, match="must be a dict"),
|
120
|
+
),
|
121
|
+
(
|
122
|
+
["T1w", "BOLD"],
|
123
|
+
{
|
124
|
+
"T1w": {"pattern": "{subject}/anat/{subject}_T1w.nii.gz"},
|
125
|
+
},
|
126
|
+
pytest.raises(
|
127
|
+
ValueError,
|
128
|
+
match="Length of `types` more than that of `patterns`.",
|
129
|
+
),
|
130
|
+
),
|
131
|
+
(
|
132
|
+
["T1w", "BOLD"],
|
133
|
+
{
|
134
|
+
"T1w": {"pattern": "{subject}/anat/{subject}_T1w.nii.gz"},
|
135
|
+
"T2w": {"pattern": "{subject}/anat/{subject}_T2w.nii.gz"},
|
136
|
+
},
|
137
|
+
pytest.raises(ValueError, match="contain all"),
|
138
|
+
),
|
139
|
+
(
|
140
|
+
["T3w"],
|
141
|
+
{
|
142
|
+
"T3w": {"pattern": "{subject}/anat/{subject}_T3w.nii.gz"},
|
143
|
+
},
|
144
|
+
pytest.raises(ValueError, match="Unknown data type"),
|
145
|
+
),
|
146
|
+
(
|
147
|
+
["BOLD"],
|
148
|
+
{
|
149
|
+
"BOLD": {"patterns": "{subject}/func/{subject}_BOLD.nii.gz"},
|
150
|
+
},
|
151
|
+
pytest.raises(KeyError, match="Mandatory key"),
|
152
|
+
),
|
153
|
+
(
|
154
|
+
["BOLD_confounds"],
|
155
|
+
{
|
156
|
+
"BOLD_confounds": {
|
157
|
+
"pattern": "{subject}/func/{subject}_confounds.tsv",
|
158
|
+
"format": "fmriprep",
|
159
|
+
"space": "MNINLin6Asym",
|
160
|
+
},
|
161
|
+
},
|
162
|
+
pytest.raises(RuntimeError, match="not accepted"),
|
163
|
+
),
|
164
|
+
(
|
165
|
+
["T1w"],
|
166
|
+
{
|
167
|
+
"T1w": {
|
168
|
+
"pattern": "{subject}/anat/{subject}*.nii",
|
169
|
+
"space": "native",
|
170
|
+
},
|
171
|
+
},
|
172
|
+
pytest.raises(ValueError, match="following a replacement"),
|
173
|
+
),
|
174
|
+
(
|
175
|
+
["T1w", "T2w", "BOLD", "BOLD_confounds"],
|
176
|
+
{
|
177
|
+
"T1w": {
|
178
|
+
"pattern": "{subject}/anat/{subject}_T1w.nii.gz",
|
179
|
+
"space": "native",
|
180
|
+
},
|
181
|
+
"T2w": {
|
182
|
+
"pattern": "{subject}/anat/{subject}_T2w.nii.gz",
|
183
|
+
"space": "native",
|
184
|
+
},
|
185
|
+
"BOLD": {
|
186
|
+
"pattern": (
|
187
|
+
"{subject}/func/{subject}_task-rest_bold.nii.gz"
|
188
|
+
),
|
189
|
+
"space": "MNI152NLin6Asym",
|
190
|
+
},
|
191
|
+
"BOLD_confounds": {
|
192
|
+
"pattern": "{subject}/func/{subject}_confounds.tsv",
|
193
|
+
"format": "fmriprep",
|
194
|
+
},
|
195
|
+
},
|
196
|
+
nullcontext(),
|
197
|
+
),
|
198
|
+
],
|
199
|
+
)
|
200
|
+
def test_validate_patterns(
|
201
|
+
types: List[str],
|
202
|
+
patterns: Union[str, Dict[str, Dict[str, str]]],
|
203
|
+
expect: ContextManager,
|
204
|
+
) -> None:
|
205
|
+
"""Test validation of patterns.
|
206
|
+
|
207
|
+
Parameters
|
208
|
+
----------
|
209
|
+
types : list of str
|
210
|
+
The parametrized data types.
|
211
|
+
patterns : str, dict
|
212
|
+
The patterns to validate.
|
213
|
+
expect : typing.ContextManager
|
214
|
+
The parametrized ContextManager object.
|
215
|
+
|
216
|
+
"""
|
217
|
+
with expect:
|
218
|
+
validate_patterns(types=types, patterns=patterns) # type: ignore
|
@@ -26,12 +26,6 @@ _testing_dataset = {
|
|
26
26
|
}
|
27
27
|
|
28
28
|
|
29
|
-
def test_DataladDataGrabber_abstractness() -> None:
|
30
|
-
"""Test DataladDataGrabber is abstract base class."""
|
31
|
-
with pytest.raises(TypeError, match=r"abstract"):
|
32
|
-
DataladDataGrabber() # type: ignore
|
33
|
-
|
34
|
-
|
35
29
|
@pytest.fixture
|
36
30
|
def concrete_datagrabber() -> Type[DataladDataGrabber]:
|
37
31
|
"""Return a concrete datalad-based DataGrabber.
|
@@ -0,0 +1,256 @@
|
|
1
|
+
"""Provide tests for DMCC13Benchmark DataGrabber."""
|
2
|
+
|
3
|
+
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
4
|
+
# License: AGPL
|
5
|
+
|
6
|
+
from typing import List, Optional, Union
|
7
|
+
|
8
|
+
import pytest
|
9
|
+
|
10
|
+
from junifer.datagrabber import DMCC13Benchmark
|
11
|
+
|
12
|
+
|
13
|
+
URI = "https://gin.g-node.org/synchon/datalad-example-dmcc13-benchmark"
|
14
|
+
|
15
|
+
|
16
|
+
@pytest.mark.parametrize(
|
17
|
+
"sessions, tasks, phase_encodings, runs, native_t1w",
|
18
|
+
[
|
19
|
+
(None, None, None, None, False),
|
20
|
+
("ses-wave1bas", "Rest", "AP", "1", False),
|
21
|
+
("ses-wave1bas", "Axcpt", "AP", "1", False),
|
22
|
+
("ses-wave1bas", "Cuedts", "AP", "1", False),
|
23
|
+
("ses-wave1bas", "Stern", "AP", "1", False),
|
24
|
+
("ses-wave1bas", "Stroop", "AP", "1", False),
|
25
|
+
("ses-wave1bas", "Rest", "PA", "2", False),
|
26
|
+
("ses-wave1bas", "Axcpt", "PA", "2", False),
|
27
|
+
("ses-wave1bas", "Cuedts", "PA", "2", False),
|
28
|
+
("ses-wave1bas", "Stern", "PA", "2", False),
|
29
|
+
("ses-wave1bas", "Stroop", "PA", "2", False),
|
30
|
+
("ses-wave1bas", "Rest", "AP", "1", True),
|
31
|
+
("ses-wave1bas", "Axcpt", "AP", "1", True),
|
32
|
+
("ses-wave1bas", "Cuedts", "AP", "1", True),
|
33
|
+
("ses-wave1bas", "Stern", "AP", "1", True),
|
34
|
+
("ses-wave1bas", "Stroop", "AP", "1", True),
|
35
|
+
("ses-wave1bas", "Rest", "PA", "2", True),
|
36
|
+
("ses-wave1bas", "Axcpt", "PA", "2", True),
|
37
|
+
("ses-wave1bas", "Cuedts", "PA", "2", True),
|
38
|
+
("ses-wave1bas", "Stern", "PA", "2", True),
|
39
|
+
("ses-wave1bas", "Stroop", "PA", "2", True),
|
40
|
+
("ses-wave1pro", "Rest", "AP", "1", False),
|
41
|
+
("ses-wave1pro", "Rest", "PA", "2", False),
|
42
|
+
("ses-wave1pro", "Rest", "AP", "1", True),
|
43
|
+
("ses-wave1pro", "Rest", "PA", "2", True),
|
44
|
+
("ses-wave1rea", "Rest", "AP", "1", False),
|
45
|
+
("ses-wave1rea", "Rest", "PA", "2", False),
|
46
|
+
("ses-wave1rea", "Rest", "AP", "1", True),
|
47
|
+
("ses-wave1rea", "Rest", "PA", "2", True),
|
48
|
+
],
|
49
|
+
)
|
50
|
+
def test_DMCC13Benchmark(
|
51
|
+
sessions: Optional[str],
|
52
|
+
tasks: Optional[str],
|
53
|
+
phase_encodings: Optional[str],
|
54
|
+
runs: Optional[str],
|
55
|
+
native_t1w: bool,
|
56
|
+
) -> None:
|
57
|
+
"""Test DMCC13Benchmark DataGrabber.
|
58
|
+
|
59
|
+
Parameters
|
60
|
+
----------
|
61
|
+
sessions : str or None
|
62
|
+
The parametrized session values.
|
63
|
+
tasks : str or None
|
64
|
+
The parametrized task values.
|
65
|
+
phase_encodings : str or None
|
66
|
+
The parametrized phase encoding values.
|
67
|
+
runs : str or None
|
68
|
+
The parametrized run values.
|
69
|
+
native_t1w : bool
|
70
|
+
The parametrized values for fetching native T1w.
|
71
|
+
|
72
|
+
"""
|
73
|
+
dg = DMCC13Benchmark(
|
74
|
+
sessions=sessions,
|
75
|
+
tasks=tasks,
|
76
|
+
phase_encodings=phase_encodings,
|
77
|
+
runs=runs,
|
78
|
+
native_t1w=native_t1w,
|
79
|
+
)
|
80
|
+
# Set URI to Gin
|
81
|
+
dg.uri = URI
|
82
|
+
|
83
|
+
with dg:
|
84
|
+
# Get all elements
|
85
|
+
all_elements = dg.get_elements()
|
86
|
+
# Get test element
|
87
|
+
test_element = all_elements[0]
|
88
|
+
# Get test element's access values
|
89
|
+
_, ses, task, phase, run = test_element
|
90
|
+
# Access data
|
91
|
+
out = dg[("sub-01", ses, task, phase, run)]
|
92
|
+
|
93
|
+
# Available data types
|
94
|
+
data_types = [
|
95
|
+
"BOLD",
|
96
|
+
"BOLD_confounds",
|
97
|
+
"BOLD_mask",
|
98
|
+
"VBM_CSF",
|
99
|
+
"VBM_GM",
|
100
|
+
"VBM_WM",
|
101
|
+
"T1w",
|
102
|
+
"T1w_mask",
|
103
|
+
]
|
104
|
+
# Add Warp if native T1w is accessed
|
105
|
+
if native_t1w:
|
106
|
+
data_types.append("Warp")
|
107
|
+
|
108
|
+
# Data type file name formats
|
109
|
+
data_file_names = [
|
110
|
+
(
|
111
|
+
f"sub-01_{ses}_task-{task}_acq-mb4{phase}_run-{run}_"
|
112
|
+
"space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz"
|
113
|
+
),
|
114
|
+
(
|
115
|
+
f"sub-01_{ses}_task-{task}_acq-mb4{phase}_run-{run}_"
|
116
|
+
"desc-confounds_regressors.tsv"
|
117
|
+
),
|
118
|
+
(
|
119
|
+
f"sub-01_{ses}_task-{task}_acq-mb4{phase}_run-{run}_"
|
120
|
+
"space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
|
121
|
+
),
|
122
|
+
"sub-01_space-MNI152NLin2009cAsym_label-CSF_probseg.nii.gz",
|
123
|
+
"sub-01_space-MNI152NLin2009cAsym_label-GM_probseg.nii.gz",
|
124
|
+
"sub-01_space-MNI152NLin2009cAsym_label-WM_probseg.nii.gz",
|
125
|
+
]
|
126
|
+
if native_t1w:
|
127
|
+
data_file_names.extend(
|
128
|
+
[
|
129
|
+
"sub-01_desc-preproc_T1w.nii.gz",
|
130
|
+
"sub-01_desc-brain_mask.nii.gz",
|
131
|
+
"sub-01_from-MNI152NLin2009cAsym_to-T1w_mode-image_xfm.h5",
|
132
|
+
]
|
133
|
+
)
|
134
|
+
else:
|
135
|
+
data_file_names.extend(
|
136
|
+
[
|
137
|
+
"sub-01_space-MNI152NLin2009cAsym_desc-preproc_T1w.nii.gz",
|
138
|
+
"sub-01_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz",
|
139
|
+
]
|
140
|
+
)
|
141
|
+
|
142
|
+
for data_type, data_file_name in zip(data_types, data_file_names):
|
143
|
+
# Assert data type
|
144
|
+
assert data_type in out
|
145
|
+
# Assert data file path exists
|
146
|
+
assert out[data_type]["path"].exists()
|
147
|
+
# Assert data file path is a file
|
148
|
+
assert out[data_type]["path"].is_file()
|
149
|
+
# Assert data file name
|
150
|
+
assert out[data_type]["path"].name == data_file_name
|
151
|
+
# Assert metadata
|
152
|
+
assert "meta" in out[data_type]
|
153
|
+
|
154
|
+
|
155
|
+
@pytest.mark.parametrize(
|
156
|
+
"types, native_t1w",
|
157
|
+
[
|
158
|
+
("BOLD", True),
|
159
|
+
("BOLD", False),
|
160
|
+
("T1w", True),
|
161
|
+
("T1w", False),
|
162
|
+
("VBM_CSF", True),
|
163
|
+
("VBM_CSF", False),
|
164
|
+
("VBM_GM", True),
|
165
|
+
("VBM_GM", False),
|
166
|
+
("VBM_WM", True),
|
167
|
+
("VBM_WM", False),
|
168
|
+
(["BOLD", "BOLD_confounds"], True),
|
169
|
+
(["BOLD", "BOLD_confounds"], False),
|
170
|
+
(["T1w", "VBM_CSF"], True),
|
171
|
+
(["T1w", "VBM_CSF"], False),
|
172
|
+
(["VBM_GM", "VBM_WM"], True),
|
173
|
+
(["VBM_GM", "VBM_WM"], False),
|
174
|
+
],
|
175
|
+
)
|
176
|
+
def test_DMCC13Benchmark_partial_data_access(
|
177
|
+
types: Union[str, List[str]],
|
178
|
+
native_t1w: bool,
|
179
|
+
) -> None:
|
180
|
+
"""Test DMCC13Benchmark DataGrabber partial data access.
|
181
|
+
|
182
|
+
Parameters
|
183
|
+
----------
|
184
|
+
types : str or list of str
|
185
|
+
The parametrized types.
|
186
|
+
native_t1w : bool
|
187
|
+
The parametrized values for fetching native T1w.
|
188
|
+
|
189
|
+
"""
|
190
|
+
dg = DMCC13Benchmark(types=types, native_t1w=native_t1w)
|
191
|
+
# Set URI to Gin
|
192
|
+
dg.uri = URI
|
193
|
+
|
194
|
+
with dg:
|
195
|
+
# Get all elements
|
196
|
+
all_elements = dg.get_elements()
|
197
|
+
# Get test element
|
198
|
+
test_element = all_elements[0]
|
199
|
+
# Get test element's access values
|
200
|
+
_, ses, task, phase, run = test_element
|
201
|
+
# Access data
|
202
|
+
out = dg[("sub-01", ses, task, phase, run)]
|
203
|
+
# Assert data type
|
204
|
+
if isinstance(types, list):
|
205
|
+
for type_ in types:
|
206
|
+
assert type_ in out
|
207
|
+
else:
|
208
|
+
assert types in out
|
209
|
+
|
210
|
+
|
211
|
+
def test_DMCC13Benchmark_incorrect_data_type() -> None:
|
212
|
+
"""Test DMCC13Benchmark DataGrabber incorrect data type."""
|
213
|
+
with pytest.raises(
|
214
|
+
ValueError, match="`patterns` must contain all `types`"
|
215
|
+
):
|
216
|
+
_ = DMCC13Benchmark(types="Orcus")
|
217
|
+
|
218
|
+
|
219
|
+
def test_DMCC13Benchmark_invalid_sessions():
|
220
|
+
"""Test DMCC13Benchmark DataGrabber invalid sessions."""
|
221
|
+
with pytest.raises(
|
222
|
+
ValueError,
|
223
|
+
match=("phonyses is not a valid session in " "the DMCC dataset"),
|
224
|
+
):
|
225
|
+
DMCC13Benchmark(sessions="phonyses")
|
226
|
+
|
227
|
+
|
228
|
+
def test_DMCC13Benchmark_invalid_tasks():
|
229
|
+
"""Test DMCC13Benchmark DataGrabber invalid tasks."""
|
230
|
+
with pytest.raises(
|
231
|
+
ValueError,
|
232
|
+
match=(
|
233
|
+
"thisisnotarealtask is not a valid task in " "the DMCC dataset"
|
234
|
+
),
|
235
|
+
):
|
236
|
+
DMCC13Benchmark(tasks="thisisnotarealtask")
|
237
|
+
|
238
|
+
|
239
|
+
def test_DMCC13Benchmark_phase_encodings():
|
240
|
+
"""Test DMCC13Benchmark DataGrabber invalid phase encodings."""
|
241
|
+
with pytest.raises(
|
242
|
+
ValueError,
|
243
|
+
match=(
|
244
|
+
"moonphase is not a valid phase encoding in " "the DMCC dataset"
|
245
|
+
),
|
246
|
+
):
|
247
|
+
DMCC13Benchmark(phase_encodings="moonphase")
|
248
|
+
|
249
|
+
|
250
|
+
def test_DMCC13Benchmark_runs():
|
251
|
+
"""Test DMCC13Benchmark DataGrabber invalid runs."""
|
252
|
+
with pytest.raises(
|
253
|
+
ValueError,
|
254
|
+
match=("cerebralrun is not a valid run in " "the DMCC dataset"),
|
255
|
+
):
|
256
|
+
DMCC13Benchmark(runs="cerebralrun")
|
@@ -26,11 +26,21 @@ def test_MultipleDataGrabber() -> None:
|
|
26
26
|
rootdir = "example_bids_ses"
|
27
27
|
replacements = ["subject", "session"]
|
28
28
|
pattern1 = {
|
29
|
-
"T1w":
|
29
|
+
"T1w": {
|
30
|
+
"pattern": (
|
31
|
+
"{subject}/{session}/anat/{subject}_{session}_T1w.nii.gz"
|
32
|
+
),
|
33
|
+
"space": "native",
|
34
|
+
},
|
30
35
|
}
|
31
36
|
pattern2 = {
|
32
|
-
"BOLD":
|
33
|
-
|
37
|
+
"BOLD": {
|
38
|
+
"pattern": (
|
39
|
+
"{subject}/{session}/func/"
|
40
|
+
"{subject}_{session}_task-rest_bold.nii.gz"
|
41
|
+
),
|
42
|
+
"space": "MNI152NLin6Asym",
|
43
|
+
},
|
34
44
|
}
|
35
45
|
dg1 = PatternDataladDataGrabber(
|
36
46
|
rootdir=rootdir,
|
@@ -84,11 +94,21 @@ def test_MultipleDataGrabber_no_intersection() -> None:
|
|
84
94
|
rootdir = "example_bids_ses"
|
85
95
|
replacements = ["subject", "session"]
|
86
96
|
pattern1 = {
|
87
|
-
"T1w":
|
97
|
+
"T1w": {
|
98
|
+
"pattern": (
|
99
|
+
"{subject}/{session}/anat/{subject}_{session}_T1w.nii.gz"
|
100
|
+
),
|
101
|
+
"space": "native",
|
102
|
+
},
|
88
103
|
}
|
89
104
|
pattern2 = {
|
90
|
-
"BOLD":
|
91
|
-
|
105
|
+
"BOLD": {
|
106
|
+
"pattern": (
|
107
|
+
"{subject}/{session}/func/"
|
108
|
+
"{subject}_{session}_task-rest_bold.nii.gz"
|
109
|
+
),
|
110
|
+
"space": "MNI152NLin6Asym",
|
111
|
+
},
|
92
112
|
}
|
93
113
|
dg1 = PatternDataladDataGrabber(
|
94
114
|
rootdir=rootdir,
|
@@ -119,7 +139,12 @@ def test_MultipleDataGrabber_get_item() -> None:
|
|
119
139
|
rootdir = "example_bids_ses"
|
120
140
|
replacements = ["subject", "session"]
|
121
141
|
pattern1 = {
|
122
|
-
"T1w":
|
142
|
+
"T1w": {
|
143
|
+
"pattern": (
|
144
|
+
"{subject}/{session}/anat/{subject}_{session}_T1w.nii.gz"
|
145
|
+
),
|
146
|
+
"space": "native",
|
147
|
+
},
|
123
148
|
}
|
124
149
|
dg1 = PatternDataladDataGrabber(
|
125
150
|
rootdir=rootdir,
|
@@ -142,10 +167,18 @@ def test_MultipleDataGrabber_validation() -> None:
|
|
142
167
|
replacement1 = ["subject", "session"]
|
143
168
|
replacement2 = ["subject"]
|
144
169
|
pattern1 = {
|
145
|
-
"T1w":
|
170
|
+
"T1w": {
|
171
|
+
"pattern": (
|
172
|
+
"{subject}/{session}/anat/{subject}_{session}_T1w.nii.gz"
|
173
|
+
),
|
174
|
+
"space": "native",
|
175
|
+
},
|
146
176
|
}
|
147
177
|
pattern2 = {
|
148
|
-
"
|
178
|
+
"BOLD": {
|
179
|
+
"pattern": "{subject}/func/{subject}_task-rest_bold.nii.gz",
|
180
|
+
"space": "MNI152NLin6Asym",
|
181
|
+
},
|
149
182
|
}
|
150
183
|
dg1 = PatternDataladDataGrabber(
|
151
184
|
rootdir=rootdir,
|
@@ -158,7 +191,7 @@ def test_MultipleDataGrabber_validation() -> None:
|
|
158
191
|
dg2 = PatternDataladDataGrabber(
|
159
192
|
rootdir=rootdir,
|
160
193
|
uri=repo_uri2,
|
161
|
-
types=["
|
194
|
+
types=["BOLD"],
|
162
195
|
patterns=pattern2,
|
163
196
|
replacements=replacement2,
|
164
197
|
)
|