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
|
@@ -3,18 +3,31 @@
|
|
|
3
3
|
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
|
|
4
4
|
# License: AGPL
|
|
5
5
|
|
|
6
|
+
from copy import deepcopy
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
6
9
|
import pytest
|
|
10
|
+
from pydantic import AnyUrl
|
|
7
11
|
|
|
8
|
-
from junifer.datagrabber import
|
|
12
|
+
from junifer.datagrabber import (
|
|
13
|
+
BaseDataGrabber,
|
|
14
|
+
MultipleDataGrabber,
|
|
15
|
+
PatternDataladDataGrabber,
|
|
16
|
+
)
|
|
17
|
+
from junifer.pipeline import PipelineComponentRegistry
|
|
9
18
|
|
|
10
19
|
|
|
11
20
|
_testing_dataset = {
|
|
12
21
|
"example_bids": {
|
|
13
|
-
"uri":
|
|
22
|
+
"uri": (
|
|
23
|
+
"https://cerebra.fz-juelich.de/junifer/datalad-example-bids.git"
|
|
24
|
+
),
|
|
14
25
|
"id": "522dfb203afcd2cd55799bf347f9b211919a7338",
|
|
15
26
|
},
|
|
16
27
|
"example_bids_ses": {
|
|
17
|
-
"uri":
|
|
28
|
+
"uri": (
|
|
29
|
+
"https://cerebra.fz-juelich.de/junifer/datalad-example-bids-ses.git"
|
|
30
|
+
),
|
|
18
31
|
"id": "3d08d55d1faad4f12ab64ac9497544a0d924d47a",
|
|
19
32
|
},
|
|
20
33
|
}
|
|
@@ -22,8 +35,8 @@ _testing_dataset = {
|
|
|
22
35
|
|
|
23
36
|
def test_MultipleDataGrabber() -> None:
|
|
24
37
|
"""Test MultipleDataGrabber."""
|
|
25
|
-
repo_uri = _testing_dataset["example_bids_ses"]["uri"]
|
|
26
|
-
rootdir = "example_bids_ses"
|
|
38
|
+
repo_uri = AnyUrl(_testing_dataset["example_bids_ses"]["uri"])
|
|
39
|
+
rootdir = Path("example_bids_ses")
|
|
27
40
|
replacements = ["subject", "session"]
|
|
28
41
|
|
|
29
42
|
dg1 = PatternDataladDataGrabber(
|
|
@@ -73,7 +86,7 @@ def test_MultipleDataGrabber() -> None:
|
|
|
73
86
|
dg2 = PatternDataladDataGrabber(
|
|
74
87
|
rootdir=rootdir,
|
|
75
88
|
uri=repo_uri,
|
|
76
|
-
types=
|
|
89
|
+
types="BOLD",
|
|
77
90
|
patterns={
|
|
78
91
|
"BOLD": {
|
|
79
92
|
"pattern": (
|
|
@@ -93,7 +106,7 @@ def test_MultipleDataGrabber() -> None:
|
|
|
93
106
|
replacements=replacements,
|
|
94
107
|
)
|
|
95
108
|
|
|
96
|
-
dg = MultipleDataGrabber([dg1, dg2])
|
|
109
|
+
dg = MultipleDataGrabber(datagrabbers=[dg1, dg2])
|
|
97
110
|
|
|
98
111
|
types = dg.get_types()
|
|
99
112
|
assert "T1w" in types
|
|
@@ -129,12 +142,12 @@ def test_MultipleDataGrabber() -> None:
|
|
|
129
142
|
|
|
130
143
|
def test_MultipleDataGrabber_no_intersection() -> None:
|
|
131
144
|
"""Test MultipleDataGrabber without intersection (0 elements)."""
|
|
132
|
-
rootdir = "example_bids_ses"
|
|
145
|
+
rootdir = Path("example_bids_ses")
|
|
133
146
|
replacements = ["subject", "session"]
|
|
134
147
|
|
|
135
148
|
dg1 = PatternDataladDataGrabber(
|
|
136
149
|
rootdir=rootdir,
|
|
137
|
-
uri=_testing_dataset["example_bids"]["uri"],
|
|
150
|
+
uri=AnyUrl(_testing_dataset["example_bids"]["uri"]),
|
|
138
151
|
types=["T1w", "Warp"],
|
|
139
152
|
patterns={
|
|
140
153
|
"T1w": {
|
|
@@ -171,8 +184,8 @@ def test_MultipleDataGrabber_no_intersection() -> None:
|
|
|
171
184
|
|
|
172
185
|
dg2 = PatternDataladDataGrabber(
|
|
173
186
|
rootdir=rootdir,
|
|
174
|
-
uri=_testing_dataset["example_bids_ses"]["uri"],
|
|
175
|
-
types=
|
|
187
|
+
uri=AnyUrl(_testing_dataset["example_bids_ses"]["uri"]),
|
|
188
|
+
types="BOLD",
|
|
176
189
|
patterns={
|
|
177
190
|
"BOLD": {
|
|
178
191
|
"pattern": (
|
|
@@ -185,7 +198,7 @@ def test_MultipleDataGrabber_no_intersection() -> None:
|
|
|
185
198
|
replacements=replacements,
|
|
186
199
|
)
|
|
187
200
|
|
|
188
|
-
dg = MultipleDataGrabber([dg1, dg2])
|
|
201
|
+
dg = MultipleDataGrabber(datagrabbers=[dg1, dg2])
|
|
189
202
|
expected_subs = set()
|
|
190
203
|
with dg:
|
|
191
204
|
subs = list(dg)
|
|
@@ -195,9 +208,9 @@ def test_MultipleDataGrabber_no_intersection() -> None:
|
|
|
195
208
|
def test_MultipleDataGrabber_get_item() -> None:
|
|
196
209
|
"""Test MultipleDataGrabber get_item() error."""
|
|
197
210
|
dg1 = PatternDataladDataGrabber(
|
|
198
|
-
rootdir="example_bids_ses",
|
|
199
|
-
uri=_testing_dataset["example_bids"]["uri"],
|
|
200
|
-
types=
|
|
211
|
+
rootdir=Path("example_bids_ses"),
|
|
212
|
+
uri=AnyUrl(_testing_dataset["example_bids"]["uri"]),
|
|
213
|
+
types="T1w",
|
|
201
214
|
patterns={
|
|
202
215
|
"T1w": {
|
|
203
216
|
"pattern": (
|
|
@@ -209,19 +222,19 @@ def test_MultipleDataGrabber_get_item() -> None:
|
|
|
209
222
|
replacements=["subject", "session"],
|
|
210
223
|
)
|
|
211
224
|
|
|
212
|
-
dg = MultipleDataGrabber([dg1])
|
|
225
|
+
dg = MultipleDataGrabber(datagrabbers=[dg1])
|
|
213
226
|
with pytest.raises(NotImplementedError):
|
|
214
|
-
dg.get_item(subject="sub-01")
|
|
227
|
+
dg.get_item(subject="sub-01")
|
|
215
228
|
|
|
216
229
|
|
|
217
230
|
def test_MultipleDataGrabber_validation() -> None:
|
|
218
231
|
"""Test MultipleDataGrabber init validation."""
|
|
219
|
-
rootdir = "example_bids_ses"
|
|
232
|
+
rootdir = Path("example_bids_ses")
|
|
220
233
|
|
|
221
234
|
dg1 = PatternDataladDataGrabber(
|
|
222
235
|
rootdir=rootdir,
|
|
223
|
-
uri=_testing_dataset["example_bids"]["uri"],
|
|
224
|
-
types=
|
|
236
|
+
uri=AnyUrl(_testing_dataset["example_bids"]["uri"]),
|
|
237
|
+
types="T1w",
|
|
225
238
|
patterns={
|
|
226
239
|
"T1w": {
|
|
227
240
|
"pattern": (
|
|
@@ -235,8 +248,8 @@ def test_MultipleDataGrabber_validation() -> None:
|
|
|
235
248
|
|
|
236
249
|
dg2 = PatternDataladDataGrabber(
|
|
237
250
|
rootdir=rootdir,
|
|
238
|
-
uri=_testing_dataset["example_bids_ses"]["uri"],
|
|
239
|
-
types=
|
|
251
|
+
uri=AnyUrl(_testing_dataset["example_bids_ses"]["uri"]),
|
|
252
|
+
types="BOLD",
|
|
240
253
|
patterns={
|
|
241
254
|
"BOLD": {
|
|
242
255
|
"pattern": "{subject}/func/{subject}_task-rest_bold.nii.gz",
|
|
@@ -246,23 +259,24 @@ def test_MultipleDataGrabber_validation() -> None:
|
|
|
246
259
|
replacements=["subject"],
|
|
247
260
|
)
|
|
248
261
|
|
|
249
|
-
|
|
250
|
-
|
|
262
|
+
# Different element keys are joined
|
|
263
|
+
dg = MultipleDataGrabber(datagrabbers=[dg1, dg2])
|
|
264
|
+
assert dg.get_element_keys() == ["subject", "session"]
|
|
251
265
|
|
|
252
|
-
with pytest.raises(RuntimeError, match="
|
|
253
|
-
MultipleDataGrabber([dg1, dg1])
|
|
266
|
+
with pytest.raises(RuntimeError, match="`T1w` is grabbed by more than"):
|
|
267
|
+
MultipleDataGrabber(datagrabbers=[dg1, dg1])
|
|
254
268
|
|
|
255
269
|
|
|
256
270
|
def test_MultipleDataGrabber_partial_pattern() -> None:
|
|
257
271
|
"""Test MultipleDataGrabber partial pattern."""
|
|
258
|
-
repo_uri = _testing_dataset["example_bids_ses"]["uri"]
|
|
259
|
-
rootdir = "example_bids_ses"
|
|
272
|
+
repo_uri = AnyUrl(_testing_dataset["example_bids_ses"]["uri"])
|
|
273
|
+
rootdir = Path("example_bids_ses")
|
|
260
274
|
replacements = ["subject", "session"]
|
|
261
275
|
|
|
262
276
|
dg1 = PatternDataladDataGrabber(
|
|
263
277
|
rootdir=rootdir,
|
|
264
278
|
uri=repo_uri,
|
|
265
|
-
types=
|
|
279
|
+
types="BOLD",
|
|
266
280
|
patterns={
|
|
267
281
|
"BOLD": {
|
|
268
282
|
"pattern": (
|
|
@@ -278,7 +292,7 @@ def test_MultipleDataGrabber_partial_pattern() -> None:
|
|
|
278
292
|
dg2 = PatternDataladDataGrabber(
|
|
279
293
|
rootdir=rootdir,
|
|
280
294
|
uri=repo_uri,
|
|
281
|
-
types=
|
|
295
|
+
types="BOLD",
|
|
282
296
|
patterns={
|
|
283
297
|
"BOLD": {
|
|
284
298
|
"confounds": {
|
|
@@ -295,7 +309,7 @@ def test_MultipleDataGrabber_partial_pattern() -> None:
|
|
|
295
309
|
partial_pattern_ok=True,
|
|
296
310
|
)
|
|
297
311
|
|
|
298
|
-
dg = MultipleDataGrabber([dg1, dg2])
|
|
312
|
+
dg = MultipleDataGrabber(datagrabbers=[dg1, dg2])
|
|
299
313
|
|
|
300
314
|
types = dg.get_types()
|
|
301
315
|
assert "BOLD" in types
|
|
@@ -324,3 +338,251 @@ def test_MultipleDataGrabber_partial_pattern() -> None:
|
|
|
324
338
|
assert len(meta["datagrabbers"]) == 2
|
|
325
339
|
assert meta["datagrabbers"][0]["class"] == "PatternDataladDataGrabber"
|
|
326
340
|
assert meta["datagrabbers"][1]["class"] == "PatternDataladDataGrabber"
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def _datasets(tmp_path: Path) -> dict[str, Path]:
|
|
344
|
+
"""Create local datasets with the data of different datagrabbers.
|
|
345
|
+
|
|
346
|
+
* ``fmriprep``: BOLD (with confounds) for ``sub-01`` and ``sub-02``, and
|
|
347
|
+
the ``rest`` and ``movie`` tasks.
|
|
348
|
+
* ``cat``: VBM_GM for ``sub-01``, ``sub-02`` and ``sub-03``.
|
|
349
|
+
* ``confounds``: BOLD confounds for ``sub-01`` and ``sub-02``, and only
|
|
350
|
+
the ``rest`` task.
|
|
351
|
+
|
|
352
|
+
Parameters
|
|
353
|
+
----------
|
|
354
|
+
tmp_path : pathlib.Path
|
|
355
|
+
The path to the test directory.
|
|
356
|
+
|
|
357
|
+
Returns
|
|
358
|
+
-------
|
|
359
|
+
dict of str and pathlib.Path
|
|
360
|
+
The paths to the datasets, by name.
|
|
361
|
+
|
|
362
|
+
"""
|
|
363
|
+
files = [
|
|
364
|
+
f"fmriprep/{s}/func/{s}_task-{t}_{suffix}"
|
|
365
|
+
for s in ("sub-01", "sub-02")
|
|
366
|
+
for t in ("rest", "movie")
|
|
367
|
+
for suffix in ("bold.nii", "desc-confounds.tsv")
|
|
368
|
+
]
|
|
369
|
+
files += [
|
|
370
|
+
f"cat/{s}/mri/mwp1{s}.nii" for s in ("sub-01", "sub-02", "sub-03")
|
|
371
|
+
]
|
|
372
|
+
files += [f"confounds/{s}/{s}_task-rest.tsv" for s in ("sub-01", "sub-02")]
|
|
373
|
+
for fname in files:
|
|
374
|
+
(tmp_path / fname).parent.mkdir(parents=True, exist_ok=True)
|
|
375
|
+
(tmp_path / fname).touch()
|
|
376
|
+
return {name: tmp_path / name for name in ("fmriprep", "cat", "confounds")}
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def _configs(datasets: dict[str, Path]) -> dict[str, dict]:
|
|
380
|
+
"""Get the configurations of the datagrabbers of the local datasets.
|
|
381
|
+
|
|
382
|
+
Parameters
|
|
383
|
+
----------
|
|
384
|
+
datasets : dict of str and pathlib.Path
|
|
385
|
+
The paths to the datasets, by name (see ``_datasets``).
|
|
386
|
+
|
|
387
|
+
Returns
|
|
388
|
+
-------
|
|
389
|
+
dict of str and dict
|
|
390
|
+
The configurations of the datagrabbers, by dataset name.
|
|
391
|
+
|
|
392
|
+
"""
|
|
393
|
+
return {
|
|
394
|
+
"fmriprep": {
|
|
395
|
+
"kind": "PatternDataGrabber",
|
|
396
|
+
"datadir": str(datasets["fmriprep"]),
|
|
397
|
+
"types": ["BOLD"],
|
|
398
|
+
"patterns": {
|
|
399
|
+
"BOLD": {
|
|
400
|
+
"pattern": "{subject}/func/{subject}_task-{task}_bold.nii",
|
|
401
|
+
"space": "MNI152NLin6Asym",
|
|
402
|
+
"confounds": {
|
|
403
|
+
"pattern": (
|
|
404
|
+
"{subject}/func/{subject}_task-{task}_"
|
|
405
|
+
"desc-confounds.tsv"
|
|
406
|
+
),
|
|
407
|
+
"format": "fmriprep",
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
"replacements": ["subject", "task"],
|
|
412
|
+
},
|
|
413
|
+
"cat": {
|
|
414
|
+
"kind": "PatternDataGrabber",
|
|
415
|
+
"datadir": str(datasets["cat"]),
|
|
416
|
+
"types": ["VBM_GM"],
|
|
417
|
+
"patterns": {
|
|
418
|
+
"VBM_GM": {
|
|
419
|
+
"pattern": "{subject}/mri/mwp1{subject}.nii",
|
|
420
|
+
"space": "MNI152NLin6Asym",
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
"replacements": ["subject"],
|
|
424
|
+
},
|
|
425
|
+
"confounds": {
|
|
426
|
+
"kind": "PatternDataGrabber",
|
|
427
|
+
"datadir": str(datasets["confounds"]),
|
|
428
|
+
"types": ["BOLD"],
|
|
429
|
+
"patterns": {
|
|
430
|
+
"BOLD": {
|
|
431
|
+
"confounds": {
|
|
432
|
+
"pattern": "{subject}/{subject}_task-{task}.tsv",
|
|
433
|
+
"format": "fmriprep",
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
"replacements": ["subject", "task"],
|
|
438
|
+
"partial_pattern_ok": True,
|
|
439
|
+
},
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def _multiple(tmp_path: Path, names: list[str]) -> MultipleDataGrabber:
|
|
444
|
+
"""Get a MultipleDataGrabber with datagrabbers of the local datasets.
|
|
445
|
+
|
|
446
|
+
Parameters
|
|
447
|
+
----------
|
|
448
|
+
tmp_path : pathlib.Path
|
|
449
|
+
The path to the test directory.
|
|
450
|
+
names : list of str
|
|
451
|
+
The names of the datasets of the datagrabbers (see ``_datasets``).
|
|
452
|
+
|
|
453
|
+
Returns
|
|
454
|
+
-------
|
|
455
|
+
MultipleDataGrabber
|
|
456
|
+
The datagrabber.
|
|
457
|
+
|
|
458
|
+
"""
|
|
459
|
+
configs = _configs(_datasets(tmp_path))
|
|
460
|
+
return PipelineComponentRegistry().build_component_instance(
|
|
461
|
+
step="datagrabber",
|
|
462
|
+
name="MultipleDataGrabber",
|
|
463
|
+
baseclass=BaseDataGrabber,
|
|
464
|
+
init_params={
|
|
465
|
+
"datagrabbers": [deepcopy(configs[name]) for name in names]
|
|
466
|
+
},
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
@pytest.mark.parametrize("names", [["fmriprep", "cat"], ["cat", "fmriprep"]])
|
|
471
|
+
def test_MultipleDataGrabber_element_keys(
|
|
472
|
+
tmp_path: Path, names: list[str]
|
|
473
|
+
) -> None:
|
|
474
|
+
"""Test MultipleDataGrabber with datagrabbers with different element keys.
|
|
475
|
+
|
|
476
|
+
Parameters
|
|
477
|
+
----------
|
|
478
|
+
tmp_path : pathlib.Path
|
|
479
|
+
The path to the test directory.
|
|
480
|
+
names : list of str
|
|
481
|
+
The parametrized datasets of the datagrabbers.
|
|
482
|
+
|
|
483
|
+
"""
|
|
484
|
+
dg = _multiple(tmp_path, names)
|
|
485
|
+
assert dg.get_element_keys() == ["subject", "task"]
|
|
486
|
+
# sub-03 has no BOLD data
|
|
487
|
+
assert dg.get_elements() == [
|
|
488
|
+
("sub-01", "movie"),
|
|
489
|
+
("sub-01", "rest"),
|
|
490
|
+
("sub-02", "movie"),
|
|
491
|
+
("sub-02", "rest"),
|
|
492
|
+
]
|
|
493
|
+
out = dg[("sub-02", "rest")]
|
|
494
|
+
assert out["BOLD"]["path"] == (
|
|
495
|
+
tmp_path / "fmriprep/sub-02/func/sub-02_task-rest_bold.nii"
|
|
496
|
+
)
|
|
497
|
+
assert out["VBM_GM"]["path"] == tmp_path / "cat/sub-02/mri/mwp1sub-02.nii"
|
|
498
|
+
for data_type in ("BOLD", "VBM_GM"):
|
|
499
|
+
assert out[data_type]["meta"]["element"] == {
|
|
500
|
+
"subject": "sub-02",
|
|
501
|
+
"task": "rest",
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
@pytest.mark.parametrize(
|
|
506
|
+
"names", [["fmriprep", "confounds"], ["confounds", "fmriprep"]]
|
|
507
|
+
)
|
|
508
|
+
def test_MultipleDataGrabber_nested_types(
|
|
509
|
+
tmp_path: Path, names: list[str]
|
|
510
|
+
) -> None:
|
|
511
|
+
"""Test MultipleDataGrabber replacing nested data types.
|
|
512
|
+
|
|
513
|
+
Parameters
|
|
514
|
+
----------
|
|
515
|
+
tmp_path : pathlib.Path
|
|
516
|
+
The path to the test directory.
|
|
517
|
+
names : list of str
|
|
518
|
+
The parametrized datasets of the datagrabbers.
|
|
519
|
+
|
|
520
|
+
"""
|
|
521
|
+
dg = _multiple(tmp_path, names)
|
|
522
|
+
# The confounds dataset only has the rest task
|
|
523
|
+
assert dg.get_elements() == [("sub-01", "rest"), ("sub-02", "rest")]
|
|
524
|
+
out = dg[("sub-01", "rest")]
|
|
525
|
+
# The BOLD image of the first dataset with the confounds of the second
|
|
526
|
+
assert out["BOLD"]["path"] == (
|
|
527
|
+
tmp_path / "fmriprep/sub-01/func/sub-01_task-rest_bold.nii"
|
|
528
|
+
)
|
|
529
|
+
assert out["BOLD"]["confounds"]["path"] == (
|
|
530
|
+
tmp_path / "confounds/sub-01/sub-01_task-rest.tsv"
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
@pytest.mark.parametrize(
|
|
535
|
+
"names, match",
|
|
536
|
+
[
|
|
537
|
+
(["fmriprep", "fmriprep"], "`BOLD` is grabbed by more than one"),
|
|
538
|
+
(
|
|
539
|
+
["confounds", "confounds"],
|
|
540
|
+
"`BOLD.confounds` is grabbed by more than one",
|
|
541
|
+
),
|
|
542
|
+
],
|
|
543
|
+
)
|
|
544
|
+
def test_MultipleDataGrabber_overlapping_types(
|
|
545
|
+
tmp_path: Path, names: list[str], match: str
|
|
546
|
+
) -> None:
|
|
547
|
+
"""Test MultipleDataGrabber errors with overlapping data types.
|
|
548
|
+
|
|
549
|
+
Parameters
|
|
550
|
+
----------
|
|
551
|
+
tmp_path : pathlib.Path
|
|
552
|
+
The path to the test directory.
|
|
553
|
+
names : list of str
|
|
554
|
+
The parametrized datasets of the datagrabbers.
|
|
555
|
+
match : str
|
|
556
|
+
The parametrized error message.
|
|
557
|
+
|
|
558
|
+
"""
|
|
559
|
+
with pytest.raises(RuntimeError, match=match):
|
|
560
|
+
_multiple(tmp_path, names)
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
def test_MultipleDataGrabber_three_datasets(tmp_path: Path) -> None:
|
|
564
|
+
"""Test MultipleDataGrabber with the data of three datasets.
|
|
565
|
+
|
|
566
|
+
Parameters
|
|
567
|
+
----------
|
|
568
|
+
tmp_path : pathlib.Path
|
|
569
|
+
The path to the test directory.
|
|
570
|
+
|
|
571
|
+
"""
|
|
572
|
+
dg = _multiple(tmp_path, ["fmriprep", "cat", "confounds"])
|
|
573
|
+
assert dg.get_types() == ["BOLD", "VBM_GM"]
|
|
574
|
+
assert dg.get_elements() == [("sub-01", "rest"), ("sub-02", "rest")]
|
|
575
|
+
out = dg[("sub-02", "rest")]
|
|
576
|
+
assert out["BOLD"]["path"].parent == tmp_path / "fmriprep/sub-02/func"
|
|
577
|
+
assert out["BOLD"]["confounds"]["path"].parent == (
|
|
578
|
+
tmp_path / "confounds/sub-02"
|
|
579
|
+
)
|
|
580
|
+
assert out["VBM_GM"]["path"].parent == tmp_path / "cat/sub-02/mri"
|
|
581
|
+
# The element being processed, and the keys that the data depends on
|
|
582
|
+
for data_type in ("BOLD", "VBM_GM"):
|
|
583
|
+
assert out[data_type]["meta"]["element"] == {
|
|
584
|
+
"subject": "sub-02",
|
|
585
|
+
"task": "rest",
|
|
586
|
+
}
|
|
587
|
+
assert out["BOLD"]["meta"]["_element_keys"] == ["subject", "task"]
|
|
588
|
+
assert out["VBM_GM"]["meta"]["_element_keys"] == ["subject"]
|