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
|
@@ -7,19 +7,23 @@ import logging
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
9
|
import pytest
|
|
10
|
-
|
|
10
|
+
from numpy.testing import assert_allclose
|
|
11
11
|
|
|
12
|
+
from junifer.datagrabber import DataType
|
|
12
13
|
from junifer.datareader import DefaultDataReader
|
|
13
|
-
from junifer.markers import ReHoParcels
|
|
14
|
+
from junifer.markers import ReHoImpl, ReHoParcels
|
|
14
15
|
from junifer.pipeline import WorkDirManager
|
|
15
|
-
from junifer.pipeline.utils import _check_afni
|
|
16
|
-
from junifer.storage import
|
|
16
|
+
from junifer.pipeline.utils import _check_afni
|
|
17
|
+
from junifer.storage import HDF5FeatureStorage
|
|
17
18
|
from junifer.testing.datagrabbers import (
|
|
19
|
+
ADHDTestingDataGrabber,
|
|
18
20
|
PartlyCloudyTestingDataGrabber,
|
|
19
|
-
SPMAuditoryTestingDataGrabber,
|
|
20
21
|
)
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
pytestmark = pytest.mark.external
|
|
25
|
+
|
|
26
|
+
|
|
23
27
|
def test_ReHoParcels(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
|
24
28
|
"""Test ReHoParcels.
|
|
25
29
|
|
|
@@ -32,7 +36,7 @@ def test_ReHoParcels(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
|
|
32
36
|
|
|
33
37
|
"""
|
|
34
38
|
with caplog.at_level(logging.DEBUG):
|
|
35
|
-
with PartlyCloudyTestingDataGrabber() as dg:
|
|
39
|
+
with PartlyCloudyTestingDataGrabber(n_timepoints=50) as dg:
|
|
36
40
|
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
|
37
41
|
# Update workdir to current test's tmp_path
|
|
38
42
|
WorkDirManager().workdir = tmp_path
|
|
@@ -40,11 +44,11 @@ def test_ReHoParcels(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
|
|
40
44
|
# Initialize marker
|
|
41
45
|
marker = ReHoParcels(
|
|
42
46
|
parcellation="TianxS1x3TxMNInonlinear2009cAsym",
|
|
43
|
-
using=
|
|
47
|
+
using=ReHoImpl.junifer,
|
|
44
48
|
)
|
|
45
49
|
# Check correct output
|
|
46
50
|
assert "vector" == marker.storage_type(
|
|
47
|
-
input_type=
|
|
51
|
+
input_type=DataType.BOLD, output_feature="reho"
|
|
48
52
|
)
|
|
49
53
|
|
|
50
54
|
# Fit transform marker on data
|
|
@@ -70,7 +74,7 @@ def test_ReHoParcels(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
|
|
70
74
|
# Reset log capture
|
|
71
75
|
caplog.clear()
|
|
72
76
|
# Initialize storage
|
|
73
|
-
storage =
|
|
77
|
+
storage = HDF5FeatureStorage(uri=tmp_path / "reho_parcels.hdf5")
|
|
74
78
|
# Fit transform marker on data with storage
|
|
75
79
|
marker.fit_transform(
|
|
76
80
|
input=element_data,
|
|
@@ -80,29 +84,31 @@ def test_ReHoParcels(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
|
|
80
84
|
assert "Creating cache" not in caplog.text
|
|
81
85
|
|
|
82
86
|
|
|
83
|
-
@pytest.mark.skipif(
|
|
84
|
-
_check_ants() is False, reason="requires ANTs to be in PATH"
|
|
85
|
-
)
|
|
86
87
|
@pytest.mark.skipif(
|
|
87
88
|
_check_afni() is False, reason="requires AFNI to be in PATH"
|
|
88
89
|
)
|
|
89
|
-
|
|
90
|
+
@pytest.mark.parametrize("masks", [None, "compute_brain_mask"])
|
|
91
|
+
def test_ReHoParcels_comparison(tmp_path: Path, masks: str | None) -> None:
|
|
90
92
|
"""Test ReHoParcels implementation comparison.
|
|
91
93
|
|
|
92
94
|
Parameters
|
|
93
95
|
----------
|
|
94
96
|
tmp_path : pathlib.Path
|
|
95
97
|
The path to the test directory.
|
|
98
|
+
masks : str or None
|
|
99
|
+
The masks to use.
|
|
96
100
|
|
|
97
101
|
"""
|
|
98
|
-
with
|
|
99
|
-
|
|
102
|
+
# Use float data with few ties: ReHo is rank-based and the
|
|
103
|
+
# implementations handle tied values differently
|
|
104
|
+
with ADHDTestingDataGrabber() as dg:
|
|
105
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
|
|
100
106
|
# Update workdir to current test's tmp_path
|
|
101
107
|
WorkDirManager().workdir = tmp_path
|
|
102
108
|
|
|
103
109
|
# Initialize marker
|
|
104
110
|
junifer_marker = ReHoParcels(
|
|
105
|
-
parcellation="Schaefer100x7", using=
|
|
111
|
+
parcellation="Schaefer100x7", using=ReHoImpl.junifer, masks=masks
|
|
106
112
|
)
|
|
107
113
|
# Fit transform marker on data
|
|
108
114
|
junifer_output = junifer_marker.fit_transform(element_data)
|
|
@@ -110,15 +116,15 @@ def test_ReHoParcels_comparison(tmp_path: Path) -> None:
|
|
|
110
116
|
junifer_output_bold = junifer_output["BOLD"]["reho"]
|
|
111
117
|
|
|
112
118
|
# Initialize marker
|
|
113
|
-
afni_marker = ReHoParcels(
|
|
119
|
+
afni_marker = ReHoParcels(
|
|
120
|
+
parcellation="Schaefer100x7", using=ReHoImpl.afni, masks=masks
|
|
121
|
+
)
|
|
114
122
|
# Fit transform marker on data
|
|
115
123
|
afni_output = afni_marker.fit_transform(element_data)
|
|
116
124
|
# Get BOLD output
|
|
117
125
|
afni_output_bold = afni_output["BOLD"]["reho"]
|
|
118
126
|
|
|
119
|
-
#
|
|
120
|
-
|
|
121
|
-
junifer_output_bold["data"]
|
|
122
|
-
afni_output_bold["data"].flatten(),
|
|
127
|
+
# Both implementations should give the same results
|
|
128
|
+
assert_allclose(
|
|
129
|
+
junifer_output_bold["data"], afni_output_bold["data"], atol=1e-6
|
|
123
130
|
)
|
|
124
|
-
assert r >= 0.2 # this is very bad, but they differ...
|
|
@@ -7,16 +7,20 @@ import logging
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
9
|
import pytest
|
|
10
|
-
import scipy as
|
|
10
|
+
import scipy.stats as sps
|
|
11
11
|
|
|
12
|
+
from junifer.datagrabber import DataType
|
|
12
13
|
from junifer.datareader import DefaultDataReader
|
|
13
|
-
from junifer.markers import ReHoSpheres
|
|
14
|
+
from junifer.markers import ReHoImpl, ReHoSpheres
|
|
14
15
|
from junifer.pipeline import WorkDirManager
|
|
15
16
|
from junifer.pipeline.utils import _check_afni
|
|
16
|
-
from junifer.storage import
|
|
17
|
+
from junifer.storage import HDF5FeatureStorage
|
|
17
18
|
from junifer.testing.datagrabbers import SPMAuditoryTestingDataGrabber
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
pytestmark = pytest.mark.external
|
|
22
|
+
|
|
23
|
+
|
|
20
24
|
COORDINATES = "DMNBuckner"
|
|
21
25
|
|
|
22
26
|
|
|
@@ -32,17 +36,17 @@ def test_ReHoSpheres(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
|
|
32
36
|
|
|
33
37
|
"""
|
|
34
38
|
with caplog.at_level(logging.DEBUG):
|
|
35
|
-
with SPMAuditoryTestingDataGrabber() as dg:
|
|
39
|
+
with SPMAuditoryTestingDataGrabber(n_timepoints=50) as dg:
|
|
36
40
|
element_data = DefaultDataReader().fit_transform(dg["sub001"])
|
|
37
41
|
# Update workdir to current test's tmp_path
|
|
38
42
|
WorkDirManager().workdir = tmp_path
|
|
39
43
|
# Initialize marker
|
|
40
44
|
marker = ReHoSpheres(
|
|
41
|
-
coords=COORDINATES, using=
|
|
45
|
+
coords=COORDINATES, using=ReHoImpl.junifer, radius=10.0
|
|
42
46
|
)
|
|
43
47
|
# Check correct output
|
|
44
48
|
assert "vector" == marker.storage_type(
|
|
45
|
-
input_type=
|
|
49
|
+
input_type=DataType.BOLD, output_feature="reho"
|
|
46
50
|
)
|
|
47
51
|
|
|
48
52
|
# Fit transform marker on data
|
|
@@ -68,7 +72,7 @@ def test_ReHoSpheres(caplog: pytest.LogCaptureFixture, tmp_path: Path) -> None:
|
|
|
68
72
|
# Reset log capture
|
|
69
73
|
caplog.clear()
|
|
70
74
|
# Initialize storage
|
|
71
|
-
storage =
|
|
75
|
+
storage = HDF5FeatureStorage(uri=tmp_path / "reho_spheres.hdf5")
|
|
72
76
|
# Fit transform marker on data with storage
|
|
73
77
|
marker.fit_transform(
|
|
74
78
|
input=element_data,
|
|
@@ -90,7 +94,7 @@ def test_ReHoSpheres_comparison(tmp_path: Path) -> None:
|
|
|
90
94
|
The path to the test directory.
|
|
91
95
|
|
|
92
96
|
"""
|
|
93
|
-
with SPMAuditoryTestingDataGrabber() as dg:
|
|
97
|
+
with SPMAuditoryTestingDataGrabber(n_timepoints=50) as dg:
|
|
94
98
|
element_data = DefaultDataReader().fit_transform(dg["sub001"])
|
|
95
99
|
# Update workdir to current test's tmp_path
|
|
96
100
|
WorkDirManager().workdir = tmp_path
|
|
@@ -98,7 +102,7 @@ def test_ReHoSpheres_comparison(tmp_path: Path) -> None:
|
|
|
98
102
|
# Initialize marker
|
|
99
103
|
junifer_marker = ReHoSpheres(
|
|
100
104
|
coords=COORDINATES,
|
|
101
|
-
using=
|
|
105
|
+
using=ReHoImpl.junifer,
|
|
102
106
|
radius=10.0,
|
|
103
107
|
)
|
|
104
108
|
# Fit transform marker on data
|
|
@@ -109,7 +113,7 @@ def test_ReHoSpheres_comparison(tmp_path: Path) -> None:
|
|
|
109
113
|
# Initialize marker
|
|
110
114
|
afni_marker = ReHoSpheres(
|
|
111
115
|
coords=COORDINATES,
|
|
112
|
-
using=
|
|
116
|
+
using=ReHoImpl.afni,
|
|
113
117
|
radius=10.0,
|
|
114
118
|
)
|
|
115
119
|
# Fit transform marker on data
|
|
@@ -118,8 +122,8 @@ def test_ReHoSpheres_comparison(tmp_path: Path) -> None:
|
|
|
118
122
|
afni_output_bold = afni_output["BOLD"]["reho"]
|
|
119
123
|
|
|
120
124
|
# Check for Pearson correlation coefficient
|
|
121
|
-
r, _ =
|
|
125
|
+
r, _ = sps.pearsonr(
|
|
122
126
|
junifer_output_bold["data"].flatten(),
|
|
123
127
|
afni_output_bold["data"].flatten(),
|
|
124
128
|
)
|
|
125
|
-
assert r >= 0.
|
|
129
|
+
assert r >= 0.99
|
|
@@ -4,19 +4,36 @@
|
|
|
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
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
from pydantic import BeforeValidator, PositiveFloat
|
|
8
11
|
|
|
9
12
|
from ..api.decorators import register_marker
|
|
10
13
|
from ..data import get_data
|
|
14
|
+
from ..datagrabber import DataType
|
|
11
15
|
from ..external.nilearn import JuniferNiftiSpheresMasker
|
|
12
16
|
from ..stats import get_aggfunc_by_name
|
|
17
|
+
from ..storage import StorageType
|
|
13
18
|
from ..typing import Dependencies, MarkerInOutMappings
|
|
14
|
-
from ..utils import
|
|
15
|
-
from .base import BaseMarker
|
|
19
|
+
from ..utils import ensure_list_or_none, raise_error, warn_with_log
|
|
20
|
+
from .base import BaseMarker, logger
|
|
16
21
|
|
|
17
22
|
|
|
18
23
|
__all__ = ["SphereAggregation"]
|
|
19
24
|
|
|
25
|
+
_on = Literal[
|
|
26
|
+
DataType.T1w,
|
|
27
|
+
DataType.T2w,
|
|
28
|
+
DataType.BOLD,
|
|
29
|
+
DataType.VBM_GM,
|
|
30
|
+
DataType.VBM_WM,
|
|
31
|
+
DataType.VBM_CSF,
|
|
32
|
+
DataType.FALFF,
|
|
33
|
+
DataType.GCOR,
|
|
34
|
+
DataType.LCOR,
|
|
35
|
+
]
|
|
36
|
+
|
|
20
37
|
|
|
21
38
|
@register_marker
|
|
22
39
|
class SphereAggregation(BaseMarker):
|
|
@@ -27,37 +44,41 @@ class SphereAggregation(BaseMarker):
|
|
|
27
44
|
coords : str
|
|
28
45
|
The name of the coordinates list to use.
|
|
29
46
|
See :func:`.list_data` for options.
|
|
30
|
-
radius : float, optional
|
|
31
|
-
The radius of the sphere in millimeters.
|
|
32
|
-
extracted from a single voxel.
|
|
33
|
-
:class
|
|
47
|
+
radius : ``zero`` or positive float or None, optional
|
|
48
|
+
The radius of the sphere in millimeters.
|
|
49
|
+
If None, the signal will be extracted from a single voxel.
|
|
50
|
+
See :class:`.JuniferNiftiSpheresMasker` for more information
|
|
34
51
|
(default None).
|
|
35
52
|
allow_overlap : bool, optional
|
|
36
|
-
Whether to allow overlapping spheres.
|
|
37
|
-
the spheres overlap (default
|
|
53
|
+
Whether to allow overlapping spheres.
|
|
54
|
+
If False, an error is raised if the spheres overlap (default False).
|
|
38
55
|
method : str, optional
|
|
39
|
-
The aggregation
|
|
40
|
-
See :func:`.get_aggfunc_by_name` for
|
|
56
|
+
The aggregation function to use.
|
|
57
|
+
See :func:`.get_aggfunc_by_name` for options
|
|
41
58
|
(default "mean").
|
|
42
|
-
method_params : dict, optional
|
|
43
|
-
The parameters to pass to the aggregation
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
59
|
+
method_params : dict or None, optional
|
|
60
|
+
The parameters to pass to the aggregation function.
|
|
61
|
+
See :func:`.get_aggfunc_by_name` for options (default None).
|
|
62
|
+
time_method : str or None, optional
|
|
63
|
+
The aggregation function to use for time series after applying
|
|
64
|
+
:term:`method` (only applicable to BOLD data). If None,
|
|
47
65
|
it will not operate on the time dimension (default None).
|
|
48
|
-
time_method_params : dict, optional
|
|
49
|
-
The parameters to pass to the time aggregation
|
|
50
|
-
|
|
66
|
+
time_method_params : dict or None, optional
|
|
67
|
+
The parameters to pass to the time aggregation function (default None).
|
|
68
|
+
on : {``DataType.T1w``, ``DataType.T2w``, ``DataType.BOLD``, \
|
|
69
|
+
``DataType.VBM_GM``, ``DataType.VBM_WM``, ``DataType.VBM_CSF``, \
|
|
70
|
+
``DataType.FALFF``, ``DataType.GCOR``, ``DataType.LCOR``} or \
|
|
71
|
+
list of them or None, optional
|
|
72
|
+
The data type(s) to apply the marker on.
|
|
73
|
+
If None, will work on all available data.
|
|
74
|
+
Check :enum:`.DataType` for valid values (default None).
|
|
75
|
+
masks : str, dict, list of them or None, optional
|
|
51
76
|
The specification of the masks to apply to regions before extracting
|
|
52
77
|
signals. Check :ref:`Using Masks <using_masks>` for more details.
|
|
53
78
|
If None, will not apply any mask (default None).
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
available data (default None).
|
|
58
|
-
name : str, optional
|
|
59
|
-
The name of the marker. By default, it will use KIND_SphereAggregation
|
|
60
|
-
where KIND is the kind of data it was applied to (default None).
|
|
79
|
+
name : str or None, optional
|
|
80
|
+
The name of the marker.
|
|
81
|
+
If None, will use the class name (default None).
|
|
61
82
|
|
|
62
83
|
Raises
|
|
63
84
|
------
|
|
@@ -70,74 +91,68 @@ class SphereAggregation(BaseMarker):
|
|
|
70
91
|
_DEPENDENCIES: ClassVar[Dependencies] = {"nilearn", "numpy"}
|
|
71
92
|
|
|
72
93
|
_MARKER_INOUT_MAPPINGS: ClassVar[MarkerInOutMappings] = {
|
|
73
|
-
|
|
74
|
-
"aggregation":
|
|
94
|
+
DataType.T1w: {
|
|
95
|
+
"aggregation": StorageType.Vector,
|
|
75
96
|
},
|
|
76
|
-
|
|
77
|
-
"aggregation":
|
|
97
|
+
DataType.T2w: {
|
|
98
|
+
"aggregation": StorageType.Vector,
|
|
78
99
|
},
|
|
79
|
-
|
|
80
|
-
"aggregation":
|
|
100
|
+
DataType.BOLD: {
|
|
101
|
+
"aggregation": StorageType.Timeseries,
|
|
81
102
|
},
|
|
82
|
-
|
|
83
|
-
"aggregation":
|
|
103
|
+
DataType.VBM_GM: {
|
|
104
|
+
"aggregation": StorageType.Vector,
|
|
84
105
|
},
|
|
85
|
-
|
|
86
|
-
"aggregation":
|
|
106
|
+
DataType.VBM_WM: {
|
|
107
|
+
"aggregation": StorageType.Vector,
|
|
87
108
|
},
|
|
88
|
-
|
|
89
|
-
"aggregation":
|
|
109
|
+
DataType.VBM_CSF: {
|
|
110
|
+
"aggregation": StorageType.Vector,
|
|
90
111
|
},
|
|
91
|
-
|
|
92
|
-
"aggregation":
|
|
112
|
+
DataType.FALFF: {
|
|
113
|
+
"aggregation": StorageType.Vector,
|
|
93
114
|
},
|
|
94
|
-
|
|
95
|
-
"aggregation":
|
|
115
|
+
DataType.GCOR: {
|
|
116
|
+
"aggregation": StorageType.Vector,
|
|
96
117
|
},
|
|
97
|
-
|
|
98
|
-
"aggregation":
|
|
118
|
+
DataType.LCOR: {
|
|
119
|
+
"aggregation": StorageType.Vector,
|
|
99
120
|
},
|
|
100
121
|
}
|
|
101
122
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
self.
|
|
120
|
-
self.
|
|
121
|
-
super().__init__(on=on, name=name)
|
|
122
|
-
|
|
123
|
-
# Verify after super init so self._on is set
|
|
124
|
-
if "BOLD" not in self._on and time_method is not None:
|
|
123
|
+
coords: str
|
|
124
|
+
radius: Literal[0] | PositiveFloat | None = None
|
|
125
|
+
allow_overlap: bool = False
|
|
126
|
+
method: str = "mean"
|
|
127
|
+
method_params: dict[str, Any] | None = None
|
|
128
|
+
time_method: str | None = None
|
|
129
|
+
time_method_params: dict[str, Any] | None = None
|
|
130
|
+
masks: Annotated[
|
|
131
|
+
dict | str | list[dict | str] | None,
|
|
132
|
+
BeforeValidator(ensure_list_or_none),
|
|
133
|
+
] = None
|
|
134
|
+
on: Annotated[
|
|
135
|
+
_on | list[_on] | None, BeforeValidator(ensure_list_or_none)
|
|
136
|
+
] = None
|
|
137
|
+
|
|
138
|
+
def validate_marker_params(self) -> None:
|
|
139
|
+
"""Run extra logical validation for marker."""
|
|
140
|
+
# self.on is set already
|
|
141
|
+
if "BOLD" not in self.on and self.time_method is not None:
|
|
125
142
|
raise_error(
|
|
126
143
|
"`time_method` can only be used with BOLD data. "
|
|
127
144
|
"Please remove `time_method` parameter."
|
|
128
145
|
)
|
|
129
|
-
if time_method is None and time_method_params is not None:
|
|
146
|
+
if self.time_method is None and self.time_method_params is not None:
|
|
130
147
|
raise_error(
|
|
131
148
|
"`time_method_params` can only be used with `time_method`. "
|
|
132
149
|
"Please remove `time_method_params` parameter."
|
|
133
150
|
)
|
|
134
|
-
self.time_method = time_method
|
|
135
|
-
self.time_method_params = time_method_params or {}
|
|
136
151
|
|
|
137
152
|
def compute(
|
|
138
153
|
self,
|
|
139
154
|
input: dict[str, Any],
|
|
140
|
-
extra_input:
|
|
155
|
+
extra_input: dict | None = None,
|
|
141
156
|
) -> dict:
|
|
142
157
|
"""Compute.
|
|
143
158
|
|
|
@@ -207,7 +222,8 @@ class SphereAggregation(BaseMarker):
|
|
|
207
222
|
agg_func=agg_func,
|
|
208
223
|
)
|
|
209
224
|
# Fit and transform the marker on the data
|
|
210
|
-
|
|
225
|
+
# nilearn maskers return 1D arrays for 3D images, keep 2D
|
|
226
|
+
out_values = np.atleast_2d(masker.fit_transform(t_input_img))
|
|
211
227
|
|
|
212
228
|
# Apply time dimension aggregation if required
|
|
213
229
|
if self.time_method is not None:
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
"""Provide abstract base class for temporal signal-to-noise ratio (tSNR)."""
|
|
2
2
|
|
|
3
3
|
# Authors: Leonard Sasse <l.sasse@fz-juelich.de>
|
|
4
|
+
# Synchon Mandal <s.mandal@fz-juelich.de>
|
|
4
5
|
# License: AGPL
|
|
5
6
|
|
|
6
7
|
from abc import abstractmethod
|
|
7
|
-
from typing import Any, ClassVar
|
|
8
|
+
from typing import Annotated, Any, ClassVar
|
|
8
9
|
|
|
9
10
|
from nilearn import image as nimg
|
|
11
|
+
from pydantic import BeforeValidator
|
|
10
12
|
|
|
13
|
+
from ...datagrabber import DataType
|
|
14
|
+
from ...storage import StorageType
|
|
11
15
|
from ...typing import Dependencies, MarkerInOutMappings
|
|
12
|
-
from ...utils import raise_error
|
|
16
|
+
from ...utils import ensure_list_or_none, raise_error
|
|
13
17
|
from ..base import BaseMarker
|
|
14
18
|
|
|
15
19
|
|
|
@@ -22,44 +26,40 @@ class TemporalSNRBase(BaseMarker):
|
|
|
22
26
|
Parameters
|
|
23
27
|
----------
|
|
24
28
|
agg_method : str, optional
|
|
25
|
-
The
|
|
26
|
-
:func:`.get_aggfunc_by_name`
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
The aggregation function to use.
|
|
30
|
+
See :func:`.get_aggfunc_by_name` for options
|
|
31
|
+
(default "mean").
|
|
32
|
+
agg_method_params : dict or None, optional
|
|
33
|
+
The parameters to pass to the aggregation function.
|
|
34
|
+
See :func:`.get_aggfunc_by_name` for options (default None).
|
|
35
|
+
masks : str, dict, list of them or None, optional
|
|
31
36
|
The specification of the masks to apply to regions before extracting
|
|
32
37
|
signals. Check :ref:`Using Masks <using_masks>` for more details.
|
|
33
38
|
If None, will not apply any mask (default None).
|
|
34
|
-
name : str, optional
|
|
35
|
-
The name of the marker.
|
|
36
|
-
None).
|
|
39
|
+
name : str or None, optional
|
|
40
|
+
The name of the marker.
|
|
41
|
+
If None, will use the class name (default None).
|
|
37
42
|
|
|
38
43
|
"""
|
|
39
44
|
|
|
40
45
|
_DEPENDENCIES: ClassVar[Dependencies] = {"nilearn"}
|
|
41
46
|
|
|
42
47
|
_MARKER_INOUT_MAPPINGS: ClassVar[MarkerInOutMappings] = {
|
|
43
|
-
|
|
44
|
-
"tsnr":
|
|
48
|
+
DataType.BOLD: {
|
|
49
|
+
"tsnr": StorageType.Vector,
|
|
45
50
|
},
|
|
46
51
|
}
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
) -> None:
|
|
55
|
-
self.agg_method = agg_method
|
|
56
|
-
self.agg_method_params = agg_method_params
|
|
57
|
-
self.masks = masks
|
|
58
|
-
super().__init__(on="BOLD", name=name)
|
|
53
|
+
agg_method: str = "mean"
|
|
54
|
+
agg_method_params: dict | None = None
|
|
55
|
+
masks: Annotated[
|
|
56
|
+
dict | str | list[dict | str] | None,
|
|
57
|
+
BeforeValidator(ensure_list_or_none),
|
|
58
|
+
] = None
|
|
59
59
|
|
|
60
60
|
@abstractmethod
|
|
61
61
|
def aggregate(
|
|
62
|
-
self, input: dict[str, Any], extra_input:
|
|
62
|
+
self, input: dict[str, Any], extra_input: dict | None = None
|
|
63
63
|
) -> dict[str, Any]:
|
|
64
64
|
"""Perform aggregation."""
|
|
65
65
|
raise_error(
|
|
@@ -70,7 +70,7 @@ class TemporalSNRBase(BaseMarker):
|
|
|
70
70
|
def compute(
|
|
71
71
|
self,
|
|
72
72
|
input: dict[str, Any],
|
|
73
|
-
extra_input:
|
|
73
|
+
extra_input: dict | None = None,
|
|
74
74
|
) -> dict:
|
|
75
75
|
"""Compute.
|
|
76
76
|
|
|
@@ -104,7 +104,9 @@ class TemporalSNRBase(BaseMarker):
|
|
|
104
104
|
"img.std(axis=-1).squeeze()", img=input["data"]
|
|
105
105
|
)
|
|
106
106
|
mask_img = nimg.math_img("(stdv_img != 0)", stdv_img=stdv_img)
|
|
107
|
-
|
|
107
|
+
# Aggregate the tSNR image, without changing the input
|
|
108
|
+
aggregation_input = dict(input.items())
|
|
109
|
+
aggregation_input["data"] = nimg.math_img(
|
|
108
110
|
"np.divide(mean_img, stdv_img, where=mask_img.astype(bool))",
|
|
109
111
|
mean_img=mean_img,
|
|
110
112
|
stdv_img=stdv_img,
|
|
@@ -113,8 +115,8 @@ class TemporalSNRBase(BaseMarker):
|
|
|
113
115
|
# Perform necessary aggregation and return
|
|
114
116
|
return {
|
|
115
117
|
"tsnr": {
|
|
116
|
-
**self.aggregate(
|
|
117
|
-
|
|
118
|
-
]
|
|
118
|
+
**self.aggregate(
|
|
119
|
+
input=aggregation_input, extra_input=extra_input
|
|
120
|
+
)["aggregation"]
|
|
119
121
|
}
|
|
120
122
|
}
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
|
4
4
|
# License: AGPL
|
|
5
5
|
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
7
7
|
|
|
8
8
|
from ...api.decorators import register_marker
|
|
9
|
+
from ...datagrabber import DataType
|
|
9
10
|
from ..maps_aggregation import MapsAggregation
|
|
10
11
|
from .temporal_snr_base import TemporalSNRBase
|
|
11
12
|
|
|
@@ -22,30 +23,20 @@ class TemporalSNRMaps(TemporalSNRBase):
|
|
|
22
23
|
maps : str
|
|
23
24
|
The name of the map(s) to use.
|
|
24
25
|
See :func:`.list_data` for options.
|
|
25
|
-
masks : str, dict
|
|
26
|
+
masks : str, dict, list of them or None, optional
|
|
26
27
|
The specification of the masks to apply to regions before extracting
|
|
27
28
|
signals. Check :ref:`Using Masks <using_masks>` for more details.
|
|
28
29
|
If None, will not apply any mask (default None).
|
|
29
|
-
name : str, optional
|
|
30
|
-
The name of the marker.
|
|
31
|
-
None).
|
|
30
|
+
name : str or None, optional
|
|
31
|
+
The name of the marker.
|
|
32
|
+
If None, will use the class name (default None).
|
|
32
33
|
|
|
33
34
|
"""
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
self,
|
|
37
|
-
maps: str,
|
|
38
|
-
masks: Union[str, dict, list[Union[dict, str]], None] = None,
|
|
39
|
-
name: Optional[str] = None,
|
|
40
|
-
) -> None:
|
|
41
|
-
self.maps = maps
|
|
42
|
-
super().__init__(
|
|
43
|
-
masks=masks,
|
|
44
|
-
name=name,
|
|
45
|
-
)
|
|
36
|
+
maps: str
|
|
46
37
|
|
|
47
38
|
def aggregate(
|
|
48
|
-
self, input: dict[str, Any], extra_input:
|
|
39
|
+
self, input: dict[str, Any], extra_input: dict | None = None
|
|
49
40
|
) -> dict:
|
|
50
41
|
"""Perform maps aggregation.
|
|
51
42
|
|
|
@@ -76,5 +67,5 @@ class TemporalSNRMaps(TemporalSNRBase):
|
|
|
76
67
|
return MapsAggregation(
|
|
77
68
|
maps=self.maps,
|
|
78
69
|
masks=self.masks,
|
|
79
|
-
on=
|
|
70
|
+
on=DataType.BOLD,
|
|
80
71
|
).compute(input=input, extra_input=extra_input)
|