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.
Files changed (33) hide show
  1. junifer/_version.py +2 -2
  2. junifer/data/coordinates/_ants_coordinates_warper.py +4 -6
  3. junifer/data/coordinates/_coordinates.py +28 -15
  4. junifer/data/coordinates/_fsl_coordinates_warper.py +4 -6
  5. junifer/data/masks/_ants_mask_warper.py +16 -9
  6. junifer/data/masks/_fsl_mask_warper.py +4 -6
  7. junifer/data/masks/_masks.py +21 -25
  8. junifer/data/parcellations/_ants_parcellation_warper.py +16 -9
  9. junifer/data/parcellations/_fsl_parcellation_warper.py +4 -6
  10. junifer/data/parcellations/_parcellations.py +20 -24
  11. junifer/data/utils.py +67 -3
  12. junifer/datagrabber/aomic/id1000.py +22 -9
  13. junifer/datagrabber/aomic/piop1.py +22 -9
  14. junifer/datagrabber/aomic/piop2.py +22 -9
  15. junifer/datagrabber/base.py +6 -1
  16. junifer/datagrabber/datalad_base.py +15 -8
  17. junifer/datagrabber/dmcc13_benchmark.py +23 -10
  18. junifer/datagrabber/hcp1200/hcp1200.py +18 -7
  19. junifer/datagrabber/pattern.py +65 -35
  20. junifer/datagrabber/pattern_validation_mixin.py +197 -87
  21. junifer/datagrabber/tests/test_dmcc13_benchmark.py +26 -9
  22. junifer/pipeline/pipeline_step_mixin.py +8 -4
  23. junifer/pipeline/update_meta_mixin.py +21 -17
  24. junifer/preprocess/warping/_ants_warper.py +23 -2
  25. junifer/preprocess/warping/_fsl_warper.py +19 -3
  26. junifer/preprocess/warping/space_warper.py +31 -4
  27. {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/METADATA +1 -1
  28. {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/RECORD +33 -33
  29. {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/WHEEL +1 -1
  30. {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/AUTHORS.rst +0 -0
  31. {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/LICENSE.md +0 -0
  32. {junifer-0.0.6.dev227.dist-info → junifer-0.0.6.dev248.dist-info}/entry_points.txt +0 -0
  33. {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.dev227'
16
- __version_tuple__ = version_tuple = (0, 0, 6, 'dev227')
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
- extra_input: Dict[str, Any],
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
- extra_input : dict, optional
41
- The other fields in the data object. Useful for accessing other
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 {extra_input['Warp']['path'].resolve()};",
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 warp / transformation file extension is not ".mat" or ".h5".
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
- # Check for warp file type to use correct tool
333
- warp_file_ext = extra_input["Warp"]["path"].suffix
334
- if warp_file_ext == ".mat":
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
- extra_input=extra_input,
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
- elif warp_file_ext == ".h5":
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
- extra_input=extra_input,
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
- extra_input: Dict[str, Any],
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
- extra_input : dict, optional
41
- The other fields in the data object. Useful for accessing other
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 {extra_input['Warp']['path'].resolve()}",
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
- extra_input: Optional[Dict[str, Any]] = None,
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
- extra_input : dict, optional
59
- The other fields in the data object. Useful for accessing other
60
- data kinds that needs to be used in the computation of mask
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 == "T1w":
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 {extra_input['Warp']['path'].resolve()}",
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
- extra_input: Dict[str, Any],
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
- extra_input : dict, optional
48
- The other fields in the data object. Useful for accessing other
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 {extra_input['Warp']['path'].resolve()}",
78
+ f"-w {warp_data['path'].resolve()}",
81
79
  f"-o {warped_mask_path.resolve()}",
82
80
  ]
83
81
  # Call applywarp
@@ -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
- target_std_space = extra_input["Warp"]["src"]
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 if mask_type in ["gm", "wm"] else "T1w",
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 = extra_input["Warp"]["src"]
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
- extra_input=None,
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
- # Check for warp file type to use correct tool
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
- extra_input=extra_input,
525
+ warp_data=warper_spec,
522
526
  )
523
- elif warp_file_ext == ".h5":
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="T1w",
532
+ dst="native",
529
533
  target_data=target_data,
530
- extra_input=extra_input,
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
- extra_input: Optional[Dict[str, Any]] = None,
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
- extra_input : dict, optional
59
- The other fields in the data object. Useful for accessing other
60
- data kinds that needs to be used in the computation of parcellation
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 == "T1w":
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 {extra_input['Warp']['path'].resolve()}",
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
- extra_input: Dict[str, Any],
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
- extra_input : dict, optional
48
- The other fields in the data object. Useful for accessing other
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 {extra_input['Warp']['path'].resolve()}",
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 = extra_input["Warp"]["src"]
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
- extra_input=None,
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
- # Check for warp file type to use correct tool
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
- extra_input=extra_input,
486
+ warp_data=warper_spec,
483
487
  )
484
- elif warp_file_ext == ".h5":
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="T1w",
493
+ dst="native",
490
494
  target_data=target_data,
491
- extra_input=extra_input,
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.logging import logger
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]