junifer 0.0.4.dev733__py3-none-any.whl → 0.0.4.dev781__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- junifer/_version.py +2 -2
- junifer/api/tests/data/partly_cloudy_agg_mean_tian.yml +16 -0
- junifer/api/tests/test_cli.py +7 -13
- junifer/api/tests/test_functions.py +156 -102
- junifer/data/coordinates.py +1 -1
- junifer/data/masks.py +213 -54
- junifer/data/parcellations.py +91 -42
- junifer/data/template_spaces.py +33 -6
- junifer/data/tests/test_masks.py +127 -62
- junifer/data/tests/test_parcellations.py +66 -49
- junifer/data/tests/test_template_spaces.py +42 -7
- junifer/datagrabber/aomic/id1000.py +3 -0
- junifer/datagrabber/aomic/piop1.py +3 -0
- junifer/datagrabber/aomic/piop2.py +3 -0
- junifer/datagrabber/dmcc13_benchmark.py +3 -0
- junifer/datagrabber/hcp1200/hcp1200.py +3 -0
- junifer/markers/falff/tests/test_falff_parcels.py +3 -3
- junifer/markers/falff/tests/test_falff_spheres.py +3 -3
- junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +46 -45
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +34 -41
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +40 -56
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +62 -74
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +99 -89
- junifer/markers/reho/tests/test_reho_parcels.py +17 -11
- junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +38 -37
- junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +34 -38
- junifer/markers/tests/test_collection.py +38 -37
- junifer/markers/tests/test_ets_rss.py +29 -41
- junifer/markers/tests/test_parcel_aggregation.py +600 -511
- junifer/markers/tests/test_sphere_aggregation.py +209 -163
- {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev781.dist-info}/METADATA +1 -1
- {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev781.dist-info}/RECORD +37 -36
- {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev781.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev781.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev781.dist-info}/WHEEL +0 -0
- {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev781.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.4.dev733.dist-info → junifer-0.0.4.dev781.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
|
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
|
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
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
129
|
-
|
130
|
-
|
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
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
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
|
-
|
154
|
-
|
155
|
-
|
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
|
-
#
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
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
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
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
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
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
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
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
|
-
|
286
|
-
|
287
|
-
|
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
|
-
|
290
|
-
|
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
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
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
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
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
|
-
|
398
|
-
|
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
|
-
|
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
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
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
|
-
|
408
|
-
|
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
|
-
|
414
|
-
|
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
|
-
|
420
|
-
|
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
|
-
|
423
|
-
|
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
|
-
|
426
|
-
nib.save(parcellation2_img, parcellation2_path)
|
520
|
+
split_mean_data = split_mean["data"]
|
427
521
|
|
428
|
-
|
429
|
-
|
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
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
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
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
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
|
-
|
544
|
-
|
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
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
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
|
-
|
593
|
-
|
594
|
-
|
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
|
-
|
597
|
-
|
598
|
-
|
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
|
-
|
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
|
-
|
609
|
-
|
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
|
-
|
613
|
-
|
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
|
-
|
621
|
-
|
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
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
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)
|