junifer 0.0.6.dev227__py3-none-any.whl → 0.0.6.dev248__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/data/coordinates/_ants_coordinates_warper.py +4 -6
- junifer/data/coordinates/_coordinates.py +28 -15
- junifer/data/coordinates/_fsl_coordinates_warper.py +4 -6
- junifer/data/masks/_ants_mask_warper.py +16 -9
- junifer/data/masks/_fsl_mask_warper.py +4 -6
- junifer/data/masks/_masks.py +21 -25
- junifer/data/parcellations/_ants_parcellation_warper.py +16 -9
- junifer/data/parcellations/_fsl_parcellation_warper.py +4 -6
- junifer/data/parcellations/_parcellations.py +20 -24
- junifer/data/utils.py +67 -3
- junifer/datagrabber/aomic/id1000.py +22 -9
- junifer/datagrabber/aomic/piop1.py +22 -9
- junifer/datagrabber/aomic/piop2.py +22 -9
- junifer/datagrabber/base.py +6 -1
- junifer/datagrabber/datalad_base.py +15 -8
- junifer/datagrabber/dmcc13_benchmark.py +23 -10
- junifer/datagrabber/hcp1200/hcp1200.py +18 -7
- junifer/datagrabber/pattern.py +65 -35
- junifer/datagrabber/pattern_validation_mixin.py +197 -87
- junifer/datagrabber/tests/test_dmcc13_benchmark.py +26 -9
- junifer/pipeline/pipeline_step_mixin.py +8 -4
- junifer/pipeline/update_meta_mixin.py +21 -17
- junifer/preprocess/warping/_ants_warper.py +23 -2
- junifer/preprocess/warping/_fsl_warper.py +19 -3
- junifer/preprocess/warping/space_warper.py +31 -4
- {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/METADATA +1 -1
- {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/RECORD +33 -33
- {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/WHEEL +1 -1
- {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/top_level.txt +0 -0
junifer/_version.py
CHANGED
@@ -12,5 +12,5 @@ __version__: str
|
|
12
12
|
__version_tuple__: VERSION_TUPLE
|
13
13
|
version_tuple: VERSION_TUPLE
|
14
14
|
|
15
|
-
__version__ = version = '0.0.6.
|
16
|
-
__version_tuple__ = version_tuple = (0, 0, 6, '
|
15
|
+
__version__ = version = '0.0.6.dev248'
|
16
|
+
__version_tuple__ = version_tuple = (0, 0, 6, 'dev248')
|
@@ -26,7 +26,7 @@ class ANTsCoordinatesWarper:
|
|
26
26
|
self,
|
27
27
|
seeds: ArrayLike,
|
28
28
|
target_data: Dict[str, Any],
|
29
|
-
|
29
|
+
warp_data: Dict[str, Any],
|
30
30
|
) -> ArrayLike:
|
31
31
|
"""Warp ``seeds`` to correct space.
|
32
32
|
|
@@ -37,10 +37,8 @@ class ANTsCoordinatesWarper:
|
|
37
37
|
target_data : dict
|
38
38
|
The corresponding item of the data object to which the coordinates
|
39
39
|
will be applied.
|
40
|
-
|
41
|
-
The
|
42
|
-
data kinds that needs to be used in the computation of coordinates
|
43
|
-
(default None).
|
40
|
+
warp_data : dict or None
|
41
|
+
The warp data item of the data object.
|
44
42
|
|
45
43
|
Returns
|
46
44
|
-------
|
@@ -79,7 +77,7 @@ class ANTsCoordinatesWarper:
|
|
79
77
|
"-f 0",
|
80
78
|
f"-i {pretransform_coordinates_path.resolve()}",
|
81
79
|
f"-o {transformed_coords_path.resolve()}",
|
82
|
-
f"-t {
|
80
|
+
f"-t {warp_data['path'].resolve()}",
|
83
81
|
]
|
84
82
|
# Call antsApplyTransformsToPoints
|
85
83
|
run_ext_cmd(
|
@@ -14,6 +14,7 @@ from numpy.typing import ArrayLike
|
|
14
14
|
from ...utils import logger, raise_error
|
15
15
|
from ...utils.singleton import Singleton
|
16
16
|
from ..pipeline_data_registry_base import BasePipelineDataRegistry
|
17
|
+
from ..utils import get_native_warper
|
17
18
|
from ._ants_coordinates_warper import ANTsCoordinatesWarper
|
18
19
|
from ._fsl_coordinates_warper import FSLCoordinatesWarper
|
19
20
|
|
@@ -311,7 +312,8 @@ class CoordinatesRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
311
312
|
Raises
|
312
313
|
------
|
313
314
|
RuntimeError
|
314
|
-
If
|
315
|
+
If warping specification required for warping using ANTs, is not
|
316
|
+
found.
|
315
317
|
ValueError
|
316
318
|
If ``extra_input`` is None when ``target_data``'s space is native.
|
317
319
|
|
@@ -329,27 +331,38 @@ class CoordinatesRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
329
331
|
f"{target_data['space']} space for further computation."
|
330
332
|
)
|
331
333
|
|
332
|
-
#
|
333
|
-
|
334
|
-
|
334
|
+
# Get native space warper spec
|
335
|
+
warper_spec = get_native_warper(
|
336
|
+
target_data=target_data,
|
337
|
+
other_data=extra_input,
|
338
|
+
)
|
339
|
+
# Conditional for warping tool implementation
|
340
|
+
if warper_spec["warper"] == "fsl":
|
335
341
|
seeds = FSLCoordinatesWarper().warp(
|
336
342
|
seeds=seeds,
|
337
343
|
target_data=target_data,
|
338
|
-
|
344
|
+
warp_data=warper_spec,
|
345
|
+
)
|
346
|
+
elif warper_spec["warper"] == "ants":
|
347
|
+
# Requires the inverse warp
|
348
|
+
inverse_warper_spec = get_native_warper(
|
349
|
+
target_data=target_data,
|
350
|
+
other_data=extra_input,
|
351
|
+
inverse=True,
|
339
352
|
)
|
340
|
-
|
353
|
+
# Check warper
|
354
|
+
if inverse_warper_spec["warper"] != "ants":
|
355
|
+
raise_error(
|
356
|
+
klass=RuntimeError,
|
357
|
+
msg=(
|
358
|
+
"Warping specification mismatch for native space "
|
359
|
+
"warping of coordinates using ANTs."
|
360
|
+
),
|
361
|
+
)
|
341
362
|
seeds = ANTsCoordinatesWarper().warp(
|
342
363
|
seeds=seeds,
|
343
364
|
target_data=target_data,
|
344
|
-
|
345
|
-
)
|
346
|
-
else:
|
347
|
-
raise_error(
|
348
|
-
msg=(
|
349
|
-
"Unknown warp / transformation file extension: "
|
350
|
-
f"{warp_file_ext}"
|
351
|
-
),
|
352
|
-
klass=RuntimeError,
|
365
|
+
warp_data=warper_spec,
|
353
366
|
)
|
354
367
|
|
355
368
|
return seeds, labels
|
@@ -26,7 +26,7 @@ class FSLCoordinatesWarper:
|
|
26
26
|
self,
|
27
27
|
seeds: ArrayLike,
|
28
28
|
target_data: Dict[str, Any],
|
29
|
-
|
29
|
+
warp_data: Dict[str, Any],
|
30
30
|
) -> ArrayLike:
|
31
31
|
"""Warp ``seeds`` to correct space.
|
32
32
|
|
@@ -37,10 +37,8 @@ class FSLCoordinatesWarper:
|
|
37
37
|
target_data : dict
|
38
38
|
The corresponding item of the data object to which the coordinates
|
39
39
|
will be applied.
|
40
|
-
|
41
|
-
The
|
42
|
-
data kinds that needs to be used in the computation of coordinates
|
43
|
-
(default None).
|
40
|
+
warp_data : dict
|
41
|
+
The warp data item of the data object.
|
44
42
|
|
45
43
|
Returns
|
46
44
|
-------
|
@@ -72,7 +70,7 @@ class FSLCoordinatesWarper:
|
|
72
70
|
"| img2imgcoord -mm",
|
73
71
|
f"-src {target_data['path'].resolve()}",
|
74
72
|
f"-dest {target_data['reference_path'].resolve()}",
|
75
|
-
f"-warp {
|
73
|
+
f"-warp {warp_data['path'].resolve()}",
|
76
74
|
f"> {transformed_coords_path.resolve()};",
|
77
75
|
f"sed -i 1d {transformed_coords_path.resolve()}",
|
78
76
|
]
|
@@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, Any, Dict, Optional
|
|
9
9
|
import nibabel as nib
|
10
10
|
|
11
11
|
from ...pipeline import WorkDirManager
|
12
|
-
from ...utils import logger, run_ext_cmd
|
12
|
+
from ...utils import logger, raise_error, run_ext_cmd
|
13
13
|
from ..template_spaces import get_template, get_xfm
|
14
14
|
|
15
15
|
|
@@ -34,7 +34,7 @@ class ANTsMaskWarper:
|
|
34
34
|
src: str,
|
35
35
|
dst: str,
|
36
36
|
target_data: Dict[str, Any],
|
37
|
-
|
37
|
+
warp_data: Optional[Dict[str, Any]],
|
38
38
|
) -> "Nifti1Image":
|
39
39
|
"""Warp ``mask_img`` to correct space.
|
40
40
|
|
@@ -55,17 +55,20 @@ class ANTsMaskWarper:
|
|
55
55
|
target_data : dict
|
56
56
|
The corresponding item of the data object to which the mask
|
57
57
|
will be applied.
|
58
|
-
|
59
|
-
The
|
60
|
-
|
61
|
-
(default None).
|
62
|
-
|
58
|
+
warp_data : dict or None
|
59
|
+
The warp data item of the data object. The value is unused if
|
60
|
+
``dst!="T1w"``.
|
63
61
|
|
64
62
|
Returns
|
65
63
|
-------
|
66
64
|
nibabel.nifti1.Nifti1Image
|
67
65
|
The transformed mask image.
|
68
66
|
|
67
|
+
Raises
|
68
|
+
------
|
69
|
+
RuntimeError
|
70
|
+
If ``warp_data`` is None when ``dst="T1w"``.
|
71
|
+
|
69
72
|
"""
|
70
73
|
# Create element-scoped tempdir so that warped mask is
|
71
74
|
# available later as nibabel stores file path reference for
|
@@ -80,7 +83,11 @@ class ANTsMaskWarper:
|
|
80
83
|
)
|
81
84
|
|
82
85
|
# Native space warping
|
83
|
-
if dst == "
|
86
|
+
if dst == "native":
|
87
|
+
# Warp data check
|
88
|
+
if warp_data is None:
|
89
|
+
raise_error("No `warp_data` provided")
|
90
|
+
|
84
91
|
logger.debug("Using ANTs for mask transformation")
|
85
92
|
|
86
93
|
# Save existing mask image to a tempfile
|
@@ -98,7 +105,7 @@ class ANTsMaskWarper:
|
|
98
105
|
f"-i {prewarp_mask_path.resolve()}",
|
99
106
|
# use resampled reference
|
100
107
|
f"-r {target_data['reference_path'].resolve()}",
|
101
|
-
f"-t {
|
108
|
+
f"-t {warp_data['path'].resolve()}",
|
102
109
|
f"-o {warped_mask_path.resolve()}",
|
103
110
|
]
|
104
111
|
# Call antsApplyTransforms
|
@@ -31,7 +31,7 @@ class FSLMaskWarper:
|
|
31
31
|
mask_name: str,
|
32
32
|
mask_img: "Nifti1Image",
|
33
33
|
target_data: Dict[str, Any],
|
34
|
-
|
34
|
+
warp_data: Dict[str, Any],
|
35
35
|
) -> "Nifti1Image":
|
36
36
|
"""Warp ``mask_img`` to correct space.
|
37
37
|
|
@@ -44,10 +44,8 @@ class FSLMaskWarper:
|
|
44
44
|
target_data : dict
|
45
45
|
The corresponding item of the data object to which the mask
|
46
46
|
will be applied.
|
47
|
-
|
48
|
-
The
|
49
|
-
data kinds that needs to be used in the computation of mask
|
50
|
-
(default None).
|
47
|
+
warp_data : dict
|
48
|
+
The warp data item of the data object.
|
51
49
|
|
52
50
|
Returns
|
53
51
|
-------
|
@@ -77,7 +75,7 @@ class FSLMaskWarper:
|
|
77
75
|
f"-i {prewarp_mask_path.resolve()}",
|
78
76
|
# use resampled reference
|
79
77
|
f"-r {target_data['reference_path'].resolve()}",
|
80
|
-
f"-w {
|
78
|
+
f"-w {warp_data['path'].resolve()}",
|
81
79
|
f"-o {warped_mask_path.resolve()}",
|
82
80
|
]
|
83
81
|
# Call applywarp
|
junifer/data/masks/_masks.py
CHANGED
@@ -29,7 +29,7 @@ from ...utils import logger, raise_error
|
|
29
29
|
from ...utils.singleton import Singleton
|
30
30
|
from ..pipeline_data_registry_base import BasePipelineDataRegistry
|
31
31
|
from ..template_spaces import get_template
|
32
|
-
from ..utils import closest_resolution
|
32
|
+
from ..utils import closest_resolution, get_native_warper
|
33
33
|
from ._ants_mask_warper import ANTsMaskWarper
|
34
34
|
from ._fsl_mask_warper import FSLMaskWarper
|
35
35
|
|
@@ -105,14 +105,16 @@ def compute_brain_mask(
|
|
105
105
|
"data type to infer target template space."
|
106
106
|
)
|
107
107
|
# Set target standard space to warp file space source
|
108
|
-
|
108
|
+
for entry in extra_input["Warp"]:
|
109
|
+
if entry["dst"] == "native":
|
110
|
+
target_std_space = entry["src"]
|
109
111
|
|
110
112
|
# Fetch template in closest resolution
|
111
113
|
template = get_template(
|
112
114
|
space=target_std_space,
|
113
115
|
target_data=target_data,
|
114
116
|
extra_input=extra_input,
|
115
|
-
template_type=mask_type
|
117
|
+
template_type=mask_type,
|
116
118
|
)
|
117
119
|
# Resample template to target image
|
118
120
|
target_img = target_data["data"]
|
@@ -357,8 +359,6 @@ class MaskRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
357
359
|
|
358
360
|
Raises
|
359
361
|
------
|
360
|
-
RuntimeError
|
361
|
-
If warp / transformation file extension is not ".mat" or ".h5".
|
362
362
|
ValueError
|
363
363
|
If extra key is provided in addition to mask name in ``masks`` or
|
364
364
|
if no mask is provided or
|
@@ -372,8 +372,6 @@ class MaskRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
372
372
|
"""
|
373
373
|
# Check pre-requirements for space manipulation
|
374
374
|
target_space = target_data["space"]
|
375
|
-
# Set target standard space to target space
|
376
|
-
target_std_space = target_space
|
377
375
|
# Extra data type requirement check if target space is native
|
378
376
|
if target_space == "native":
|
379
377
|
# Check for extra inputs
|
@@ -383,8 +381,16 @@ class MaskRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
383
381
|
"data types in particular for transformation to "
|
384
382
|
f"{target_data['space']} space for further computation."
|
385
383
|
)
|
384
|
+
# Get native space warper spec
|
385
|
+
warper_spec = get_native_warper(
|
386
|
+
target_data=target_data,
|
387
|
+
other_data=extra_input,
|
388
|
+
)
|
386
389
|
# Set target standard space to warp file space source
|
387
|
-
target_std_space =
|
390
|
+
target_std_space = warper_spec["src"]
|
391
|
+
else:
|
392
|
+
# Set target standard space to target space
|
393
|
+
target_std_space = target_space
|
388
394
|
|
389
395
|
# Get the min of the voxels sizes and use it as the resolution
|
390
396
|
target_img = target_data["data"]
|
@@ -489,7 +495,7 @@ class MaskRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
489
495
|
src=mask_space,
|
490
496
|
dst=target_std_space,
|
491
497
|
target_data=target_data,
|
492
|
-
|
498
|
+
warp_data=None,
|
493
499
|
)
|
494
500
|
|
495
501
|
all_masks.append(mask_img)
|
@@ -510,32 +516,22 @@ class MaskRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
510
516
|
|
511
517
|
# Warp mask if target data is native
|
512
518
|
if target_space == "native":
|
513
|
-
# extra_input check done earlier
|
514
|
-
|
515
|
-
warp_file_ext = extra_input["Warp"]["path"].suffix
|
516
|
-
if warp_file_ext == ".mat":
|
519
|
+
# extra_input check done earlier and warper_spec exists
|
520
|
+
if warper_spec["warper"] == "fsl":
|
517
521
|
mask_img = FSLMaskWarper().warp(
|
518
522
|
mask_name="native",
|
519
523
|
mask_img=mask_img,
|
520
524
|
target_data=target_data,
|
521
|
-
|
525
|
+
warp_data=warper_spec,
|
522
526
|
)
|
523
|
-
elif
|
527
|
+
elif warper_spec["warper"] == "ants":
|
524
528
|
mask_img = ANTsMaskWarper().warp(
|
525
529
|
mask_name="native",
|
526
530
|
mask_img=mask_img,
|
527
531
|
src="",
|
528
|
-
dst="
|
532
|
+
dst="native",
|
529
533
|
target_data=target_data,
|
530
|
-
|
531
|
-
)
|
532
|
-
else:
|
533
|
-
raise_error(
|
534
|
-
msg=(
|
535
|
-
"Unknown warp / transformation file extension: "
|
536
|
-
f"{warp_file_ext}"
|
537
|
-
),
|
538
|
-
klass=RuntimeError,
|
534
|
+
warp_data=warper_spec,
|
539
535
|
)
|
540
536
|
|
541
537
|
return mask_img
|
@@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, Any, Dict, Optional
|
|
9
9
|
import nibabel as nib
|
10
10
|
|
11
11
|
from ...pipeline import WorkDirManager
|
12
|
-
from ...utils import logger, run_ext_cmd
|
12
|
+
from ...utils import logger, raise_error, run_ext_cmd
|
13
13
|
from ..template_spaces import get_template, get_xfm
|
14
14
|
|
15
15
|
|
@@ -34,7 +34,7 @@ class ANTsParcellationWarper:
|
|
34
34
|
src: str,
|
35
35
|
dst: str,
|
36
36
|
target_data: Dict[str, Any],
|
37
|
-
|
37
|
+
warp_data: Optional[Dict[str, Any]],
|
38
38
|
) -> "Nifti1Image":
|
39
39
|
"""Warp ``parcellation_img`` to correct space.
|
40
40
|
|
@@ -55,17 +55,20 @@ class ANTsParcellationWarper:
|
|
55
55
|
target_data : dict
|
56
56
|
The corresponding item of the data object to which the parcellation
|
57
57
|
will be applied.
|
58
|
-
|
59
|
-
The
|
60
|
-
|
61
|
-
(default None).
|
62
|
-
|
58
|
+
warp_data : dict or None
|
59
|
+
The warp data item of the data object. The value is unused if
|
60
|
+
``dst!="T1w"``.
|
63
61
|
|
64
62
|
Returns
|
65
63
|
-------
|
66
64
|
nibabel.nifti1.Nifti1Image
|
67
65
|
The transformed parcellation image.
|
68
66
|
|
67
|
+
Raises
|
68
|
+
------
|
69
|
+
ValueError
|
70
|
+
If ``warp_data`` is None when ``dst="T1w"``.
|
71
|
+
|
69
72
|
"""
|
70
73
|
# Create element-scoped tempdir so that warped parcellation is
|
71
74
|
# available later as nibabel stores file path reference for
|
@@ -80,7 +83,11 @@ class ANTsParcellationWarper:
|
|
80
83
|
)
|
81
84
|
|
82
85
|
# Native space warping
|
83
|
-
if dst == "
|
86
|
+
if dst == "native":
|
87
|
+
# Warp data check
|
88
|
+
if warp_data is None:
|
89
|
+
raise_error("No `warp_data` provided")
|
90
|
+
|
84
91
|
logger.debug("Using ANTs for parcellation transformation")
|
85
92
|
|
86
93
|
# Save existing parcellation image to a tempfile
|
@@ -102,7 +109,7 @@ class ANTsParcellationWarper:
|
|
102
109
|
f"-i {prewarp_parcellation_path.resolve()}",
|
103
110
|
# use resampled reference
|
104
111
|
f"-r {target_data['reference_path'].resolve()}",
|
105
|
-
f"-t {
|
112
|
+
f"-t {warp_data['path'].resolve()}",
|
106
113
|
f"-o {warped_parcellation_path.resolve()}",
|
107
114
|
]
|
108
115
|
# Call antsApplyTransforms
|
@@ -31,7 +31,7 @@ class FSLParcellationWarper:
|
|
31
31
|
parcellation_name: str,
|
32
32
|
parcellation_img: "Nifti1Image",
|
33
33
|
target_data: Dict[str, Any],
|
34
|
-
|
34
|
+
warp_data: Dict[str, Any],
|
35
35
|
) -> "Nifti1Image":
|
36
36
|
"""Warp ``parcellation_img`` to correct space.
|
37
37
|
|
@@ -44,10 +44,8 @@ class FSLParcellationWarper:
|
|
44
44
|
target_data : dict
|
45
45
|
The corresponding item of the data object to which the parcellation
|
46
46
|
will be applied.
|
47
|
-
|
48
|
-
The
|
49
|
-
data kinds that needs to be used in the computation of parcellation
|
50
|
-
(default None).
|
47
|
+
warp_data : dict
|
48
|
+
The warp data item of the data object.
|
51
49
|
|
52
50
|
Returns
|
53
51
|
-------
|
@@ -81,7 +79,7 @@ class FSLParcellationWarper:
|
|
81
79
|
f"-i {prewarp_parcellation_path.resolve()}",
|
82
80
|
# use resampled reference
|
83
81
|
f"-r {target_data['reference_path'].resolve()}",
|
84
|
-
f"-w {
|
82
|
+
f"-w {warp_data['path'].resolve()}",
|
85
83
|
f"-o {warped_parcellation_path.resolve()}",
|
86
84
|
]
|
87
85
|
# Call applywarp
|
@@ -23,7 +23,7 @@ from nilearn import datasets, image
|
|
23
23
|
from ...utils import logger, raise_error, warn_with_log
|
24
24
|
from ...utils.singleton import Singleton
|
25
25
|
from ..pipeline_data_registry_base import BasePipelineDataRegistry
|
26
|
-
from ..utils import closest_resolution
|
26
|
+
from ..utils import closest_resolution, get_native_warper
|
27
27
|
from ._ants_parcellation_warper import ANTsParcellationWarper
|
28
28
|
from ._fsl_parcellation_warper import FSLParcellationWarper
|
29
29
|
|
@@ -394,16 +394,12 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
394
394
|
|
395
395
|
Raises
|
396
396
|
------
|
397
|
-
RuntimeError
|
398
|
-
If warp / transformation file extension is not ".mat" or ".h5".
|
399
397
|
ValueError
|
400
398
|
If ``extra_input`` is None when ``target_data``'s space is native.
|
401
399
|
|
402
400
|
"""
|
403
401
|
# Check pre-requirements for space manipulation
|
404
402
|
target_space = target_data["space"]
|
405
|
-
# Set target standard space to target space
|
406
|
-
target_std_space = target_space
|
407
403
|
# Extra data type requirement check if target space is native
|
408
404
|
if target_space == "native":
|
409
405
|
# Check for extra inputs
|
@@ -413,8 +409,16 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
413
409
|
"data types in particular for transformation to "
|
414
410
|
f"{target_data['space']} space for further computation."
|
415
411
|
)
|
412
|
+
# Get native space warper spec
|
413
|
+
warper_spec = get_native_warper(
|
414
|
+
target_data=target_data,
|
415
|
+
other_data=extra_input,
|
416
|
+
)
|
416
417
|
# Set target standard space to warp file space source
|
417
|
-
target_std_space =
|
418
|
+
target_std_space = warper_spec["src"]
|
419
|
+
else:
|
420
|
+
# Set target standard space to target space
|
421
|
+
target_std_space = target_space
|
418
422
|
|
419
423
|
# Get the min of the voxels sizes and use it as the resolution
|
420
424
|
target_img = target_data["data"]
|
@@ -428,12 +432,14 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
428
432
|
all_parcellations = []
|
429
433
|
all_labels = []
|
430
434
|
for name in parcellations:
|
435
|
+
# Load parcellation
|
431
436
|
img, labels, _, space = self.load(
|
432
437
|
name=name,
|
433
438
|
resolution=resolution,
|
434
439
|
)
|
435
440
|
|
436
|
-
# Convert parcellation spaces if required
|
441
|
+
# Convert parcellation spaces if required;
|
442
|
+
# cannot be "native" due to earlier check
|
437
443
|
if space != target_std_space:
|
438
444
|
raw_img = ANTsParcellationWarper().warp(
|
439
445
|
parcellation_name=name,
|
@@ -441,7 +447,7 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
441
447
|
src=space,
|
442
448
|
dst=target_std_space,
|
443
449
|
target_data=target_data,
|
444
|
-
|
450
|
+
warp_data=None,
|
445
451
|
)
|
446
452
|
# Remove extra dimension added by ANTs
|
447
453
|
img = image.math_img("np.squeeze(img)", img=raw_img)
|
@@ -471,32 +477,22 @@ class ParcellationRegistry(BasePipelineDataRegistry, metaclass=Singleton):
|
|
471
477
|
|
472
478
|
# Warp parcellation if target space is native
|
473
479
|
if target_space == "native":
|
474
|
-
# extra_input check done earlier
|
475
|
-
|
476
|
-
warp_file_ext = extra_input["Warp"]["path"].suffix
|
477
|
-
if warp_file_ext == ".mat":
|
480
|
+
# extra_input check done earlier and warper_spec exists
|
481
|
+
if warper_spec["warper"] == "fsl":
|
478
482
|
resampled_parcellation_img = FSLParcellationWarper().warp(
|
479
483
|
parcellation_name="native",
|
480
484
|
parcellation_img=resampled_parcellation_img,
|
481
485
|
target_data=target_data,
|
482
|
-
|
486
|
+
warp_data=warper_spec,
|
483
487
|
)
|
484
|
-
elif
|
488
|
+
elif warper_spec["warper"] == "ants":
|
485
489
|
resampled_parcellation_img = ANTsParcellationWarper().warp(
|
486
490
|
parcellation_name="native",
|
487
491
|
parcellation_img=resampled_parcellation_img,
|
488
492
|
src="",
|
489
|
-
dst="
|
493
|
+
dst="native",
|
490
494
|
target_data=target_data,
|
491
|
-
|
492
|
-
)
|
493
|
-
else:
|
494
|
-
raise_error(
|
495
|
-
msg=(
|
496
|
-
"Unknown warp / transformation file extension: "
|
497
|
-
f"{warp_file_ext}"
|
498
|
-
),
|
499
|
-
klass=RuntimeError,
|
495
|
+
warp_data=warper_spec,
|
500
496
|
)
|
501
497
|
|
502
498
|
return resampled_parcellation_img, labels
|
junifer/data/utils.py
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
5
5
|
# License: AGPL
|
6
6
|
|
7
|
-
from typing import List, Optional, Union
|
7
|
+
from typing import Dict, List, MutableMapping, Optional, Union
|
8
8
|
|
9
9
|
import numpy as np
|
10
10
|
|
11
|
-
from ..utils
|
11
|
+
from ..utils import logger, raise_error
|
12
12
|
|
13
13
|
|
14
|
-
__all__ = ["closest_resolution"]
|
14
|
+
__all__ = ["closest_resolution", "get_native_warper"]
|
15
15
|
|
16
16
|
|
17
17
|
def closest_resolution(
|
@@ -49,3 +49,67 @@ def closest_resolution(
|
|
49
49
|
closest = np.min(valid_resolution)
|
50
50
|
|
51
51
|
return closest
|
52
|
+
|
53
|
+
|
54
|
+
def get_native_warper(
|
55
|
+
target_data: MutableMapping,
|
56
|
+
other_data: MutableMapping,
|
57
|
+
inverse: bool = False,
|
58
|
+
) -> Dict:
|
59
|
+
"""Get correct warping specification for native space.
|
60
|
+
|
61
|
+
Parameters
|
62
|
+
----------
|
63
|
+
target_data : dict
|
64
|
+
The target data from the pipeline data object.
|
65
|
+
other_data : dict
|
66
|
+
The other data in the pipeline data object.
|
67
|
+
inverse : bool, optional
|
68
|
+
Whether to get the inverse warping specification (default False).
|
69
|
+
|
70
|
+
Returns
|
71
|
+
-------
|
72
|
+
dict
|
73
|
+
The correct warping specification.
|
74
|
+
|
75
|
+
Raises
|
76
|
+
------
|
77
|
+
RuntimeError
|
78
|
+
If no warper or multiple possible warpers are found.
|
79
|
+
|
80
|
+
"""
|
81
|
+
# Get possible warpers
|
82
|
+
possible_warpers = []
|
83
|
+
for entry in other_data["Warp"]:
|
84
|
+
if not inverse:
|
85
|
+
if (
|
86
|
+
entry["src"] == target_data["prewarp_space"]
|
87
|
+
and entry["dst"] == "native"
|
88
|
+
):
|
89
|
+
possible_warpers.append(entry)
|
90
|
+
else:
|
91
|
+
if (
|
92
|
+
entry["dst"] == target_data["prewarp_space"]
|
93
|
+
and entry["src"] == "native"
|
94
|
+
):
|
95
|
+
possible_warpers.append(entry)
|
96
|
+
|
97
|
+
# Check for no warper
|
98
|
+
if not possible_warpers:
|
99
|
+
raise_error(
|
100
|
+
klass=RuntimeError,
|
101
|
+
msg="Could not find correct warping specification",
|
102
|
+
)
|
103
|
+
|
104
|
+
# Check for multiple possible warpers
|
105
|
+
if len(possible_warpers) > 1:
|
106
|
+
raise_error(
|
107
|
+
klass=RuntimeError,
|
108
|
+
msg=(
|
109
|
+
"Cannot proceed as multiple warping specification found, "
|
110
|
+
"adjust either the DataGrabber or the working space: "
|
111
|
+
f"{possible_warpers}"
|
112
|
+
),
|
113
|
+
)
|
114
|
+
|
115
|
+
return possible_warpers[0]
|