junifer 0.0.3.dev188__py3-none-any.whl → 0.0.4__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 +14 -2
- junifer/api/cli.py +162 -17
- junifer/api/functions.py +87 -419
- junifer/api/parser.py +24 -0
- junifer/api/queue_context/__init__.py +8 -0
- junifer/api/queue_context/gnu_parallel_local_adapter.py +258 -0
- junifer/api/queue_context/htcondor_adapter.py +365 -0
- junifer/api/queue_context/queue_context_adapter.py +60 -0
- junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +192 -0
- junifer/api/queue_context/tests/test_htcondor_adapter.py +257 -0
- junifer/api/res/afni/run_afni_docker.sh +6 -6
- junifer/api/res/ants/ResampleImage +3 -0
- junifer/api/res/ants/antsApplyTransforms +3 -0
- junifer/api/res/ants/antsApplyTransformsToPoints +3 -0
- junifer/api/res/ants/run_ants_docker.sh +39 -0
- junifer/api/res/fsl/applywarp +3 -0
- junifer/api/res/fsl/flirt +3 -0
- junifer/api/res/fsl/img2imgcoord +3 -0
- junifer/api/res/fsl/run_fsl_docker.sh +39 -0
- junifer/api/res/fsl/std2imgcoord +3 -0
- junifer/api/res/run_conda.sh +4 -4
- junifer/api/res/run_venv.sh +22 -0
- junifer/api/tests/data/partly_cloudy_agg_mean_tian.yml +16 -0
- junifer/api/tests/test_api_utils.py +21 -3
- junifer/api/tests/test_cli.py +232 -9
- junifer/api/tests/test_functions.py +211 -439
- junifer/api/tests/test_parser.py +1 -1
- junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +6 -1
- junifer/configs/juseless/datagrabbers/camcan_vbm.py +6 -1
- junifer/configs/juseless/datagrabbers/ixi_vbm.py +6 -1
- junifer/configs/juseless/datagrabbers/tests/test_ucla.py +8 -8
- junifer/configs/juseless/datagrabbers/ucla.py +44 -26
- junifer/configs/juseless/datagrabbers/ukb_vbm.py +6 -1
- junifer/data/VOIs/meta/AutobiographicalMemory_VOIs.txt +23 -0
- junifer/data/VOIs/meta/Power2013_MNI_VOIs.tsv +264 -0
- junifer/data/__init__.py +4 -0
- junifer/data/coordinates.py +298 -31
- junifer/data/masks.py +360 -28
- junifer/data/parcellations.py +621 -188
- junifer/data/template_spaces.py +190 -0
- junifer/data/tests/test_coordinates.py +34 -3
- junifer/data/tests/test_data_utils.py +1 -0
- junifer/data/tests/test_masks.py +202 -86
- junifer/data/tests/test_parcellations.py +266 -55
- junifer/data/tests/test_template_spaces.py +104 -0
- junifer/data/utils.py +4 -2
- junifer/datagrabber/__init__.py +1 -0
- junifer/datagrabber/aomic/id1000.py +111 -70
- junifer/datagrabber/aomic/piop1.py +116 -53
- junifer/datagrabber/aomic/piop2.py +116 -53
- junifer/datagrabber/aomic/tests/test_id1000.py +27 -27
- junifer/datagrabber/aomic/tests/test_piop1.py +27 -27
- junifer/datagrabber/aomic/tests/test_piop2.py +27 -27
- junifer/datagrabber/base.py +62 -10
- junifer/datagrabber/datalad_base.py +0 -2
- junifer/datagrabber/dmcc13_benchmark.py +372 -0
- junifer/datagrabber/hcp1200/datalad_hcp1200.py +5 -0
- junifer/datagrabber/hcp1200/hcp1200.py +30 -13
- junifer/datagrabber/pattern.py +133 -27
- junifer/datagrabber/pattern_datalad.py +111 -13
- junifer/datagrabber/tests/test_base.py +57 -6
- junifer/datagrabber/tests/test_datagrabber_utils.py +204 -76
- junifer/datagrabber/tests/test_datalad_base.py +0 -6
- junifer/datagrabber/tests/test_dmcc13_benchmark.py +256 -0
- junifer/datagrabber/tests/test_multiple.py +43 -10
- junifer/datagrabber/tests/test_pattern.py +125 -178
- junifer/datagrabber/tests/test_pattern_datalad.py +44 -25
- junifer/datagrabber/utils.py +151 -16
- junifer/datareader/default.py +36 -10
- junifer/external/nilearn/junifer_nifti_spheres_masker.py +6 -0
- junifer/markers/base.py +25 -16
- junifer/markers/collection.py +35 -16
- junifer/markers/complexity/__init__.py +27 -0
- junifer/markers/complexity/complexity_base.py +149 -0
- junifer/markers/complexity/hurst_exponent.py +136 -0
- junifer/markers/complexity/multiscale_entropy_auc.py +140 -0
- junifer/markers/complexity/perm_entropy.py +132 -0
- junifer/markers/complexity/range_entropy.py +136 -0
- junifer/markers/complexity/range_entropy_auc.py +145 -0
- junifer/markers/complexity/sample_entropy.py +134 -0
- junifer/markers/complexity/tests/test_complexity_base.py +19 -0
- junifer/markers/complexity/tests/test_hurst_exponent.py +69 -0
- junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +68 -0
- junifer/markers/complexity/tests/test_perm_entropy.py +68 -0
- junifer/markers/complexity/tests/test_range_entropy.py +69 -0
- junifer/markers/complexity/tests/test_range_entropy_auc.py +69 -0
- junifer/markers/complexity/tests/test_sample_entropy.py +68 -0
- junifer/markers/complexity/tests/test_weighted_perm_entropy.py +68 -0
- junifer/markers/complexity/weighted_perm_entropy.py +133 -0
- junifer/markers/falff/_afni_falff.py +153 -0
- junifer/markers/falff/_junifer_falff.py +142 -0
- junifer/markers/falff/falff_base.py +91 -84
- junifer/markers/falff/falff_parcels.py +61 -45
- junifer/markers/falff/falff_spheres.py +64 -48
- junifer/markers/falff/tests/test_falff_parcels.py +89 -121
- junifer/markers/falff/tests/test_falff_spheres.py +92 -127
- junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +1 -0
- junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +1 -0
- junifer/markers/functional_connectivity/functional_connectivity_base.py +1 -0
- junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +46 -44
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +34 -39
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +40 -52
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +62 -70
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +99 -85
- junifer/markers/parcel_aggregation.py +60 -38
- junifer/markers/reho/_afni_reho.py +192 -0
- junifer/markers/reho/_junifer_reho.py +281 -0
- junifer/markers/reho/reho_base.py +69 -34
- junifer/markers/reho/reho_parcels.py +26 -16
- junifer/markers/reho/reho_spheres.py +23 -9
- junifer/markers/reho/tests/test_reho_parcels.py +93 -92
- junifer/markers/reho/tests/test_reho_spheres.py +88 -86
- junifer/markers/sphere_aggregation.py +54 -9
- junifer/markers/temporal_snr/temporal_snr_base.py +1 -0
- 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 +43 -42
- junifer/markers/tests/test_ets_rss.py +29 -37
- junifer/markers/tests/test_parcel_aggregation.py +587 -468
- junifer/markers/tests/test_sphere_aggregation.py +209 -157
- junifer/markers/utils.py +2 -40
- junifer/onthefly/read_transform.py +13 -6
- junifer/pipeline/__init__.py +1 -0
- junifer/pipeline/pipeline_step_mixin.py +105 -41
- junifer/pipeline/registry.py +17 -0
- junifer/pipeline/singleton.py +45 -0
- junifer/pipeline/tests/test_pipeline_step_mixin.py +139 -51
- junifer/pipeline/tests/test_update_meta_mixin.py +1 -0
- junifer/pipeline/tests/test_workdir_manager.py +104 -0
- junifer/pipeline/update_meta_mixin.py +8 -2
- junifer/pipeline/utils.py +154 -15
- junifer/pipeline/workdir_manager.py +246 -0
- junifer/preprocess/__init__.py +3 -0
- junifer/preprocess/ants/__init__.py +4 -0
- junifer/preprocess/ants/ants_apply_transforms_warper.py +185 -0
- junifer/preprocess/ants/tests/test_ants_apply_transforms_warper.py +56 -0
- junifer/preprocess/base.py +96 -69
- junifer/preprocess/bold_warper.py +265 -0
- junifer/preprocess/confounds/fmriprep_confound_remover.py +91 -134
- junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +106 -111
- junifer/preprocess/fsl/__init__.py +4 -0
- junifer/preprocess/fsl/apply_warper.py +179 -0
- junifer/preprocess/fsl/tests/test_apply_warper.py +45 -0
- junifer/preprocess/tests/test_bold_warper.py +159 -0
- junifer/preprocess/tests/test_preprocess_base.py +6 -6
- junifer/preprocess/warping/__init__.py +6 -0
- junifer/preprocess/warping/_ants_warper.py +167 -0
- junifer/preprocess/warping/_fsl_warper.py +109 -0
- junifer/preprocess/warping/space_warper.py +213 -0
- junifer/preprocess/warping/tests/test_space_warper.py +198 -0
- junifer/stats.py +18 -4
- junifer/storage/base.py +9 -1
- junifer/storage/hdf5.py +8 -3
- junifer/storage/pandas_base.py +2 -1
- junifer/storage/sqlite.py +1 -0
- junifer/storage/tests/test_hdf5.py +2 -1
- junifer/storage/tests/test_sqlite.py +8 -8
- junifer/storage/tests/test_utils.py +6 -6
- junifer/storage/utils.py +1 -0
- junifer/testing/datagrabbers.py +11 -7
- junifer/testing/utils.py +1 -0
- junifer/tests/test_stats.py +2 -0
- junifer/utils/__init__.py +1 -0
- junifer/utils/helpers.py +53 -0
- junifer/utils/logging.py +14 -3
- junifer/utils/tests/test_helpers.py +35 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/METADATA +59 -28
- junifer-0.0.4.dist-info/RECORD +257 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/WHEEL +1 -1
- junifer/markers/falff/falff_estimator.py +0 -334
- junifer/markers/falff/tests/test_falff_estimator.py +0 -238
- junifer/markers/reho/reho_estimator.py +0 -515
- junifer/markers/reho/tests/test_reho_estimator.py +0 -260
- junifer-0.0.3.dev188.dist-info/RECORD +0 -199
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.3.dev188.dist-info → junifer-0.0.4.dist-info}/top_level.txt +0 -0
@@ -1,22 +1,23 @@
|
|
1
1
|
"""Provide tests for sphere aggregation."""
|
2
2
|
|
3
3
|
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
|
4
|
+
# Synchon Mandal <s.mandal@fz-juelich.de>
|
4
5
|
# License: AGPL
|
5
6
|
|
6
|
-
import typing
|
7
7
|
from pathlib import Path
|
8
|
-
from typing import Dict
|
9
8
|
|
10
|
-
import nibabel as nib
|
11
9
|
import pytest
|
12
|
-
from nilearn import datasets
|
13
|
-
from nilearn.image import concat_imgs
|
14
10
|
from nilearn.maskers import NiftiSpheresMasker
|
15
11
|
from numpy.testing import assert_array_equal
|
16
12
|
|
17
|
-
from junifer.data import
|
13
|
+
from junifer.data import get_coordinates, get_mask
|
14
|
+
from junifer.datareader import DefaultDataReader
|
18
15
|
from junifer.markers.sphere_aggregation import SphereAggregation
|
19
16
|
from junifer.storage import SQLiteFeatureStorage
|
17
|
+
from junifer.testing.datagrabbers import (
|
18
|
+
OasisVBMTestingDataGrabber,
|
19
|
+
SPMAuditoryTestingDataGrabber,
|
20
|
+
)
|
20
21
|
|
21
22
|
|
22
23
|
# Define common variables
|
@@ -36,51 +37,66 @@ def test_SphereAggregation_input_output() -> None:
|
|
36
37
|
|
37
38
|
def test_SphereAggregation_3D() -> None:
|
38
39
|
"""Test SphereAggregation object on 3D images."""
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
40
|
+
with OasisVBMTestingDataGrabber() as dg:
|
41
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
42
|
+
# Create SphereAggregation object
|
43
|
+
marker = SphereAggregation(
|
44
|
+
coords=COORDS, method="mean", radius=RADIUS, on="VBM_GM"
|
45
|
+
)
|
46
|
+
sphere_agg_vbm_gm_data = marker.fit_transform(element_data)["VBM_GM"][
|
47
|
+
"data"
|
48
|
+
]
|
49
|
+
|
50
|
+
# Compare with nilearn
|
51
|
+
# Load testing coordinates
|
52
|
+
testing_coords, _ = get_coordinates(
|
53
|
+
coords=COORDS, target_data=element_data["VBM_GM"]
|
54
|
+
)
|
55
|
+
# Extract data
|
56
|
+
nifti_spheres_masker = NiftiSpheresMasker(
|
57
|
+
seeds=testing_coords, radius=RADIUS
|
58
|
+
)
|
59
|
+
nifti_spheres_masked_vbm_gm = nifti_spheres_masker.fit_transform(
|
60
|
+
element_data["VBM_GM"]["data"]
|
61
|
+
)
|
57
62
|
|
58
|
-
|
59
|
-
|
60
|
-
|
63
|
+
assert sphere_agg_vbm_gm_data.ndim == 2
|
64
|
+
assert_array_equal(
|
65
|
+
nifti_spheres_masked_vbm_gm.shape, sphere_agg_vbm_gm_data.shape
|
66
|
+
)
|
67
|
+
assert_array_equal(nifti_spheres_masked_vbm_gm, sphere_agg_vbm_gm_data)
|
61
68
|
|
62
69
|
|
63
70
|
def test_SphereAggregation_4D() -> None:
|
64
71
|
"""Test SphereAggregation object on 4D images."""
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
72
|
+
with SPMAuditoryTestingDataGrabber() as dg:
|
73
|
+
element_data = DefaultDataReader().fit_transform(dg["sub001"])
|
74
|
+
# Create SphereAggregation object
|
75
|
+
marker = SphereAggregation(
|
76
|
+
coords=COORDS, method="mean", radius=RADIUS, on="BOLD"
|
77
|
+
)
|
78
|
+
sphere_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
|
79
|
+
"data"
|
80
|
+
]
|
81
|
+
|
82
|
+
# Compare with nilearn
|
83
|
+
# Load testing coordinates
|
84
|
+
testing_coords, _ = get_coordinates(
|
85
|
+
coords=COORDS, target_data=element_data["BOLD"]
|
86
|
+
)
|
87
|
+
# Extract data
|
88
|
+
nifti_spheres_masker = NiftiSpheresMasker(
|
89
|
+
seeds=testing_coords, radius=RADIUS
|
90
|
+
)
|
91
|
+
nifti_spheres_masked_bold = nifti_spheres_masker.fit_transform(
|
92
|
+
element_data["BOLD"]["data"]
|
93
|
+
)
|
80
94
|
|
81
|
-
|
82
|
-
|
83
|
-
|
95
|
+
assert sphere_agg_bold_data.ndim == 2
|
96
|
+
assert_array_equal(
|
97
|
+
nifti_spheres_masked_bold.shape, sphere_agg_bold_data.shape
|
98
|
+
)
|
99
|
+
assert_array_equal(nifti_spheres_masked_bold, sphere_agg_bold_data)
|
84
100
|
|
85
101
|
|
86
102
|
def test_SphereAggregation_storage(tmp_path: Path) -> None:
|
@@ -92,124 +108,143 @@ def test_SphereAggregation_storage(tmp_path: Path) -> None:
|
|
92
108
|
The path to the test directory.
|
93
109
|
|
94
110
|
"""
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
fmri_img = concat_imgs(subject_data.func) # type: ignore
|
125
|
-
input = {"BOLD": {"data": fmri_img, "meta": meta}}
|
126
|
-
marker = SphereAggregation(
|
127
|
-
coords=COORDS, method="mean", radius=RADIUS, on="BOLD"
|
128
|
-
)
|
129
|
-
|
130
|
-
marker.fit_transform(input, storage=storage)
|
131
|
-
features: Dict = typing.cast(Dict, storage.list_features())
|
132
|
-
assert any(
|
133
|
-
x["name"] == "BOLD_SphereAggregation" for x in features.values()
|
134
|
-
)
|
111
|
+
# Store 3D
|
112
|
+
with OasisVBMTestingDataGrabber() as dg:
|
113
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
114
|
+
storage = SQLiteFeatureStorage(
|
115
|
+
uri=tmp_path / "test_sphere_storage_3D.sqlite", upsert="ignore"
|
116
|
+
)
|
117
|
+
marker = SphereAggregation(
|
118
|
+
coords=COORDS, method="mean", radius=RADIUS, on="VBM_GM"
|
119
|
+
)
|
120
|
+
marker.fit_transform(input=element_data, storage=storage)
|
121
|
+
features = storage.list_features()
|
122
|
+
assert any(
|
123
|
+
x["name"] == "VBM_GM_SphereAggregation" for x in features.values()
|
124
|
+
)
|
125
|
+
|
126
|
+
# Store 4D
|
127
|
+
with SPMAuditoryTestingDataGrabber() as dg:
|
128
|
+
element_data = DefaultDataReader().fit_transform(dg["sub001"])
|
129
|
+
storage = SQLiteFeatureStorage(
|
130
|
+
uri=tmp_path / "test_sphere_storage_4D.sqlite", upsert="ignore"
|
131
|
+
)
|
132
|
+
marker = SphereAggregation(
|
133
|
+
coords=COORDS, method="mean", radius=RADIUS, on="BOLD"
|
134
|
+
)
|
135
|
+
marker.fit_transform(input=element_data, storage=storage)
|
136
|
+
features = storage.list_features()
|
137
|
+
assert any(
|
138
|
+
x["name"] == "BOLD_SphereAggregation" for x in features.values()
|
139
|
+
)
|
135
140
|
|
136
141
|
|
137
142
|
def test_SphereAggregation_3D_mask() -> None:
|
138
143
|
"""Test SphereAggregation object on 3D images using mask."""
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
144
|
+
with OasisVBMTestingDataGrabber() as dg:
|
145
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
146
|
+
# Create SphereAggregation object
|
147
|
+
marker = SphereAggregation(
|
148
|
+
coords=COORDS,
|
149
|
+
method="mean",
|
150
|
+
radius=RADIUS,
|
151
|
+
on="VBM_GM",
|
152
|
+
masks="compute_brain_mask",
|
153
|
+
)
|
154
|
+
sphere_agg_vbm_gm_data = marker.fit_transform(element_data)["VBM_GM"][
|
155
|
+
"data"
|
156
|
+
]
|
157
|
+
|
158
|
+
# Compare with nilearn
|
159
|
+
# Load testing coordinates
|
160
|
+
testing_coords, _ = get_coordinates(
|
161
|
+
coords=COORDS, target_data=element_data["VBM_GM"]
|
162
|
+
)
|
163
|
+
# Load mask
|
164
|
+
mask_img = get_mask(
|
165
|
+
"compute_brain_mask", target_data=element_data["VBM_GM"]
|
166
|
+
)
|
167
|
+
# Extract data
|
168
|
+
nifti_spheres_masker = NiftiSpheresMasker(
|
169
|
+
seeds=testing_coords, radius=RADIUS, mask_img=mask_img
|
170
|
+
)
|
171
|
+
nifti_spheres_masked_vbm_agg = nifti_spheres_masker.fit_transform(
|
172
|
+
element_data["VBM_GM"]["data"]
|
173
|
+
)
|
174
|
+
|
175
|
+
assert sphere_agg_vbm_gm_data.ndim == 2
|
176
|
+
assert_array_equal(
|
177
|
+
nifti_spheres_masked_vbm_agg.shape,
|
178
|
+
nifti_spheres_masked_vbm_agg.shape,
|
179
|
+
)
|
180
|
+
assert_array_equal(
|
181
|
+
nifti_spheres_masked_vbm_agg, nifti_spheres_masked_vbm_agg
|
182
|
+
)
|
170
183
|
|
171
184
|
|
172
185
|
def test_SphereAggregation_4D_agg_time() -> None:
|
173
186
|
"""Test SphereAggregation object on 4D images, aggregating time."""
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
radius=RADIUS,
|
202
|
-
time_method="select",
|
203
|
-
time_method_params={"pick": [0]},
|
204
|
-
)
|
205
|
-
|
206
|
-
input = {"BOLD": {"data": fmri_img, "meta": {}}}
|
207
|
-
jun_values4d = marker.fit_transform(input)["BOLD"]["data"]
|
208
|
-
|
209
|
-
assert jun_values4d.ndim == 2
|
210
|
-
assert_array_equal(auto_pick_0.shape, jun_values4d.shape)
|
211
|
-
assert_array_equal(auto_pick_0, jun_values4d)
|
187
|
+
with SPMAuditoryTestingDataGrabber() as dg:
|
188
|
+
element_data = DefaultDataReader().fit_transform(dg["sub001"])
|
189
|
+
# Create SphereAggregation object
|
190
|
+
marker = SphereAggregation(
|
191
|
+
coords=COORDS,
|
192
|
+
method="mean",
|
193
|
+
radius=RADIUS,
|
194
|
+
time_method="mean",
|
195
|
+
on="BOLD",
|
196
|
+
)
|
197
|
+
sphere_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
|
198
|
+
"data"
|
199
|
+
]
|
200
|
+
|
201
|
+
# Compare with nilearn
|
202
|
+
# Load testing coordinates
|
203
|
+
testing_coords, _ = get_coordinates(
|
204
|
+
coords=COORDS, target_data=element_data["BOLD"]
|
205
|
+
)
|
206
|
+
# Extract data
|
207
|
+
nifti_spheres_masker = NiftiSpheresMasker(
|
208
|
+
seeds=testing_coords, radius=RADIUS
|
209
|
+
)
|
210
|
+
nifti_spheres_masked_bold = nifti_spheres_masker.fit_transform(
|
211
|
+
element_data["BOLD"]["data"]
|
212
|
+
)
|
213
|
+
nifti_spheres_masked_bold_mean = nifti_spheres_masked_bold.mean(axis=0)
|
212
214
|
|
215
|
+
assert sphere_agg_bold_data.ndim == 1
|
216
|
+
assert_array_equal(
|
217
|
+
nifti_spheres_masked_bold_mean.shape, sphere_agg_bold_data.shape
|
218
|
+
)
|
219
|
+
assert_array_equal(
|
220
|
+
nifti_spheres_masked_bold_mean, sphere_agg_bold_data
|
221
|
+
)
|
222
|
+
|
223
|
+
# Test picking first time point
|
224
|
+
nifti_spheres_masked_bold_pick_0 = nifti_spheres_masked_bold[:1, :]
|
225
|
+
marker = SphereAggregation(
|
226
|
+
coords=COORDS,
|
227
|
+
method="mean",
|
228
|
+
radius=RADIUS,
|
229
|
+
time_method="select",
|
230
|
+
time_method_params={"pick": [0]},
|
231
|
+
on="BOLD",
|
232
|
+
)
|
233
|
+
sphere_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
|
234
|
+
"data"
|
235
|
+
]
|
236
|
+
|
237
|
+
assert sphere_agg_bold_data.ndim == 2
|
238
|
+
assert_array_equal(
|
239
|
+
nifti_spheres_masked_bold_pick_0.shape, sphere_agg_bold_data.shape
|
240
|
+
)
|
241
|
+
assert_array_equal(
|
242
|
+
nifti_spheres_masked_bold_pick_0, sphere_agg_bold_data
|
243
|
+
)
|
244
|
+
|
245
|
+
|
246
|
+
def test_SphereAggregation_errors() -> None:
|
247
|
+
"""Test errors for SphereAggregation."""
|
213
248
|
with pytest.raises(ValueError, match="can only be used with BOLD data"):
|
214
249
|
SphereAggregation(
|
215
250
|
coords=COORDS,
|
@@ -231,6 +266,23 @@ def test_SphereAggregation_4D_agg_time() -> None:
|
|
231
266
|
on="VBM_GM",
|
232
267
|
)
|
233
268
|
|
234
|
-
|
235
|
-
|
236
|
-
|
269
|
+
|
270
|
+
def test_SphereAggregation_warning() -> None:
|
271
|
+
"""Test warning for SphereAggregation."""
|
272
|
+
with SPMAuditoryTestingDataGrabber() as dg:
|
273
|
+
element_data = DefaultDataReader().fit_transform(dg["sub001"])
|
274
|
+
with pytest.warns(
|
275
|
+
RuntimeWarning, match="No time dimension to aggregate"
|
276
|
+
):
|
277
|
+
marker = SphereAggregation(
|
278
|
+
coords=COORDS,
|
279
|
+
method="mean",
|
280
|
+
radius=RADIUS,
|
281
|
+
time_method="select",
|
282
|
+
time_method_params={"pick": [0]},
|
283
|
+
on="BOLD",
|
284
|
+
)
|
285
|
+
element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
|
286
|
+
..., 0:1
|
287
|
+
]
|
288
|
+
marker.fit_transform(element_data)
|
junifer/markers/utils.py
CHANGED
@@ -5,9 +5,10 @@
|
|
5
5
|
# Sami Hamdan <s.hamdan@fz-juelich.de>
|
6
6
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
7
7
|
# Federico Raimondo <f.raimondo@fz-juelich.de>
|
8
|
+
# Amir Omidvarnia <a.omidvarnia@fz-juelich.de>
|
8
9
|
# License: AGPL
|
9
10
|
|
10
|
-
from typing import
|
11
|
+
from typing import Callable, List, Optional, Tuple, Union
|
11
12
|
|
12
13
|
import numpy as np
|
13
14
|
import pandas as pd
|
@@ -16,45 +17,6 @@ from scipy.stats import zscore
|
|
16
17
|
from ..utils import raise_error
|
17
18
|
|
18
19
|
|
19
|
-
def singleton(cls: Type) -> Type:
|
20
|
-
"""Make a class singleton.
|
21
|
-
|
22
|
-
Parameters
|
23
|
-
----------
|
24
|
-
cls : class
|
25
|
-
The class to designate as singleton.
|
26
|
-
|
27
|
-
Returns
|
28
|
-
-------
|
29
|
-
class
|
30
|
-
The only instance of the class.
|
31
|
-
|
32
|
-
"""
|
33
|
-
instances: Dict = {}
|
34
|
-
|
35
|
-
def get_instance(*args: Any, **kwargs: Any) -> Type:
|
36
|
-
"""Get the only instance for a class.
|
37
|
-
|
38
|
-
Parameters
|
39
|
-
----------
|
40
|
-
*args : tuple
|
41
|
-
The positional arguments to pass to the class.
|
42
|
-
**kwargs : dict
|
43
|
-
The keyword arguments to pass to the class.
|
44
|
-
|
45
|
-
Returns
|
46
|
-
-------
|
47
|
-
class
|
48
|
-
The only instance of the class.
|
49
|
-
|
50
|
-
"""
|
51
|
-
if cls not in instances:
|
52
|
-
instances[cls] = cls(*args, **kwargs)
|
53
|
-
return instances[cls]
|
54
|
-
|
55
|
-
return get_instance
|
56
|
-
|
57
|
-
|
58
20
|
def _ets(
|
59
21
|
bold_ts: np.ndarray,
|
60
22
|
roi_names: Union[None, List[str]] = None,
|
@@ -17,8 +17,9 @@ if TYPE_CHECKING:
|
|
17
17
|
|
18
18
|
def read_transform(
|
19
19
|
storage: Type["BaseFeatureStorage"],
|
20
|
-
feature_name: str,
|
21
20
|
transform: str,
|
21
|
+
feature_name: Optional[str] = None,
|
22
|
+
feature_md5: Optional[str] = None,
|
22
23
|
transform_args: Optional[Tuple] = None,
|
23
24
|
transform_kw_args: Optional[Dict] = None,
|
24
25
|
) -> pd.DataFrame:
|
@@ -28,11 +29,13 @@ def read_transform(
|
|
28
29
|
----------
|
29
30
|
storage : storage-like
|
30
31
|
The storage class, for example, SQLiteFeatureStorage.
|
31
|
-
feature_name : str
|
32
|
-
Name of the feature to read.
|
33
32
|
transform : str
|
34
33
|
The kind of transform formatted as ``<package>_<function>``,
|
35
34
|
for example, ``bctpy_degrees_und``.
|
35
|
+
feature_name : str, optional
|
36
|
+
Name of the feature to read (default None).
|
37
|
+
feature_md5 : str, optional
|
38
|
+
MD5 hash of the feature to read (default None).
|
36
39
|
transform_args : tuple, optional
|
37
40
|
The positional arguments for the callable of ``transform``
|
38
41
|
(default None).
|
@@ -62,7 +65,9 @@ def read_transform(
|
|
62
65
|
transform_kw_args = transform_kw_args or {}
|
63
66
|
|
64
67
|
# Read storage
|
65
|
-
stored_data = storage.read(
|
68
|
+
stored_data = storage.read(
|
69
|
+
feature_name=feature_name, feature_md5=feature_md5
|
70
|
+
) # type: ignore
|
66
71
|
# Retrieve package and function
|
67
72
|
package, func_str = transform.split("_", 1)
|
68
73
|
# Condition for package
|
@@ -105,7 +110,8 @@ def read_transform(
|
|
105
110
|
# Apply function and store subject-wise
|
106
111
|
output_list = []
|
107
112
|
logger.debug(
|
108
|
-
f"Computing '{package}.{func_str}' for feature
|
113
|
+
f"Computing '{package}.{func_str}' for feature "
|
114
|
+
f"{feature_name or feature_md5} ..."
|
109
115
|
)
|
110
116
|
for subject in range(stored_data["data"].shape[2]):
|
111
117
|
output = func(
|
@@ -119,7 +125,8 @@ def read_transform(
|
|
119
125
|
idx_df = pd.DataFrame(data=stored_data["element"])
|
120
126
|
# Create multiindex from dataframe
|
121
127
|
logger.debug(
|
122
|
-
|
128
|
+
"Generating pandas.MultiIndex for feature "
|
129
|
+
f"{feature_name or feature_md5} ..."
|
123
130
|
)
|
124
131
|
data_idx = pd.MultiIndex.from_frame(df=idx_df)
|
125
132
|
|
junifer/pipeline/__init__.py
CHANGED