junifer 0.0.4.dev733__py3-none-any.whl → 0.0.4.dev782__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 (37) hide show
  1. junifer/_version.py +2 -2
  2. junifer/api/tests/data/partly_cloudy_agg_mean_tian.yml +16 -0
  3. junifer/api/tests/test_cli.py +7 -13
  4. junifer/api/tests/test_functions.py +156 -102
  5. junifer/data/coordinates.py +1 -1
  6. junifer/data/masks.py +213 -54
  7. junifer/data/parcellations.py +91 -42
  8. junifer/data/template_spaces.py +33 -6
  9. junifer/data/tests/test_masks.py +127 -62
  10. junifer/data/tests/test_parcellations.py +66 -49
  11. junifer/data/tests/test_template_spaces.py +42 -7
  12. junifer/datagrabber/aomic/id1000.py +3 -0
  13. junifer/datagrabber/aomic/piop1.py +3 -0
  14. junifer/datagrabber/aomic/piop2.py +3 -0
  15. junifer/datagrabber/dmcc13_benchmark.py +3 -0
  16. junifer/datagrabber/hcp1200/hcp1200.py +3 -0
  17. junifer/markers/falff/tests/test_falff_parcels.py +3 -3
  18. junifer/markers/falff/tests/test_falff_spheres.py +3 -3
  19. junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +46 -45
  20. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +34 -41
  21. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +40 -56
  22. junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +62 -74
  23. junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +99 -89
  24. junifer/markers/reho/tests/test_reho_parcels.py +17 -11
  25. junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +38 -37
  26. junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +34 -38
  27. junifer/markers/tests/test_collection.py +38 -37
  28. junifer/markers/tests/test_ets_rss.py +29 -41
  29. junifer/markers/tests/test_parcel_aggregation.py +600 -511
  30. junifer/markers/tests/test_sphere_aggregation.py +209 -163
  31. {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev782.dist-info}/METADATA +1 -1
  32. {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev782.dist-info}/RECORD +37 -36
  33. {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev782.dist-info}/AUTHORS.rst +0 -0
  34. {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev782.dist-info}/LICENSE.md +0 -0
  35. {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev782.dist-info}/WHEEL +0 -0
  36. {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev782.dist-info}/entry_points.txt +0 -0
  37. {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev782.dist-info}/top_level.txt +0 -0
@@ -10,16 +10,17 @@ from pathlib import Path
10
10
  import nibabel as nib
11
11
  import numpy as np
12
12
  import pytest
13
- from nilearn import datasets
14
- from nilearn.image import concat_imgs, math_img, new_img_like, resample_to_img
13
+ from nilearn.image import math_img, new_img_like
15
14
  from nilearn.maskers import NiftiLabelsMasker, NiftiMasker
16
15
  from nilearn.masking import compute_brain_mask
17
16
  from numpy.testing import assert_array_almost_equal, assert_array_equal
18
17
  from scipy.stats import trim_mean
19
18
 
20
- from junifer.data import load_mask, load_parcellation, register_parcellation
19
+ from junifer.data import get_mask, get_parcellation, register_parcellation
20
+ from junifer.datareader import DefaultDataReader
21
21
  from junifer.markers.parcel_aggregation import ParcelAggregation
22
22
  from junifer.storage import SQLiteFeatureStorage
23
+ from junifer.testing.datagrabbers import PartlyCloudyTestingDataGrabber
23
24
 
24
25
 
25
26
  def test_ParcelAggregation_input_output() -> None:
@@ -36,123 +37,145 @@ def test_ParcelAggregation_input_output() -> None:
36
37
 
37
38
  def test_ParcelAggregation_3D() -> None:
38
39
  """Test ParcelAggregation object on 3D images."""
39
- # Get the testing parcellation (for nilearn)
40
- parcellation = datasets.fetch_atlas_schaefer_2018(n_rois=100)
41
-
42
- # Get the oasis VBM data
43
- oasis_dataset = datasets.fetch_oasis_vbm(n_subjects=1)
44
- vbm = oasis_dataset.gray_matter_maps[0]
45
- img = nib.load(vbm)
46
-
47
- # Mask parcellation manually
48
- parcellation_img_res = resample_to_img(
49
- parcellation.maps,
50
- img,
51
- interpolation="nearest",
52
- )
53
- parcellation_bin = math_img(
54
- "img != 0",
55
- img=parcellation_img_res,
56
- )
57
-
58
- # Create NiftiMasker
59
- masker = NiftiMasker(parcellation_bin, target_affine=img.affine)
60
- data = masker.fit_transform(img)
61
- parcellation_values = masker.transform(parcellation_img_res)
62
- parcellation_values = np.squeeze(parcellation_values).astype(int)
63
-
64
- # Compute the mean manually
65
- manual = []
66
- for t_v in sorted(np.unique(parcellation_values)):
67
- t_values = np.mean(data[:, parcellation_values == t_v])
68
- manual.append(t_values)
69
- manual = np.array(manual)[np.newaxis, :]
70
-
71
- # Create NiftiLabelsMasker
72
- nifti_masker = NiftiLabelsMasker(labels_img=parcellation.maps)
73
- auto = nifti_masker.fit_transform(img)
74
-
75
- # Check that arrays are almost equal
76
- assert_array_almost_equal(auto, manual)
77
-
78
- # Use the ParcelAggregation object
79
- marker = ParcelAggregation(
80
- parcellation="Schaefer100x7",
81
- method="mean",
82
- name="gmd_schaefer100x7_mean",
83
- on="VBM_GM",
84
- ) # Test passing "on" as a keyword argument
85
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
86
- jun_values3d_mean = marker.fit_transform(input)["VBM_GM"]["data"]
87
-
88
- assert jun_values3d_mean.ndim == 2
89
- assert jun_values3d_mean.shape[0] == 1
90
- assert_array_equal(manual, jun_values3d_mean)
91
-
92
- # Test using another function (std)
93
- manual = []
94
- for t_v in sorted(np.unique(parcellation_values)):
95
- t_values = np.std(data[:, parcellation_values == t_v])
96
- manual.append(t_values)
97
- manual = np.array(manual)[np.newaxis, :]
98
-
99
- # Use the ParcelAggregation object
100
- marker = ParcelAggregation(parcellation="Schaefer100x7", method="std")
101
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
102
- jun_values3d_std = marker.fit_transform(input)["VBM_GM"]["data"]
103
-
104
- assert jun_values3d_std.ndim == 2
105
- assert jun_values3d_std.shape[0] == 1
106
- assert_array_equal(manual, jun_values3d_std)
107
-
108
- # Test using another function with parameters
109
- manual = []
110
- for t_v in sorted(np.unique(parcellation_values)):
111
- t_values = trim_mean(
112
- data[:, parcellation_values == t_v],
113
- proportiontocut=0.1,
114
- axis=None, # type: ignore
115
- )
116
- manual.append(t_values)
117
- manual = np.array(manual)[np.newaxis, :]
118
-
119
- # Use the ParcelAggregation object
120
- marker = ParcelAggregation(
121
- parcellation="Schaefer100x7",
122
- method="trim_mean",
123
- method_params={"proportiontocut": 0.1},
124
- )
125
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
126
- jun_values3d_tm = marker.fit_transform(input)["VBM_GM"]["data"]
40
+ with PartlyCloudyTestingDataGrabber() as dg:
41
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
42
+ # Create ParcelAggregation object
43
+ marker = ParcelAggregation(
44
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
45
+ method="mean",
46
+ on="BOLD",
47
+ )
48
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
49
+ ..., 0:1
50
+ ]
51
+
52
+ # Compare with nilearn
53
+ # Load testing parcellation
54
+ testing_parcellation, _ = get_parcellation(
55
+ parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
56
+ target_data=element_data["BOLD"],
57
+ )
58
+ # Binarize parcellation
59
+ testing_parcellation_bin = math_img(
60
+ "img != 0",
61
+ img=testing_parcellation,
62
+ )
63
+ # Create NiftiMasker
64
+ masker = NiftiMasker(
65
+ testing_parcellation_bin,
66
+ target_affine=element_data["BOLD"]["data"].affine,
67
+ )
68
+ data = masker.fit_transform(element_data["BOLD"]["data"])
69
+ parcellation_values = np.squeeze(
70
+ masker.transform(testing_parcellation)
71
+ ).astype(int)
72
+ # Compute the mean manually
73
+ manual = []
74
+ for t_v in sorted(np.unique(parcellation_values)):
75
+ t_values = np.mean(data[:, parcellation_values == t_v])
76
+ manual.append(t_values)
77
+ manual = np.array(manual)[np.newaxis, :]
78
+
79
+ # Create NiftiLabelsMasker
80
+ nifti_labels_masker = NiftiLabelsMasker(
81
+ labels_img=testing_parcellation
82
+ )
83
+ nifti_labels_masked_bold = nifti_labels_masker.fit_transform(
84
+ element_data["BOLD"]["data"].slicer[..., 0:1]
85
+ )
127
86
 
128
- assert jun_values3d_tm.ndim == 2
129
- assert jun_values3d_tm.shape[0] == 1
130
- assert_array_equal(manual, jun_values3d_tm)
87
+ parcel_agg_mean_bold_data = marker.fit_transform(element_data)["BOLD"][
88
+ "data"
89
+ ]
90
+ # Check that arrays are almost equal
91
+ assert_array_equal(parcel_agg_mean_bold_data, manual)
92
+ assert_array_almost_equal(nifti_labels_masked_bold, manual)
93
+
94
+ # Check further
95
+ assert parcel_agg_mean_bold_data.ndim == 2
96
+ assert parcel_agg_mean_bold_data.shape[0] == 1
97
+ assert_array_equal(
98
+ nifti_labels_masked_bold.shape, parcel_agg_mean_bold_data.shape
99
+ )
100
+ assert_array_equal(nifti_labels_masked_bold, parcel_agg_mean_bold_data)
101
+
102
+ # Compute std manually
103
+ manual = []
104
+ for t_v in sorted(np.unique(parcellation_values)):
105
+ t_values = np.std(data[:, parcellation_values == t_v])
106
+ manual.append(t_values)
107
+ manual = np.array(manual)[np.newaxis, :]
108
+
109
+ # Create ParcelAggregation object
110
+ marker = ParcelAggregation(
111
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
112
+ method="std",
113
+ on="BOLD",
114
+ )
115
+ parcel_agg_std_bold_data = marker.fit_transform(element_data)["BOLD"][
116
+ "data"
117
+ ]
118
+ assert parcel_agg_std_bold_data.ndim == 2
119
+ assert parcel_agg_std_bold_data.shape[0] == 1
120
+ assert_array_equal(parcel_agg_std_bold_data, manual)
121
+
122
+ # Test using another function with parameters
123
+ manual = []
124
+ for t_v in sorted(np.unique(parcellation_values)):
125
+ t_values = trim_mean(
126
+ data[:, parcellation_values == t_v],
127
+ proportiontocut=0.1,
128
+ axis=None, # type: ignore
129
+ )
130
+ manual.append(t_values)
131
+ manual = np.array(manual)[np.newaxis, :]
132
+
133
+ # Create ParcelAggregation object
134
+ marker = ParcelAggregation(
135
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
136
+ method="trim_mean",
137
+ method_params={"proportiontocut": 0.1},
138
+ on="BOLD",
139
+ )
140
+ parcel_agg_trim_mean_bold_data = marker.fit_transform(element_data)[
141
+ "BOLD"
142
+ ]["data"]
143
+ assert parcel_agg_trim_mean_bold_data.ndim == 2
144
+ assert parcel_agg_trim_mean_bold_data.shape[0] == 1
145
+ assert_array_equal(parcel_agg_trim_mean_bold_data, manual)
131
146
 
132
147
 
133
148
  def test_ParcelAggregation_4D():
134
149
  """Test ParcelAggregation object on 4D images."""
135
- # Get the testing parcellation (for nilearn)
136
- parcellation = datasets.fetch_atlas_schaefer_2018(
137
- n_rois=100, yeo_networks=7, resolution_mm=2
138
- )
139
-
140
- # Get the SPM auditory data:
141
- subject_data = datasets.fetch_spm_auditory()
142
- fmri_img = concat_imgs(subject_data.func) # type: ignore
143
-
144
- # Create NiftiLabelsMasker
145
- nifti_masker = NiftiLabelsMasker(labels_img=parcellation.maps)
146
- auto4d = nifti_masker.fit_transform(fmri_img)
147
-
148
- # Create ParcelAggregation object
149
- marker = ParcelAggregation(parcellation="Schaefer100x7", method="mean")
150
- input = {"BOLD": {"data": fmri_img, "meta": {}, "space": "MNI"}}
151
- jun_values4d = marker.fit_transform(input)["BOLD"]["data"]
150
+ with PartlyCloudyTestingDataGrabber() as dg:
151
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
152
+ # Create ParcelAggregation object
153
+ marker = ParcelAggregation(
154
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym", method="mean"
155
+ )
156
+ parcel_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
157
+ "data"
158
+ ]
159
+
160
+ # Compare with nilearn
161
+ # Load testing parcellation
162
+ testing_parcellation, _ = get_parcellation(
163
+ parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
164
+ target_data=element_data["BOLD"],
165
+ )
166
+ # Extract data
167
+ nifti_labels_masker = NiftiLabelsMasker(
168
+ labels_img=testing_parcellation
169
+ )
170
+ nifti_labels_masked_bold = nifti_labels_masker.fit_transform(
171
+ element_data["BOLD"]["data"]
172
+ )
152
173
 
153
- assert jun_values4d.ndim == 2
154
- assert_array_equal(auto4d.shape, jun_values4d.shape)
155
- assert_array_equal(auto4d, jun_values4d)
174
+ assert parcel_agg_bold_data.ndim == 2
175
+ assert_array_equal(
176
+ nifti_labels_masked_bold.shape, parcel_agg_bold_data.shape
177
+ )
178
+ assert_array_equal(nifti_labels_masked_bold, parcel_agg_bold_data)
156
179
 
157
180
 
158
181
  def test_ParcelAggregation_storage(tmp_path: Path) -> None:
@@ -164,130 +187,148 @@ def test_ParcelAggregation_storage(tmp_path: Path) -> None:
164
187
  The path to the test directory.
165
188
 
166
189
  """
167
- # Get the oasis VBM data
168
- oasis_dataset = datasets.fetch_oasis_vbm(n_subjects=1)
169
- vbm = oasis_dataset.gray_matter_maps[0]
170
- img = nib.load(vbm)
171
- uri = tmp_path / "test_sphere_storage_3D.sqlite"
172
-
173
- storage = SQLiteFeatureStorage(uri=uri, upsert="ignore")
174
- meta = {
175
- "element": {"subject": "sub-01", "session": "ses-01"},
176
- "dependencies": {"nilearn", "nibabel"},
177
- }
178
- input = {"VBM_GM": {"data": img, "meta": meta, "space": "MNI"}}
179
- marker = ParcelAggregation(
180
- parcellation="Schaefer100x7", method="mean", on="VBM_GM"
181
- )
182
-
183
- marker.fit_transform(input, storage=storage)
184
-
185
- features = storage.list_features()
186
- assert any(
187
- x["name"] == "VBM_GM_ParcelAggregation" for x in features.values()
188
- )
189
-
190
- meta = {
191
- "element": {"subject": "sub-01", "session": "ses-01"},
192
- "dependencies": {"nilearn", "nibabel"},
193
- }
194
- # Get the SPM auditory data
195
- subject_data = datasets.fetch_spm_auditory()
196
- fmri_img = concat_imgs(subject_data.func) # type: ignore
197
- input = {"BOLD": {"data": fmri_img, "meta": meta, "space": "MNI"}}
198
- marker = ParcelAggregation(
199
- parcellation="Schaefer100x7", method="mean", on="BOLD"
200
- )
190
+ # Store 3D
191
+ with PartlyCloudyTestingDataGrabber() as dg:
192
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
193
+ storage = SQLiteFeatureStorage(
194
+ uri=tmp_path / "test_parcel_storage_3D.sqlite", upsert="ignore"
195
+ )
196
+ marker = ParcelAggregation(
197
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
198
+ method="mean",
199
+ on="BOLD",
200
+ )
201
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
202
+ ..., 0:1
203
+ ]
204
+ marker.fit_transform(input=element_data, storage=storage)
205
+ features = storage.list_features()
206
+ assert any(
207
+ x["name"] == "BOLD_ParcelAggregation" for x in features.values()
208
+ )
201
209
 
202
- marker.fit_transform(input, storage=storage)
203
- features = storage.list_features()
204
- assert any(
205
- x["name"] == "BOLD_ParcelAggregation" for x in features.values()
206
- )
210
+ # Store 4D
211
+ with PartlyCloudyTestingDataGrabber() as dg:
212
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
213
+ storage = SQLiteFeatureStorage(
214
+ uri=tmp_path / "test_parcel_storage_4D.sqlite", upsert="ignore"
215
+ )
216
+ marker = ParcelAggregation(
217
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
218
+ method="mean",
219
+ on="BOLD",
220
+ )
221
+ marker.fit_transform(input=element_data, storage=storage)
222
+ features = storage.list_features()
223
+ assert any(
224
+ x["name"] == "BOLD_ParcelAggregation" for x in features.values()
225
+ )
207
226
 
208
227
 
209
228
  def test_ParcelAggregation_3D_mask() -> None:
210
229
  """Test ParcelAggregation object on 3D images with mask."""
230
+ with PartlyCloudyTestingDataGrabber() as dg:
231
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
232
+ # Create ParcelAggregation object
233
+ marker = ParcelAggregation(
234
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
235
+ method="mean",
236
+ name="tian_mean",
237
+ on="BOLD",
238
+ masks="compute_brain_mask",
239
+ )
240
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
241
+ ..., 0:1
242
+ ]
243
+ parcel_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
244
+ "data"
245
+ ]
246
+
247
+ # Compare with nilearn
248
+ # Load testing parcellation
249
+ testing_parcellation, _ = get_parcellation(
250
+ parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
251
+ target_data=element_data["BOLD"],
252
+ )
253
+ # Load mask
254
+ mask_img = get_mask(
255
+ "compute_brain_mask", target_data=element_data["BOLD"]
256
+ )
257
+ # Extract data
258
+ nifti_labels_masker = NiftiLabelsMasker(
259
+ labels_img=testing_parcellation, mask_img=mask_img
260
+ )
261
+ nifti_labels_masked_bold = nifti_labels_masker.fit_transform(
262
+ element_data["BOLD"]["data"].slicer[..., 0:1]
263
+ )
211
264
 
212
- # Get the testing parcellation (for nilearn)
213
- parcellation = datasets.fetch_atlas_schaefer_2018(n_rois=100)
214
-
215
- # Get one mask
216
- mask_img, _, _ = load_mask("GM_prob0.2")
217
-
218
- # Get the oasis VBM data
219
- oasis_dataset = datasets.fetch_oasis_vbm(n_subjects=1)
220
- vbm = oasis_dataset.gray_matter_maps[0]
221
- img = nib.load(vbm)
222
-
223
- # Create NiftiLabelsMasker
224
- nifti_masker = NiftiLabelsMasker(
225
- labels_img=parcellation.maps, mask_img=mask_img
226
- )
227
- auto = nifti_masker.fit_transform(img)
228
-
229
- # Use the ParcelAggregation object
230
- marker = ParcelAggregation(
231
- parcellation="Schaefer100x7",
232
- method="mean",
233
- masks="GM_prob0.2",
234
- name="gmd_schaefer100x7_mean",
235
- on="VBM_GM",
236
- ) # Test passing "on" as a keyword argument
237
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
238
- jun_values3d_mean = marker.fit_transform(input)["VBM_GM"]["data"]
239
-
240
- assert jun_values3d_mean.ndim == 2
241
- assert jun_values3d_mean.shape[0] == 1
242
- assert_array_almost_equal(auto, jun_values3d_mean)
265
+ assert parcel_agg_bold_data.ndim == 2
266
+ assert_array_equal(
267
+ nifti_labels_masked_bold.shape, parcel_agg_bold_data.shape
268
+ )
269
+ assert_array_equal(nifti_labels_masked_bold, parcel_agg_bold_data)
243
270
 
244
271
 
245
272
  def test_ParcelAggregation_3D_mask_computed() -> None:
246
273
  """Test ParcelAggregation object on 3D images with computed masks."""
274
+ with PartlyCloudyTestingDataGrabber() as dg:
275
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
276
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
277
+ ..., 0:1
278
+ ]
279
+
280
+ # Compare with nilearn
281
+ # Load testing parcellation
282
+ testing_parcellation, _ = get_parcellation(
283
+ parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
284
+ target_data=element_data["BOLD"],
285
+ )
286
+ # Get a mask
287
+ mask_img = compute_brain_mask(
288
+ element_data["BOLD"]["data"], threshold=0.2
289
+ )
290
+ # Create NiftiLabelsMasker
291
+ nifti_labels_masker = NiftiLabelsMasker(
292
+ labels_img=testing_parcellation, mask_img=mask_img
293
+ )
294
+ nifti_labels_masked_bold_good = nifti_labels_masker.fit_transform(
295
+ element_data["BOLD"]["data"]
296
+ )
247
297
 
248
- # Get the testing parcellation (for nilearn)
249
- parcellation = datasets.fetch_atlas_schaefer_2018(n_rois=100)
250
-
251
- # Get the oasis VBM data
252
- oasis_dataset = datasets.fetch_oasis_vbm(n_subjects=1)
253
- vbm = oasis_dataset.gray_matter_maps[0]
254
- img = nib.load(vbm)
255
-
256
- # Get one mask
257
- mask_img = compute_brain_mask(img, threshold=0.2)
258
-
259
- # Create NiftiLabelsMasker
260
- nifti_masker = NiftiLabelsMasker(
261
- labels_img=parcellation.maps, mask_img=mask_img
262
- )
263
- auto = nifti_masker.fit_transform(img)
264
-
265
- # Get one mask
266
- mask_img = compute_brain_mask(img, threshold=0.5)
267
-
268
- # Create NiftiLabelsMasker
269
- nifti_masker = NiftiLabelsMasker(
270
- labels_img=parcellation.maps, mask_img=mask_img
271
- )
272
- auto_bad = nifti_masker.fit_transform(img)
273
-
274
- # Use the ParcelAggregation object
275
- marker = ParcelAggregation(
276
- parcellation="Schaefer100x7",
277
- method="mean",
278
- masks={"compute_brain_mask": {"threshold": 0.2}},
279
- name="gmd_schaefer100x7_mean",
280
- on="VBM_GM",
281
- ) # Test passing "on" as a keyword argument
282
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
283
- jun_values3d_mean = marker.fit_transform(input)["VBM_GM"]["data"]
298
+ # Get another mask
299
+ mask_img = compute_brain_mask(
300
+ element_data["BOLD"]["data"], threshold=0.5
301
+ )
302
+ # Create NiftiLabelsMasker
303
+ nifti_labels_masker = NiftiLabelsMasker(
304
+ labels_img=testing_parcellation, mask_img=mask_img
305
+ )
306
+ nifti_labels_masked_bold_bad = nifti_labels_masker.fit_transform(
307
+ mask_img
308
+ )
284
309
 
285
- assert jun_values3d_mean.ndim == 2
286
- assert jun_values3d_mean.shape[0] == 1
287
- assert_array_almost_equal(auto, jun_values3d_mean)
310
+ # Use the ParcelAggregation object
311
+ marker = ParcelAggregation(
312
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
313
+ method="mean",
314
+ masks={"compute_brain_mask": {"threshold": 0.2}},
315
+ name="tian_mean",
316
+ on="BOLD",
317
+ )
318
+ parcel_agg_mean_bold_data = marker.fit_transform(element_data)["BOLD"][
319
+ "data"
320
+ ]
321
+
322
+ assert parcel_agg_mean_bold_data.ndim == 2
323
+ assert parcel_agg_mean_bold_data.shape[0] == 1
324
+ assert_array_almost_equal(
325
+ nifti_labels_masked_bold_good, parcel_agg_mean_bold_data
326
+ )
288
327
 
289
- with pytest.raises(AssertionError):
290
- assert_array_almost_equal(jun_values3d_mean, auto_bad)
328
+ with pytest.raises(AssertionError):
329
+ assert_array_almost_equal(
330
+ parcel_agg_mean_bold_data, nifti_labels_masked_bold_bad
331
+ )
291
332
 
292
333
 
293
334
  def test_ParcelAggregation_3D_multiple_non_overlapping(tmp_path: Path) -> None:
@@ -299,89 +340,93 @@ def test_ParcelAggregation_3D_multiple_non_overlapping(tmp_path: Path) -> None:
299
340
  The path to the test directory.
300
341
 
301
342
  """
343
+ with PartlyCloudyTestingDataGrabber() as dg:
344
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
345
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
346
+ ..., 0:1
347
+ ]
348
+
349
+ # Load testing parcellation
350
+ testing_parcellation, labels = get_parcellation(
351
+ parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
352
+ target_data=element_data["BOLD"],
353
+ )
302
354
 
303
- # Get the testing parcellation
304
- parcellation, labels, _, _ = load_parcellation("Schaefer100x7")
305
-
306
- assert parcellation is not None
307
-
308
- # Get the oasis VBM data
309
- oasis_dataset = datasets.fetch_oasis_vbm(n_subjects=1)
310
- vbm = oasis_dataset.gray_matter_maps[0]
311
- img = nib.load(vbm)
312
-
313
- # Create two parcellations from it
314
- parcellation_data = parcellation.get_fdata()
315
- parcellation1_data = parcellation_data.copy()
316
- parcellation1_data[parcellation1_data > 50] = 0
317
- parcellation2_data = parcellation_data.copy()
318
- parcellation2_data[parcellation2_data <= 50] = 0
319
- parcellation2_data[parcellation2_data > 0] -= 50
320
- labels1 = labels[:50]
321
- labels2 = labels[50:]
322
-
323
- parcellation1_img = new_img_like(parcellation, parcellation1_data)
324
- parcellation2_img = new_img_like(parcellation, parcellation2_data)
325
-
326
- parcellation1_path = tmp_path / "parcellation1.nii.gz"
327
- parcellation2_path = tmp_path / "parcellation2.nii.gz"
328
-
329
- nib.save(parcellation1_img, parcellation1_path)
330
- nib.save(parcellation2_img, parcellation2_path)
331
-
332
- register_parcellation(
333
- name="Schaefer100x7_low",
334
- parcellation_path=parcellation1_path,
335
- parcels_labels=labels1,
336
- space="MNI",
337
- overwrite=True,
338
- )
339
- register_parcellation(
340
- name="Schaefer100x7_high",
341
- parcellation_path=parcellation2_path,
342
- parcels_labels=labels2,
343
- space="MNI",
344
- overwrite=True,
345
- )
355
+ # Create two parcellations from it
356
+ parcellation_data = testing_parcellation.get_fdata()
357
+ parcellation1_data = parcellation_data.copy()
358
+ parcellation1_data[parcellation1_data > 8] = 0
359
+ parcellation2_data = parcellation_data.copy()
360
+ parcellation2_data[parcellation2_data <= 8] = 0
361
+ parcellation2_data[parcellation2_data > 0] -= 8
362
+ labels1 = labels[:8]
363
+ labels2 = labels[8:]
364
+
365
+ parcellation1_img = new_img_like(
366
+ testing_parcellation, parcellation1_data
367
+ )
368
+ parcellation2_img = new_img_like(
369
+ testing_parcellation, parcellation2_data
370
+ )
371
+
372
+ parcellation1_path = tmp_path / "parcellation1.nii.gz"
373
+ parcellation2_path = tmp_path / "parcellation2.nii.gz"
374
+
375
+ nib.save(parcellation1_img, parcellation1_path)
376
+ nib.save(parcellation2_img, parcellation2_path)
377
+
378
+ register_parcellation(
379
+ name="TianxS1x3TxMNInonlinear2009cAsym_low",
380
+ parcellation_path=parcellation1_path,
381
+ parcels_labels=labels1,
382
+ space="MNI152NLin2009cAsym",
383
+ overwrite=True,
384
+ )
385
+ register_parcellation(
386
+ name="TianxS1x3TxMNInonlinear2009cAsym_high",
387
+ parcellation_path=parcellation2_path,
388
+ parcels_labels=labels2,
389
+ space="MNI152NLin2009cAsym",
390
+ overwrite=True,
391
+ )
392
+
393
+ # Use the ParcelAggregation object on the original parcellation
394
+ marker_original = ParcelAggregation(
395
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
396
+ method="mean",
397
+ name="tian_mean",
398
+ on="BOLD",
399
+ )
400
+ orig_mean = marker_original.fit_transform(element_data)["BOLD"]
401
+
402
+ orig_mean_data = orig_mean["data"]
403
+ assert orig_mean_data.ndim == 2
404
+ assert orig_mean_data.shape == (1, 16)
405
+
406
+ # Use the ParcelAggregation object on the two parcellations
407
+ marker_split = ParcelAggregation(
408
+ parcellation=[
409
+ "TianxS1x3TxMNInonlinear2009cAsym_low",
410
+ "TianxS1x3TxMNInonlinear2009cAsym_high",
411
+ ],
412
+ method="mean",
413
+ name="tian_mean",
414
+ on="BOLD",
415
+ )
416
+
417
+ # No warnings should be raised
418
+ with warnings.catch_warnings():
419
+ warnings.simplefilter("error", category=UserWarning)
420
+ split_mean = marker_split.fit_transform(element_data)["BOLD"]
421
+
422
+ split_mean_data = split_mean["data"]
346
423
 
347
- # Use the ParcelAggregation object on the original parcellation
348
- marker_original = ParcelAggregation(
349
- parcellation="Schaefer100x7",
350
- method="mean",
351
- name="gmd_schaefer100x7_mean",
352
- on="VBM_GM",
353
- ) # Test passing "on" as a keyword argument
354
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
355
- orig_mean = marker_original.fit_transform(input)["VBM_GM"]
356
-
357
- orig_mean_data = orig_mean["data"]
358
- assert orig_mean_data.ndim == 2
359
- assert orig_mean_data.shape[0] == 1
360
- assert orig_mean_data.shape[1] == 100
361
- # assert_array_almost_equal(auto, jun_values3d_mean)
362
-
363
- # Use the ParcelAggregation object on the two parcellations
364
- marker_split = ParcelAggregation(
365
- parcellation=["Schaefer100x7_low", "Schaefer100x7_high"],
366
- method="mean",
367
- name="gmd_schaefer100x7_mean",
368
- on="VBM_GM",
369
- ) # Test passing "on" as a keyword argument
370
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
371
-
372
- # No warnings should be raised
373
- with warnings.catch_warnings():
374
- warnings.simplefilter("error", category=UserWarning)
375
- split_mean = marker_split.fit_transform(input)["VBM_GM"]
376
- split_mean_data = split_mean["data"]
377
-
378
- assert split_mean_data.ndim == 2
379
- assert split_mean_data.shape[0] == 1
380
- assert split_mean_data.shape[1] == 100
381
-
382
- # Data and labels should be the same
383
- assert_array_equal(orig_mean_data, split_mean_data)
384
- assert orig_mean["col_names"] == split_mean["col_names"]
424
+ assert split_mean_data.ndim == 2
425
+ assert split_mean_data.shape == (1, 16)
426
+
427
+ # Data and labels should be the same
428
+ assert_array_equal(orig_mean_data, split_mean_data)
429
+ assert orig_mean["col_names"] == split_mean["col_names"]
385
430
 
386
431
 
387
432
  def test_ParcelAggregation_3D_multiple_overlapping(tmp_path: Path) -> None:
@@ -393,95 +438,100 @@ def test_ParcelAggregation_3D_multiple_overlapping(tmp_path: Path) -> None:
393
438
  The path to the test directory.
394
439
 
395
440
  """
441
+ with PartlyCloudyTestingDataGrabber() as dg:
442
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
443
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
444
+ ..., 0:1
445
+ ]
446
+
447
+ # Load testing parcellation
448
+ testing_parcellation, labels = get_parcellation(
449
+ parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
450
+ target_data=element_data["BOLD"],
451
+ )
396
452
 
397
- # Get the testing parcellation
398
- parcellation, labels, _, _ = load_parcellation("Schaefer100x7")
453
+ # Create two parcellations from it
454
+ parcellation_data = testing_parcellation.get_fdata()
455
+ parcellation1_data = parcellation_data.copy()
456
+ parcellation1_data[parcellation1_data > 8] = 0
457
+ parcellation2_data = parcellation_data.copy()
399
458
 
400
- assert parcellation is not None
459
+ # Make the second parcellation overlap with the first
460
+ parcellation2_data[parcellation2_data <= 6] = 0
461
+ parcellation2_data[parcellation2_data > 0] -= 6
462
+ labels1 = [f"low_{x}" for x in labels[:8]] # Change the labels
463
+ labels2 = [f"high_{x}" for x in labels[6:]] # Change the labels
401
464
 
402
- # Get the oasis VBM data
403
- oasis_dataset = datasets.fetch_oasis_vbm(n_subjects=1)
404
- vbm = oasis_dataset.gray_matter_maps[0]
405
- img = nib.load(vbm)
465
+ parcellation1_img = new_img_like(
466
+ testing_parcellation, parcellation1_data
467
+ )
468
+ parcellation2_img = new_img_like(
469
+ testing_parcellation, parcellation2_data
470
+ )
406
471
 
407
- # Create two parcellations from it
408
- parcellation_data = parcellation.get_fdata()
409
- parcellation1_data = parcellation_data.copy()
410
- parcellation1_data[parcellation1_data > 50] = 0
411
- parcellation2_data = parcellation_data.copy()
472
+ parcellation1_path = tmp_path / "parcellation1.nii.gz"
473
+ parcellation2_path = tmp_path / "parcellation2.nii.gz"
412
474
 
413
- # Make the second parcellation overlap with the first
414
- parcellation2_data[parcellation2_data <= 45] = 0
415
- parcellation2_data[parcellation2_data > 0] -= 45
416
- labels1 = [f"low_{x}" for x in labels[:50]] # Change the labels
417
- labels2 = [f"high_{x}" for x in labels[45:]] # Change the labels
475
+ nib.save(parcellation1_img, parcellation1_path)
476
+ nib.save(parcellation2_img, parcellation2_path)
418
477
 
419
- parcellation1_img = new_img_like(parcellation, parcellation1_data)
420
- parcellation2_img = new_img_like(parcellation, parcellation2_data)
478
+ register_parcellation(
479
+ name="TianxS1x3TxMNInonlinear2009cAsym_low",
480
+ parcellation_path=parcellation1_path,
481
+ parcels_labels=labels1,
482
+ space="MNI152NLin2009cAsym",
483
+ overwrite=True,
484
+ )
485
+ register_parcellation(
486
+ name="TianxS1x3TxMNInonlinear2009cAsym_high",
487
+ parcellation_path=parcellation2_path,
488
+ parcels_labels=labels2,
489
+ space="MNI152NLin2009cAsym",
490
+ overwrite=True,
491
+ )
421
492
 
422
- parcellation1_path = tmp_path / "parcellation1.nii.gz"
423
- parcellation2_path = tmp_path / "parcellation2.nii.gz"
493
+ # Use the ParcelAggregation object on the original parcellation
494
+ marker_original = ParcelAggregation(
495
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
496
+ method="mean",
497
+ name="tian_mean",
498
+ on="BOLD",
499
+ )
500
+ orig_mean = marker_original.fit_transform(element_data)["BOLD"]
501
+
502
+ orig_mean_data = orig_mean["data"]
503
+ assert orig_mean_data.ndim == 2
504
+ assert orig_mean_data.shape == (1, 16)
505
+
506
+ # Use the ParcelAggregation object on the two parcellations
507
+ marker_split = ParcelAggregation(
508
+ parcellation=[
509
+ "TianxS1x3TxMNInonlinear2009cAsym_low",
510
+ "TianxS1x3TxMNInonlinear2009cAsym_high",
511
+ ],
512
+ method="mean",
513
+ name="tian_mean",
514
+ on="BOLD",
515
+ )
516
+ # Warning should be raised
517
+ with pytest.warns(RuntimeWarning, match="overlapping voxels"):
518
+ split_mean = marker_split.fit_transform(element_data)["BOLD"]
424
519
 
425
- nib.save(parcellation1_img, parcellation1_path)
426
- nib.save(parcellation2_img, parcellation2_path)
520
+ split_mean_data = split_mean["data"]
427
521
 
428
- register_parcellation(
429
- name="Schaefer100x7_low2",
430
- parcellation_path=parcellation1_path,
431
- parcels_labels=labels1,
432
- space="MNI",
433
- overwrite=True,
434
- )
435
- register_parcellation(
436
- name="Schaefer100x7_high2",
437
- parcellation_path=parcellation2_path,
438
- parcels_labels=labels2,
439
- space="MNI",
440
- overwrite=True,
441
- )
522
+ assert split_mean_data.ndim == 2
523
+ assert split_mean_data.shape == (1, 18)
442
524
 
443
- # Use the ParcelAggregation object on the original parcellation
444
- marker_original = ParcelAggregation(
445
- parcellation="Schaefer100x7",
446
- method="mean",
447
- name="gmd_schaefer100x7_mean",
448
- on="VBM_GM",
449
- ) # Test passing "on" as a keyword argument
450
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
451
- orig_mean = marker_original.fit_transform(input)["VBM_GM"]
452
-
453
- orig_mean_data = orig_mean["data"]
454
- assert orig_mean_data.ndim == 2
455
- assert orig_mean_data.shape[0] == 1
456
- assert orig_mean_data.shape[1] == 100
457
- # assert_array_almost_equal(auto, jun_values3d_mean)
458
-
459
- # Use the ParcelAggregation object on the two parcellations
460
- marker_split = ParcelAggregation(
461
- parcellation=["Schaefer100x7_low2", "Schaefer100x7_high2"],
462
- method="mean",
463
- name="gmd_schaefer100x7_mean",
464
- on="VBM_GM",
465
- ) # Test passing "on" as a keyword argument
466
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
467
- with pytest.warns(RuntimeWarning, match="overlapping voxels"):
468
- split_mean = marker_split.fit_transform(input)["VBM_GM"]
469
- split_mean_data = split_mean["data"]
470
-
471
- assert split_mean_data.ndim == 2
472
- assert split_mean_data.shape[0] == 1
473
- assert split_mean_data.shape[1] == 105
474
-
475
- # Overlapping voxels should be NaN
476
- assert np.isnan(split_mean_data[:, 50:55]).all()
477
-
478
- non_nan = split_mean_data[~np.isnan(split_mean_data)]
479
- # Data should be the same
480
- assert_array_equal(orig_mean_data, non_nan[None, :])
481
-
482
- # Labels should be "low" for the first 50 and "high" for the second 50
483
- assert all(x.startswith("low") for x in split_mean["col_names"][:50])
484
- assert all(x.startswith("high") for x in split_mean["col_names"][50:])
525
+ # Overlapping voxels should be NaN
526
+ assert np.isnan(split_mean_data[:, 8:10]).all()
527
+
528
+ non_nan = split_mean_data[~np.isnan(split_mean_data)]
529
+ # Data should be the same
530
+ assert_array_equal(orig_mean_data, non_nan[None, :])
531
+
532
+ # Labels should be "low" for the first 8 and "high" for the second 8
533
+ assert all(x.startswith("low") for x in split_mean["col_names"][:8])
534
+ assert all(x.startswith("high") for x in split_mean["col_names"][8:])
485
535
 
486
536
 
487
537
  def test_ParcelAggregation_3D_multiple_duplicated_labels(
@@ -495,135 +545,164 @@ def test_ParcelAggregation_3D_multiple_duplicated_labels(
495
545
  The path to the test directory.
496
546
 
497
547
  """
548
+ with PartlyCloudyTestingDataGrabber() as dg:
549
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
550
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
551
+ ..., 0:1
552
+ ]
553
+
554
+ # Load testing parcellation
555
+ testing_parcellation, labels = get_parcellation(
556
+ parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
557
+ target_data=element_data["BOLD"],
558
+ )
498
559
 
499
- # Get the testing parcellation
500
- parcellation, labels, _, _ = load_parcellation("Schaefer100x7")
501
-
502
- assert parcellation is not None
503
-
504
- # Get the oasis VBM data
505
- oasis_dataset = datasets.fetch_oasis_vbm(n_subjects=1)
506
- vbm = oasis_dataset.gray_matter_maps[0]
507
- img = nib.load(vbm)
508
-
509
- # Create two parcellations from it
510
- parcellation_data = parcellation.get_fdata()
511
- parcellation1_data = parcellation_data.copy()
512
- parcellation1_data[parcellation1_data > 50] = 0
513
- parcellation2_data = parcellation_data.copy()
514
- parcellation2_data[parcellation2_data <= 50] = 0
515
- parcellation2_data[parcellation2_data > 0] -= 50
516
- labels1 = labels[:50]
517
- labels2 = labels[49:-1] # One label is duplicated
518
-
519
- parcellation1_img = new_img_like(parcellation, parcellation1_data)
520
- parcellation2_img = new_img_like(parcellation, parcellation2_data)
521
-
522
- parcellation1_path = tmp_path / "parcellation1.nii.gz"
523
- parcellation2_path = tmp_path / "parcellation2.nii.gz"
524
-
525
- nib.save(parcellation1_img, parcellation1_path)
526
- nib.save(parcellation2_img, parcellation2_path)
527
-
528
- register_parcellation(
529
- name="Schaefer100x7_low",
530
- parcellation_path=parcellation1_path,
531
- parcels_labels=labels1,
532
- space="MNI",
533
- overwrite=True,
534
- )
535
- register_parcellation(
536
- name="Schaefer100x7_high",
537
- parcellation_path=parcellation2_path,
538
- parcels_labels=labels2,
539
- space="MNI",
540
- overwrite=True,
541
- )
560
+ # Create two parcellations from it
561
+ parcellation_data = testing_parcellation.get_fdata()
562
+ parcellation1_data = parcellation_data.copy()
563
+ parcellation1_data[parcellation1_data > 8] = 0
564
+ parcellation2_data = parcellation_data.copy()
565
+ parcellation2_data[parcellation2_data <= 8] = 0
566
+ parcellation2_data[parcellation2_data > 0] -= 8
567
+ labels1 = labels[:8]
568
+ labels2 = labels[7:-1] # One label is duplicated
569
+
570
+ parcellation1_img = new_img_like(
571
+ testing_parcellation, parcellation1_data
572
+ )
573
+ parcellation2_img = new_img_like(
574
+ testing_parcellation, parcellation2_data
575
+ )
542
576
 
543
- # Use the ParcelAggregation object on the original parcellation
544
- marker_original = ParcelAggregation(
545
- parcellation="Schaefer100x7",
546
- method="mean",
547
- name="gmd_schaefer100x7_mean",
548
- on="VBM_GM",
549
- ) # Test passing "on" as a keyword argument
550
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
551
- orig_mean = marker_original.fit_transform(input)["VBM_GM"]
552
-
553
- orig_mean_data = orig_mean["data"]
554
- assert orig_mean_data.ndim == 2
555
- assert orig_mean_data.shape[0] == 1
556
- assert orig_mean_data.shape[1] == 100
557
- # assert_array_almost_equal(auto, jun_values3d_mean)
558
-
559
- # Use the ParcelAggregation object on the two parcellations
560
- marker_split = ParcelAggregation(
561
- parcellation=["Schaefer100x7_low", "Schaefer100x7_high"],
562
- method="mean",
563
- name="gmd_schaefer100x7_mean",
564
- on="VBM_GM",
565
- ) # Test passing "on" as a keyword argument
566
- input = {"VBM_GM": {"data": img, "meta": {}, "space": "MNI"}}
567
-
568
- with pytest.warns(RuntimeWarning, match="duplicated labels."):
569
- split_mean = marker_split.fit_transform(input)["VBM_GM"]
570
- split_mean_data = split_mean["data"]
571
-
572
- assert split_mean_data.ndim == 2
573
- assert split_mean_data.shape[0] == 1
574
- assert split_mean_data.shape[1] == 100
575
-
576
- # Data should be the same
577
- assert_array_equal(orig_mean_data, split_mean_data)
578
-
579
- # Labels should be prefixed with the parcellation name
580
- col_names = [f"Schaefer100x7_low_{x}" for x in labels1]
581
- col_names += [f"Schaefer100x7_high_{x}" for x in labels2]
582
- assert col_names == split_mean["col_names"]
577
+ parcellation1_path = tmp_path / "parcellation1.nii.gz"
578
+ parcellation2_path = tmp_path / "parcellation2.nii.gz"
583
579
 
580
+ nib.save(parcellation1_img, parcellation1_path)
581
+ nib.save(parcellation2_img, parcellation2_path)
584
582
 
585
- def test_ParcelAggregation_4D_agg_time():
586
- """Test ParcelAggregation object on 4D images, aggregating time."""
587
- # Get the testing parcellation (for nilearn)
588
- parcellation = datasets.fetch_atlas_schaefer_2018(
589
- n_rois=100, yeo_networks=7, resolution_mm=2
590
- )
583
+ register_parcellation(
584
+ name="TianxS1x3TxMNInonlinear2009cAsym_low",
585
+ parcellation_path=parcellation1_path,
586
+ parcels_labels=labels1,
587
+ space="MNI152NLin2009cAsym",
588
+ overwrite=True,
589
+ )
590
+ register_parcellation(
591
+ name="TianxS1x3TxMNInonlinear2009cAsym_high",
592
+ parcellation_path=parcellation2_path,
593
+ parcels_labels=labels2,
594
+ space="MNI152NLin2009cAsym",
595
+ overwrite=True,
596
+ )
591
597
 
592
- # Get the SPM auditory data:
593
- subject_data = datasets.fetch_spm_auditory()
594
- fmri_img = concat_imgs(subject_data.func) # type: ignore
598
+ # Use the ParcelAggregation object on the original parcellation
599
+ marker_original = ParcelAggregation(
600
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
601
+ method="mean",
602
+ name="tian_mean",
603
+ on="BOLD",
604
+ )
605
+ orig_mean = marker_original.fit_transform(element_data)["BOLD"]
606
+
607
+ orig_mean_data = orig_mean["data"]
608
+ assert orig_mean_data.ndim == 2
609
+ assert orig_mean_data.shape == (1, 16)
610
+
611
+ # Use the ParcelAggregation object on the two parcellations
612
+ marker_split = ParcelAggregation(
613
+ parcellation=[
614
+ "TianxS1x3TxMNInonlinear2009cAsym_low",
615
+ "TianxS1x3TxMNInonlinear2009cAsym_high",
616
+ ],
617
+ method="mean",
618
+ name="tian_mean",
619
+ on="BOLD",
620
+ )
595
621
 
596
- # Create NiftiLabelsMasker
597
- nifti_masker = NiftiLabelsMasker(labels_img=parcellation.maps)
598
- auto4d = nifti_masker.fit_transform(fmri_img)
599
- auto_mean = auto4d.mean(axis=0)
622
+ # Warning should be raised
623
+ with pytest.warns(RuntimeWarning, match="duplicated labels."):
624
+ split_mean = marker_split.fit_transform(element_data)["BOLD"]
600
625
 
601
- # Create ParcelAggregation object
602
- marker = ParcelAggregation(
603
- parcellation="Schaefer100x7", method="mean", time_method="mean"
604
- )
605
- input = {"BOLD": {"data": fmri_img, "meta": {}, "space": "MNI"}}
606
- jun_values4d = marker.fit_transform(input)["BOLD"]["data"]
626
+ split_mean_data = split_mean["data"]
607
627
 
608
- assert jun_values4d.ndim == 1
609
- assert_array_equal(auto_mean.shape, jun_values4d.shape)
610
- assert_array_almost_equal(auto_mean, jun_values4d, decimal=2)
628
+ assert split_mean_data.ndim == 2
629
+ assert split_mean_data.shape == (1, 16)
611
630
 
612
- auto_pick_0 = auto4d[:1, :]
613
- marker = ParcelAggregation(
614
- parcellation="Schaefer100x7",
615
- method="mean",
616
- time_method="select",
617
- time_method_params={"pick": [0]},
618
- )
631
+ # Data should be the same
632
+ assert_array_equal(orig_mean_data, split_mean_data)
619
633
 
620
- input = {"BOLD": {"data": fmri_img, "meta": {}, "space": "MNI"}}
621
- jun_values4d = marker.fit_transform(input)["BOLD"]["data"]
634
+ # Labels should be prefixed with the parcellation name
635
+ col_names = [
636
+ f"TianxS1x3TxMNInonlinear2009cAsym_low_{x}" for x in labels1
637
+ ]
638
+ col_names += [
639
+ f"TianxS1x3TxMNInonlinear2009cAsym_high_{x}" for x in labels2
640
+ ]
641
+ assert col_names == split_mean["col_names"]
622
642
 
623
- assert jun_values4d.ndim == 2
624
- assert_array_equal(auto_pick_0.shape, jun_values4d.shape)
625
- assert_array_equal(auto_pick_0, jun_values4d)
626
643
 
644
+ def test_ParcelAggregation_4D_agg_time():
645
+ """Test ParcelAggregation object on 4D images, aggregating time."""
646
+ with PartlyCloudyTestingDataGrabber() as dg:
647
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
648
+ # Create ParcelAggregation object
649
+ marker = ParcelAggregation(
650
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
651
+ method="mean",
652
+ time_method="mean",
653
+ on="BOLD",
654
+ )
655
+ parcel_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
656
+ "data"
657
+ ]
658
+
659
+ # Compare with nilearn
660
+ # Loading testing parcellation
661
+ testing_parcellation, _ = get_parcellation(
662
+ parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
663
+ target_data=element_data["BOLD"],
664
+ )
665
+ # Extract data
666
+ nifti_labels_masker = NiftiLabelsMasker(
667
+ labels_img=testing_parcellation
668
+ )
669
+ nifti_labels_masked_bold = nifti_labels_masker.fit_transform(
670
+ element_data["BOLD"]["data"]
671
+ )
672
+ nifti_labels_masked_bold_mean = nifti_labels_masked_bold.mean(axis=0)
673
+
674
+ assert parcel_agg_bold_data.ndim == 1
675
+ assert_array_equal(
676
+ nifti_labels_masked_bold_mean.shape, parcel_agg_bold_data.shape
677
+ )
678
+ assert_array_almost_equal(
679
+ nifti_labels_masked_bold_mean, parcel_agg_bold_data, decimal=2
680
+ )
681
+
682
+ # Test picking first time point
683
+ nifti_labels_masked_bold_pick_0 = nifti_labels_masked_bold[:1, :]
684
+ marker = ParcelAggregation(
685
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
686
+ method="mean",
687
+ time_method="select",
688
+ time_method_params={"pick": [0]},
689
+ on="BOLD",
690
+ )
691
+ parcel_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
692
+ "data"
693
+ ]
694
+
695
+ assert parcel_agg_bold_data.ndim == 2
696
+ assert_array_equal(
697
+ nifti_labels_masked_bold_pick_0.shape, parcel_agg_bold_data.shape
698
+ )
699
+ assert_array_equal(
700
+ nifti_labels_masked_bold_pick_0, parcel_agg_bold_data
701
+ )
702
+
703
+
704
+ def test_ParcelAggregation_errors() -> None:
705
+ """Test errors for ParcelAggregation."""
627
706
  with pytest.raises(ValueError, match="can only be used with BOLD data"):
628
707
  ParcelAggregation(
629
708
  parcellation="Schaefer100x7",
@@ -643,12 +722,22 @@ def test_ParcelAggregation_4D_agg_time():
643
722
  on="VBM_GM",
644
723
  )
645
724
 
646
- with pytest.warns(RuntimeWarning, match="No time dimension to aggregate"):
647
- input = {
648
- "BOLD": {
649
- "data": fmri_img.slicer[..., 0:1],
650
- "meta": {},
651
- "space": "MNI",
652
- }
653
- }
654
- marker.fit_transform(input)
725
+
726
+ def test_ParcelAggregation_warning() -> None:
727
+ """Test warning for ParcelAggregation."""
728
+ with PartlyCloudyTestingDataGrabber() as dg:
729
+ element_data = DefaultDataReader().fit_transform(dg["sub-01"])
730
+ with pytest.warns(
731
+ RuntimeWarning, match="No time dimension to aggregate"
732
+ ):
733
+ marker = ParcelAggregation(
734
+ parcellation="TianxS1x3TxMNInonlinear2009cAsym",
735
+ method="mean",
736
+ time_method="select",
737
+ time_method_params={"pick": [0]},
738
+ on="BOLD",
739
+ )
740
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
741
+ ..., 0:1
742
+ ]
743
+ marker.fit_transform(element_data)