junifer 0.0.4.dev831__py3-none-any.whl → 0.0.5__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 (206) hide show
  1. junifer/__init__.py +17 -0
  2. junifer/_version.py +2 -2
  3. junifer/api/__init__.py +4 -1
  4. junifer/api/cli.py +91 -1
  5. junifer/api/decorators.py +9 -0
  6. junifer/api/functions.py +56 -10
  7. junifer/api/parser.py +3 -0
  8. junifer/api/queue_context/__init__.py +4 -1
  9. junifer/api/queue_context/gnu_parallel_local_adapter.py +16 -6
  10. junifer/api/queue_context/htcondor_adapter.py +16 -5
  11. junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +41 -12
  12. junifer/api/queue_context/tests/test_htcondor_adapter.py +48 -15
  13. junifer/api/res/afni/run_afni_docker.sh +1 -1
  14. junifer/api/res/ants/run_ants_docker.sh +1 -1
  15. junifer/api/res/freesurfer/mri_binarize +3 -0
  16. junifer/api/res/freesurfer/mri_mc +3 -0
  17. junifer/api/res/freesurfer/mri_pretess +3 -0
  18. junifer/api/res/freesurfer/mris_convert +3 -0
  19. junifer/api/res/freesurfer/run_freesurfer_docker.sh +61 -0
  20. junifer/api/res/fsl/run_fsl_docker.sh +1 -1
  21. junifer/api/res/{run_conda.sh → run_conda.bash} +1 -1
  22. junifer/api/res/run_conda.zsh +23 -0
  23. junifer/api/res/run_venv.bash +22 -0
  24. junifer/api/res/{run_venv.sh → run_venv.zsh} +1 -1
  25. junifer/api/tests/test_api_utils.py +4 -2
  26. junifer/api/tests/test_cli.py +83 -0
  27. junifer/api/tests/test_functions.py +27 -2
  28. junifer/configs/__init__.py +1 -1
  29. junifer/configs/juseless/__init__.py +4 -1
  30. junifer/configs/juseless/datagrabbers/__init__.py +10 -1
  31. junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +4 -3
  32. junifer/configs/juseless/datagrabbers/camcan_vbm.py +3 -0
  33. junifer/configs/juseless/datagrabbers/ixi_vbm.py +4 -3
  34. junifer/configs/juseless/datagrabbers/tests/test_ucla.py +1 -3
  35. junifer/configs/juseless/datagrabbers/ucla.py +12 -9
  36. junifer/configs/juseless/datagrabbers/ukb_vbm.py +3 -0
  37. junifer/data/__init__.py +21 -1
  38. junifer/data/coordinates.py +10 -19
  39. junifer/data/masks/ukb/UKB_15K_GM_template.nii.gz +0 -0
  40. junifer/data/masks.py +58 -87
  41. junifer/data/parcellations.py +14 -3
  42. junifer/data/template_spaces.py +4 -1
  43. junifer/data/tests/test_masks.py +26 -37
  44. junifer/data/utils.py +3 -0
  45. junifer/datagrabber/__init__.py +18 -1
  46. junifer/datagrabber/aomic/__init__.py +3 -0
  47. junifer/datagrabber/aomic/id1000.py +70 -37
  48. junifer/datagrabber/aomic/piop1.py +69 -36
  49. junifer/datagrabber/aomic/piop2.py +71 -38
  50. junifer/datagrabber/aomic/tests/test_id1000.py +44 -100
  51. junifer/datagrabber/aomic/tests/test_piop1.py +65 -108
  52. junifer/datagrabber/aomic/tests/test_piop2.py +45 -102
  53. junifer/datagrabber/base.py +13 -6
  54. junifer/datagrabber/datalad_base.py +13 -1
  55. junifer/datagrabber/dmcc13_benchmark.py +36 -53
  56. junifer/datagrabber/hcp1200/__init__.py +3 -0
  57. junifer/datagrabber/hcp1200/datalad_hcp1200.py +3 -0
  58. junifer/datagrabber/hcp1200/hcp1200.py +4 -1
  59. junifer/datagrabber/multiple.py +45 -6
  60. junifer/datagrabber/pattern.py +170 -62
  61. junifer/datagrabber/pattern_datalad.py +25 -12
  62. junifer/datagrabber/pattern_validation_mixin.py +388 -0
  63. junifer/datagrabber/tests/test_datalad_base.py +4 -4
  64. junifer/datagrabber/tests/test_dmcc13_benchmark.py +46 -19
  65. junifer/datagrabber/tests/test_multiple.py +161 -84
  66. junifer/datagrabber/tests/test_pattern.py +45 -0
  67. junifer/datagrabber/tests/test_pattern_datalad.py +4 -4
  68. junifer/datagrabber/tests/test_pattern_validation_mixin.py +249 -0
  69. junifer/datareader/__init__.py +4 -1
  70. junifer/datareader/default.py +95 -43
  71. junifer/external/BrainPrint/brainprint/__init__.py +4 -0
  72. junifer/external/BrainPrint/brainprint/_version.py +3 -0
  73. junifer/external/BrainPrint/brainprint/asymmetry.py +91 -0
  74. junifer/external/BrainPrint/brainprint/brainprint.py +441 -0
  75. junifer/external/BrainPrint/brainprint/surfaces.py +258 -0
  76. junifer/external/BrainPrint/brainprint/utils/__init__.py +1 -0
  77. junifer/external/BrainPrint/brainprint/utils/_config.py +112 -0
  78. junifer/external/BrainPrint/brainprint/utils/utils.py +188 -0
  79. junifer/external/__init__.py +1 -1
  80. junifer/external/nilearn/__init__.py +5 -1
  81. junifer/external/nilearn/junifer_connectivity_measure.py +483 -0
  82. junifer/external/nilearn/junifer_nifti_spheres_masker.py +23 -9
  83. junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +1089 -0
  84. junifer/external/nilearn/tests/test_junifer_nifti_spheres_masker.py +76 -1
  85. junifer/markers/__init__.py +23 -1
  86. junifer/markers/base.py +68 -28
  87. junifer/markers/brainprint.py +459 -0
  88. junifer/markers/collection.py +10 -2
  89. junifer/markers/complexity/__init__.py +10 -0
  90. junifer/markers/complexity/complexity_base.py +26 -43
  91. junifer/markers/complexity/hurst_exponent.py +3 -0
  92. junifer/markers/complexity/multiscale_entropy_auc.py +3 -0
  93. junifer/markers/complexity/perm_entropy.py +3 -0
  94. junifer/markers/complexity/range_entropy.py +3 -0
  95. junifer/markers/complexity/range_entropy_auc.py +3 -0
  96. junifer/markers/complexity/sample_entropy.py +3 -0
  97. junifer/markers/complexity/tests/test_hurst_exponent.py +11 -3
  98. junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +11 -3
  99. junifer/markers/complexity/tests/test_perm_entropy.py +11 -3
  100. junifer/markers/complexity/tests/test_range_entropy.py +11 -3
  101. junifer/markers/complexity/tests/test_range_entropy_auc.py +11 -3
  102. junifer/markers/complexity/tests/test_sample_entropy.py +11 -3
  103. junifer/markers/complexity/tests/test_weighted_perm_entropy.py +11 -3
  104. junifer/markers/complexity/weighted_perm_entropy.py +3 -0
  105. junifer/markers/ets_rss.py +27 -42
  106. junifer/markers/falff/__init__.py +3 -0
  107. junifer/markers/falff/_afni_falff.py +5 -2
  108. junifer/markers/falff/_junifer_falff.py +3 -0
  109. junifer/markers/falff/falff_base.py +20 -46
  110. junifer/markers/falff/falff_parcels.py +56 -27
  111. junifer/markers/falff/falff_spheres.py +60 -29
  112. junifer/markers/falff/tests/test_falff_parcels.py +39 -23
  113. junifer/markers/falff/tests/test_falff_spheres.py +39 -23
  114. junifer/markers/functional_connectivity/__init__.py +9 -0
  115. junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +63 -60
  116. junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +45 -32
  117. junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +49 -36
  118. junifer/markers/functional_connectivity/functional_connectivity_base.py +71 -70
  119. junifer/markers/functional_connectivity/functional_connectivity_parcels.py +34 -25
  120. junifer/markers/functional_connectivity/functional_connectivity_spheres.py +40 -30
  121. junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +11 -7
  122. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +27 -7
  123. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +28 -12
  124. junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +35 -11
  125. junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +36 -62
  126. junifer/markers/parcel_aggregation.py +47 -61
  127. junifer/markers/reho/__init__.py +3 -0
  128. junifer/markers/reho/_afni_reho.py +5 -2
  129. junifer/markers/reho/_junifer_reho.py +4 -1
  130. junifer/markers/reho/reho_base.py +8 -27
  131. junifer/markers/reho/reho_parcels.py +28 -17
  132. junifer/markers/reho/reho_spheres.py +27 -18
  133. junifer/markers/reho/tests/test_reho_parcels.py +8 -3
  134. junifer/markers/reho/tests/test_reho_spheres.py +8 -3
  135. junifer/markers/sphere_aggregation.py +43 -59
  136. junifer/markers/temporal_snr/__init__.py +3 -0
  137. junifer/markers/temporal_snr/temporal_snr_base.py +23 -32
  138. junifer/markers/temporal_snr/temporal_snr_parcels.py +9 -6
  139. junifer/markers/temporal_snr/temporal_snr_spheres.py +9 -6
  140. junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +6 -3
  141. junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +6 -3
  142. junifer/markers/tests/test_brainprint.py +58 -0
  143. junifer/markers/tests/test_collection.py +9 -8
  144. junifer/markers/tests/test_ets_rss.py +15 -9
  145. junifer/markers/tests/test_markers_base.py +17 -18
  146. junifer/markers/tests/test_parcel_aggregation.py +93 -32
  147. junifer/markers/tests/test_sphere_aggregation.py +72 -19
  148. junifer/onthefly/__init__.py +4 -1
  149. junifer/onthefly/read_transform.py +3 -0
  150. junifer/pipeline/__init__.py +9 -1
  151. junifer/pipeline/pipeline_step_mixin.py +21 -4
  152. junifer/pipeline/registry.py +3 -0
  153. junifer/pipeline/singleton.py +3 -0
  154. junifer/pipeline/tests/test_registry.py +1 -1
  155. junifer/pipeline/update_meta_mixin.py +3 -0
  156. junifer/pipeline/utils.py +67 -1
  157. junifer/pipeline/workdir_manager.py +3 -0
  158. junifer/preprocess/__init__.py +10 -2
  159. junifer/preprocess/base.py +6 -3
  160. junifer/preprocess/confounds/__init__.py +3 -0
  161. junifer/preprocess/confounds/fmriprep_confound_remover.py +47 -60
  162. junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +72 -113
  163. junifer/preprocess/smoothing/__init__.py +9 -0
  164. junifer/preprocess/smoothing/_afni_smoothing.py +119 -0
  165. junifer/preprocess/smoothing/_fsl_smoothing.py +116 -0
  166. junifer/preprocess/smoothing/_nilearn_smoothing.py +69 -0
  167. junifer/preprocess/smoothing/smoothing.py +174 -0
  168. junifer/preprocess/smoothing/tests/test_smoothing.py +94 -0
  169. junifer/preprocess/warping/__init__.py +3 -0
  170. junifer/preprocess/warping/_ants_warper.py +3 -0
  171. junifer/preprocess/warping/_fsl_warper.py +3 -0
  172. junifer/stats.py +4 -1
  173. junifer/storage/__init__.py +9 -1
  174. junifer/storage/base.py +40 -1
  175. junifer/storage/hdf5.py +71 -9
  176. junifer/storage/pandas_base.py +3 -0
  177. junifer/storage/sqlite.py +3 -0
  178. junifer/storage/tests/test_hdf5.py +82 -10
  179. junifer/storage/utils.py +9 -0
  180. junifer/testing/__init__.py +4 -1
  181. junifer/testing/datagrabbers.py +13 -6
  182. junifer/testing/tests/test_partlycloudytesting_datagrabber.py +7 -7
  183. junifer/testing/utils.py +3 -0
  184. junifer/utils/__init__.py +13 -2
  185. junifer/utils/fs.py +3 -0
  186. junifer/utils/helpers.py +32 -1
  187. junifer/utils/logging.py +33 -4
  188. junifer/utils/tests/test_logging.py +8 -0
  189. {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/METADATA +17 -16
  190. junifer-0.0.5.dist-info/RECORD +275 -0
  191. {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/WHEEL +1 -1
  192. junifer/datagrabber/tests/test_datagrabber_utils.py +0 -218
  193. junifer/datagrabber/utils.py +0 -230
  194. junifer/preprocess/ants/__init__.py +0 -4
  195. junifer/preprocess/ants/ants_apply_transforms_warper.py +0 -185
  196. junifer/preprocess/ants/tests/test_ants_apply_transforms_warper.py +0 -56
  197. junifer/preprocess/bold_warper.py +0 -265
  198. junifer/preprocess/fsl/__init__.py +0 -4
  199. junifer/preprocess/fsl/apply_warper.py +0 -179
  200. junifer/preprocess/fsl/tests/test_apply_warper.py +0 -45
  201. junifer/preprocess/tests/test_bold_warper.py +0 -159
  202. junifer-0.0.4.dev831.dist-info/RECORD +0 -257
  203. {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/AUTHORS.rst +0 -0
  204. {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/LICENSE.md +0 -0
  205. {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/entry_points.txt +0 -0
  206. {junifer-0.0.4.dev831.dist-info → junifer-0.0.5.dist-info}/top_level.txt +0 -0
@@ -17,6 +17,9 @@ from ..utils import logger, raise_error, warn_with_log
17
17
  from .base import BaseMarker
18
18
 
19
19
 
20
+ __all__ = ["ParcelAggregation"]
21
+
22
+
20
23
  @register_marker
21
24
  class ParcelAggregation(BaseMarker):
22
25
  """Class for parcel aggregation.
@@ -60,6 +63,36 @@ class ParcelAggregation(BaseMarker):
60
63
 
61
64
  _DEPENDENCIES: ClassVar[Set[str]] = {"nilearn", "numpy"}
62
65
 
66
+ _MARKER_INOUT_MAPPINGS: ClassVar[Dict[str, Dict[str, str]]] = {
67
+ "T1w": {
68
+ "aggregation": "vector",
69
+ },
70
+ "T2w": {
71
+ "aggregation": "vector",
72
+ },
73
+ "BOLD": {
74
+ "aggregation": "timeseries",
75
+ },
76
+ "VBM_GM": {
77
+ "aggregation": "vector",
78
+ },
79
+ "VBM_WM": {
80
+ "aggregation": "vector",
81
+ },
82
+ "VBM_CSF": {
83
+ "aggregation": "vector",
84
+ },
85
+ "fALFF": {
86
+ "aggregation": "vector",
87
+ },
88
+ "GCOR": {
89
+ "aggregation": "vector",
90
+ },
91
+ "LCOR": {
92
+ "aggregation": "vector",
93
+ },
94
+ }
95
+
63
96
  def __init__(
64
97
  self,
65
98
  parcellation: Union[str, List[str]],
@@ -93,61 +126,6 @@ class ParcelAggregation(BaseMarker):
93
126
  self.time_method = time_method
94
127
  self.time_method_params = time_method_params or {}
95
128
 
96
- def get_valid_inputs(self) -> List[str]:
97
- """Get valid data types for input.
98
-
99
- Returns
100
- -------
101
- list of str
102
- The list of data types that can be used as input for this marker.
103
-
104
- """
105
- return [
106
- "T1w",
107
- "T2w",
108
- "BOLD",
109
- "VBM_GM",
110
- "VBM_WM",
111
- "VBM_CSF",
112
- "fALFF",
113
- "GCOR",
114
- "LCOR",
115
- ]
116
-
117
- def get_output_type(self, input_type: str) -> str:
118
- """Get output type.
119
-
120
- Parameters
121
- ----------
122
- input_type : str
123
- The data type input to the marker.
124
-
125
- Returns
126
- -------
127
- str
128
- The storage type output by the marker.
129
-
130
- Raises
131
- ------
132
- ValueError
133
- If the ``input_type`` is invalid.
134
-
135
- """
136
-
137
- if input_type in [
138
- "VBM_GM",
139
- "VBM_WM",
140
- "VBM_CSF",
141
- "fALFF",
142
- "GCOR",
143
- "LCOR",
144
- ]:
145
- return "vector"
146
- elif input_type == "BOLD":
147
- return "timeseries"
148
- else:
149
- raise_error(f"Unknown input kind for {input_type}")
150
-
151
129
  def compute(
152
130
  self, input: Dict[str, Any], extra_input: Optional[Dict] = None
153
131
  ) -> Dict:
@@ -171,8 +149,10 @@ class ParcelAggregation(BaseMarker):
171
149
  to the user or stored in the storage by calling the store method
172
150
  with this as a parameter. The dictionary has the following keys:
173
151
 
174
- * ``data`` : the actual computed values as a numpy.ndarray
175
- * ``col_names`` : the column labels for the computed values as list
152
+ * ``aggregation`` : dictionary with the following keys:
153
+
154
+ - ``data`` : ROI values as ``numpy.ndarray``
155
+ - ``col_names`` : ROI labels as list of str
176
156
 
177
157
  Warns
178
158
  -----
@@ -195,7 +175,9 @@ class ParcelAggregation(BaseMarker):
195
175
  )
196
176
 
197
177
  # Get binarized parcellation image for masking
198
- parcellation_bin = math_img("img != 0", img=parcellation_img)
178
+ parcellation_bin = math_img(
179
+ "np.squeeze(img) != 0", img=parcellation_img
180
+ )
199
181
 
200
182
  # Load mask
201
183
  if self.masks is not None:
@@ -206,7 +188,7 @@ class ParcelAggregation(BaseMarker):
206
188
  )
207
189
  # Get "logical and" version of parcellation and mask
208
190
  parcellation_bin = math_img(
209
- "np.logical_and(img, mask)",
191
+ "np.logical_and(img, np.squeeze(mask))",
210
192
  img=parcellation_bin,
211
193
  mask=mask_img,
212
194
  )
@@ -248,5 +230,9 @@ class ParcelAggregation(BaseMarker):
248
230
  "available."
249
231
  )
250
232
  # Format the output
251
- out = {"data": out_values, "col_names": labels}
252
- return out
233
+ return {
234
+ "aggregation": {
235
+ "data": out_values,
236
+ "col_names": labels,
237
+ },
238
+ }
@@ -5,3 +5,6 @@
5
5
 
6
6
  from .reho_parcels import ReHoParcels
7
7
  from .reho_spheres import ReHoSpheres
8
+
9
+
10
+ __all__ = ["ReHoParcels", "ReHoSpheres"]
@@ -26,6 +26,9 @@ if TYPE_CHECKING:
26
26
  from nibabel import Nifti1Image
27
27
 
28
28
 
29
+ __all__ = ["AFNIReHo"]
30
+
31
+
29
32
  @singleton
30
33
  class AFNIReHo:
31
34
  """Class for computing ReHo using AFNI.
@@ -72,7 +75,7 @@ class AFNIReHo:
72
75
  Number of voxels in the neighbourhood, inclusive. Can be:
73
76
 
74
77
  * 7 : for facewise neighbours only
75
- * 19 : for face- and edge-wise nieghbours
78
+ * 19 : for face- and edge-wise neighbours
76
79
  * 27 : for face-, edge-, and node-wise neighbors
77
80
 
78
81
  (default 27).
@@ -178,7 +181,7 @@ class AFNIReHo:
178
181
  convert_cmd = [
179
182
  "3dAFNItoNIFTI",
180
183
  f"-prefix {reho_afni_to_nifti_out_path.resolve()}",
181
- f"{reho_out_path_prefix}+tlrc.BRIK",
184
+ f"{reho_out_path_prefix}+orig.BRIK",
182
185
  ]
183
186
  # Call 3dAFNItoNIFTI
184
187
  run_ext_cmd(name="3dAFNItoNIFTI", cmd=convert_cmd)
@@ -28,6 +28,9 @@ if TYPE_CHECKING:
28
28
  from nibabel import Nifti1Image
29
29
 
30
30
 
31
+ __all__ = ["JuniferReHo"]
32
+
33
+
31
34
  @singleton
32
35
  class JuniferReHo:
33
36
  """Class for computing ReHo using junifer.
@@ -60,7 +63,7 @@ class JuniferReHo:
60
63
  Number of voxels in the neighbourhood, inclusive. Can be:
61
64
 
62
65
  * 7 : for facewise neighbours only
63
- * 19 : for face- and edge-wise nieghbours
66
+ * 19 : for face- and edge-wise neighbours
64
67
  * 27 : for face-, edge-, and node-wise neighbors
65
68
  * 125 : for 5x5 cuboidal volume
66
69
 
@@ -26,6 +26,8 @@ from ._junifer_reho import JuniferReHo
26
26
  if TYPE_CHECKING:
27
27
  from nibabel import Nifti1Image
28
28
 
29
+ __all__ = ["ReHoBase"]
30
+
29
31
 
30
32
  class ReHoBase(BaseMarker):
31
33
  """Base class for regional homogeneity computation.
@@ -60,6 +62,12 @@ class ReHoBase(BaseMarker):
60
62
  },
61
63
  ]
62
64
 
65
+ _MARKER_INOUT_MAPPINGS: ClassVar[Dict[str, Dict[str, str]]] = {
66
+ "BOLD": {
67
+ "reho": "vector",
68
+ },
69
+ }
70
+
63
71
  def __init__(
64
72
  self,
65
73
  using: str,
@@ -74,33 +82,6 @@ class ReHoBase(BaseMarker):
74
82
  self.using = using
75
83
  super().__init__(on="BOLD", name=name)
76
84
 
77
- def get_valid_inputs(self) -> List[str]:
78
- """Get valid data types for input.
79
-
80
- Returns
81
- -------
82
- list of str
83
- The list of data types that can be used as input for this marker.
84
-
85
- """
86
- return ["BOLD"]
87
-
88
- def get_output_type(self, input_type: str) -> str:
89
- """Get output type.
90
-
91
- Parameters
92
- ----------
93
- input_type : str
94
- The data type input to the marker.
95
-
96
- Returns
97
- -------
98
- str
99
- The storage type output by the marker.
100
-
101
- """
102
- return "vector"
103
-
104
85
  def _compute(
105
86
  self,
106
87
  input_data: Dict[str, Any],
@@ -14,6 +14,9 @@ from ..parcel_aggregation import ParcelAggregation
14
14
  from .reho_base import ReHoBase
15
15
 
16
16
 
17
+ __all__ = ["ReHoParcels"]
18
+
19
+
17
20
  @register_marker
18
21
  class ReHoParcels(ReHoBase):
19
22
  """Class for regional homogeneity on parcels.
@@ -37,7 +40,7 @@ class ReHoParcels(ReHoBase):
37
40
  Number of voxels in the neighbourhood, inclusive. Can be:
38
41
 
39
42
  - 7 : for facewise neighbours only
40
- - 19 : for face- and edge-wise nieghbours
43
+ - 19 : for face- and edge-wise neighbours
41
44
  - 27 : for face-, edge-, and node-wise neighbors
42
45
 
43
46
  * ``neigh_rad`` : positive float, optional
@@ -67,7 +70,7 @@ class ReHoParcels(ReHoBase):
67
70
  Number of voxels in the neighbourhood, inclusive. Can be:
68
71
 
69
72
  * 7 : for facewise neighbours only
70
- * 19 : for face- and edge-wise nieghbours
73
+ * 19 : for face- and edge-wise neighbours
71
74
  * 27 : for face-, edge-, and node-wise neighbors
72
75
  * 125 : for 5x5 cuboidal volume
73
76
 
@@ -122,11 +125,14 @@ class ReHoParcels(ReHoBase):
122
125
  Returns
123
126
  -------
124
127
  dict
125
- The computed result as dictionary. The dictionary has the following
126
- keys:
128
+ The computed result as dictionary. This will be either returned
129
+ to the user or stored in the storage by calling the store method
130
+ with this as a parameter. The dictionary has the following keys:
127
131
 
128
- * ``data`` : the actual computed values as a 1D numpy.ndarray
129
- * ``col_names`` : the column labels for the parcels as a list
132
+ * ``reho`` : dictionary with the following keys:
133
+
134
+ - ``data`` : ROI values as ``numpy.ndarray``
135
+ - ``col_names`` : ROI labels as list of str
130
136
 
131
137
  """
132
138
  logger.info("Calculating ReHo for parcels")
@@ -142,22 +148,27 @@ class ReHoParcels(ReHoBase):
142
148
  else:
143
149
  reho_map, reho_file_path = self._compute(input_data=input)
144
150
 
145
- # Initialize parcel aggregation
151
+ # Perform aggregation on reho map
152
+ aggregation_input = dict(input.items())
153
+ aggregation_input["data"] = reho_map
154
+ aggregation_input["path"] = reho_file_path
146
155
  parcel_aggregation = ParcelAggregation(
147
156
  parcellation=self.parcellation,
148
157
  method=self.agg_method,
149
158
  method_params=self.agg_method_params,
150
159
  masks=self.masks,
151
160
  on="BOLD",
152
- )
153
- # Perform aggregation on reho map
154
- parcel_aggregation_input = dict(input.items())
155
- parcel_aggregation_input["data"] = reho_map
156
- parcel_aggregation_input["path"] = reho_file_path
157
- output = parcel_aggregation.compute(
158
- input=parcel_aggregation_input,
161
+ ).compute(
162
+ input=aggregation_input,
159
163
  extra_input=extra_input,
160
164
  )
161
- # Only use the first row and expand row dimension
162
- output["data"] = output["data"][0][np.newaxis, :]
163
- return output
165
+
166
+ return {
167
+ "reho": {
168
+ # Only use the first row and expand row dimension
169
+ "data": parcel_aggregation["aggregation"]["data"][0][
170
+ np.newaxis, :
171
+ ],
172
+ "col_names": parcel_aggregation["aggregation"]["col_names"],
173
+ }
174
+ }
@@ -14,6 +14,9 @@ from ..sphere_aggregation import SphereAggregation
14
14
  from .reho_base import ReHoBase
15
15
 
16
16
 
17
+ __all__ = ["ReHoSpheres"]
18
+
19
+
17
20
  @register_marker
18
21
  class ReHoSpheres(ReHoBase):
19
22
  """Class for regional homogeneity on spheres.
@@ -48,7 +51,7 @@ class ReHoSpheres(ReHoBase):
48
51
  Number of voxels in the neighbourhood, inclusive. Can be:
49
52
 
50
53
  - 7 : for facewise neighbours only
51
- - 19 : for face- and edge-wise nieghbours
54
+ - 19 : for face- and edge-wise neighbours
52
55
  - 27 : for face-, edge-, and node-wise neighbors
53
56
 
54
57
  * ``neigh_rad`` : positive float, optional
@@ -78,7 +81,7 @@ class ReHoSpheres(ReHoBase):
78
81
  Number of voxels in the neighbourhood, inclusive. Can be:
79
82
 
80
83
  * 7 : for facewise neighbours only
81
- * 19 : for face- and edge-wise nieghbours
84
+ * 19 : for face- and edge-wise neighbours
82
85
  * 27 : for face-, edge-, and node-wise neighbors
83
86
  * 125 : for 5x5 cuboidal volume
84
87
 
@@ -137,11 +140,14 @@ class ReHoSpheres(ReHoBase):
137
140
  Returns
138
141
  -------
139
142
  dict
140
- The computed result as dictionary. The dictionary has the following
141
- keys:
143
+ The computed result as dictionary. This will be either returned
144
+ to the user or stored in the storage by calling the store method
145
+ with this as a parameter. The dictionary has the following keys:
146
+
147
+ * ``reho`` : dictionary with the following keys:
142
148
 
143
- * ``data`` : the actual computed values as a 1D numpy.ndarray
144
- * ``col_names`` : the column labels for the spheres as a list
149
+ - ``data`` : ROI values as ``numpy.ndarray``
150
+ - ``col_names`` : ROI labels as list of str
145
151
 
146
152
  """
147
153
  logger.info("Calculating ReHo for spheres")
@@ -157,7 +163,10 @@ class ReHoSpheres(ReHoBase):
157
163
  else:
158
164
  reho_map, reho_file_path = self._compute(input_data=input)
159
165
 
160
- # Initialize sphere aggregation
166
+ # Perform aggregation on reho map
167
+ aggregation_input = dict(input.items())
168
+ aggregation_input["data"] = reho_map
169
+ aggregation_input["path"] = reho_file_path
161
170
  sphere_aggregation = SphereAggregation(
162
171
  coords=self.coords,
163
172
  radius=self.radius,
@@ -166,14 +175,14 @@ class ReHoSpheres(ReHoBase):
166
175
  method_params=self.agg_method_params,
167
176
  masks=self.masks,
168
177
  on="BOLD",
169
- )
170
- # Perform aggregation on reho map
171
- sphere_aggregation_input = dict(input.items())
172
- sphere_aggregation_input["data"] = reho_map
173
- sphere_aggregation_input["path"] = reho_file_path
174
- output = sphere_aggregation.compute(
175
- input=sphere_aggregation_input, extra_input=extra_input
176
- )
177
- # Only use the first row and expand row dimension
178
- output["data"] = output["data"][0][np.newaxis, :]
179
- return output
178
+ ).compute(input=aggregation_input, extra_input=extra_input)
179
+
180
+ return {
181
+ "reho": {
182
+ # Only use the first row and expand row dimension
183
+ "data": sphere_aggregation["aggregation"]["data"][0][
184
+ np.newaxis, :
185
+ ],
186
+ "col_names": sphere_aggregation["aggregation"]["col_names"],
187
+ }
188
+ }
@@ -42,6 +42,11 @@ def test_ReHoParcels(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
42
42
  parcellation="TianxS1x3TxMNInonlinear2009cAsym",
43
43
  using="junifer",
44
44
  )
45
+ # Check correct output
46
+ assert "vector" == marker.get_output_type(
47
+ input_type="BOLD", output_feature="reho"
48
+ )
49
+
45
50
  # Fit transform marker on data
46
51
  output = marker.fit_transform(element_data)
47
52
 
@@ -49,7 +54,7 @@ def test_ReHoParcels(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
49
54
 
50
55
  # Get BOLD output
51
56
  assert "BOLD" in output
52
- output_bold = output["BOLD"]
57
+ output_bold = output["BOLD"]["reho"]
53
58
  # Assert BOLD output keys
54
59
  assert "data" in output_bold
55
60
  assert "col_names" in output_bold
@@ -102,14 +107,14 @@ def test_ReHoParcels_comparison(tmp_path: Path) -> None:
102
107
  # Fit transform marker on data
103
108
  junifer_output = junifer_marker.fit_transform(element_data)
104
109
  # Get BOLD output
105
- junifer_output_bold = junifer_output["BOLD"]
110
+ junifer_output_bold = junifer_output["BOLD"]["reho"]
106
111
 
107
112
  # Initialize marker
108
113
  afni_marker = ReHoParcels(parcellation="Schaefer100x7", using="afni")
109
114
  # Fit transform marker on data
110
115
  afni_output = afni_marker.fit_transform(element_data)
111
116
  # Get BOLD output
112
- afni_output_bold = afni_output["BOLD"]
117
+ afni_output_bold = afni_output["BOLD"]["reho"]
113
118
 
114
119
  # Check for Pearson correlation coefficient
115
120
  r, _ = sp.stats.pearsonr(
@@ -40,6 +40,11 @@ def test_ReHoSpheres(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
40
40
  marker = ReHoSpheres(
41
41
  coords=COORDINATES, using="junifer", radius=10.0
42
42
  )
43
+ # Check correct output
44
+ assert "vector" == marker.get_output_type(
45
+ input_type="BOLD", output_feature="reho"
46
+ )
47
+
43
48
  # Fit transform marker on data
44
49
  output = marker.fit_transform(element_data)
45
50
 
@@ -47,7 +52,7 @@ def test_ReHoSpheres(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
47
52
 
48
53
  # Get BOLD output
49
54
  assert "BOLD" in output
50
- output_bold = output["BOLD"]
55
+ output_bold = output["BOLD"]["reho"]
51
56
  # Assert BOLD output keys
52
57
  assert "data" in output_bold
53
58
  assert "col_names" in output_bold
@@ -99,7 +104,7 @@ def test_ReHoSpheres_comparison(tmp_path: Path) -> None:
99
104
  # Fit transform marker on data
100
105
  junifer_output = junifer_marker.fit_transform(element_data)
101
106
  # Get BOLD output
102
- junifer_output_bold = junifer_output["BOLD"]
107
+ junifer_output_bold = junifer_output["BOLD"]["reho"]
103
108
 
104
109
  # Initialize marker
105
110
  afni_marker = ReHoSpheres(
@@ -110,7 +115,7 @@ def test_ReHoSpheres_comparison(tmp_path: Path) -> None:
110
115
  # Fit transform marker on data
111
116
  afni_output = afni_marker.fit_transform(element_data)
112
117
  # Get BOLD output
113
- afni_output_bold = afni_output["BOLD"]
118
+ afni_output_bold = afni_output["BOLD"]["reho"]
114
119
 
115
120
  # Check for Pearson correlation coefficient
116
121
  r, _ = sp.stats.pearsonr(
@@ -14,6 +14,9 @@ from ..utils import logger, raise_error, warn_with_log
14
14
  from .base import BaseMarker
15
15
 
16
16
 
17
+ __all__ = ["SphereAggregation"]
18
+
19
+
17
20
  @register_marker
18
21
  class SphereAggregation(BaseMarker):
19
22
  """Class for sphere aggregation.
@@ -65,6 +68,36 @@ class SphereAggregation(BaseMarker):
65
68
 
66
69
  _DEPENDENCIES: ClassVar[Set[str]] = {"nilearn", "numpy"}
67
70
 
71
+ _MARKER_INOUT_MAPPINGS: ClassVar[Dict[str, Dict[str, str]]] = {
72
+ "T1w": {
73
+ "aggregation": "vector",
74
+ },
75
+ "T2w": {
76
+ "aggregation": "vector",
77
+ },
78
+ "BOLD": {
79
+ "aggregation": "timeseries",
80
+ },
81
+ "VBM_GM": {
82
+ "aggregation": "vector",
83
+ },
84
+ "VBM_WM": {
85
+ "aggregation": "vector",
86
+ },
87
+ "VBM_CSF": {
88
+ "aggregation": "vector",
89
+ },
90
+ "fALFF": {
91
+ "aggregation": "vector",
92
+ },
93
+ "GCOR": {
94
+ "aggregation": "vector",
95
+ },
96
+ "LCOR": {
97
+ "aggregation": "vector",
98
+ },
99
+ }
100
+
68
101
  def __init__(
69
102
  self,
70
103
  coords: str,
@@ -100,61 +133,6 @@ class SphereAggregation(BaseMarker):
100
133
  self.time_method = time_method
101
134
  self.time_method_params = time_method_params or {}
102
135
 
103
- def get_valid_inputs(self) -> List[str]:
104
- """Get valid data types for input.
105
-
106
- Returns
107
- -------
108
- list of str
109
- The list of data types that can be used as input for this marker.
110
-
111
- """
112
- return [
113
- "T1w",
114
- "T2w",
115
- "BOLD",
116
- "VBM_GM",
117
- "VBM_WM",
118
- "VBM_CSF",
119
- "fALFF",
120
- "GCOR",
121
- "LCOR",
122
- ]
123
-
124
- def get_output_type(self, input_type: str) -> str:
125
- """Get output type.
126
-
127
- Parameters
128
- ----------
129
- input_type : str
130
- The data type input to the marker.
131
-
132
- Returns
133
- -------
134
- str
135
- The storage type output by the marker.
136
-
137
- Raises
138
- ------
139
- ValueError
140
- If the ``input_type`` is invalid.
141
-
142
- """
143
-
144
- if input_type in [
145
- "VBM_GM",
146
- "VBM_WM",
147
- "VBM_CSF",
148
- "fALFF",
149
- "GCOR",
150
- "LCOR",
151
- ]:
152
- return "vector"
153
- elif input_type == "BOLD":
154
- return "timeseries"
155
- else:
156
- raise_error(f"Unknown input kind for {input_type}")
157
-
158
136
  def compute(
159
137
  self,
160
138
  input: Dict[str, Any],
@@ -180,8 +158,10 @@ class SphereAggregation(BaseMarker):
180
158
  to the user or stored in the storage by calling the store method
181
159
  with this as a parameter. The dictionary has the following keys:
182
160
 
183
- * ``data`` : the actual computed values as a numpy.ndarray
184
- * ``col_names`` : the column labels for the computed values as list
161
+ * ``aggregation`` : dictionary with the following keys:
162
+
163
+ - ``data`` : ROI values as ``numpy.ndarray``
164
+ - ``col_names`` : ROI labels as list of str
185
165
 
186
166
  Warns
187
167
  -----
@@ -238,5 +218,9 @@ class SphereAggregation(BaseMarker):
238
218
  "available."
239
219
  )
240
220
  # Format the output
241
- out = {"data": out_values, "col_names": labels}
242
- return out
221
+ return {
222
+ "aggregation": {
223
+ "data": out_values,
224
+ "col_names": labels,
225
+ },
226
+ }
@@ -5,3 +5,6 @@
5
5
 
6
6
  from .temporal_snr_parcels import TemporalSNRParcels
7
7
  from .temporal_snr_spheres import TemporalSNRSpheres
8
+
9
+
10
+ __all__ = ["TemporalSNRParcels", "TemporalSNRSpheres"]