junifer 0.0.5.dev68__py3-none-any.whl → 0.0.5.dev93__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 +2 -2
- junifer/api/functions.py +1 -1
- junifer/configs/juseless/datagrabbers/tests/test_ucla.py +1 -3
- junifer/configs/juseless/datagrabbers/ucla.py +9 -9
- junifer/data/masks.py +10 -22
- junifer/data/parcellations.py +1 -1
- junifer/data/tests/test_masks.py +8 -28
- junifer/datagrabber/aomic/id1000.py +34 -38
- junifer/datagrabber/aomic/piop1.py +33 -37
- junifer/datagrabber/aomic/piop2.py +35 -39
- junifer/datagrabber/aomic/tests/test_id1000.py +10 -11
- junifer/datagrabber/aomic/tests/test_piop1.py +10 -11
- junifer/datagrabber/aomic/tests/test_piop2.py +10 -11
- junifer/datagrabber/datalad_base.py +10 -1
- junifer/datagrabber/dmcc13_benchmark.py +36 -54
- junifer/datagrabber/pattern.py +116 -46
- junifer/datagrabber/pattern_datalad.py +22 -12
- junifer/datagrabber/tests/test_datagrabber_utils.py +15 -9
- junifer/datagrabber/tests/test_dmcc13_benchmark.py +46 -19
- junifer/datagrabber/utils.py +127 -54
- junifer/datareader/default.py +91 -42
- junifer/preprocess/base.py +2 -2
- junifer/preprocess/confounds/fmriprep_confound_remover.py +44 -60
- junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +72 -113
- junifer/storage/base.py +37 -1
- junifer/storage/hdf5.py +68 -9
- junifer/storage/tests/test_hdf5.py +82 -10
- junifer/testing/datagrabbers.py +5 -5
- junifer/testing/tests/test_partlycloudytesting_datagrabber.py +7 -7
- {junifer-0.0.5.dev68.dist-info → junifer-0.0.5.dev93.dist-info}/METADATA +1 -1
- {junifer-0.0.5.dev68.dist-info → junifer-0.0.5.dev93.dist-info}/RECORD +36 -36
- {junifer-0.0.5.dev68.dist-info → junifer-0.0.5.dev93.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.5.dev68.dist-info → junifer-0.0.5.dev93.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.5.dev68.dist-info → junifer-0.0.5.dev93.dist-info}/WHEEL +0 -0
- {junifer-0.0.5.dev68.dist-info → junifer-0.0.5.dev93.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.5.dev68.dist-info → junifer-0.0.5.dev93.dist-info}/top_level.txt +0 -0
@@ -57,19 +57,19 @@ def test_DataladAOMICPIOP2(tasks: Optional[str]) -> None:
|
|
57
57
|
assert out["BOLD"]["path"].exists()
|
58
58
|
assert out["BOLD"]["path"].is_file()
|
59
59
|
|
60
|
-
# asserts type
|
61
|
-
assert "
|
60
|
+
# asserts type BOLD.confounds
|
61
|
+
assert "confounds" in out["BOLD"]
|
62
62
|
|
63
63
|
assert (
|
64
|
-
out["
|
64
|
+
out["BOLD"]["confounds"]["path"].name == f"{sub}_task-{new_task}_"
|
65
65
|
"desc-confounds_regressors.tsv"
|
66
66
|
)
|
67
67
|
|
68
|
-
assert out["
|
69
|
-
assert out["
|
68
|
+
assert out["BOLD"]["confounds"]["path"].exists()
|
69
|
+
assert out["BOLD"]["confounds"]["path"].is_file()
|
70
70
|
|
71
|
-
# assert
|
72
|
-
assert out["
|
71
|
+
# assert BOLD.mask
|
72
|
+
assert out["BOLD"]["mask"]["path"].exists()
|
73
73
|
|
74
74
|
# asserts type "T1w"
|
75
75
|
assert "T1w" in out
|
@@ -82,8 +82,8 @@ def test_DataladAOMICPIOP2(tasks: Optional[str]) -> None:
|
|
82
82
|
assert out["T1w"]["path"].exists()
|
83
83
|
assert out["T1w"]["path"].is_file()
|
84
84
|
|
85
|
-
# asserts
|
86
|
-
assert out["
|
85
|
+
# asserts T1w.mask
|
86
|
+
assert out["T1w"]["mask"]["path"].exists()
|
87
87
|
|
88
88
|
# asserts type "VBM_CSF"
|
89
89
|
assert "VBM_CSF" in out
|
@@ -141,13 +141,12 @@ def test_DataladAOMICPIOP2(tasks: Optional[str]) -> None:
|
|
141
141
|
"types",
|
142
142
|
[
|
143
143
|
"BOLD",
|
144
|
-
"BOLD_confounds",
|
145
144
|
"T1w",
|
146
145
|
"VBM_CSF",
|
147
146
|
"VBM_GM",
|
148
147
|
"VBM_WM",
|
149
148
|
"DWI",
|
150
|
-
["BOLD", "
|
149
|
+
["BOLD", "VBM_CSF"],
|
151
150
|
["T1w", "VBM_CSF"],
|
152
151
|
["VBM_GM", "VBM_WM"],
|
153
152
|
["DWI", "BOLD"],
|
@@ -176,7 +176,16 @@ class DataladDataGrabber(BaseDataGrabber):
|
|
176
176
|
The unmodified input dictionary.
|
177
177
|
|
178
178
|
"""
|
179
|
-
to_get = [
|
179
|
+
to_get = []
|
180
|
+
for type_val in out.values():
|
181
|
+
# Iterate to check for nested "types" like mask
|
182
|
+
for k, v in type_val.items():
|
183
|
+
# Add base data type path
|
184
|
+
if k == "path":
|
185
|
+
to_get.append(v)
|
186
|
+
# Add nested data type path
|
187
|
+
if isinstance(v, dict) and "path" in v:
|
188
|
+
to_get.append(v["path"])
|
180
189
|
|
181
190
|
if len(to_get) > 0:
|
182
191
|
logger.debug(f"Getting {len(to_get)} files using datalad:")
|
@@ -25,17 +25,16 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
|
|
25
25
|
The directory where the datalad dataset will be cloned. If None,
|
26
26
|
the datalad dataset will be cloned into a temporary directory
|
27
27
|
(default None).
|
28
|
-
types: {"BOLD", "
|
29
|
-
|
30
|
-
"native_t1w = True")} or a list of the options, optional
|
28
|
+
types: {"BOLD", "T1w", "VBM_CSF", "VBM_GM", "VBM_WM"} or \
|
29
|
+
list of the options, optional
|
31
30
|
DMCC data types. If None, all available data types are selected.
|
32
31
|
(default None).
|
33
|
-
sessions: {"ses-wave1bas", "ses-wave1pro", "ses-wave1rea"} or
|
34
|
-
|
32
|
+
sessions: {"ses-wave1bas", "ses-wave1pro", "ses-wave1rea"} or \
|
33
|
+
list of the options, optional
|
35
34
|
DMCC sessions. If None, all available sessions are selected
|
36
35
|
(default None).
|
37
36
|
tasks: {"Rest", "Axcpt", "Cuedts", "Stern", "Stroop"} or \
|
38
|
-
|
37
|
+
list of the options, optional
|
39
38
|
DMCC task sessions. If None, all available task sessions are selected
|
40
39
|
(default None).
|
41
40
|
phase_encodings : {"AP", "PA"} or list of the options, optional
|
@@ -148,24 +147,23 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
|
|
148
147
|
"space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz"
|
149
148
|
),
|
150
149
|
"space": "MNI152NLin2009cAsym",
|
151
|
-
"
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
"
|
167
|
-
|
168
|
-
"space": "MNI152NLin2009cAsym",
|
150
|
+
"mask": {
|
151
|
+
"pattern": (
|
152
|
+
"derivatives/fmriprep-1.3.2/{subject}/{session}/"
|
153
|
+
"/func/{subject}_{session}_task-{task}_acq-mb4"
|
154
|
+
"{phase_encoding}_run-{run}_"
|
155
|
+
"space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
|
156
|
+
),
|
157
|
+
"space": "MNI152NLin2009cAsym",
|
158
|
+
},
|
159
|
+
"confounds": {
|
160
|
+
"pattern": (
|
161
|
+
"derivatives/fmriprep-1.3.2/{subject}/{session}/"
|
162
|
+
"func/{subject}_{session}_task-{task}_acq-mb4"
|
163
|
+
"{phase_encoding}_run-{run}_desc-confounds_regressors.tsv"
|
164
|
+
),
|
165
|
+
"format": "fmriprep",
|
166
|
+
},
|
169
167
|
},
|
170
168
|
"T1w": {
|
171
169
|
"pattern": (
|
@@ -173,14 +171,13 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
|
|
173
171
|
"{subject}_space-MNI152NLin2009cAsym_desc-preproc_T1w.nii.gz"
|
174
172
|
),
|
175
173
|
"space": "MNI152NLin2009cAsym",
|
176
|
-
"
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
"
|
182
|
-
|
183
|
-
"space": "MNI152NLin2009cAsym",
|
174
|
+
"mask": {
|
175
|
+
"pattern": (
|
176
|
+
"derivatives/fmriprep-1.3.2/{subject}/anat/"
|
177
|
+
"{subject}_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
|
178
|
+
),
|
179
|
+
"space": "MNI152NLin2009cAsym",
|
180
|
+
},
|
184
181
|
},
|
185
182
|
"VBM_CSF": {
|
186
183
|
"pattern": (
|
@@ -216,14 +213,13 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
|
|
216
213
|
"{subject}_desc-preproc_T1w.nii.gz"
|
217
214
|
),
|
218
215
|
"space": "native",
|
219
|
-
"
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
"
|
225
|
-
|
226
|
-
"space": "native",
|
216
|
+
"mask": {
|
217
|
+
"pattern": (
|
218
|
+
"derivatives/fmriprep-1.3.2/{subject}/anat/"
|
219
|
+
"{subject}_desc-brain_mask.nii.gz"
|
220
|
+
),
|
221
|
+
"space": "native",
|
222
|
+
},
|
227
223
|
},
|
228
224
|
"Warp": {
|
229
225
|
"pattern": (
|
@@ -298,20 +294,6 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
|
|
298
294
|
phase_encoding=phase_encoding,
|
299
295
|
run=run,
|
300
296
|
)
|
301
|
-
if out.get("BOLD"):
|
302
|
-
out["BOLD"]["mask_item"] = "BOLD_mask"
|
303
|
-
# Add space information
|
304
|
-
out["BOLD"].update({"space": "MNI152NLin2009cAsym"})
|
305
|
-
if out.get("T1w"):
|
306
|
-
out["T1w"]["mask_item"] = "T1w_mask"
|
307
|
-
# Add space information
|
308
|
-
if self.native_t1w:
|
309
|
-
out["T1w"].update({"space": "native"})
|
310
|
-
else:
|
311
|
-
out["T1w"].update({"space": "MNI152NLin2009cAsym"})
|
312
|
-
if out.get("Warp"):
|
313
|
-
# Add source space information
|
314
|
-
out["Warp"].update({"src": "MNI152NLin2009cAsym"})
|
315
297
|
return out
|
316
298
|
|
317
299
|
def get_elements(self) -> List:
|
junifer/datagrabber/pattern.py
CHANGED
@@ -40,7 +40,12 @@ class PatternDataGrabber(BaseDataGrabber):
|
|
40
40
|
|
41
41
|
{
|
42
42
|
"mandatory": ["pattern", "space"],
|
43
|
-
"optional":
|
43
|
+
"optional": {
|
44
|
+
"mask": {
|
45
|
+
"mandatory": ["pattern", "space"],
|
46
|
+
"optional": []
|
47
|
+
}
|
48
|
+
}
|
44
49
|
}
|
45
50
|
|
46
51
|
* ``"T2w"`` :
|
@@ -49,7 +54,12 @@ class PatternDataGrabber(BaseDataGrabber):
|
|
49
54
|
|
50
55
|
{
|
51
56
|
"mandatory": ["pattern", "space"],
|
52
|
-
"optional":
|
57
|
+
"optional": {
|
58
|
+
"mask": {
|
59
|
+
"mandatory": ["pattern", "space"],
|
60
|
+
"optional": []
|
61
|
+
}
|
62
|
+
}
|
53
63
|
}
|
54
64
|
|
55
65
|
* ``"BOLD"`` :
|
@@ -58,7 +68,16 @@ class PatternDataGrabber(BaseDataGrabber):
|
|
58
68
|
|
59
69
|
{
|
60
70
|
"mandatory": ["pattern", "space"],
|
61
|
-
"optional":
|
71
|
+
"optional": {
|
72
|
+
"mask": {
|
73
|
+
"mandatory": ["pattern", "space"],
|
74
|
+
"optional": []
|
75
|
+
}
|
76
|
+
"confounds": {
|
77
|
+
"mandatory": ["pattern", "format"],
|
78
|
+
"optional": []
|
79
|
+
}
|
80
|
+
}
|
62
81
|
}
|
63
82
|
|
64
83
|
* ``"Warp"`` :
|
@@ -70,15 +89,6 @@ class PatternDataGrabber(BaseDataGrabber):
|
|
70
89
|
"optional": []
|
71
90
|
}
|
72
91
|
|
73
|
-
* ``"BOLD_confounds"`` :
|
74
|
-
|
75
|
-
.. code-block:: none
|
76
|
-
|
77
|
-
{
|
78
|
-
"mandatory": ["pattern", "format"],
|
79
|
-
"optional": []
|
80
|
-
}
|
81
|
-
|
82
92
|
* ``"VBM_GM"`` :
|
83
93
|
|
84
94
|
.. code-block:: none
|
@@ -246,6 +256,64 @@ class PatternDataGrabber(BaseDataGrabber):
|
|
246
256
|
)
|
247
257
|
return pattern.format(**element)
|
248
258
|
|
259
|
+
def _get_path_from_patterns(
|
260
|
+
self, element: Dict, pattern: str, data_type: str
|
261
|
+
) -> Path:
|
262
|
+
"""Get path from resolved patterns.
|
263
|
+
|
264
|
+
Parameters
|
265
|
+
----------
|
266
|
+
element : dict
|
267
|
+
The element to be used in the replacement.
|
268
|
+
pattern : str
|
269
|
+
The pattern to be replaced.
|
270
|
+
data_type : str
|
271
|
+
The data type of the pattern.
|
272
|
+
|
273
|
+
Returns
|
274
|
+
-------
|
275
|
+
pathlib.Path
|
276
|
+
The path for the resolved pattern.
|
277
|
+
|
278
|
+
Raises
|
279
|
+
------
|
280
|
+
RuntimeError
|
281
|
+
If more than one file matches for a data type's pattern or
|
282
|
+
if no file matches for a data type's pattern or
|
283
|
+
if file cannot be accessed for an element.
|
284
|
+
|
285
|
+
"""
|
286
|
+
# Replace element in the pattern for globbing
|
287
|
+
resolved_pattern = self._replace_patterns_glob(element, pattern)
|
288
|
+
# Resolve path for wildcard
|
289
|
+
if "*" in resolved_pattern:
|
290
|
+
t_matches = list(self.datadir.absolute().glob(resolved_pattern))
|
291
|
+
# Multiple matches
|
292
|
+
if len(t_matches) > 1:
|
293
|
+
raise_error(
|
294
|
+
f"More than one file matches for {element} / {data_type}:"
|
295
|
+
f" {t_matches}",
|
296
|
+
klass=RuntimeError,
|
297
|
+
)
|
298
|
+
# No matches
|
299
|
+
elif len(t_matches) == 0:
|
300
|
+
raise_error(
|
301
|
+
f"No file matches for {element} / {data_type}",
|
302
|
+
klass=RuntimeError,
|
303
|
+
)
|
304
|
+
path = t_matches[0]
|
305
|
+
else:
|
306
|
+
path = self.datadir / resolved_pattern
|
307
|
+
if not self.skip_file_check:
|
308
|
+
if not path.exists() and not path.is_symlink():
|
309
|
+
raise_error(
|
310
|
+
f"Cannot access {data_type} for {element}: "
|
311
|
+
f"File {path} does not exist",
|
312
|
+
klass=RuntimeError,
|
313
|
+
)
|
314
|
+
|
315
|
+
return path
|
316
|
+
|
249
317
|
def get_element_keys(self) -> List[str]:
|
250
318
|
"""Get element keys.
|
251
319
|
|
@@ -279,47 +347,49 @@ class PatternDataGrabber(BaseDataGrabber):
|
|
279
347
|
Dictionary of dictionaries for each type of data required for the
|
280
348
|
specified element.
|
281
349
|
|
282
|
-
Raises
|
283
|
-
------
|
284
|
-
RuntimeError
|
285
|
-
If more than one file matches for a data type's pattern or
|
286
|
-
if no file matches for a data type's pattern or
|
287
|
-
if file cannot be accessed for an element.
|
288
|
-
|
289
350
|
"""
|
290
351
|
out = {}
|
291
352
|
for t_type in self.types:
|
353
|
+
# Data type dictionary
|
292
354
|
t_pattern = self.patterns[t_type]
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
if
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
355
|
+
# Copy data type dictionary in output
|
356
|
+
out[t_type] = t_pattern.copy()
|
357
|
+
# Iterate to check for nested "types" like mask
|
358
|
+
for k, v in t_pattern.items():
|
359
|
+
# Resolve pattern for base data type
|
360
|
+
if k == "pattern":
|
361
|
+
logger.info(f"Resolving path from pattern for {t_type}")
|
362
|
+
# Resolve pattern
|
363
|
+
base_data_type_pattern_path = self._get_path_from_patterns(
|
364
|
+
element=element,
|
365
|
+
pattern=v,
|
366
|
+
data_type=t_type,
|
303
367
|
)
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
368
|
+
# Remove pattern key
|
369
|
+
out[t_type].pop("pattern")
|
370
|
+
# Add path key
|
371
|
+
out[t_type].update({"path": base_data_type_pattern_path})
|
372
|
+
# Resolve pattern for nested data type
|
373
|
+
if isinstance(v, dict) and "pattern" in v:
|
374
|
+
# Set nested type key for easier access
|
375
|
+
t_nested_type = f"{t_type}.{k}"
|
376
|
+
logger.info(
|
377
|
+
f"Resolving path from pattern for {t_nested_type}"
|
308
378
|
)
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
f"Cannot access {t_type} for {element}: "
|
316
|
-
f"File {t_out} does not exist",
|
317
|
-
klass=RuntimeError,
|
379
|
+
# Resolve pattern
|
380
|
+
nested_data_type_pattern_path = (
|
381
|
+
self._get_path_from_patterns(
|
382
|
+
element=element,
|
383
|
+
pattern=v["pattern"],
|
384
|
+
data_type=t_nested_type,
|
318
385
|
)
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
386
|
+
)
|
387
|
+
# Remove pattern key
|
388
|
+
out[t_type][k].pop("pattern")
|
389
|
+
# Add path key
|
390
|
+
out[t_type][k].update(
|
391
|
+
{"path": nested_data_type_pattern_path}
|
392
|
+
)
|
323
393
|
|
324
394
|
return out
|
325
395
|
|
@@ -32,7 +32,12 @@ class PatternDataladDataGrabber(DataladDataGrabber, PatternDataGrabber):
|
|
32
32
|
|
33
33
|
{
|
34
34
|
"mandatory": ["pattern", "space"],
|
35
|
-
"optional":
|
35
|
+
"optional": {
|
36
|
+
"mask": {
|
37
|
+
"mandatory": ["pattern", "space"],
|
38
|
+
"optional": []
|
39
|
+
}
|
40
|
+
}
|
36
41
|
}
|
37
42
|
|
38
43
|
* ``"T2w"`` :
|
@@ -41,7 +46,12 @@ class PatternDataladDataGrabber(DataladDataGrabber, PatternDataGrabber):
|
|
41
46
|
|
42
47
|
{
|
43
48
|
"mandatory": ["pattern", "space"],
|
44
|
-
"optional":
|
49
|
+
"optional": {
|
50
|
+
"mask": {
|
51
|
+
"mandatory": ["pattern", "space"],
|
52
|
+
"optional": []
|
53
|
+
}
|
54
|
+
}
|
45
55
|
}
|
46
56
|
|
47
57
|
* ``"BOLD"`` :
|
@@ -50,7 +60,16 @@ class PatternDataladDataGrabber(DataladDataGrabber, PatternDataGrabber):
|
|
50
60
|
|
51
61
|
{
|
52
62
|
"mandatory": ["pattern", "space"],
|
53
|
-
"optional":
|
63
|
+
"optional": {
|
64
|
+
"mask": {
|
65
|
+
"mandatory": ["pattern", "space"],
|
66
|
+
"optional": []
|
67
|
+
}
|
68
|
+
"confounds": {
|
69
|
+
"mandatory": ["pattern", "format"],
|
70
|
+
"optional": []
|
71
|
+
}
|
72
|
+
}
|
54
73
|
}
|
55
74
|
|
56
75
|
* ``"Warp"`` :
|
@@ -62,15 +81,6 @@ class PatternDataladDataGrabber(DataladDataGrabber, PatternDataGrabber):
|
|
62
81
|
"optional": []
|
63
82
|
}
|
64
83
|
|
65
|
-
* ``"BOLD_confounds"`` :
|
66
|
-
|
67
|
-
.. code-block:: none
|
68
|
-
|
69
|
-
{
|
70
|
-
"mandatory": ["pattern", "format"],
|
71
|
-
"optional": []
|
72
|
-
}
|
73
|
-
|
74
84
|
* ``"VBM_GM"`` :
|
75
85
|
|
76
86
|
.. code-block:: none
|
@@ -151,12 +151,18 @@ def test_validate_replacements(
|
|
151
151
|
pytest.raises(KeyError, match="Mandatory key"),
|
152
152
|
),
|
153
153
|
(
|
154
|
-
["
|
154
|
+
["BOLD"],
|
155
155
|
{
|
156
|
-
"
|
157
|
-
"pattern":
|
158
|
-
|
156
|
+
"BOLD": {
|
157
|
+
"pattern": (
|
158
|
+
"{subject}/func/{subject}_task-rest_bold.nii.gz"
|
159
|
+
),
|
159
160
|
"space": "MNINLin6Asym",
|
161
|
+
"confounds": {
|
162
|
+
"pattern": "{subject}/func/{subject}_confounds.tsv",
|
163
|
+
"format": "fmriprep",
|
164
|
+
},
|
165
|
+
"zip": "zap",
|
160
166
|
},
|
161
167
|
},
|
162
168
|
pytest.raises(RuntimeError, match="not accepted"),
|
@@ -172,7 +178,7 @@ def test_validate_replacements(
|
|
172
178
|
pytest.raises(ValueError, match="following a replacement"),
|
173
179
|
),
|
174
180
|
(
|
175
|
-
["T1w", "T2w", "BOLD"
|
181
|
+
["T1w", "T2w", "BOLD"],
|
176
182
|
{
|
177
183
|
"T1w": {
|
178
184
|
"pattern": "{subject}/anat/{subject}_T1w.nii.gz",
|
@@ -187,10 +193,10 @@ def test_validate_replacements(
|
|
187
193
|
"{subject}/func/{subject}_task-rest_bold.nii.gz"
|
188
194
|
),
|
189
195
|
"space": "MNI152NLin6Asym",
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
196
|
+
"confounds": {
|
197
|
+
"pattern": "{subject}/func/{subject}_confounds.tsv",
|
198
|
+
"format": "fmriprep",
|
199
|
+
},
|
194
200
|
},
|
195
201
|
},
|
196
202
|
nullcontext(),
|
@@ -93,13 +93,10 @@ def test_DMCC13Benchmark(
|
|
93
93
|
# Available data types
|
94
94
|
data_types = [
|
95
95
|
"BOLD",
|
96
|
-
"BOLD_confounds",
|
97
|
-
"BOLD_mask",
|
98
96
|
"VBM_CSF",
|
99
97
|
"VBM_GM",
|
100
98
|
"VBM_WM",
|
101
99
|
"T1w",
|
102
|
-
"T1w_mask",
|
103
100
|
]
|
104
101
|
# Add Warp if native T1w is accessed
|
105
102
|
if native_t1w:
|
@@ -111,14 +108,6 @@ def test_DMCC13Benchmark(
|
|
111
108
|
f"sub-01_{ses}_task-{task}_acq-mb4{phase}_run-{run}_"
|
112
109
|
"space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz"
|
113
110
|
),
|
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
111
|
"sub-01_space-MNI152NLin2009cAsym_label-CSF_probseg.nii.gz",
|
123
112
|
"sub-01_space-MNI152NLin2009cAsym_label-GM_probseg.nii.gz",
|
124
113
|
"sub-01_space-MNI152NLin2009cAsym_label-WM_probseg.nii.gz",
|
@@ -127,16 +116,12 @@ def test_DMCC13Benchmark(
|
|
127
116
|
data_file_names.extend(
|
128
117
|
[
|
129
118
|
"sub-01_desc-preproc_T1w.nii.gz",
|
130
|
-
"sub-01_desc-brain_mask.nii.gz",
|
131
119
|
"sub-01_from-MNI152NLin2009cAsym_to-T1w_mode-image_xfm.h5",
|
132
120
|
]
|
133
121
|
)
|
134
122
|
else:
|
135
|
-
data_file_names.
|
136
|
-
|
137
|
-
"sub-01_space-MNI152NLin2009cAsym_desc-preproc_T1w.nii.gz",
|
138
|
-
"sub-01_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz",
|
139
|
-
]
|
123
|
+
data_file_names.append(
|
124
|
+
"sub-01_space-MNI152NLin2009cAsym_desc-preproc_T1w.nii.gz"
|
140
125
|
)
|
141
126
|
|
142
127
|
for data_type, data_file_name in zip(data_types, data_file_names):
|
@@ -151,6 +136,48 @@ def test_DMCC13Benchmark(
|
|
151
136
|
# Assert metadata
|
152
137
|
assert "meta" in out[data_type]
|
153
138
|
|
139
|
+
# Check BOLD nested data types
|
140
|
+
for type_, file_name in zip(
|
141
|
+
("mask", "confounds"),
|
142
|
+
(
|
143
|
+
(
|
144
|
+
f"sub-01_{ses}_task-{task}_acq-mb4{phase}_run-{run}_"
|
145
|
+
"space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
|
146
|
+
),
|
147
|
+
(
|
148
|
+
f"sub-01_{ses}_task-{task}_acq-mb4{phase}_run-{run}_"
|
149
|
+
"desc-confounds_regressors.tsv"
|
150
|
+
),
|
151
|
+
),
|
152
|
+
):
|
153
|
+
# Assert data type
|
154
|
+
assert type_ in out["BOLD"]
|
155
|
+
# Assert data file path exists
|
156
|
+
assert out["BOLD"][type_]["path"].exists()
|
157
|
+
# Assert data file path is a file
|
158
|
+
assert out["BOLD"][type_]["path"].is_file()
|
159
|
+
# Assert data file name
|
160
|
+
assert out["BOLD"][type_]["path"].name == file_name
|
161
|
+
|
162
|
+
# Check T1w nested data types
|
163
|
+
# Assert data type
|
164
|
+
assert "mask" in out["T1w"]
|
165
|
+
# Assert data file path exists
|
166
|
+
assert out["T1w"]["mask"]["path"].exists()
|
167
|
+
# Assert data file path is a file
|
168
|
+
assert out["T1w"]["mask"]["path"].is_file()
|
169
|
+
# Assert data file name
|
170
|
+
if native_t1w:
|
171
|
+
assert (
|
172
|
+
out["T1w"]["mask"]["path"].name
|
173
|
+
== "sub-01_desc-brain_mask.nii.gz"
|
174
|
+
)
|
175
|
+
else:
|
176
|
+
assert (
|
177
|
+
out["T1w"]["mask"]["path"].name
|
178
|
+
== "sub-01_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
|
179
|
+
)
|
180
|
+
|
154
181
|
|
155
182
|
@pytest.mark.parametrize(
|
156
183
|
"types, native_t1w",
|
@@ -165,8 +192,8 @@ def test_DMCC13Benchmark(
|
|
165
192
|
("VBM_GM", False),
|
166
193
|
("VBM_WM", True),
|
167
194
|
("VBM_WM", False),
|
168
|
-
(["BOLD", "
|
169
|
-
(["BOLD", "
|
195
|
+
(["BOLD", "VBM_CSF"], True),
|
196
|
+
(["BOLD", "VBM_CSF"], False),
|
170
197
|
(["T1w", "VBM_CSF"], True),
|
171
198
|
(["T1w", "VBM_CSF"], False),
|
172
199
|
(["VBM_GM", "VBM_WM"], True),
|