junifer 0.0.6.dev175__py3-none-any.whl → 0.0.6.dev201__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 (78) hide show
  1. junifer/_version.py +2 -2
  2. junifer/data/__init__.pyi +17 -31
  3. junifer/data/_dispatch.py +251 -0
  4. junifer/data/coordinates/__init__.py +9 -0
  5. junifer/data/coordinates/__init__.pyi +5 -0
  6. junifer/data/coordinates/_ants_coordinates_warper.py +96 -0
  7. junifer/data/coordinates/_coordinates.py +356 -0
  8. junifer/data/coordinates/_fsl_coordinates_warper.py +83 -0
  9. junifer/data/{tests → coordinates/tests}/test_coordinates.py +25 -31
  10. junifer/data/masks/__init__.py +9 -0
  11. junifer/data/masks/__init__.pyi +6 -0
  12. junifer/data/masks/_ants_mask_warper.py +144 -0
  13. junifer/data/masks/_fsl_mask_warper.py +87 -0
  14. junifer/data/masks/_masks.py +624 -0
  15. junifer/data/{tests → masks/tests}/test_masks.py +63 -58
  16. junifer/data/parcellations/__init__.py +9 -0
  17. junifer/data/parcellations/__init__.pyi +6 -0
  18. junifer/data/parcellations/_ants_parcellation_warper.py +154 -0
  19. junifer/data/parcellations/_fsl_parcellation_warper.py +91 -0
  20. junifer/data/{parcellations.py → parcellations/_parcellations.py} +450 -473
  21. junifer/data/{tests → parcellations/tests}/test_parcellations.py +73 -81
  22. junifer/data/pipeline_data_registry_base.py +74 -0
  23. junifer/data/utils.py +4 -0
  24. junifer/markers/complexity/hurst_exponent.py +2 -2
  25. junifer/markers/complexity/multiscale_entropy_auc.py +2 -2
  26. junifer/markers/complexity/perm_entropy.py +2 -2
  27. junifer/markers/complexity/range_entropy.py +2 -2
  28. junifer/markers/complexity/range_entropy_auc.py +2 -2
  29. junifer/markers/complexity/sample_entropy.py +2 -2
  30. junifer/markers/complexity/weighted_perm_entropy.py +2 -2
  31. junifer/markers/ets_rss.py +2 -2
  32. junifer/markers/falff/falff_parcels.py +2 -2
  33. junifer/markers/falff/falff_spheres.py +2 -2
  34. junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +1 -1
  35. junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +1 -1
  36. junifer/markers/functional_connectivity/functional_connectivity_parcels.py +1 -1
  37. junifer/markers/functional_connectivity/functional_connectivity_spheres.py +1 -1
  38. junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +3 -3
  39. junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +2 -2
  40. junifer/markers/parcel_aggregation.py +11 -7
  41. junifer/markers/reho/reho_parcels.py +2 -2
  42. junifer/markers/reho/reho_spheres.py +2 -2
  43. junifer/markers/sphere_aggregation.py +11 -7
  44. junifer/markers/temporal_snr/temporal_snr_parcels.py +2 -2
  45. junifer/markers/temporal_snr/temporal_snr_spheres.py +2 -2
  46. junifer/markers/tests/test_ets_rss.py +3 -3
  47. junifer/markers/tests/test_parcel_aggregation.py +24 -24
  48. junifer/markers/tests/test_sphere_aggregation.py +6 -6
  49. junifer/pipeline/pipeline_component_registry.py +1 -1
  50. junifer/preprocess/confounds/fmriprep_confound_remover.py +6 -3
  51. {junifer-0.0.6.dev175.dist-info → junifer-0.0.6.dev201.dist-info}/METADATA +1 -1
  52. {junifer-0.0.6.dev175.dist-info → junifer-0.0.6.dev201.dist-info}/RECORD +76 -62
  53. {junifer-0.0.6.dev175.dist-info → junifer-0.0.6.dev201.dist-info}/WHEEL +1 -1
  54. junifer/data/coordinates.py +0 -408
  55. junifer/data/masks.py +0 -670
  56. /junifer/data/{VOIs → coordinates/VOIs}/meta/AutobiographicalMemory_VOIs.txt +0 -0
  57. /junifer/data/{VOIs → coordinates/VOIs}/meta/CogAC_VOIs.txt +0 -0
  58. /junifer/data/{VOIs → coordinates/VOIs}/meta/CogAR_VOIs.txt +0 -0
  59. /junifer/data/{VOIs → coordinates/VOIs}/meta/DMNBuckner_VOIs.txt +0 -0
  60. /junifer/data/{VOIs → coordinates/VOIs}/meta/Dosenbach2010_MNI_VOIs.txt +0 -0
  61. /junifer/data/{VOIs → coordinates/VOIs}/meta/Empathy_VOIs.txt +0 -0
  62. /junifer/data/{VOIs → coordinates/VOIs}/meta/Motor_VOIs.txt +0 -0
  63. /junifer/data/{VOIs → coordinates/VOIs}/meta/MultiTask_VOIs.txt +0 -0
  64. /junifer/data/{VOIs → coordinates/VOIs}/meta/PhysioStress_VOIs.txt +0 -0
  65. /junifer/data/{VOIs → coordinates/VOIs}/meta/Power2011_MNI_VOIs.txt +0 -0
  66. /junifer/data/{VOIs → coordinates/VOIs}/meta/Power2013_MNI_VOIs.tsv +0 -0
  67. /junifer/data/{VOIs → coordinates/VOIs}/meta/Rew_VOIs.txt +0 -0
  68. /junifer/data/{VOIs → coordinates/VOIs}/meta/Somatosensory_VOIs.txt +0 -0
  69. /junifer/data/{VOIs → coordinates/VOIs}/meta/ToM_VOIs.txt +0 -0
  70. /junifer/data/{VOIs → coordinates/VOIs}/meta/VigAtt_VOIs.txt +0 -0
  71. /junifer/data/{VOIs → coordinates/VOIs}/meta/WM_VOIs.txt +0 -0
  72. /junifer/data/{VOIs → coordinates/VOIs}/meta/eMDN_VOIs.txt +0 -0
  73. /junifer/data/{VOIs → coordinates/VOIs}/meta/eSAD_VOIs.txt +0 -0
  74. /junifer/data/{VOIs → coordinates/VOIs}/meta/extDMN_VOIs.txt +0 -0
  75. {junifer-0.0.6.dev175.dist-info → junifer-0.0.6.dev201.dist-info}/AUTHORS.rst +0 -0
  76. {junifer-0.0.6.dev175.dist-info → junifer-0.0.6.dev201.dist-info}/LICENSE.md +0 -0
  77. {junifer-0.0.6.dev175.dist-info → junifer-0.0.6.dev201.dist-info}/entry_points.txt +0 -0
  78. {junifer-0.0.6.dev175.dist-info → junifer-0.0.6.dev201.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.dev175'
16
- __version_tuple__ = version_tuple = (0, 0, 6, 'dev175')
15
+ __version__ = version = '0.0.6.dev201'
16
+ __version_tuple__ = version_tuple = (0, 0, 6, 'dev201')
junifer/data/__init__.pyi CHANGED
@@ -1,41 +1,27 @@
1
1
  __all__ = [
2
- "list_coordinates",
3
- "load_coordinates",
4
- "register_coordinates",
5
- "get_coordinates",
6
- "list_parcellations",
7
- "load_parcellation",
8
- "register_parcellation",
9
- "merge_parcellations",
10
- "get_parcellation",
11
- "list_masks",
12
- "load_mask",
13
- "register_mask",
14
- "get_mask",
2
+ "CoordinatesRegistry",
3
+ "ParcellationRegistry",
4
+ "MaskRegistry",
5
+ "get_data",
6
+ "list_data",
7
+ "load_data",
8
+ "register_data",
9
+ "deregister_data",
15
10
  "get_template",
16
11
  "get_xfm",
17
12
  "utils",
18
13
  ]
19
14
 
20
- from .coordinates import (
21
- list_coordinates,
22
- load_coordinates,
23
- register_coordinates,
24
- get_coordinates,
25
- )
26
- from .parcellations import (
27
- list_parcellations,
28
- load_parcellation,
29
- register_parcellation,
30
- merge_parcellations,
31
- get_parcellation,
32
- )
15
+ from .coordinates import CoordinatesRegistry
16
+ from .parcellations import ParcellationRegistry
17
+ from .masks import MaskRegistry
33
18
 
34
- from .masks import (
35
- list_masks,
36
- load_mask,
37
- register_mask,
38
- get_mask,
19
+ from ._dispatch import (
20
+ get_data,
21
+ list_data,
22
+ load_data,
23
+ register_data,
24
+ deregister_data,
39
25
  )
40
26
 
41
27
  from .template_spaces import get_template, get_xfm
@@ -0,0 +1,251 @@
1
+ """Provide dispatch functions for pipeline data registries."""
2
+
3
+ # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
+ # License: AGPL
5
+
6
+ from pathlib import Path
7
+ from typing import (
8
+ TYPE_CHECKING,
9
+ Any,
10
+ Callable,
11
+ Dict,
12
+ List,
13
+ Optional,
14
+ Tuple,
15
+ Union,
16
+ )
17
+
18
+ from numpy.typing import ArrayLike
19
+
20
+ from ..utils import raise_error
21
+ from .coordinates import CoordinatesRegistry
22
+ from .masks import MaskRegistry
23
+ from .parcellations import ParcellationRegistry
24
+
25
+
26
+ if TYPE_CHECKING:
27
+ from nibabel.nifti1 import Nifti1Image
28
+
29
+
30
+ __all__ = [
31
+ "get_data",
32
+ "list_data",
33
+ "load_data",
34
+ "register_data",
35
+ "deregister_data",
36
+ ]
37
+
38
+
39
+ def get_data(
40
+ kind: str,
41
+ names: Union[
42
+ str, # coordinates, parcellation, mask
43
+ List[str], # parcellation, mask
44
+ Dict, # mask
45
+ List[Dict], # mask
46
+ ],
47
+ target_data: Dict[str, Any],
48
+ extra_input: Optional[Dict[str, Any]] = None,
49
+ ) -> Union[
50
+ Tuple[ArrayLike, List[str]], # coordinates
51
+ Tuple["Nifti1Image", List[str]], # parcellation
52
+ "Nifti1Image", # mask
53
+ ]:
54
+ """Get tailored ``kind`` for ``target_data``.
55
+
56
+ Parameters
57
+ ----------
58
+ kind : {"coordinates", "parcellation", "mask"}
59
+ Kind of data to fetch and apply.
60
+ names : str or dict or list of str / dict
61
+ The registered name(s) of the data.
62
+ target_data : dict
63
+ The corresponding item of the data object to which the data
64
+ will be applied.
65
+ extra_input : dict, optional
66
+ The other fields in the data object. Useful for accessing other
67
+ data types that need to be used in the computation of data
68
+ (default None).
69
+
70
+ Returns
71
+ -------
72
+ tuple of numpy.ndarray, list of str; \
73
+ tuple of nibabel.nifti1.Nifti1Image, list of str; \
74
+ nibabel.nifti1.Nifti1Image
75
+
76
+ Raises
77
+ ------
78
+ ValueError
79
+ If ``kind`` is invalid value.
80
+
81
+ """
82
+
83
+ if kind == "coordinates":
84
+ return CoordinatesRegistry().get(
85
+ coords=names,
86
+ target_data=target_data,
87
+ extra_input=extra_input,
88
+ )
89
+ elif kind == "parcellation":
90
+ return ParcellationRegistry().get(
91
+ parcellations=names,
92
+ target_data=target_data,
93
+ extra_input=extra_input,
94
+ )
95
+ elif kind == "mask":
96
+ return MaskRegistry().get(
97
+ masks=names,
98
+ target_data=target_data,
99
+ extra_input=extra_input,
100
+ )
101
+ else:
102
+ raise_error(f"Unknown data kind: {kind}")
103
+
104
+
105
+ def list_data(kind: str) -> List[str]:
106
+ """List available data for ``kind``.
107
+
108
+ Parameters
109
+ ----------
110
+ kind : {"coordinates", "parcellation", "mask"}
111
+ Kind of data registry to list.
112
+
113
+ Returns
114
+ -------
115
+ list of str
116
+ Available data for the registry.
117
+
118
+ Raises
119
+ ------
120
+ ValueError
121
+ If ``kind`` is invalid value.
122
+
123
+ """
124
+
125
+ if kind == "coordinates":
126
+ return CoordinatesRegistry().list
127
+ elif kind == "parcellation":
128
+ return ParcellationRegistry().list
129
+ elif kind == "mask":
130
+ return MaskRegistry().list
131
+ else:
132
+ raise_error(f"Unknown data kind: {kind}")
133
+
134
+
135
+ def load_data(
136
+ kind: str,
137
+ name: str,
138
+ **kwargs,
139
+ ) -> Union[
140
+ Tuple[ArrayLike, List[str], str], # coordinates
141
+ Tuple[Optional["Nifti1Image"], List[str], Path, str], # parcellation
142
+ Tuple[
143
+ Optional[Union["Nifti1Image", Callable]], Optional[Path], str
144
+ ], # mask
145
+ ]:
146
+ """Load ``kind`` named ``name``.
147
+
148
+ Parameters
149
+ ----------
150
+ kind : {"coordinates", "parcellation", "mask"}
151
+ Kind of data to load.
152
+ name : str
153
+ The registered name of the data.
154
+ **kwargs
155
+ Keyword arguments are passed to respective registry class method.
156
+
157
+ Returns
158
+ -------
159
+ tuple of numpy.ndarray, list of str, str; \
160
+ tuple of nibabel.nifti1.Nifti1Image or None, \
161
+ list of str, pathlib.Path, str; \
162
+ tuple of nibabel.nifti1.Nifti1Image or callable or None, \
163
+ pathlib.Path or None, str
164
+
165
+ Raises
166
+ ------
167
+ ValueError
168
+ If ``kind`` is invalid value.
169
+
170
+ """
171
+
172
+ if kind == "coordinates":
173
+ return CoordinatesRegistry().load(name=name)
174
+ elif kind == "parcellation":
175
+ return ParcellationRegistry().load(name=name, **kwargs)
176
+ elif kind == "mask":
177
+ return MaskRegistry().load(name=name, **kwargs)
178
+ else:
179
+ raise_error(f"Unknown data kind: {kind}")
180
+
181
+
182
+ def register_data(
183
+ kind: str,
184
+ name: str,
185
+ space: str,
186
+ overwrite: bool = False,
187
+ **kwargs,
188
+ ) -> None:
189
+ """Register ``name`` under ``kind``.
190
+
191
+ Parameters
192
+ ----------
193
+ kind : {"coordinates", "parcellation", "mask"}
194
+ Kind of data to register.
195
+ name : str
196
+ The name to register.
197
+ space : str
198
+ The template space of the data.
199
+ overwrite : bool, optional
200
+ If True, overwrite an existing data with the same name.
201
+ **kwargs
202
+ Keyword arguments are passed to respective registry class method.
203
+
204
+ Raises
205
+ ------
206
+ ValueError
207
+ If ``kind`` is invalid value.
208
+
209
+ """
210
+
211
+ if kind == "coordinates":
212
+ return CoordinatesRegistry().register(
213
+ name=name, space=space, overwrite=overwrite, **kwargs
214
+ )
215
+ elif kind == "parcellation":
216
+ return ParcellationRegistry().register(
217
+ name=name, space=space, overwrite=overwrite, **kwargs
218
+ )
219
+ elif kind == "mask":
220
+ return MaskRegistry().load(
221
+ name=name, space=space, overwrite=overwrite, **kwargs
222
+ )
223
+ else:
224
+ raise_error(f"Unknown data kind: {kind}")
225
+
226
+
227
+ def deregister_data(kind: str, name: str) -> None:
228
+ """De-register ``name`` from ``kind``.
229
+
230
+ Parameters
231
+ ----------
232
+ kind : {"coordinates", "parcellation", "mask"}
233
+ Kind of data to register.
234
+ name : str
235
+ The name to de-register.
236
+
237
+ Raises
238
+ ------
239
+ ValueError
240
+ If ``kind`` is invalid value.
241
+
242
+ """
243
+
244
+ if kind == "coordinates":
245
+ return CoordinatesRegistry().deregister(name=name)
246
+ elif kind == "parcellation":
247
+ return ParcellationRegistry().register(name=name)
248
+ elif kind == "mask":
249
+ return MaskRegistry().load(name=name)
250
+ else:
251
+ raise_error(f"Unknown data kind: {kind}")
@@ -0,0 +1,9 @@
1
+ """Coordinates."""
2
+
3
+ # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
+ # License: AGPL
5
+
6
+ import lazy_loader as lazy
7
+
8
+
9
+ __getattr__, __dir__, __all__ = lazy.attach_stub(__name__, __file__)
@@ -0,0 +1,5 @@
1
+ __all__ = [
2
+ "CoordinatesRegistry",
3
+ ]
4
+
5
+ from ._coordinates import CoordinatesRegistry
@@ -0,0 +1,96 @@
1
+ """Provide class for coordinates space warping via ANTs."""
2
+
3
+ # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
+ # License: AGPL
5
+
6
+ from typing import Any, Dict
7
+
8
+ import numpy as np
9
+ from numpy.typing import ArrayLike
10
+
11
+ from ...pipeline import WorkDirManager
12
+ from ...utils import logger, run_ext_cmd
13
+
14
+
15
+ __all__ = ["ANTsCoordinatesWarper"]
16
+
17
+
18
+ class ANTsCoordinatesWarper:
19
+ """Class for coordinates space warping via ANTs.
20
+
21
+ This class uses ANTs ``antsApplyTransformsToPoints`` for transformation.
22
+
23
+ """
24
+
25
+ def warp(
26
+ self,
27
+ seeds: ArrayLike,
28
+ target_data: Dict[str, Any],
29
+ extra_input: Dict[str, Any],
30
+ ) -> ArrayLike:
31
+ """Warp ``seeds`` to correct space.
32
+
33
+ Parameters
34
+ ----------
35
+ seeds : array-like
36
+ The coordinates to transform.
37
+ target_data : dict
38
+ The corresponding item of the data object to which the coordinates
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).
44
+
45
+ Returns
46
+ -------
47
+ numpy.ndarray
48
+ The transformed coordinates.
49
+
50
+ """
51
+ logger.debug("Using ANTs for coordinates transformation")
52
+
53
+ # Create element-specific tempdir for storing post-warping assets
54
+ element_tempdir = WorkDirManager().get_element_tempdir(
55
+ prefix="ants_coordinates_warper"
56
+ )
57
+
58
+ # Save existing coordinates to a tempfile
59
+ pretransform_coordinates_path = (
60
+ element_tempdir / "pretransform_coordinates.txt"
61
+ )
62
+ np.savetxt(
63
+ pretransform_coordinates_path,
64
+ seeds,
65
+ delimiter=",",
66
+ # Add header while saving to make ANTs work
67
+ header="x,y,z",
68
+ )
69
+
70
+ # Create a tempfile for transformed coordinates output
71
+ transformed_coords_path = (
72
+ element_tempdir / "coordinates_transformed.txt"
73
+ )
74
+ # Set antsApplyTransformsToPoints command
75
+ apply_transforms_to_points_cmd = [
76
+ "antsApplyTransformsToPoints",
77
+ "-d 3",
78
+ "-p 1",
79
+ "-f 0",
80
+ f"-i {pretransform_coordinates_path.resolve()}",
81
+ f"-o {transformed_coords_path.resolve()}",
82
+ f"-t {extra_input['Warp']['path'].resolve()};",
83
+ ]
84
+ # Call antsApplyTransformsToPoints
85
+ run_ext_cmd(
86
+ name="antsApplyTransformsToPoints",
87
+ cmd=apply_transforms_to_points_cmd,
88
+ )
89
+
90
+ # Load coordinates
91
+ return np.loadtxt(
92
+ # Skip header when reading
93
+ transformed_coords_path,
94
+ delimiter=",",
95
+ skiprows=1,
96
+ )