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,20 +3,36 @@
|
|
|
3
3
|
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
|
4
4
|
# License: AGPL
|
|
5
5
|
|
|
6
|
-
from typing import Any, ClassVar,
|
|
6
|
+
from typing import Annotated, Any, ClassVar, Literal
|
|
7
7
|
|
|
8
|
+
import numpy as np
|
|
8
9
|
from nilearn.maskers import NiftiMapsMasker
|
|
10
|
+
from pydantic import BeforeValidator
|
|
9
11
|
|
|
10
12
|
from ..api.decorators import register_marker
|
|
11
13
|
from ..data import get_data
|
|
14
|
+
from ..datagrabber import DataType
|
|
12
15
|
from ..stats import get_aggfunc_by_name
|
|
16
|
+
from ..storage import StorageType
|
|
13
17
|
from ..typing import Dependencies, MarkerInOutMappings
|
|
14
|
-
from ..utils import
|
|
15
|
-
from .base import BaseMarker
|
|
18
|
+
from ..utils import ensure_list_or_none, raise_error, warn_with_log
|
|
19
|
+
from .base import BaseMarker, logger
|
|
16
20
|
|
|
17
21
|
|
|
18
22
|
__all__ = ["MapsAggregation"]
|
|
19
23
|
|
|
24
|
+
_on = Literal[
|
|
25
|
+
DataType.T1w,
|
|
26
|
+
DataType.T2w,
|
|
27
|
+
DataType.BOLD,
|
|
28
|
+
DataType.VBM_GM,
|
|
29
|
+
DataType.VBM_WM,
|
|
30
|
+
DataType.VBM_CSF,
|
|
31
|
+
DataType.FALFF,
|
|
32
|
+
DataType.GCOR,
|
|
33
|
+
DataType.LCOR,
|
|
34
|
+
]
|
|
35
|
+
|
|
20
36
|
|
|
21
37
|
@register_marker
|
|
22
38
|
class MapsAggregation(BaseMarker):
|
|
@@ -27,23 +43,26 @@ class MapsAggregation(BaseMarker):
|
|
|
27
43
|
maps : str
|
|
28
44
|
The name of the map(s) to use.
|
|
29
45
|
See :func:`.list_data` for options.
|
|
30
|
-
time_method : str, optional
|
|
31
|
-
The
|
|
32
|
-
|
|
46
|
+
time_method : str or None, optional
|
|
47
|
+
The aggregation function to use for time series after applying
|
|
48
|
+
:term:`method` (only applicable to BOLD data). If None,
|
|
33
49
|
it will not operate on the time dimension (default None).
|
|
34
|
-
time_method_params : dict, optional
|
|
50
|
+
time_method_params : dict or None, optional
|
|
35
51
|
The parameters to pass to the time aggregation method (default None).
|
|
36
|
-
|
|
52
|
+
on : {``DataType.T1w``, ``DataType.T2w``, ``DataType.BOLD``, \
|
|
53
|
+
``DataType.VBM_GM``, ``DataType.VBM_WM``, ``DataType.VBM_CSF``, \
|
|
54
|
+
``DataType.FALFF``, ``DataType.GCOR``, ``DataType.LCOR``} or \
|
|
55
|
+
list of them or None, optional
|
|
56
|
+
The data type(s) to apply the marker on.
|
|
57
|
+
If None, will work on all available data.
|
|
58
|
+
Check :enum:`.DataType` for valid values (default None).
|
|
59
|
+
masks : str, dict, list of them or None, optional
|
|
37
60
|
The specification of the masks to apply to regions before extracting
|
|
38
61
|
signals. Check :ref:`Using Masks <using_masks>` for more details.
|
|
39
62
|
If None, will not apply any mask (default None).
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
available data (default None).
|
|
44
|
-
name : str, optional
|
|
45
|
-
The name of the marker. If None, will use the class name (default
|
|
46
|
-
None).
|
|
63
|
+
name : str or None, optional
|
|
64
|
+
The name of the marker.
|
|
65
|
+
If None, will use the class name (default None).
|
|
47
66
|
|
|
48
67
|
Raises
|
|
49
68
|
------
|
|
@@ -56,64 +75,62 @@ class MapsAggregation(BaseMarker):
|
|
|
56
75
|
_DEPENDENCIES: ClassVar[Dependencies] = {"nilearn", "numpy"}
|
|
57
76
|
|
|
58
77
|
_MARKER_INOUT_MAPPINGS: ClassVar[MarkerInOutMappings] = {
|
|
59
|
-
|
|
60
|
-
"aggregation":
|
|
78
|
+
DataType.T1w: {
|
|
79
|
+
"aggregation": StorageType.Vector,
|
|
61
80
|
},
|
|
62
|
-
|
|
63
|
-
"aggregation":
|
|
81
|
+
DataType.T2w: {
|
|
82
|
+
"aggregation": StorageType.Vector,
|
|
64
83
|
},
|
|
65
|
-
|
|
66
|
-
"aggregation":
|
|
84
|
+
DataType.BOLD: {
|
|
85
|
+
"aggregation": StorageType.Timeseries,
|
|
67
86
|
},
|
|
68
|
-
|
|
69
|
-
"aggregation":
|
|
87
|
+
DataType.VBM_GM: {
|
|
88
|
+
"aggregation": StorageType.Vector,
|
|
70
89
|
},
|
|
71
|
-
|
|
72
|
-
"aggregation":
|
|
90
|
+
DataType.VBM_WM: {
|
|
91
|
+
"aggregation": StorageType.Vector,
|
|
73
92
|
},
|
|
74
|
-
|
|
75
|
-
"aggregation":
|
|
93
|
+
DataType.VBM_CSF: {
|
|
94
|
+
"aggregation": StorageType.Vector,
|
|
76
95
|
},
|
|
77
|
-
|
|
78
|
-
"aggregation":
|
|
96
|
+
DataType.FALFF: {
|
|
97
|
+
"aggregation": StorageType.Vector,
|
|
79
98
|
},
|
|
80
|
-
|
|
81
|
-
"aggregation":
|
|
99
|
+
DataType.GCOR: {
|
|
100
|
+
"aggregation": StorageType.Vector,
|
|
82
101
|
},
|
|
83
|
-
|
|
84
|
-
"aggregation":
|
|
102
|
+
DataType.LCOR: {
|
|
103
|
+
"aggregation": StorageType.Vector,
|
|
85
104
|
},
|
|
86
105
|
}
|
|
87
106
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
#
|
|
102
|
-
if "BOLD" not in self.
|
|
107
|
+
maps: str
|
|
108
|
+
time_method: str | None = None
|
|
109
|
+
time_method_params: dict[str, Any] | None = None
|
|
110
|
+
masks: Annotated[
|
|
111
|
+
dict | str | list[dict | str] | None,
|
|
112
|
+
BeforeValidator(ensure_list_or_none),
|
|
113
|
+
] = None
|
|
114
|
+
on: Annotated[
|
|
115
|
+
_on | list[_on] | None, BeforeValidator(ensure_list_or_none)
|
|
116
|
+
] = None
|
|
117
|
+
|
|
118
|
+
def validate_marker_params(self) -> None:
|
|
119
|
+
"""Run extra logical validation for marker."""
|
|
120
|
+
# self.on is set already
|
|
121
|
+
if "BOLD" not in self.on and self.time_method is not None:
|
|
103
122
|
raise_error(
|
|
104
123
|
"`time_method` can only be used with BOLD data. "
|
|
105
124
|
"Please remove `time_method` parameter."
|
|
106
125
|
)
|
|
107
|
-
if time_method is None and time_method_params is not None:
|
|
126
|
+
if self.time_method is None and self.time_method_params is not None:
|
|
108
127
|
raise_error(
|
|
109
128
|
"`time_method_params` can only be used with `time_method`. "
|
|
110
129
|
"Please remove `time_method_params` parameter."
|
|
111
130
|
)
|
|
112
|
-
self.time_method = time_method
|
|
113
|
-
self.time_method_params = time_method_params or {}
|
|
114
131
|
|
|
115
132
|
def compute(
|
|
116
|
-
self, input: dict[str, Any], extra_input:
|
|
133
|
+
self, input: dict[str, Any], extra_input: dict | None = None
|
|
117
134
|
) -> dict:
|
|
118
135
|
"""Compute.
|
|
119
136
|
|
|
@@ -169,15 +186,20 @@ class MapsAggregation(BaseMarker):
|
|
|
169
186
|
extra_input=extra_input,
|
|
170
187
|
)
|
|
171
188
|
|
|
172
|
-
# Initialize masker
|
|
189
|
+
# Initialize masker; the maps (and mask) are already tailored to the
|
|
190
|
+
# input image, so no resampling is needed
|
|
173
191
|
logger.debug("Masking")
|
|
174
192
|
masker = NiftiMapsMasker(
|
|
175
193
|
maps_img=maps_img,
|
|
176
194
|
mask_img=mask_img,
|
|
177
|
-
|
|
195
|
+
resampling_target=None,
|
|
196
|
+
standardize=None,
|
|
197
|
+
# Not used, and computing their data at fit time reads the data
|
|
198
|
+
reports=False,
|
|
178
199
|
)
|
|
179
200
|
# Mask the input data and extract data
|
|
180
|
-
|
|
201
|
+
# nilearn maskers return 1D arrays for 3D images, keep 2D
|
|
202
|
+
data = np.atleast_2d(masker.fit_transform(t_input_img))
|
|
181
203
|
|
|
182
204
|
# Apply time dimension aggregation if required
|
|
183
205
|
if self.time_method is not None:
|
|
@@ -4,22 +4,42 @@
|
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
|
5
5
|
# License: AGPL
|
|
6
6
|
|
|
7
|
-
from typing import Any, ClassVar,
|
|
7
|
+
from typing import Annotated, Any, ClassVar, Literal
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
from nilearn.image import math_img
|
|
11
11
|
from nilearn.maskers import NiftiMasker
|
|
12
|
+
from pydantic import BeforeValidator
|
|
12
13
|
|
|
13
14
|
from ..api.decorators import register_marker
|
|
14
15
|
from ..data import get_data
|
|
16
|
+
from ..datagrabber import DataType
|
|
15
17
|
from ..stats import get_aggfunc_by_name
|
|
18
|
+
from ..storage import StorageType
|
|
16
19
|
from ..typing import Dependencies, MarkerInOutMappings
|
|
17
|
-
from ..utils import
|
|
18
|
-
|
|
20
|
+
from ..utils import (
|
|
21
|
+
ensure_list,
|
|
22
|
+
ensure_list_or_none,
|
|
23
|
+
raise_error,
|
|
24
|
+
warn_with_log,
|
|
25
|
+
)
|
|
26
|
+
from .base import BaseMarker, logger
|
|
19
27
|
|
|
20
28
|
|
|
21
29
|
__all__ = ["ParcelAggregation"]
|
|
22
30
|
|
|
31
|
+
_on = Literal[
|
|
32
|
+
DataType.T1w,
|
|
33
|
+
DataType.T2w,
|
|
34
|
+
DataType.BOLD,
|
|
35
|
+
DataType.VBM_GM,
|
|
36
|
+
DataType.VBM_WM,
|
|
37
|
+
DataType.VBM_CSF,
|
|
38
|
+
DataType.FALFF,
|
|
39
|
+
DataType.GCOR,
|
|
40
|
+
DataType.LCOR,
|
|
41
|
+
]
|
|
42
|
+
|
|
23
43
|
|
|
24
44
|
@register_marker
|
|
25
45
|
class ParcelAggregation(BaseMarker):
|
|
@@ -30,29 +50,33 @@ class ParcelAggregation(BaseMarker):
|
|
|
30
50
|
parcellation : str or list of str
|
|
31
51
|
The name(s) of the parcellation(s) to use.
|
|
32
52
|
See :func:`.list_data` for options.
|
|
33
|
-
method : str
|
|
34
|
-
The
|
|
35
|
-
:func:`.get_aggfunc_by_name
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
53
|
+
method : str, optional
|
|
54
|
+
The aggregation function to use.
|
|
55
|
+
See :func:`.get_aggfunc_by_name` for options
|
|
56
|
+
(default "mean").
|
|
57
|
+
method_params : dict or None, optional
|
|
58
|
+
The parameters to pass to the aggregation function.
|
|
59
|
+
See :func:`.get_aggfunc_by_name` for options (default None).
|
|
60
|
+
time_method : str or None, optional
|
|
61
|
+
The aggregation function to use for time series after applying
|
|
62
|
+
:term:`method` (only applicable to BOLD data). If None,
|
|
42
63
|
it will not operate on the time dimension (default None).
|
|
43
|
-
time_method_params : dict, optional
|
|
44
|
-
The parameters to pass to the time aggregation
|
|
45
|
-
|
|
64
|
+
time_method_params : dict or None, optional
|
|
65
|
+
The parameters to pass to the time aggregation function (default None).
|
|
66
|
+
on : {``DataType.T1w``, ``DataType.T2w``, ``DataType.BOLD``, \
|
|
67
|
+
``DataType.VBM_GM``, ``DataType.VBM_WM``, ``DataType.VBM_CSF``, \
|
|
68
|
+
``DataType.FALFF``, ``DataType.GCOR``, ``DataType.LCOR``} or \
|
|
69
|
+
list of them or None, optional
|
|
70
|
+
The data type(s) to apply the marker on.
|
|
71
|
+
If None, will work on all available data.
|
|
72
|
+
Check :enum:`.DataType` for valid values (default None).
|
|
73
|
+
masks : str, dict, list of them or None, optional
|
|
46
74
|
The specification of the masks to apply to regions before extracting
|
|
47
75
|
signals. Check :ref:`Using Masks <using_masks>` for more details.
|
|
48
76
|
If None, will not apply any mask (default None).
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
available data (default None).
|
|
53
|
-
name : str, optional
|
|
54
|
-
The name of the marker. If None, will use the class name (default
|
|
55
|
-
None).
|
|
77
|
+
name : str or None, optional
|
|
78
|
+
The name of the marker.
|
|
79
|
+
If None, will use the class name (default None).
|
|
56
80
|
|
|
57
81
|
Raises
|
|
58
82
|
------
|
|
@@ -65,70 +89,64 @@ class ParcelAggregation(BaseMarker):
|
|
|
65
89
|
_DEPENDENCIES: ClassVar[Dependencies] = {"nilearn", "numpy"}
|
|
66
90
|
|
|
67
91
|
_MARKER_INOUT_MAPPINGS: ClassVar[MarkerInOutMappings] = {
|
|
68
|
-
|
|
69
|
-
"aggregation":
|
|
92
|
+
DataType.T1w: {
|
|
93
|
+
"aggregation": StorageType.Vector,
|
|
70
94
|
},
|
|
71
|
-
|
|
72
|
-
"aggregation":
|
|
95
|
+
DataType.T2w: {
|
|
96
|
+
"aggregation": StorageType.Vector,
|
|
73
97
|
},
|
|
74
|
-
|
|
75
|
-
"aggregation":
|
|
98
|
+
DataType.BOLD: {
|
|
99
|
+
"aggregation": StorageType.Timeseries,
|
|
76
100
|
},
|
|
77
|
-
|
|
78
|
-
"aggregation":
|
|
101
|
+
DataType.VBM_GM: {
|
|
102
|
+
"aggregation": StorageType.Vector,
|
|
79
103
|
},
|
|
80
|
-
|
|
81
|
-
"aggregation":
|
|
104
|
+
DataType.VBM_WM: {
|
|
105
|
+
"aggregation": StorageType.Vector,
|
|
82
106
|
},
|
|
83
|
-
|
|
84
|
-
"aggregation":
|
|
107
|
+
DataType.VBM_CSF: {
|
|
108
|
+
"aggregation": StorageType.Vector,
|
|
85
109
|
},
|
|
86
|
-
|
|
87
|
-
"aggregation":
|
|
110
|
+
DataType.FALFF: {
|
|
111
|
+
"aggregation": StorageType.Vector,
|
|
88
112
|
},
|
|
89
|
-
|
|
90
|
-
"aggregation":
|
|
113
|
+
DataType.GCOR: {
|
|
114
|
+
"aggregation": StorageType.Vector,
|
|
91
115
|
},
|
|
92
|
-
|
|
93
|
-
"aggregation":
|
|
116
|
+
DataType.LCOR: {
|
|
117
|
+
"aggregation": StorageType.Vector,
|
|
94
118
|
},
|
|
95
119
|
}
|
|
96
120
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
self.
|
|
113
|
-
self.
|
|
114
|
-
super().__init__(on=on, name=name)
|
|
115
|
-
|
|
116
|
-
# Verify after super init so self._on is set
|
|
117
|
-
if "BOLD" not in self._on and time_method is not None:
|
|
121
|
+
parcellation: Annotated[str | list[str], BeforeValidator(ensure_list)]
|
|
122
|
+
method: str = "mean"
|
|
123
|
+
method_params: dict[str, Any] | None = None
|
|
124
|
+
time_method: str | None = None
|
|
125
|
+
time_method_params: dict[str, Any] | None = None
|
|
126
|
+
masks: Annotated[
|
|
127
|
+
dict | str | list[dict | str] | None,
|
|
128
|
+
BeforeValidator(ensure_list_or_none),
|
|
129
|
+
] = None
|
|
130
|
+
on: Annotated[
|
|
131
|
+
_on | list[_on] | None, BeforeValidator(ensure_list_or_none)
|
|
132
|
+
] = None
|
|
133
|
+
|
|
134
|
+
def validate_marker_params(self) -> None:
|
|
135
|
+
"""Run extra logical validation for marker."""
|
|
136
|
+
# self.on is set already
|
|
137
|
+
if "BOLD" not in self.on and self.time_method is not None:
|
|
118
138
|
raise_error(
|
|
119
139
|
"`time_method` can only be used with BOLD data. "
|
|
120
140
|
"Please remove `time_method` parameter."
|
|
121
141
|
)
|
|
122
|
-
if time_method is None and time_method_params is not None:
|
|
142
|
+
if self.time_method is None and self.time_method_params is not None:
|
|
123
143
|
raise_error(
|
|
124
144
|
"`time_method_params` can only be used with `time_method`. "
|
|
125
145
|
"Please remove `time_method_params` parameter."
|
|
126
146
|
)
|
|
127
|
-
self.time_method = time_method
|
|
128
|
-
self.time_method_params = time_method_params or {}
|
|
129
147
|
|
|
130
148
|
def compute(
|
|
131
|
-
self, input: dict[str, Any], extra_input:
|
|
149
|
+
self, input: dict[str, Any], extra_input: dict | None = None
|
|
132
150
|
) -> dict:
|
|
133
151
|
"""Compute.
|
|
134
152
|
|
|
@@ -198,13 +216,16 @@ class ParcelAggregation(BaseMarker):
|
|
|
198
216
|
mask=mask_img,
|
|
199
217
|
)
|
|
200
218
|
|
|
201
|
-
# Initialize masker
|
|
219
|
+
# Initialize masker; the parcellation (and mask) are already
|
|
220
|
+
# tailored to the input image, so no target affine is needed (it
|
|
221
|
+
# would make nilearn crop and copy the input image)
|
|
202
222
|
logger.debug("Masking")
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
)
|
|
223
|
+
# No reports, as they are not used and computing their data at fit
|
|
224
|
+
# time reads the data
|
|
225
|
+
masker = NiftiMasker(parcellation_bin, standardize=None, reports=False)
|
|
206
226
|
# Mask the input data and the parcellation
|
|
207
|
-
|
|
227
|
+
# nilearn maskers return 1D arrays for 3D images, keep 2D
|
|
228
|
+
data = np.atleast_2d(masker.fit_transform(t_input_img))
|
|
208
229
|
parcellation_values = np.squeeze(
|
|
209
230
|
masker.transform(parcellation_img)
|
|
210
231
|
).astype(int)
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
__all__ = [
|
|
1
|
+
__all__ = [
|
|
2
|
+
"ReHoImpl",
|
|
3
|
+
"ReHoMaps",
|
|
4
|
+
"ReHoParcels",
|
|
5
|
+
"ReHoSpheres",
|
|
6
|
+
]
|
|
2
7
|
|
|
8
|
+
from .reho_base import ReHoImpl
|
|
3
9
|
from .reho_maps import ReHoMaps
|
|
4
10
|
from .reho_parcels import ReHoParcels
|
|
5
11
|
from .reho_spheres import ReHoSpheres
|
|
@@ -3,20 +3,21 @@
|
|
|
3
3
|
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
|
4
4
|
# License: AGPL
|
|
5
5
|
|
|
6
|
+
import atexit
|
|
6
7
|
from functools import lru_cache
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from typing import (
|
|
9
10
|
TYPE_CHECKING,
|
|
10
11
|
ClassVar,
|
|
11
|
-
Optional,
|
|
12
12
|
)
|
|
13
13
|
|
|
14
14
|
import nibabel as nib
|
|
15
15
|
|
|
16
|
-
from ...pipeline import WorkDirManager
|
|
16
|
+
from ...pipeline import ExtDep, WorkDirManager
|
|
17
17
|
from ...typing import ExternalDependencies
|
|
18
|
-
from ...utils import
|
|
18
|
+
from ...utils import run_ext_cmd
|
|
19
19
|
from ...utils.singleton import Singleton
|
|
20
|
+
from ..base import logger
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
if TYPE_CHECKING:
|
|
@@ -36,13 +37,15 @@ class AFNIReHo(metaclass=Singleton):
|
|
|
36
37
|
|
|
37
38
|
_EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
|
|
38
39
|
{
|
|
39
|
-
"name":
|
|
40
|
+
"name": ExtDep.AFNI,
|
|
40
41
|
"commands": ["3dReHo", "3dAFNItoNIFTI"],
|
|
41
42
|
},
|
|
42
43
|
]
|
|
43
44
|
|
|
44
|
-
def
|
|
45
|
-
|
|
45
|
+
def __init__(self) -> None:
|
|
46
|
+
atexit.register(self._del)
|
|
47
|
+
|
|
48
|
+
def _del(self) -> None:
|
|
46
49
|
# Clear the computation cache
|
|
47
50
|
logger.debug("Clearing cache for ReHo computation via AFNI")
|
|
48
51
|
self.compute.cache_clear()
|
|
@@ -52,14 +55,15 @@ class AFNIReHo(metaclass=Singleton):
|
|
|
52
55
|
self,
|
|
53
56
|
input_path: Path,
|
|
54
57
|
nneigh: int = 27,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
mask_path: Path | None = None,
|
|
59
|
+
neigh_rad: float | None = None,
|
|
60
|
+
neigh_x: float | None = None,
|
|
61
|
+
neigh_y: float | None = None,
|
|
62
|
+
neigh_z: float | None = None,
|
|
63
|
+
box_rad: int | None = None,
|
|
64
|
+
box_x: int | None = None,
|
|
65
|
+
box_y: int | None = None,
|
|
66
|
+
box_z: int | None = None,
|
|
63
67
|
) -> tuple["Nifti1Image", Path]:
|
|
64
68
|
"""Compute ReHo map.
|
|
65
69
|
|
|
@@ -75,6 +79,9 @@ class AFNIReHo(metaclass=Singleton):
|
|
|
75
79
|
* 27 : for face-, edge-, and node-wise neighbors
|
|
76
80
|
|
|
77
81
|
(default 27).
|
|
82
|
+
mask_path : pathlib.Path or None, optional
|
|
83
|
+
Path to the mask to restrict the computation to, passed to
|
|
84
|
+
``3dReHo`` as ``-mask``. If None, no mask is used (default None).
|
|
78
85
|
neigh_rad : positive float, optional
|
|
79
86
|
The radius of a desired neighbourhood (default None).
|
|
80
87
|
neigh_x : positive float, optional
|
|
@@ -140,6 +147,8 @@ class AFNIReHo(metaclass=Singleton):
|
|
|
140
147
|
f"-prefix {reho_out_path_prefix.resolve()}",
|
|
141
148
|
f"-inset {input_path.resolve()}",
|
|
142
149
|
]
|
|
150
|
+
if mask_path is not None:
|
|
151
|
+
reho_cmd.append(f"-mask {mask_path.resolve()}")
|
|
143
152
|
# Check ellipsoidal / cuboidal volume arguments
|
|
144
153
|
if neigh_rad:
|
|
145
154
|
reho_cmd.append(f"-neigh_RAD {neigh_rad}")
|