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,15 +4,52 @@
|
|
|
4
4
|
# Leonard Sasse <l.sasse@fz-juelich.de>
|
|
5
5
|
# License: AGPL
|
|
6
6
|
|
|
7
|
+
from enum import StrEnum
|
|
7
8
|
from pathlib import Path
|
|
8
|
-
from typing import
|
|
9
|
+
from typing import Annotated, Literal
|
|
10
|
+
|
|
11
|
+
from pydantic import BeforeValidator
|
|
9
12
|
|
|
10
13
|
from ....api.decorators import register_datagrabber
|
|
11
|
-
from ....datagrabber import PatternDataGrabber
|
|
12
|
-
from ....
|
|
14
|
+
from ....datagrabber import ConfoundsFormat, DataType, PatternDataGrabber
|
|
15
|
+
from ....typing import DataGrabberPatterns
|
|
16
|
+
from ....utils import ensure_list
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
__all__ = ["JuselessUCLA", "UCLATask"]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class UCLATask(StrEnum):
|
|
23
|
+
"""Accepted UCLA tasks."""
|
|
13
24
|
|
|
25
|
+
REST = "rest"
|
|
26
|
+
BART = "bart"
|
|
27
|
+
BHT = "bht"
|
|
28
|
+
PAMENC = "pamenc"
|
|
29
|
+
PAMRET = "pamret"
|
|
30
|
+
SCAP = "scap"
|
|
31
|
+
TASKSWITCH = "taskswitch"
|
|
32
|
+
STOPSIGNAL = "stopsignal"
|
|
14
33
|
|
|
15
|
-
|
|
34
|
+
|
|
35
|
+
_types = Literal[
|
|
36
|
+
DataType.BOLD,
|
|
37
|
+
DataType.T1w,
|
|
38
|
+
DataType.VBM_CSF,
|
|
39
|
+
DataType.VBM_GM,
|
|
40
|
+
DataType.VBM_WM,
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
_tasks = Literal[
|
|
44
|
+
UCLATask.REST,
|
|
45
|
+
UCLATask.BART,
|
|
46
|
+
UCLATask.BHT,
|
|
47
|
+
UCLATask.PAMENC,
|
|
48
|
+
UCLATask.PAMRET,
|
|
49
|
+
UCLATask.SCAP,
|
|
50
|
+
UCLATask.TASKSWITCH,
|
|
51
|
+
UCLATask.STOPSIGNAL,
|
|
52
|
+
]
|
|
16
53
|
|
|
17
54
|
|
|
18
55
|
@register_datagrabber
|
|
@@ -23,118 +60,88 @@ class JuselessUCLA(PatternDataGrabber):
|
|
|
23
60
|
|
|
24
61
|
Parameters
|
|
25
62
|
----------
|
|
26
|
-
datadir :
|
|
63
|
+
datadir : Path, optional
|
|
27
64
|
The directory where the dataset is stored.
|
|
28
65
|
(default "/data/project/psychosis_thalamus/data/fmriprep").
|
|
29
66
|
types: {"BOLD", "T1w", "VBM_CSF", "VBM_GM", "VBM_WM"} or \
|
|
30
67
|
list of the options, optional
|
|
31
|
-
|
|
32
|
-
(default None).
|
|
68
|
+
The data type(s) to grab.
|
|
33
69
|
tasks : {"rest", "bart", "bht", "pamenc", "pamret", \
|
|
34
70
|
"scap", "taskswitch", "stopsignal"} or \
|
|
35
|
-
list of the options
|
|
36
|
-
UCLA task sessions.
|
|
37
|
-
|
|
71
|
+
list of the options, optional
|
|
72
|
+
UCLA task sessions.
|
|
73
|
+
By default, all available task are selected.
|
|
38
74
|
|
|
39
75
|
"""
|
|
40
76
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
)
|
|
73
|
-
self.tasks = tasks
|
|
74
|
-
# The patterns
|
|
75
|
-
patterns = {
|
|
76
|
-
"BOLD": {
|
|
77
|
-
"pattern": (
|
|
78
|
-
"{subject}/func/{subject}_task-{task}_bold_space-"
|
|
79
|
-
"MNI152NLin2009cAsym_preproc.nii.gz"
|
|
80
|
-
),
|
|
81
|
-
"space": "MNI152NLin2009cAsym",
|
|
82
|
-
"confounds": {
|
|
83
|
-
"pattern": (
|
|
84
|
-
"{subject}/func/{subject}_"
|
|
85
|
-
"task-{task}_bold_confounds.tsv"
|
|
86
|
-
),
|
|
87
|
-
"space": "fmriprep",
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
"T1w": {
|
|
91
|
-
"pattern": (
|
|
92
|
-
"{subject}/anat/{subject}_"
|
|
93
|
-
"T1w_space-MNI152NLin2009cAsym_preproc.nii.gz"
|
|
94
|
-
),
|
|
95
|
-
"space": "MNI152NLin2009cAsym",
|
|
96
|
-
},
|
|
97
|
-
"VBM_CSF": {
|
|
98
|
-
"pattern": (
|
|
99
|
-
"{subject}/anat/{subject}_T1w_space-"
|
|
100
|
-
"MNI152NLin2009cAsym_class-CSF_probtissue.nii.gz"
|
|
101
|
-
),
|
|
102
|
-
"space": "MNI152NLin2009cAsym",
|
|
103
|
-
},
|
|
104
|
-
"VBM_GM": {
|
|
105
|
-
"pattern": (
|
|
106
|
-
"{subject}/anat/{subject}_T1w_space-"
|
|
107
|
-
"MNI152NLin2009cAsym_class-GM_probtissue.nii.gz"
|
|
108
|
-
),
|
|
109
|
-
"space": "MNI152NLin2009cAsym",
|
|
110
|
-
},
|
|
111
|
-
"VBM_WM": {
|
|
77
|
+
# the commented out uri leads to new open neuro dataset which does
|
|
78
|
+
# NOT have preprocessed data
|
|
79
|
+
# uri = "https://github.com/OpenNeuroDatasets/ds000030.git"
|
|
80
|
+
datadir: Path = Path("/data/project/psychosis_thalamus/data/fmriprep")
|
|
81
|
+
types: Annotated[_types | list[_types], BeforeValidator(ensure_list)] = [ # noqa: RUF012
|
|
82
|
+
DataType.BOLD,
|
|
83
|
+
DataType.T1w,
|
|
84
|
+
DataType.VBM_CSF,
|
|
85
|
+
DataType.VBM_GM,
|
|
86
|
+
DataType.VBM_WM,
|
|
87
|
+
]
|
|
88
|
+
tasks: Annotated[
|
|
89
|
+
UCLATask | list[UCLATask], BeforeValidator(ensure_list)
|
|
90
|
+
] = [ # noqa: RUF012
|
|
91
|
+
UCLATask.REST,
|
|
92
|
+
UCLATask.BART,
|
|
93
|
+
UCLATask.BHT,
|
|
94
|
+
UCLATask.PAMENC,
|
|
95
|
+
UCLATask.PAMRET,
|
|
96
|
+
UCLATask.SCAP,
|
|
97
|
+
UCLATask.TASKSWITCH,
|
|
98
|
+
UCLATask.STOPSIGNAL,
|
|
99
|
+
]
|
|
100
|
+
patterns: DataGrabberPatterns = { # noqa: RUF012
|
|
101
|
+
"BOLD": {
|
|
102
|
+
"pattern": (
|
|
103
|
+
"{subject}/func/{subject}_task-{task}_bold_space-"
|
|
104
|
+
"MNI152NLin2009cAsym_preproc.nii.gz"
|
|
105
|
+
),
|
|
106
|
+
"space": "MNI152NLin2009cAsym",
|
|
107
|
+
"confounds": {
|
|
112
108
|
"pattern": (
|
|
113
|
-
"{subject}/
|
|
114
|
-
"-MNI152NLin2009cAsym_class-WM_probtissue.nii.gz"
|
|
109
|
+
"{subject}/func/{subject}_task-{task}_bold_confounds.tsv"
|
|
115
110
|
),
|
|
116
|
-
"space": "
|
|
111
|
+
"space": "fmriprep",
|
|
117
112
|
},
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
113
|
+
},
|
|
114
|
+
"T1w": {
|
|
115
|
+
"pattern": (
|
|
116
|
+
"{subject}/anat/{subject}_"
|
|
117
|
+
"T1w_space-MNI152NLin2009cAsym_preproc.nii.gz"
|
|
118
|
+
),
|
|
119
|
+
"space": "MNI152NLin2009cAsym",
|
|
120
|
+
},
|
|
121
|
+
"VBM_CSF": {
|
|
122
|
+
"pattern": (
|
|
123
|
+
"{subject}/anat/{subject}_T1w_space-"
|
|
124
|
+
"MNI152NLin2009cAsym_class-CSF_probtissue.nii.gz"
|
|
125
|
+
),
|
|
126
|
+
"space": "MNI152NLin2009cAsym",
|
|
127
|
+
},
|
|
128
|
+
"VBM_GM": {
|
|
129
|
+
"pattern": (
|
|
130
|
+
"{subject}/anat/{subject}_T1w_space-"
|
|
131
|
+
"MNI152NLin2009cAsym_class-GM_probtissue.nii.gz"
|
|
132
|
+
),
|
|
133
|
+
"space": "MNI152NLin2009cAsym",
|
|
134
|
+
},
|
|
135
|
+
"VBM_WM": {
|
|
136
|
+
"pattern": (
|
|
137
|
+
"{subject}/anat/{subject}_T1w_space"
|
|
138
|
+
"-MNI152NLin2009cAsym_class-WM_probtissue.nii.gz"
|
|
139
|
+
),
|
|
140
|
+
"space": "MNI152NLin2009cAsym",
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
replacements: list[str] = ["subject", "task"] # noqa: RUF012
|
|
144
|
+
confounds_format: ConfoundsFormat = ConfoundsFormat.FMRIPrep
|
|
138
145
|
|
|
139
146
|
def get_elements(self) -> list:
|
|
140
147
|
"""Implement fetching list of elements in the dataset.
|
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
# License: AGPL
|
|
7
7
|
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import
|
|
9
|
+
from typing import Literal
|
|
10
|
+
|
|
11
|
+
from pydantic import AnyUrl
|
|
10
12
|
|
|
11
13
|
from ....api.decorators import register_datagrabber
|
|
12
|
-
from ....datagrabber import PatternDataladDataGrabber
|
|
14
|
+
from ....datagrabber import DataType, PatternDataladDataGrabber
|
|
15
|
+
from ....typing import DataGrabberPatterns
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
__all__ = ["JuselessDataladUKBVBM"]
|
|
@@ -23,29 +26,20 @@ class JuselessDataladUKBVBM(PatternDataladDataGrabber):
|
|
|
23
26
|
|
|
24
27
|
Parameters
|
|
25
28
|
----------
|
|
26
|
-
datadir :
|
|
27
|
-
|
|
28
|
-
the datalad dataset will be cloned into a temporary
|
|
29
|
-
|
|
29
|
+
datadir : pathlib.Path, optional
|
|
30
|
+
That path where the datalad dataset will be cloned.
|
|
31
|
+
If not specified, the datalad dataset will be cloned into a temporary
|
|
32
|
+
directory.
|
|
30
33
|
|
|
31
34
|
"""
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
super().__init__(
|
|
45
|
-
types=types,
|
|
46
|
-
datadir=datadir,
|
|
47
|
-
uri=uri,
|
|
48
|
-
rootdir=rootdir,
|
|
49
|
-
replacements=replacements,
|
|
50
|
-
patterns=patterns,
|
|
51
|
-
)
|
|
36
|
+
uri: AnyUrl = AnyUrl("ria+http://ukb.ds.inm7.de#~cat_m0wp1")
|
|
37
|
+
rootdir: Path = Path("m0wp1")
|
|
38
|
+
types: list[Literal[DataType.VBM_GM]] = [DataType.VBM_GM] # noqa: RUF012
|
|
39
|
+
patterns: DataGrabberPatterns = { # noqa: RUF012
|
|
40
|
+
"VBM_GM": {
|
|
41
|
+
"pattern": "m0wp1{subject}_ses-{session}_T1w.nii.gz",
|
|
42
|
+
"space": "IXI549Space",
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
replacements: list[str] = ["subject", "session"] # noqa: RUF012
|
junifer/configs/py.typed
ADDED
|
File without changes
|
junifer/conftest.py
CHANGED
|
@@ -4,14 +4,64 @@
|
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
|
5
5
|
# License: AGPL
|
|
6
6
|
|
|
7
|
+
import gc
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
|
|
9
10
|
import pytest
|
|
10
11
|
|
|
11
|
-
from junifer.datagrabber import PatternDataladDataGrabber
|
|
12
12
|
from junifer.utils.singleton import Singleton
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
# Vendored packages, whose tests are not collected. Paths are relative to
|
|
16
|
+
# this file, so it also works when testing the installed package.
|
|
17
|
+
_VENDORED = [
|
|
18
|
+
Path(__file__).parent / "external" / "BrainPrint",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# TODO: replace with ``collect_ignore`` once datalad/datalad#7967 is fixed
|
|
23
|
+
# (see juaml/junifer#518)
|
|
24
|
+
def pytest_ignore_collect(collection_path: Path) -> bool | None:
|
|
25
|
+
"""Do not collect the tests of vendored packages.
|
|
26
|
+
|
|
27
|
+
This replaces ``collect_ignore``, which is not applied when datalad's
|
|
28
|
+
pytest plugin (datalad >= 1.4) is installed: its ``pytest_ignore_collect``
|
|
29
|
+
returns False for directories, so pytest's own check is never called.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
collection_path : pathlib.Path
|
|
34
|
+
The path being considered for collection.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
bool or None
|
|
39
|
+
True to ignore the path, None to let other hooks decide.
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
if any(collection_path.is_relative_to(path) for path in _VENDORED):
|
|
43
|
+
return True
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def pytest_collection_finish(session: pytest.Session) -> None:
|
|
48
|
+
"""Exclude the objects alive after collection from garbage collection.
|
|
49
|
+
|
|
50
|
+
nilearn (< 0.14) forces a full garbage collection every time it gets
|
|
51
|
+
the data of an image, which has to go over all the objects of the test
|
|
52
|
+
session (modules, collected tests, etc.). Freezing them makes these
|
|
53
|
+
collections much faster.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
session : pytest.Session
|
|
58
|
+
The pytest session.
|
|
59
|
+
|
|
60
|
+
"""
|
|
61
|
+
gc.collect()
|
|
62
|
+
gc.freeze()
|
|
63
|
+
|
|
64
|
+
|
|
15
65
|
@pytest.fixture(autouse=True)
|
|
16
66
|
def reset_singletons() -> None:
|
|
17
67
|
"""Reset all singletons."""
|
|
@@ -29,29 +79,18 @@ def reset_singletons() -> None:
|
|
|
29
79
|
del elem
|
|
30
80
|
|
|
31
81
|
|
|
32
|
-
@pytest.fixture
|
|
33
|
-
def
|
|
34
|
-
"""
|
|
82
|
+
@pytest.fixture(autouse=True)
|
|
83
|
+
def clear_computation_caches() -> None:
|
|
84
|
+
"""Clear the cached computations of ReHo and ALFF estimators.
|
|
35
85
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
tmp_path : pathlib.Path
|
|
39
|
-
The path to the test directory.
|
|
86
|
+
The estimators are singletons whose ``compute`` is cached per input
|
|
87
|
+
path, so results from earlier tests would otherwise be reused.
|
|
40
88
|
|
|
41
89
|
"""
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"{subject-padded}_task-{task}_run-{run}_space-MNI152NLin6Asym"
|
|
50
|
-
"_res-2_desc-preproc_bold.nii.gz"
|
|
51
|
-
),
|
|
52
|
-
"space": "MNI152NLin6Asym",
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
replacements=["subject", "subject-padded", "task", "run"],
|
|
56
|
-
)
|
|
57
|
-
return dg
|
|
90
|
+
from junifer.markers.falff._afni_falff import AFNIALFF
|
|
91
|
+
from junifer.markers.falff._junifer_falff import JuniferALFF
|
|
92
|
+
from junifer.markers.reho._afni_reho import AFNIReHo
|
|
93
|
+
from junifer.markers.reho._junifer_reho import JuniferReHo
|
|
94
|
+
|
|
95
|
+
for klass in (AFNIALFF, JuniferALFF, AFNIReHo, JuniferReHo):
|
|
96
|
+
klass.compute.cache_clear()
|
junifer/data/_dispatch.py
CHANGED
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
|
4
4
|
# License: AGPL
|
|
5
5
|
|
|
6
|
-
from collections.abc import Iterator, MutableMapping
|
|
6
|
+
from collections.abc import Callable, Iterator, MutableMapping
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import (
|
|
9
9
|
TYPE_CHECKING,
|
|
10
10
|
Any,
|
|
11
|
-
Callable,
|
|
12
11
|
Optional,
|
|
13
12
|
Union,
|
|
14
13
|
)
|
|
@@ -95,7 +94,7 @@ class DataDispatcher(MutableMapping):
|
|
|
95
94
|
# Update global
|
|
96
95
|
self._registries[key] = value
|
|
97
96
|
|
|
98
|
-
def popitem():
|
|
97
|
+
def popitem(self):
|
|
99
98
|
"""Not implemented."""
|
|
100
99
|
pass
|
|
101
100
|
|
|
@@ -110,14 +109,9 @@ class DataDispatcher(MutableMapping):
|
|
|
110
109
|
|
|
111
110
|
def get_data(
|
|
112
111
|
kind: str,
|
|
113
|
-
names:
|
|
114
|
-
str, # coordinates, parcellation, mask
|
|
115
|
-
list[str], # parcellation, mask
|
|
116
|
-
dict, # mask
|
|
117
|
-
list[dict], # mask
|
|
118
|
-
],
|
|
112
|
+
names: str | list[str] | dict | list[dict],
|
|
119
113
|
target_data: dict[str, Any],
|
|
120
|
-
extra_input:
|
|
114
|
+
extra_input: dict[str, Any] | None = None,
|
|
121
115
|
) -> Union[
|
|
122
116
|
tuple[ArrayLike, list[str]], # coordinates
|
|
123
117
|
tuple["Nifti1Image", dict[int, str]], # parcellation
|
|
@@ -196,15 +190,11 @@ def load_data(
|
|
|
196
190
|
kind: str,
|
|
197
191
|
name: str,
|
|
198
192
|
**kwargs,
|
|
199
|
-
) ->
|
|
200
|
-
tuple[ArrayLike, list[str], str]
|
|
201
|
-
tuple[
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
tuple[
|
|
205
|
-
Optional[Union["Nifti1Image", Callable]], Optional[Path], str
|
|
206
|
-
], # mask
|
|
207
|
-
]:
|
|
193
|
+
) -> (
|
|
194
|
+
tuple[ArrayLike, list[str], str]
|
|
195
|
+
| tuple[Optional["Nifti1Image"], list[str], Path, str]
|
|
196
|
+
| tuple[Union["Nifti1Image", Callable] | None, Path | None, str]
|
|
197
|
+
):
|
|
208
198
|
"""Load ``kind`` named ``name``.
|
|
209
199
|
|
|
210
200
|
Parameters
|
|
@@ -9,7 +9,7 @@ import numpy as np
|
|
|
9
9
|
from numpy.typing import ArrayLike
|
|
10
10
|
|
|
11
11
|
from ...pipeline import WorkDirManager
|
|
12
|
-
from ...utils import
|
|
12
|
+
from ...utils import run_ext_cmd
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
__all__ = ["ANTsCoordinatesWarper"]
|
|
@@ -46,6 +46,9 @@ class ANTsCoordinatesWarper:
|
|
|
46
46
|
The transformed coordinates.
|
|
47
47
|
|
|
48
48
|
"""
|
|
49
|
+
# Imported here to avoid circular import
|
|
50
|
+
from ._coordinates import logger
|
|
51
|
+
|
|
49
52
|
logger.debug("Using ANTs for coordinates transformation")
|
|
50
53
|
|
|
51
54
|
# Create element-specific tempdir for storing post-warping assets
|
|
@@ -4,15 +4,17 @@
|
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
|
5
5
|
# License: AGPL
|
|
6
6
|
|
|
7
|
+
from collections import Counter
|
|
7
8
|
from pathlib import Path
|
|
8
|
-
from typing import Any
|
|
9
|
+
from typing import Any
|
|
9
10
|
|
|
10
11
|
import numpy as np
|
|
11
12
|
import pandas as pd
|
|
13
|
+
import structlog
|
|
12
14
|
from junifer_data import get
|
|
13
15
|
from numpy.typing import ArrayLike
|
|
14
16
|
|
|
15
|
-
from ...utils import
|
|
17
|
+
from ...utils import raise_error
|
|
16
18
|
from ..pipeline_data_registry_base import BasePipelineDataRegistry
|
|
17
19
|
from ..utils import JUNIFER_DATA_PARAMS, get_dataset_path, get_native_warper
|
|
18
20
|
from ._ants_coordinates_warper import ANTsCoordinatesWarper
|
|
@@ -21,6 +23,49 @@ from ._fsl_coordinates_warper import FSLCoordinatesWarper
|
|
|
21
23
|
|
|
22
24
|
__all__ = ["CoordinatesRegistry"]
|
|
23
25
|
|
|
26
|
+
_log = structlog.get_logger("junifer")
|
|
27
|
+
logger = _log.bind(pkg="data")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _sanitize_names(names: list) -> list:
|
|
31
|
+
"""Make the VOI names safe to use as feature names.
|
|
32
|
+
|
|
33
|
+
Spaces in the names are replaced with ``_`` and duplicated names get a
|
|
34
|
+
``-{i}`` suffix, where ``i`` is the (1-based) occurrence of the name,
|
|
35
|
+
skipping suffixes that would clash with another name. Non-string names
|
|
36
|
+
are left untouched.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
names : list
|
|
41
|
+
The names of the VOIs.
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
list
|
|
46
|
+
The sanitized, unique names of the VOIs.
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
names = [x.replace(" ", "_") if isinstance(x, str) else x for x in names]
|
|
50
|
+
counts = Counter(names)
|
|
51
|
+
# Unique names are kept, so suffixed names must not clash with them
|
|
52
|
+
used = {name for name in names if counts[name] == 1}
|
|
53
|
+
next_idx: Counter = Counter()
|
|
54
|
+
out = []
|
|
55
|
+
for name in names:
|
|
56
|
+
if counts[name] > 1:
|
|
57
|
+
# Find the next suffix not in use
|
|
58
|
+
while True:
|
|
59
|
+
next_idx[name] += 1
|
|
60
|
+
new_name = f"{name}-{next_idx[name]}"
|
|
61
|
+
if new_name not in used:
|
|
62
|
+
break
|
|
63
|
+
used.add(new_name)
|
|
64
|
+
out.append(new_name)
|
|
65
|
+
else:
|
|
66
|
+
out.append(name)
|
|
67
|
+
return out
|
|
68
|
+
|
|
24
69
|
|
|
25
70
|
class CoordinatesRegistry(BasePipelineDataRegistry):
|
|
26
71
|
"""Class for coordinates data registry.
|
|
@@ -135,7 +180,7 @@ class CoordinatesRegistry(BasePipelineDataRegistry):
|
|
|
135
180
|
coordinates: ArrayLike,
|
|
136
181
|
voi_names: list[str],
|
|
137
182
|
space: str,
|
|
138
|
-
overwrite:
|
|
183
|
+
overwrite: bool | None = False,
|
|
139
184
|
) -> None:
|
|
140
185
|
"""Register a custom user coordinates.
|
|
141
186
|
|
|
@@ -289,8 +334,8 @@ class CoordinatesRegistry(BasePipelineDataRegistry):
|
|
|
289
334
|
)
|
|
290
335
|
# Convert dataframe to numpy ndarray
|
|
291
336
|
coords = df_coords.iloc[:, [0, 1, 2]].to_numpy()
|
|
292
|
-
# Get label names
|
|
293
|
-
names = list(df_coords.iloc[:, [3]].values[:, 0])
|
|
337
|
+
# Get label names, made unique and without spaces
|
|
338
|
+
names = _sanitize_names(list(df_coords.iloc[:, [3]].values[:, 0]))
|
|
294
339
|
# Load data for external ones
|
|
295
340
|
else:
|
|
296
341
|
coords = t_coord["coords"]
|
|
@@ -302,7 +347,7 @@ class CoordinatesRegistry(BasePipelineDataRegistry):
|
|
|
302
347
|
self,
|
|
303
348
|
coords: str,
|
|
304
349
|
target_data: dict[str, Any],
|
|
305
|
-
extra_input:
|
|
350
|
+
extra_input: dict[str, Any] | None = None,
|
|
306
351
|
) -> tuple[ArrayLike, list[str]]:
|
|
307
352
|
"""Get coordinates, tailored for the target data.
|
|
308
353
|
|
|
@@ -9,7 +9,7 @@ import numpy as np
|
|
|
9
9
|
from numpy.typing import ArrayLike
|
|
10
10
|
|
|
11
11
|
from ...pipeline import WorkDirManager
|
|
12
|
-
from ...utils import
|
|
12
|
+
from ...utils import run_ext_cmd
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
__all__ = ["FSLCoordinatesWarper"]
|
|
@@ -46,6 +46,9 @@ class FSLCoordinatesWarper:
|
|
|
46
46
|
The transformed coordinates.
|
|
47
47
|
|
|
48
48
|
"""
|
|
49
|
+
# Imported here to avoid circular import
|
|
50
|
+
from ._coordinates import logger
|
|
51
|
+
|
|
49
52
|
logger.debug("Using FSL for coordinates transformation")
|
|
50
53
|
|
|
51
54
|
# Create element-specific tempdir for storing post-warping assets
|
|
@@ -16,7 +16,10 @@ from junifer.data import (
|
|
|
16
16
|
register_data,
|
|
17
17
|
)
|
|
18
18
|
from junifer.datareader import DefaultDataReader
|
|
19
|
-
from junifer.testing.datagrabbers import
|
|
19
|
+
from junifer.testing.datagrabbers import UCLACNPVBMTestingDataGrabber
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
pytestmark = pytest.mark.external
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
def test_register_built_in_check() -> None:
|
|
@@ -121,6 +124,15 @@ def test_load() -> None:
|
|
|
121
124
|
assert space == "MNI"
|
|
122
125
|
|
|
123
126
|
|
|
127
|
+
def test_load_unique_names() -> None:
|
|
128
|
+
"""Test loading coordinates with duplicated names and spaces."""
|
|
129
|
+
_, names, _ = load_data(kind="coordinates", name="Dosenbach")
|
|
130
|
+
assert len(names) == 160 # type: ignore
|
|
131
|
+
assert len(set(names)) == 160 # type: ignore
|
|
132
|
+
assert not any(" " in x for x in names) # type: ignore
|
|
133
|
+
assert names[:5] == ["vmPFC-1", "aPFC-1", "aPFC-2", "mPFC", "aPFC-3"]
|
|
134
|
+
|
|
135
|
+
|
|
124
136
|
def test_load_nonexisting() -> None:
|
|
125
137
|
"""Test loading coordinates that not exist."""
|
|
126
138
|
with pytest.raises(ValueError, match=r"not found"):
|
|
@@ -130,8 +142,8 @@ def test_load_nonexisting() -> None:
|
|
|
130
142
|
def test_get() -> None:
|
|
131
143
|
"""Test tailored coordinates fetch."""
|
|
132
144
|
reader = DefaultDataReader()
|
|
133
|
-
with
|
|
134
|
-
element = dg["sub-
|
|
145
|
+
with UCLACNPVBMTestingDataGrabber() as dg:
|
|
146
|
+
element = dg["sub-10206"]
|
|
135
147
|
element_data = reader.fit_transform(element)
|
|
136
148
|
vbm_gm = element_data["VBM_GM"]
|
|
137
149
|
# Get tailored coordinates
|