junifer 0.0.7.dev332__py3-none-any.whl → 0.0.8__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 +9 -19
- junifer/api/__init__.pyi +17 -2
- junifer/api/functions.py +222 -39
- junifer/api/queue_context/__init__.pyi +11 -3
- junifer/api/queue_context/gnu_parallel_local_adapter.py +81 -120
- junifer/api/queue_context/htcondor_adapter.py +118 -181
- junifer/api/queue_context/queue_context_adapter.py +51 -7
- junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +10 -35
- junifer/api/queue_context/tests/test_htcondor_adapter.py +13 -50
- junifer/api/res/fsl/run_fsl_docker.sh +4 -0
- junifer/api/tests/test_functions.py +863 -36
- junifer/cli/__init__.py +1 -7
- junifer/cli/cli.py +41 -22
- junifer/cli/parser.py +23 -147
- junifer/cli/tests/data/gmd_mean.yaml +6 -6
- junifer/cli/tests/data/gmd_mean_htcondor.yaml +6 -5
- junifer/cli/tests/data/partly_cloudy_agg_mean_tian.yml +1 -0
- junifer/cli/tests/test_cli.py +120 -4
- junifer/cli/tests/test_cli_utils.py +23 -6
- junifer/cli/utils.py +14 -9
- junifer/configs/__init__.py +5 -0
- junifer/configs/__init__.pyi +0 -0
- junifer/configs/juseless/datagrabbers/__init__.pyi +4 -2
- junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +18 -24
- junifer/configs/juseless/datagrabbers/camcan_vbm.py +20 -27
- junifer/configs/juseless/datagrabbers/ixi_vbm.py +44 -52
- junifer/configs/juseless/datagrabbers/tests/test_ixi_vbm.py +0 -7
- junifer/configs/juseless/datagrabbers/tests/test_ucla.py +2 -19
- junifer/configs/juseless/datagrabbers/ucla.py +111 -104
- junifer/configs/juseless/datagrabbers/ukb_vbm.py +19 -25
- junifer/configs/py.typed +0 -0
- junifer/conftest.py +63 -24
- junifer/data/_dispatch.py +9 -19
- junifer/data/coordinates/_ants_coordinates_warper.py +4 -1
- junifer/data/coordinates/_coordinates.py +51 -6
- junifer/data/coordinates/_fsl_coordinates_warper.py +4 -1
- junifer/data/coordinates/tests/test_coordinates.py +15 -3
- junifer/data/coordinates/tests/test_coordinates_names.py +37 -0
- junifer/data/maps/_ants_maps_warper.py +18 -12
- junifer/data/maps/_fsl_maps_warper.py +7 -3
- junifer/data/maps/_maps.py +12 -8
- junifer/data/maps/tests/test_maps.py +13 -21
- junifer/data/masks/_ants_mask_warper.py +18 -12
- junifer/data/masks/_fsl_mask_warper.py +7 -3
- junifer/data/masks/_masks.py +15 -12
- junifer/data/masks/tests/test_masks.py +20 -17
- junifer/data/parcellations/_ants_parcellation_warper.py +18 -12
- junifer/data/parcellations/_fsl_parcellation_warper.py +7 -5
- junifer/data/parcellations/_parcellations.py +125 -91
- junifer/data/parcellations/tests/test_parcellations.py +122 -1
- junifer/data/template_spaces.py +117 -50
- junifer/data/tests/test_template_spaces.py +10 -7
- junifer/data/utils.py +10 -8
- junifer/datagrabber/__init__.pyi +38 -5
- junifer/datagrabber/aomic/__init__.pyi +8 -1
- junifer/datagrabber/aomic/_types.py +22 -0
- junifer/datagrabber/aomic/id1000.py +193 -183
- junifer/datagrabber/aomic/piop1.py +215 -259
- junifer/datagrabber/aomic/piop2.py +211 -244
- junifer/datagrabber/aomic/tests/test_id1000.py +70 -53
- junifer/datagrabber/aomic/tests/test_piop1.py +98 -102
- junifer/datagrabber/aomic/tests/test_piop2.py +88 -85
- junifer/datagrabber/base.py +253 -79
- junifer/datagrabber/datalad_base.py +127 -76
- junifer/datagrabber/dmcc13_benchmark.py +204 -289
- junifer/datagrabber/hcp1200/__init__.pyi +7 -2
- junifer/datagrabber/hcp1200/datalad_hcp1200.py +61 -40
- junifer/datagrabber/hcp1200/hcp1200.py +151 -164
- junifer/datagrabber/hcp1200/tests/test_hcp1200.py +116 -128
- junifer/datagrabber/multiple.py +183 -63
- junifer/datagrabber/pattern.py +358 -227
- junifer/datagrabber/pattern_datalad.py +84 -124
- junifer/datagrabber/pattern_validation_mixin.py +22 -50
- junifer/datagrabber/tests/test_base.py +17 -4
- junifer/datagrabber/tests/test_datalad_base.py +20 -27
- junifer/datagrabber/tests/test_dmcc13_benchmark.py +110 -122
- junifer/datagrabber/tests/test_multiple.py +293 -31
- junifer/datagrabber/tests/test_pattern.py +577 -18
- junifer/datagrabber/tests/test_pattern_datalad.py +177 -107
- junifer/datagrabber/tests/test_pattern_validation_mixin.py +9 -51
- junifer/datareader/default.py +8 -5
- junifer/datareader/tests/test_default_reader.py +1 -1
- junifer/external/BrainPrint/.codecov.yml +2 -0
- junifer/external/BrainPrint/.codespellignore +2 -0
- junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/bug-report.md +45 -0
- junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/documentation.md +12 -0
- junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/feature-request.md +24 -0
- junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/questions-help-support.md +28 -0
- junifer/external/BrainPrint/.github/dependabot.yml +6 -0
- junifer/external/BrainPrint/.github/workflows/build.yml +53 -0
- junifer/external/BrainPrint/.github/workflows/code-style.yml +44 -0
- junifer/external/BrainPrint/.github/workflows/doc.yml +65 -0
- junifer/external/BrainPrint/.github/workflows/publish.yml +31 -0
- junifer/external/BrainPrint/.github/workflows/pytest.yml +54 -0
- junifer/external/BrainPrint/.gitignore +123 -0
- junifer/external/BrainPrint/LICENSE +21 -0
- junifer/external/BrainPrint/README.md +108 -0
- junifer/external/BrainPrint/brainprint/cli/__init__.py +11 -0
- junifer/external/BrainPrint/brainprint/cli/help_text.py +169 -0
- junifer/external/BrainPrint/brainprint/cli/parser.py +150 -0
- junifer/external/BrainPrint/brainprint/cli/utils.py +14 -0
- junifer/external/BrainPrint/brainprint/commands/__init__.py +0 -0
- junifer/external/BrainPrint/brainprint/commands/sys_info.py +18 -0
- junifer/external/BrainPrint/brainprint/utils/tests/__init__.py +0 -0
- junifer/external/BrainPrint/brainprint/utils/tests/test_config.py +33 -0
- junifer/external/BrainPrint/doc/Makefile +20 -0
- junifer/external/BrainPrint/doc/_static/.gitkeep +0 -0
- junifer/external/BrainPrint/doc/_templates/autosummary/class.rst +10 -0
- junifer/external/BrainPrint/doc/_templates/autosummary/function.rst +8 -0
- junifer/external/BrainPrint/doc/_templates/autosummary/module.rst +6 -0
- junifer/external/BrainPrint/doc/api/index.rst +11 -0
- junifer/external/BrainPrint/doc/conf.py +272 -0
- junifer/external/BrainPrint/doc/index.rst +140 -0
- junifer/external/BrainPrint/doc/links.inc +36 -0
- junifer/external/BrainPrint/doc/make.bat +35 -0
- junifer/external/BrainPrint/doc/references.bib +23 -0
- junifer/external/BrainPrint/pyproject.toml +170 -0
- junifer/external/BrainPrint/setup.py +3 -0
- junifer/external/__init__.py +5 -0
- junifer/external/__init__.pyi +0 -0
- junifer/external/nilearn/junifer_connectivity_measure.py +95 -39
- junifer/external/nilearn/junifer_nifti_spheres_masker.py +226 -67
- junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +39 -27
- junifer/external/nilearn/tests/test_junifer_nifti_spheres_masker.py +231 -21
- junifer/external/py.typed +0 -0
- junifer/markers/__init__.pyi +6 -3
- junifer/markers/base.py +126 -76
- junifer/markers/brainprint.py +30 -39
- junifer/markers/complexity/__init__.py +20 -3
- junifer/markers/complexity/complexity_base.py +40 -41
- junifer/markers/complexity/hurst_exponent.py +22 -35
- junifer/markers/complexity/multiscale_entropy_auc.py +53 -41
- junifer/markers/complexity/perm_entropy.py +22 -36
- junifer/markers/complexity/range_entropy.py +22 -35
- junifer/markers/complexity/range_entropy_auc.py +27 -36
- junifer/markers/complexity/sample_entropy.py +22 -36
- junifer/markers/complexity/tests/test_complexity_registry.py +48 -0
- junifer/markers/complexity/tests/test_hurst_exponent.py +47 -36
- junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +50 -36
- junifer/markers/complexity/tests/test_perm_entropy.py +48 -36
- junifer/markers/complexity/tests/test_range_entropy.py +47 -36
- junifer/markers/complexity/tests/test_range_entropy_auc.py +47 -36
- junifer/markers/complexity/tests/test_sample_entropy.py +48 -36
- junifer/markers/complexity/tests/test_weighted_perm_entropy.py +50 -36
- junifer/markers/complexity/weighted_perm_entropy.py +22 -36
- junifer/markers/ets_rss.py +35 -31
- junifer/markers/falff/__init__.pyi +7 -1
- junifer/markers/falff/_afni_falff.py +22 -9
- junifer/markers/falff/_junifer_falff.py +47 -31
- junifer/markers/falff/falff_base.py +80 -60
- junifer/markers/falff/falff_maps.py +17 -41
- junifer/markers/falff/falff_parcels.py +26 -51
- junifer/markers/falff/falff_spheres.py +34 -61
- junifer/markers/falff/tests/test_falff_maps.py +20 -23
- junifer/markers/falff/tests/test_falff_mask.py +99 -0
- junifer/markers/falff/tests/test_falff_parcels.py +14 -10
- junifer/markers/falff/tests/test_falff_spheres.py +14 -10
- junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +32 -34
- junifer/markers/functional_connectivity/edge_functional_connectivity_maps.py +12 -25
- junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +19 -34
- junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +24 -44
- junifer/markers/functional_connectivity/functional_connectivity_base.py +50 -40
- junifer/markers/functional_connectivity/functional_connectivity_maps.py +12 -25
- junifer/markers/functional_connectivity/functional_connectivity_parcels.py +19 -34
- junifer/markers/functional_connectivity/functional_connectivity_spheres.py +24 -45
- junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +21 -22
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_maps.py +8 -7
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +8 -4
- junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +8 -4
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_maps.py +8 -7
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +9 -5
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +8 -12
- junifer/markers/maps_aggregation.py +77 -55
- junifer/markers/parcel_aggregation.py +91 -70
- junifer/markers/reho/__init__.pyi +7 -1
- junifer/markers/reho/_afni_reho.py +23 -14
- junifer/markers/reho/_junifer_reho.py +112 -123
- junifer/markers/reho/reho_base.py +115 -37
- junifer/markers/reho/reho_maps.py +18 -32
- junifer/markers/reho/reho_parcels.py +26 -41
- junifer/markers/reho/reho_spheres.py +33 -54
- junifer/markers/reho/tests/test_junifer_reho.py +178 -0
- junifer/markers/reho/tests/test_reho_maps.py +27 -25
- junifer/markers/reho/tests/test_reho_parcels.py +28 -22
- junifer/markers/reho/tests/test_reho_spheres.py +16 -12
- junifer/markers/sphere_aggregation.py +88 -72
- junifer/markers/temporal_snr/temporal_snr_base.py +32 -30
- junifer/markers/temporal_snr/temporal_snr_maps.py +9 -18
- junifer/markers/temporal_snr/temporal_snr_parcels.py +19 -27
- junifer/markers/temporal_snr/temporal_snr_spheres.py +27 -41
- junifer/markers/temporal_snr/tests/test_temporal_snr_base.py +2 -2
- junifer/markers/temporal_snr/tests/test_temporal_snr_maps.py +17 -22
- junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +11 -3
- junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +9 -9
- junifer/markers/tests/test_brainprint.py +10 -9
- junifer/markers/tests/test_ets_rss.py +7 -3
- junifer/markers/tests/test_lost_regions.py +279 -0
- junifer/markers/tests/test_maps_aggregation.py +67 -114
- junifer/markers/tests/test_marker_utils.py +40 -1
- junifer/markers/tests/test_markers_base.py +275 -6
- junifer/markers/tests/test_parcel_aggregation.py +91 -53
- junifer/markers/tests/test_sphere_aggregation.py +53 -47
- junifer/markers/utils.py +267 -5
- junifer/onthefly/__init__.py +2 -3
- junifer/onthefly/__init__.pyi +4 -0
- junifer/onthefly/_brainprint.py +3 -5
- junifer/onthefly/py.typed +0 -0
- junifer/onthefly/read_transform.py +11 -9
- junifer/onthefly/tests/test_read_transform.py +7 -7
- junifer/pipeline/__init__.pyi +4 -2
- junifer/pipeline/marker_collection.py +14 -10
- junifer/pipeline/pipeline_component_registry.py +25 -6
- junifer/pipeline/pipeline_step_mixin.py +5 -12
- junifer/pipeline/tests/test_data_object_dumper.py +10 -10
- junifer/pipeline/tests/test_marker_collection.py +145 -168
- junifer/pipeline/tests/test_pipeline_component_registry.py +52 -8
- junifer/pipeline/tests/test_pipeline_step_mixin.py +12 -26
- junifer/pipeline/tests/test_update_meta_mixin.py +4 -5
- junifer/pipeline/tests/test_workdir_manager.py +39 -0
- junifer/pipeline/update_meta_mixin.py +13 -10
- junifer/pipeline/utils.py +22 -17
- junifer/pipeline/workdir_manager.py +41 -32
- junifer/preprocess/__init__.pyi +9 -4
- junifer/preprocess/_temporal_filter.py +34 -33
- junifer/preprocess/_temporal_slicer.py +17 -30
- junifer/preprocess/base.py +99 -55
- junifer/preprocess/confounds/__init__.pyi +10 -2
- junifer/preprocess/confounds/fmriprep_confound_remover.py +87 -109
- junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +64 -45
- junifer/preprocess/smoothing/__init__.pyi +2 -2
- junifer/preprocess/smoothing/_afni_smoothing.py +8 -7
- junifer/preprocess/smoothing/_fsl_smoothing.py +6 -4
- junifer/preprocess/smoothing/_nilearn_smoothing.py +7 -5
- junifer/preprocess/smoothing/smoothing.py +59 -40
- junifer/preprocess/smoothing/tests/test_smoothing.py +28 -8
- junifer/preprocess/tests/test_preprocess_base.py +17 -9
- junifer/preprocess/tests/test_temporal_filter.py +37 -16
- junifer/preprocess/tests/test_temporal_slicer.py +12 -12
- junifer/preprocess/warping/__init__.pyi +2 -2
- junifer/preprocess/warping/_ants_warper.py +56 -40
- junifer/preprocess/warping/_fsl_warper.py +49 -36
- junifer/preprocess/warping/_utils.py +106 -0
- junifer/preprocess/warping/space_warper.py +99 -98
- junifer/preprocess/warping/tests/test_space_warper.py +46 -41
- junifer/preprocess/warping/tests/test_warping_utils.py +163 -0
- junifer/stats.py +46 -34
- junifer/storage/__init__.pyi +8 -4
- junifer/storage/base.py +129 -64
- junifer/storage/hdf5.py +307 -199
- junifer/storage/pandas_base.py +46 -24
- junifer/storage/sqlite.py +99 -62
- junifer/storage/tests/data/collected_h5io_fork.hdf5 +0 -0
- junifer/storage/tests/test_hdf5.py +147 -12
- junifer/storage/tests/test_repeated_storage.py +293 -0
- junifer/storage/tests/test_sqlite.py +9 -20
- junifer/storage/tests/test_storage_base.py +18 -21
- junifer/storage/tests/test_utils.py +83 -22
- junifer/storage/utils.py +58 -38
- junifer/testing/__init__.pyi +2 -2
- junifer/testing/datagrabbers.py +480 -44
- junifer/testing/registry.py +12 -0
- junifer/testing/tests/test_adhdtesting_datagrabber.py +24 -0
- junifer/testing/tests/test_oasisvmbtesting_datagrabber.py +5 -0
- junifer/testing/tests/test_partlycloudytesting_datagrabber.py +52 -0
- junifer/testing/tests/test_spmauditory_datagrabber.py +16 -0
- junifer/testing/tests/test_testing_registry.py +31 -0
- junifer/testing/tests/test_testing_utils.py +35 -0
- junifer/testing/tests/test_uclacnpvbmtesting_datagrabber.py +81 -0
- junifer/testing/utils.py +33 -1
- junifer/tests/test_stats.py +1 -5
- junifer/typing/__init__.pyi +2 -0
- junifer/typing/_typing.py +34 -19
- junifer/typing/py.typed +0 -0
- junifer/utils/__init__.pyi +10 -1
- junifer/utils/_config.py +1 -2
- junifer/utils/helpers.py +68 -2
- junifer/utils/logging.py +31 -7
- junifer/utils/tests/test_helpers.py +36 -1
- {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/METADATA +43 -35
- junifer-0.0.8.dist-info/RECORD +402 -0
- {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/WHEEL +1 -1
- junifer/cli/tests/test_parser.py +0 -280
- junifer/external/h5io/h5io/__init__.py +0 -15
- junifer/external/h5io/h5io/_h5io.py +0 -767
- junifer/external/h5io/h5io/_version.py +0 -1
- junifer/external/h5io/h5io/chunked_array.py +0 -94
- junifer/external/h5io/h5io/chunked_list.py +0 -65
- junifer/markers/complexity/__init__.pyi +0 -17
- junifer-0.0.7.dev332.dist-info/RECORD +0 -353
- {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/licenses/AUTHORS.rst +0 -0
- {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/licenses/LICENSE.md +0 -0
- {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/top_level.txt +0 -0
|
@@ -4,9 +4,18 @@
|
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
|
5
5
|
# License: AGPL
|
|
6
6
|
|
|
7
|
+
from collections.abc import Callable
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import nibabel as nib
|
|
11
|
+
import numpy as np
|
|
12
|
+
import pandas as pd
|
|
7
13
|
import pytest
|
|
14
|
+
from nilearn.image import get_data
|
|
8
15
|
|
|
9
|
-
from junifer.
|
|
16
|
+
from junifer.datagrabber import DataType
|
|
17
|
+
from junifer.markers import BaseMarker
|
|
18
|
+
from junifer.storage import StorageType
|
|
10
19
|
|
|
11
20
|
|
|
12
21
|
def test_base_marker_abstractness() -> None:
|
|
@@ -21,14 +30,12 @@ def test_base_marker_subclassing() -> None:
|
|
|
21
30
|
# Create concrete class
|
|
22
31
|
class MyBaseMarker(BaseMarker):
|
|
23
32
|
_MARKER_INOUT_MAPPINGS = { # noqa: RUF012
|
|
24
|
-
|
|
25
|
-
"feat_1":
|
|
33
|
+
DataType.BOLD: {
|
|
34
|
+
"feat_1": StorageType.Timeseries,
|
|
26
35
|
},
|
|
27
36
|
}
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
self.parameter = 1
|
|
31
|
-
super().__init__(on, name)
|
|
38
|
+
parameter: int = 1
|
|
32
39
|
|
|
33
40
|
def compute(self, input, extra_input):
|
|
34
41
|
return {
|
|
@@ -105,3 +112,265 @@ def test_base_marker_subclassing() -> None:
|
|
|
105
112
|
# Check output
|
|
106
113
|
assert "BOLD" in output
|
|
107
114
|
assert "T2" not in output
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _fit(change: Callable, tmp_path: Path) -> dict:
|
|
118
|
+
"""Fit a marker that applies a function to its input.
|
|
119
|
+
|
|
120
|
+
Parameters
|
|
121
|
+
----------
|
|
122
|
+
change : callable
|
|
123
|
+
The function, called with the input and the extra input.
|
|
124
|
+
tmp_path : pathlib.Path
|
|
125
|
+
The path to the test directory.
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
dict
|
|
130
|
+
The output of the marker.
|
|
131
|
+
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
class Marker(BaseMarker):
|
|
135
|
+
_MARKER_INOUT_MAPPINGS = { # noqa: RUF012
|
|
136
|
+
DataType.BOLD: {"feat": StorageType.Vector},
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
def compute(self, input, extra_input=None):
|
|
140
|
+
change(input, extra_input)
|
|
141
|
+
return {"feat": {"data": np.zeros((1, 1)), "col_names": ["x"]}}
|
|
142
|
+
|
|
143
|
+
marker = Marker(on=["BOLD"], name="marker")
|
|
144
|
+
return marker.fit_transform(input=_input(tmp_path))
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _input(tmp_path: Path) -> dict:
|
|
148
|
+
"""Get input data with the types of values the markers check.
|
|
149
|
+
|
|
150
|
+
Parameters
|
|
151
|
+
----------
|
|
152
|
+
tmp_path : pathlib.Path
|
|
153
|
+
The path to the test directory.
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
dict
|
|
158
|
+
The input data.
|
|
159
|
+
|
|
160
|
+
"""
|
|
161
|
+
# Non-integer values, which change when read as float32
|
|
162
|
+
values = np.full((2, 2, 2), 0.1)
|
|
163
|
+
# File-backed image, with its data cached
|
|
164
|
+
t1w_path = tmp_path / "t1w.nii.gz"
|
|
165
|
+
nib.save(nib.Nifti1Image(values, np.eye(4)), t1w_path)
|
|
166
|
+
t1w = nib.load(t1w_path)
|
|
167
|
+
t1w.get_fdata()
|
|
168
|
+
# File-backed image, without its data loaded
|
|
169
|
+
mask_path = tmp_path / "mask.nii.gz"
|
|
170
|
+
nib.save(nib.Nifti1Image(values, np.eye(4)), mask_path)
|
|
171
|
+
meta = {
|
|
172
|
+
"datagrabber": "dg",
|
|
173
|
+
"element": {"subject": "sub-01"},
|
|
174
|
+
"dependencies": {"numpy"},
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
"BOLD": {
|
|
178
|
+
"path": tmp_path / "bold.nii.gz",
|
|
179
|
+
# In-memory image
|
|
180
|
+
"data": nib.Nifti1Image(np.full((2, 2, 2, 3), 0.1), np.eye(4)),
|
|
181
|
+
"array": np.arange(4.0),
|
|
182
|
+
"mask": nib.load(mask_path),
|
|
183
|
+
"confounds": {"data": pd.DataFrame({"a": [1.0, 2.0, 3.0]})},
|
|
184
|
+
"meta": meta,
|
|
185
|
+
},
|
|
186
|
+
"T1w": {"path": t1w_path, "data": t1w, "meta": meta.copy()},
|
|
187
|
+
"Warp": [{"src": "MNI", "dst": "native"}],
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def replace_value(input: dict, extra_input: dict) -> None:
|
|
192
|
+
"""Replace a value."""
|
|
193
|
+
input["data"] = "new"
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def add_nested_value(input: dict, extra_input: dict) -> None:
|
|
197
|
+
"""Add a value to a nested dictionary."""
|
|
198
|
+
input["meta"]["new"] = 1
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def remove_nested_value(input: dict, extra_input: dict) -> None:
|
|
202
|
+
"""Remove the values of a nested dictionary."""
|
|
203
|
+
input["meta"]["element"].clear()
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def remove_value(input: dict, extra_input: dict) -> None:
|
|
207
|
+
"""Remove a value."""
|
|
208
|
+
del input["path"]
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def change_array(input: dict, extra_input: dict) -> None:
|
|
212
|
+
"""Change an array in place."""
|
|
213
|
+
input["array"][0] = 9.0
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def reshape_array(input: dict, extra_input: dict) -> None:
|
|
217
|
+
"""Change the shape of an array in place."""
|
|
218
|
+
input["array"].shape = (2, 2)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def change_array_dtype(input: dict, extra_input: dict) -> None:
|
|
222
|
+
"""Change the dtype of an array in place."""
|
|
223
|
+
input["array"].dtype = np.int64
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def change_image_data(input: dict, extra_input: dict) -> None:
|
|
227
|
+
"""Change the data of an in-memory image in place."""
|
|
228
|
+
np.asarray(input["data"].dataobj)[0, 0, 0, 0] = 9.0
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def change_image_affine(input: dict, extra_input: dict) -> None:
|
|
232
|
+
"""Change the affine of an image in place."""
|
|
233
|
+
input["data"].affine[0, 3] = 9.0
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def change_dataframe(input: dict, extra_input: dict) -> None:
|
|
237
|
+
"""Change a column of a data frame in place."""
|
|
238
|
+
input["confounds"]["data"]["a"] = 0.0
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def rename_dataframe_column(input: dict, extra_input: dict) -> None:
|
|
242
|
+
"""Rename a column of a data frame in place."""
|
|
243
|
+
input["confounds"]["data"].rename(columns={"a": "b"}, inplace=True)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def change_list_item(input: dict, extra_input: dict) -> None:
|
|
247
|
+
"""Change an item of a list."""
|
|
248
|
+
extra_input["Warp"][0]["dst"] = "MNI"
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def append_to_list(input: dict, extra_input: dict) -> None:
|
|
252
|
+
"""Append an item to a list."""
|
|
253
|
+
extra_input["Warp"].append({})
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def clear_set(input: dict, extra_input: dict) -> None:
|
|
257
|
+
"""Remove the items of a set."""
|
|
258
|
+
input["meta"]["dependencies"].clear()
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def change_cached_image_data(input: dict, extra_input: dict) -> None:
|
|
262
|
+
"""Change the cached data of an image of the extra input."""
|
|
263
|
+
extra_input["T1w"]["data"].get_fdata()[0, 0, 0] = 9.0
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def change_image_data_read_with_nilearn(
|
|
267
|
+
input: dict, extra_input: dict
|
|
268
|
+
) -> None:
|
|
269
|
+
"""Change the data of an image, after loading it with nilearn."""
|
|
270
|
+
get_data(input["mask"])[0, 0, 0] = 9.0
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def change_image_data_read_with_nibabel(
|
|
274
|
+
input: dict, extra_input: dict
|
|
275
|
+
) -> None:
|
|
276
|
+
"""Change the data of an image, after loading it with nibabel."""
|
|
277
|
+
input["mask"].get_fdata()[0, 0, 0] = 9.0
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
# The changes of the input and the paths of the data they change
|
|
281
|
+
_CHANGES = {
|
|
282
|
+
replace_value: "BOLD.data",
|
|
283
|
+
add_nested_value: "BOLD.meta.new",
|
|
284
|
+
remove_nested_value: "BOLD.meta.element.subject",
|
|
285
|
+
remove_value: "BOLD.path",
|
|
286
|
+
change_array: "BOLD.array",
|
|
287
|
+
reshape_array: "BOLD.array",
|
|
288
|
+
change_array_dtype: "BOLD.array",
|
|
289
|
+
change_image_data: "BOLD.data",
|
|
290
|
+
change_image_affine: "BOLD.data",
|
|
291
|
+
change_dataframe: "BOLD.confounds.data",
|
|
292
|
+
rename_dataframe_column: "BOLD.confounds.data",
|
|
293
|
+
change_list_item: "Warp.0.dst",
|
|
294
|
+
append_to_list: "Warp.1",
|
|
295
|
+
clear_set: "BOLD.meta.dependencies",
|
|
296
|
+
change_cached_image_data: "T1w.data",
|
|
297
|
+
change_image_data_read_with_nilearn: "BOLD.mask",
|
|
298
|
+
change_image_data_read_with_nibabel: "BOLD.mask",
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
@pytest.mark.parametrize(
|
|
303
|
+
"change, changed",
|
|
304
|
+
_CHANGES.items(),
|
|
305
|
+
ids=[change.__name__ for change in _CHANGES],
|
|
306
|
+
)
|
|
307
|
+
def test_base_marker_input_changed(
|
|
308
|
+
tmp_path: Path, change: Callable, changed: str
|
|
309
|
+
) -> None:
|
|
310
|
+
"""Test markers cannot change their input data.
|
|
311
|
+
|
|
312
|
+
Parameters
|
|
313
|
+
----------
|
|
314
|
+
tmp_path : pathlib.Path
|
|
315
|
+
The path to the test directory.
|
|
316
|
+
change : callable
|
|
317
|
+
The parametrized change of the input.
|
|
318
|
+
changed : str
|
|
319
|
+
The parametrized path of the changed data.
|
|
320
|
+
|
|
321
|
+
"""
|
|
322
|
+
with pytest.raises(RuntimeError, match=rf"marker changed .*{changed}"):
|
|
323
|
+
_fit(change, tmp_path)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def test_base_marker_input_not_changed(tmp_path: Path) -> None:
|
|
327
|
+
"""Test markers that only read their input data.
|
|
328
|
+
|
|
329
|
+
Parameters
|
|
330
|
+
----------
|
|
331
|
+
tmp_path : pathlib.Path
|
|
332
|
+
The path to the test directory.
|
|
333
|
+
|
|
334
|
+
"""
|
|
335
|
+
|
|
336
|
+
def read(input: dict, extra_input: dict) -> None:
|
|
337
|
+
input["data"].get_fdata()
|
|
338
|
+
float(np.sum(input["array"]))
|
|
339
|
+
float(input["confounds"]["data"]["a"].sum())
|
|
340
|
+
# Replace the cached float64 data with float32
|
|
341
|
+
extra_input["T1w"]["data"].get_fdata(dtype=np.float32)
|
|
342
|
+
# Cache float32 data
|
|
343
|
+
input["mask"].get_fdata(dtype=np.float32)
|
|
344
|
+
get_data(input["mask"])
|
|
345
|
+
set(input["meta"]["dependencies"])
|
|
346
|
+
[warp["dst"] for warp in extra_input["Warp"]]
|
|
347
|
+
|
|
348
|
+
out = _fit(read, tmp_path)
|
|
349
|
+
assert "feat" in out["BOLD"]
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def test_base_marker_input_not_loaded(tmp_path: Path) -> None:
|
|
353
|
+
"""Test checking the input does not load the data of the images.
|
|
354
|
+
|
|
355
|
+
Parameters
|
|
356
|
+
----------
|
|
357
|
+
tmp_path : pathlib.Path
|
|
358
|
+
The path to the test directory.
|
|
359
|
+
|
|
360
|
+
"""
|
|
361
|
+
input = _input(tmp_path)
|
|
362
|
+
|
|
363
|
+
class Marker(BaseMarker):
|
|
364
|
+
_MARKER_INOUT_MAPPINGS = { # noqa: RUF012
|
|
365
|
+
DataType.BOLD: {"feat": StorageType.Vector},
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
def compute(self, input, extra_input=None):
|
|
369
|
+
return {"feat": {"data": np.zeros((1, 1)), "col_names": ["x"]}}
|
|
370
|
+
|
|
371
|
+
Marker(on=["BOLD"], name="marker").fit_transform(input=input)
|
|
372
|
+
# The file-backed image without its data loaded is still not loaded
|
|
373
|
+
mask = input["BOLD"]["mask"]
|
|
374
|
+
assert not mask.in_memory
|
|
375
|
+
assert getattr(mask, "_data_cache", None) is None
|
|
376
|
+
assert getattr(mask, "_fdata_cache", None) is None
|
|
@@ -17,68 +17,75 @@ from numpy.testing import assert_array_almost_equal, assert_array_equal
|
|
|
17
17
|
from scipy.stats import trim_mean
|
|
18
18
|
|
|
19
19
|
from junifer.data import MaskRegistry, ParcellationRegistry
|
|
20
|
+
from junifer.datagrabber import DataType
|
|
20
21
|
from junifer.datareader import DefaultDataReader
|
|
21
22
|
from junifer.markers.parcel_aggregation import ParcelAggregation
|
|
22
|
-
from junifer.storage import
|
|
23
|
-
from junifer.testing.datagrabbers import
|
|
23
|
+
from junifer.storage import HDF5FeatureStorage, StorageType
|
|
24
|
+
from junifer.testing.datagrabbers import (
|
|
25
|
+
PartlyCloudyTestingDataGrabber,
|
|
26
|
+
UCLACNPVBMTestingDataGrabber,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
pytestmark = pytest.mark.external
|
|
24
31
|
|
|
25
32
|
|
|
26
33
|
@pytest.mark.parametrize(
|
|
27
34
|
"input_type, storage_type",
|
|
28
35
|
[
|
|
29
36
|
(
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
DataType.T1w,
|
|
38
|
+
StorageType.Vector,
|
|
32
39
|
),
|
|
33
40
|
(
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
DataType.T2w,
|
|
42
|
+
StorageType.Vector,
|
|
36
43
|
),
|
|
37
44
|
(
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
DataType.BOLD,
|
|
46
|
+
StorageType.Timeseries,
|
|
40
47
|
),
|
|
41
48
|
(
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
DataType.VBM_GM,
|
|
50
|
+
StorageType.Vector,
|
|
44
51
|
),
|
|
45
52
|
(
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
DataType.VBM_WM,
|
|
54
|
+
StorageType.Vector,
|
|
48
55
|
),
|
|
49
56
|
(
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
DataType.VBM_CSF,
|
|
58
|
+
StorageType.Vector,
|
|
52
59
|
),
|
|
53
60
|
(
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
DataType.FALFF,
|
|
62
|
+
StorageType.Vector,
|
|
56
63
|
),
|
|
57
64
|
(
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
DataType.GCOR,
|
|
66
|
+
StorageType.Vector,
|
|
60
67
|
),
|
|
61
68
|
(
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
DataType.LCOR,
|
|
70
|
+
StorageType.Vector,
|
|
64
71
|
),
|
|
65
72
|
],
|
|
66
73
|
)
|
|
67
74
|
def test_ParcelAggregation_input_output(
|
|
68
|
-
input_type:
|
|
75
|
+
input_type: DataType, storage_type: StorageType
|
|
69
76
|
) -> None:
|
|
70
77
|
"""Test ParcelAggregation input and output types.
|
|
71
78
|
|
|
72
79
|
Parameters
|
|
73
80
|
----------
|
|
74
|
-
input_type :
|
|
81
|
+
input_type : DataType
|
|
75
82
|
The parametrized input type.
|
|
76
|
-
storage_type :
|
|
83
|
+
storage_type : StorageType
|
|
77
84
|
The parametrized storage type.
|
|
78
85
|
|
|
79
86
|
"""
|
|
80
87
|
assert storage_type == ParcelAggregation(
|
|
81
|
-
parcellation="Schaefer100x7", method="mean", on=input_type
|
|
88
|
+
parcellation=["Schaefer100x7"], method="mean", on=[input_type]
|
|
82
89
|
).storage_type(input_type=input_type, output_feature="aggregation")
|
|
83
90
|
|
|
84
91
|
|
|
@@ -90,7 +97,7 @@ def test_ParcelAggregation_3D() -> None:
|
|
|
90
97
|
marker = ParcelAggregation(
|
|
91
98
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
92
99
|
method="mean",
|
|
93
|
-
on=
|
|
100
|
+
on=DataType.BOLD,
|
|
94
101
|
)
|
|
95
102
|
element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
|
|
96
103
|
..., 0:1
|
|
@@ -108,10 +115,7 @@ def test_ParcelAggregation_3D() -> None:
|
|
|
108
115
|
img=testing_parcellation,
|
|
109
116
|
)
|
|
110
117
|
# Create NiftiMasker
|
|
111
|
-
masker = NiftiMasker(
|
|
112
|
-
testing_parcellation_bin,
|
|
113
|
-
target_affine=element_data["BOLD"]["data"].affine,
|
|
114
|
-
)
|
|
118
|
+
masker = NiftiMasker(testing_parcellation_bin)
|
|
115
119
|
data = masker.fit_transform(element_data["BOLD"]["data"])
|
|
116
120
|
parcellation_values = np.squeeze(
|
|
117
121
|
masker.transform(testing_parcellation)
|
|
@@ -157,7 +161,7 @@ def test_ParcelAggregation_3D() -> None:
|
|
|
157
161
|
marker = ParcelAggregation(
|
|
158
162
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
159
163
|
method="std",
|
|
160
|
-
on=
|
|
164
|
+
on=DataType.BOLD,
|
|
161
165
|
)
|
|
162
166
|
parcel_agg_std_bold_data = marker.fit_transform(element_data)["BOLD"][
|
|
163
167
|
"aggregation"
|
|
@@ -182,7 +186,7 @@ def test_ParcelAggregation_3D() -> None:
|
|
|
182
186
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
183
187
|
method="trim_mean",
|
|
184
188
|
method_params={"proportiontocut": 0.1},
|
|
185
|
-
on=
|
|
189
|
+
on=DataType.BOLD,
|
|
186
190
|
)
|
|
187
191
|
parcel_agg_trim_mean_bold_data = marker.fit_transform(element_data)[
|
|
188
192
|
"BOLD"
|
|
@@ -192,6 +196,40 @@ def test_ParcelAggregation_3D() -> None:
|
|
|
192
196
|
assert_array_equal(parcel_agg_trim_mean_bold_data, manual)
|
|
193
197
|
|
|
194
198
|
|
|
199
|
+
def test_ParcelAggregation_VBM() -> None:
|
|
200
|
+
"""Test ParcelAggregation on VBM data in the parcellation space."""
|
|
201
|
+
parcellation = "TianxS1x3TxMNInonlinear2009cAsym"
|
|
202
|
+
with UCLACNPVBMTestingDataGrabber() as dg:
|
|
203
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-10206"])
|
|
204
|
+
vbm = element_data["VBM_GM"]
|
|
205
|
+
marker = ParcelAggregation(
|
|
206
|
+
parcellation=parcellation, method="mean", on=DataType.VBM_GM
|
|
207
|
+
)
|
|
208
|
+
parcel_agg_vbm_data = marker.fit_transform(element_data)["VBM_GM"][
|
|
209
|
+
"aggregation"
|
|
210
|
+
]["data"]
|
|
211
|
+
|
|
212
|
+
# Same space and grid, so the parcellation is used as is
|
|
213
|
+
tailored, _ = ParcellationRegistry().get(
|
|
214
|
+
parcellations=[parcellation], target_data=vbm
|
|
215
|
+
)
|
|
216
|
+
raw, _, _, _ = ParcellationRegistry().load(
|
|
217
|
+
name=parcellation,
|
|
218
|
+
target_space=vbm["space"],
|
|
219
|
+
resolution=2,
|
|
220
|
+
)
|
|
221
|
+
assert_array_equal(tailored.affine, raw.affine)
|
|
222
|
+
assert_array_equal(tailored.get_fdata(), raw.get_fdata())
|
|
223
|
+
|
|
224
|
+
# Compare with nilearn
|
|
225
|
+
# nilearn returns a 1D array for 3D images
|
|
226
|
+
nifti_labels_masked_vbm = np.atleast_2d(
|
|
227
|
+
NiftiLabelsMasker(labels_img=raw).fit_transform(vbm["data"])
|
|
228
|
+
)
|
|
229
|
+
assert parcel_agg_vbm_data.shape == (1, 16)
|
|
230
|
+
assert_array_almost_equal(nifti_labels_masked_vbm, parcel_agg_vbm_data)
|
|
231
|
+
|
|
232
|
+
|
|
195
233
|
def test_ParcelAggregation_4D():
|
|
196
234
|
"""Test ParcelAggregation object on 4D images."""
|
|
197
235
|
with PartlyCloudyTestingDataGrabber() as dg:
|
|
@@ -237,13 +275,13 @@ def test_ParcelAggregation_storage(tmp_path: Path) -> None:
|
|
|
237
275
|
# Store 3D
|
|
238
276
|
with PartlyCloudyTestingDataGrabber() as dg:
|
|
239
277
|
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
|
240
|
-
storage =
|
|
241
|
-
uri=tmp_path / "test_parcel_storage_3D.
|
|
278
|
+
storage = HDF5FeatureStorage(
|
|
279
|
+
uri=tmp_path / "test_parcel_storage_3D.hdf5",
|
|
242
280
|
)
|
|
243
281
|
marker = ParcelAggregation(
|
|
244
282
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
245
283
|
method="mean",
|
|
246
|
-
on=
|
|
284
|
+
on=DataType.BOLD,
|
|
247
285
|
)
|
|
248
286
|
element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
|
|
249
287
|
..., 0:1
|
|
@@ -258,13 +296,13 @@ def test_ParcelAggregation_storage(tmp_path: Path) -> None:
|
|
|
258
296
|
# Store 4D
|
|
259
297
|
with PartlyCloudyTestingDataGrabber() as dg:
|
|
260
298
|
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
|
261
|
-
storage =
|
|
262
|
-
uri=tmp_path / "test_parcel_storage_4D.
|
|
299
|
+
storage = HDF5FeatureStorage(
|
|
300
|
+
uri=tmp_path / "test_parcel_storage_4D.hdf5",
|
|
263
301
|
)
|
|
264
302
|
marker = ParcelAggregation(
|
|
265
303
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
266
304
|
method="mean",
|
|
267
|
-
on=
|
|
305
|
+
on=DataType.BOLD,
|
|
268
306
|
)
|
|
269
307
|
marker.fit_transform(input=element_data, storage=storage)
|
|
270
308
|
features = storage.list_features()
|
|
@@ -283,8 +321,8 @@ def test_ParcelAggregation_3D_mask() -> None:
|
|
|
283
321
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
284
322
|
method="mean",
|
|
285
323
|
name="tian_mean",
|
|
286
|
-
on=
|
|
287
|
-
masks="compute_brain_mask",
|
|
324
|
+
on=DataType.BOLD,
|
|
325
|
+
masks=["compute_brain_mask"],
|
|
288
326
|
)
|
|
289
327
|
element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
|
|
290
328
|
..., 0:1
|
|
@@ -360,9 +398,9 @@ def test_ParcelAggregation_3D_mask_computed() -> None:
|
|
|
360
398
|
marker = ParcelAggregation(
|
|
361
399
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
362
400
|
method="mean",
|
|
363
|
-
masks={"compute_brain_mask": {"threshold": 0.2}},
|
|
401
|
+
masks=[{"compute_brain_mask": {"threshold": 0.2}}],
|
|
364
402
|
name="tian_mean",
|
|
365
|
-
on=
|
|
403
|
+
on=DataType.BOLD,
|
|
366
404
|
)
|
|
367
405
|
parcel_agg_mean_bold_data = marker.fit_transform(element_data)["BOLD"][
|
|
368
406
|
"aggregation"
|
|
@@ -444,7 +482,7 @@ def test_ParcelAggregation_3D_multiple_non_overlapping(tmp_path: Path) -> None:
|
|
|
444
482
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
445
483
|
method="mean",
|
|
446
484
|
name="tian_mean",
|
|
447
|
-
on=
|
|
485
|
+
on=DataType.BOLD,
|
|
448
486
|
)
|
|
449
487
|
orig_mean = marker_original.fit_transform(element_data)["BOLD"][
|
|
450
488
|
"aggregation"
|
|
@@ -462,7 +500,7 @@ def test_ParcelAggregation_3D_multiple_non_overlapping(tmp_path: Path) -> None:
|
|
|
462
500
|
],
|
|
463
501
|
method="mean",
|
|
464
502
|
name="tian_mean",
|
|
465
|
-
on=
|
|
503
|
+
on=DataType.BOLD,
|
|
466
504
|
)
|
|
467
505
|
|
|
468
506
|
# No warnings should be raised
|
|
@@ -549,7 +587,7 @@ def test_ParcelAggregation_3D_multiple_overlapping(tmp_path: Path) -> None:
|
|
|
549
587
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
550
588
|
method="mean",
|
|
551
589
|
name="tian_mean",
|
|
552
|
-
on=
|
|
590
|
+
on=DataType.BOLD,
|
|
553
591
|
)
|
|
554
592
|
orig_mean = marker_original.fit_transform(element_data)["BOLD"][
|
|
555
593
|
"aggregation"
|
|
@@ -567,7 +605,7 @@ def test_ParcelAggregation_3D_multiple_overlapping(tmp_path: Path) -> None:
|
|
|
567
605
|
],
|
|
568
606
|
method="mean",
|
|
569
607
|
name="tian_mean",
|
|
570
|
-
on=
|
|
608
|
+
on=DataType.BOLD,
|
|
571
609
|
)
|
|
572
610
|
# Warning should be raised
|
|
573
611
|
with pytest.warns(RuntimeWarning, match="overlapping voxels"):
|
|
@@ -658,7 +696,7 @@ def test_ParcelAggregation_3D_multiple_duplicated_labels(
|
|
|
658
696
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
659
697
|
method="mean",
|
|
660
698
|
name="tian_mean",
|
|
661
|
-
on=
|
|
699
|
+
on=DataType.BOLD,
|
|
662
700
|
)
|
|
663
701
|
orig_mean = marker_original.fit_transform(element_data)["BOLD"][
|
|
664
702
|
"aggregation"
|
|
@@ -676,7 +714,7 @@ def test_ParcelAggregation_3D_multiple_duplicated_labels(
|
|
|
676
714
|
],
|
|
677
715
|
method="mean",
|
|
678
716
|
name="tian_mean",
|
|
679
|
-
on=
|
|
717
|
+
on=DataType.BOLD,
|
|
680
718
|
)
|
|
681
719
|
|
|
682
720
|
# Warning should be raised
|
|
@@ -712,7 +750,7 @@ def test_ParcelAggregation_4D_agg_time():
|
|
|
712
750
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
713
751
|
method="mean",
|
|
714
752
|
time_method="mean",
|
|
715
|
-
on=
|
|
753
|
+
on=DataType.BOLD,
|
|
716
754
|
)
|
|
717
755
|
parcel_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
|
|
718
756
|
"aggregation"
|
|
@@ -744,11 +782,11 @@ def test_ParcelAggregation_4D_agg_time():
|
|
|
744
782
|
# Test picking first time point
|
|
745
783
|
nifti_labels_masked_bold_pick_0 = nifti_labels_masked_bold[:1, :]
|
|
746
784
|
marker = ParcelAggregation(
|
|
747
|
-
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
785
|
+
parcellation=["TianxS1x3TxMNInonlinear2009cAsym"],
|
|
748
786
|
method="mean",
|
|
749
787
|
time_method="select",
|
|
750
788
|
time_method_params={"pick": [0]},
|
|
751
|
-
on=
|
|
789
|
+
on=DataType.BOLD,
|
|
752
790
|
)
|
|
753
791
|
parcel_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
|
|
754
792
|
"aggregation"
|
|
@@ -771,7 +809,7 @@ def test_ParcelAggregation_errors() -> None:
|
|
|
771
809
|
method="mean",
|
|
772
810
|
time_method="select",
|
|
773
811
|
time_method_params={"pick": [0]},
|
|
774
|
-
on=
|
|
812
|
+
on=[DataType.VBM_GM],
|
|
775
813
|
)
|
|
776
814
|
|
|
777
815
|
with pytest.raises(
|
|
@@ -781,7 +819,7 @@ def test_ParcelAggregation_errors() -> None:
|
|
|
781
819
|
parcellation="Schaefer100x7",
|
|
782
820
|
method="mean",
|
|
783
821
|
time_method_params={"pick": [0]},
|
|
784
|
-
on=
|
|
822
|
+
on=[DataType.VBM_GM],
|
|
785
823
|
)
|
|
786
824
|
|
|
787
825
|
|
|
@@ -797,7 +835,7 @@ def test_ParcelAggregation_warning() -> None:
|
|
|
797
835
|
method="mean",
|
|
798
836
|
time_method="select",
|
|
799
837
|
time_method_params={"pick": [0]},
|
|
800
|
-
on=
|
|
838
|
+
on=DataType.BOLD,
|
|
801
839
|
)
|
|
802
840
|
element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
|
|
803
841
|
..., 0:1
|