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
|
@@ -6,20 +6,25 @@
|
|
|
6
6
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
|
+
import numpy as np
|
|
9
10
|
import pytest
|
|
10
11
|
from nilearn.maskers import NiftiSpheresMasker
|
|
11
12
|
from numpy.testing import assert_array_equal
|
|
12
13
|
|
|
13
14
|
from junifer.data import CoordinatesRegistry, MaskRegistry
|
|
15
|
+
from junifer.datagrabber import DataType
|
|
14
16
|
from junifer.datareader import DefaultDataReader
|
|
15
17
|
from junifer.markers.sphere_aggregation import SphereAggregation
|
|
16
|
-
from junifer.storage import
|
|
18
|
+
from junifer.storage import HDF5FeatureStorage, StorageType
|
|
17
19
|
from junifer.testing.datagrabbers import (
|
|
18
|
-
OasisVBMTestingDataGrabber,
|
|
19
20
|
SPMAuditoryTestingDataGrabber,
|
|
21
|
+
UCLACNPVBMTestingDataGrabber,
|
|
20
22
|
)
|
|
21
23
|
|
|
22
24
|
|
|
25
|
+
pytestmark = pytest.mark.external
|
|
26
|
+
|
|
27
|
+
|
|
23
28
|
# Define common variables
|
|
24
29
|
COORDS = "DMNBuckner"
|
|
25
30
|
RADIUS = 8
|
|
@@ -29,70 +34,70 @@ RADIUS = 8
|
|
|
29
34
|
"input_type, storage_type",
|
|
30
35
|
[
|
|
31
36
|
(
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
DataType.T1w,
|
|
38
|
+
StorageType.Vector,
|
|
34
39
|
),
|
|
35
40
|
(
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
DataType.T2w,
|
|
42
|
+
StorageType.Vector,
|
|
38
43
|
),
|
|
39
44
|
(
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
DataType.BOLD,
|
|
46
|
+
StorageType.Timeseries,
|
|
42
47
|
),
|
|
43
48
|
(
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
DataType.VBM_GM,
|
|
50
|
+
StorageType.Vector,
|
|
46
51
|
),
|
|
47
52
|
(
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
DataType.VBM_WM,
|
|
54
|
+
StorageType.Vector,
|
|
50
55
|
),
|
|
51
56
|
(
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
DataType.VBM_CSF,
|
|
58
|
+
StorageType.Vector,
|
|
54
59
|
),
|
|
55
60
|
(
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
DataType.FALFF,
|
|
62
|
+
StorageType.Vector,
|
|
58
63
|
),
|
|
59
64
|
(
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
DataType.GCOR,
|
|
66
|
+
StorageType.Vector,
|
|
62
67
|
),
|
|
63
68
|
(
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
DataType.LCOR,
|
|
70
|
+
StorageType.Vector,
|
|
66
71
|
),
|
|
67
72
|
],
|
|
68
73
|
)
|
|
69
74
|
def test_SphereAggregation_input_output(
|
|
70
|
-
input_type:
|
|
75
|
+
input_type: DataType, storage_type: StorageType
|
|
71
76
|
) -> None:
|
|
72
77
|
"""Test SphereAggregation input and output types.
|
|
73
78
|
|
|
74
79
|
Parameters
|
|
75
80
|
----------
|
|
76
|
-
input_type :
|
|
81
|
+
input_type : DataType
|
|
77
82
|
The parametrized input type.
|
|
78
|
-
storage_type :
|
|
83
|
+
storage_type : StorageType
|
|
79
84
|
The parametrized storage type.
|
|
80
85
|
|
|
81
86
|
"""
|
|
82
87
|
assert storage_type == SphereAggregation(
|
|
83
88
|
coords="DMNBuckner",
|
|
84
89
|
method="mean",
|
|
85
|
-
on=input_type,
|
|
90
|
+
on=[input_type],
|
|
86
91
|
).storage_type(input_type=input_type, output_feature="aggregation")
|
|
87
92
|
|
|
88
93
|
|
|
89
94
|
def test_SphereAggregation_3D() -> None:
|
|
90
95
|
"""Test SphereAggregation object on 3D images."""
|
|
91
|
-
with
|
|
92
|
-
element_data = DefaultDataReader().fit_transform(dg["sub-
|
|
96
|
+
with UCLACNPVBMTestingDataGrabber() as dg:
|
|
97
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-10206"])
|
|
93
98
|
# Create SphereAggregation object
|
|
94
99
|
marker = SphereAggregation(
|
|
95
|
-
coords=COORDS, method="mean", radius=RADIUS, on=
|
|
100
|
+
coords=COORDS, method="mean", radius=RADIUS, on=[DataType.VBM_GM]
|
|
96
101
|
)
|
|
97
102
|
sphere_agg_vbm_gm_data = marker.fit_transform(element_data)["VBM_GM"][
|
|
98
103
|
"aggregation"
|
|
@@ -107,8 +112,9 @@ def test_SphereAggregation_3D() -> None:
|
|
|
107
112
|
nifti_spheres_masker = NiftiSpheresMasker(
|
|
108
113
|
seeds=testing_coords, radius=RADIUS
|
|
109
114
|
)
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
# nilearn returns a 1D array for 3D images
|
|
116
|
+
nifti_spheres_masked_vbm_gm = np.atleast_2d(
|
|
117
|
+
nifti_spheres_masker.fit_transform(element_data["VBM_GM"]["data"])
|
|
112
118
|
)
|
|
113
119
|
|
|
114
120
|
assert sphere_agg_vbm_gm_data.ndim == 2
|
|
@@ -124,7 +130,7 @@ def test_SphereAggregation_4D() -> None:
|
|
|
124
130
|
element_data = DefaultDataReader().fit_transform(dg["sub001"])
|
|
125
131
|
# Create SphereAggregation object
|
|
126
132
|
marker = SphereAggregation(
|
|
127
|
-
coords=COORDS, method="mean", radius=RADIUS, on=
|
|
133
|
+
coords=COORDS, method="mean", radius=RADIUS, on=DataType.BOLD
|
|
128
134
|
)
|
|
129
135
|
sphere_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
|
|
130
136
|
"aggregation"
|
|
@@ -160,13 +166,13 @@ def test_SphereAggregation_storage(tmp_path: Path) -> None:
|
|
|
160
166
|
|
|
161
167
|
"""
|
|
162
168
|
# Store 3D
|
|
163
|
-
with
|
|
164
|
-
element_data = DefaultDataReader().fit_transform(dg["sub-
|
|
165
|
-
storage =
|
|
166
|
-
uri=tmp_path / "test_sphere_storage_3D.
|
|
169
|
+
with UCLACNPVBMTestingDataGrabber() as dg:
|
|
170
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-10206"])
|
|
171
|
+
storage = HDF5FeatureStorage(
|
|
172
|
+
uri=tmp_path / "test_sphere_storage_3D.hdf5",
|
|
167
173
|
)
|
|
168
174
|
marker = SphereAggregation(
|
|
169
|
-
coords=COORDS, method="mean", radius=RADIUS, on=
|
|
175
|
+
coords=COORDS, method="mean", radius=RADIUS, on=[DataType.VBM_GM]
|
|
170
176
|
)
|
|
171
177
|
marker.fit_transform(input=element_data, storage=storage)
|
|
172
178
|
features = storage.list_features()
|
|
@@ -178,11 +184,11 @@ def test_SphereAggregation_storage(tmp_path: Path) -> None:
|
|
|
178
184
|
# Store 4D
|
|
179
185
|
with SPMAuditoryTestingDataGrabber() as dg:
|
|
180
186
|
element_data = DefaultDataReader().fit_transform(dg["sub001"])
|
|
181
|
-
storage =
|
|
182
|
-
uri=tmp_path / "test_sphere_storage_4D.
|
|
187
|
+
storage = HDF5FeatureStorage(
|
|
188
|
+
uri=tmp_path / "test_sphere_storage_4D.hdf5",
|
|
183
189
|
)
|
|
184
190
|
marker = SphereAggregation(
|
|
185
|
-
coords=COORDS, method="mean", radius=RADIUS, on=
|
|
191
|
+
coords=COORDS, method="mean", radius=RADIUS, on=DataType.BOLD
|
|
186
192
|
)
|
|
187
193
|
marker.fit_transform(input=element_data, storage=storage)
|
|
188
194
|
features = storage.list_features()
|
|
@@ -194,15 +200,15 @@ def test_SphereAggregation_storage(tmp_path: Path) -> None:
|
|
|
194
200
|
|
|
195
201
|
def test_SphereAggregation_3D_mask() -> None:
|
|
196
202
|
"""Test SphereAggregation object on 3D images using mask."""
|
|
197
|
-
with
|
|
198
|
-
element_data = DefaultDataReader().fit_transform(dg["sub-
|
|
203
|
+
with UCLACNPVBMTestingDataGrabber() as dg:
|
|
204
|
+
element_data = DefaultDataReader().fit_transform(dg["sub-10206"])
|
|
199
205
|
# Create SphereAggregation object
|
|
200
206
|
marker = SphereAggregation(
|
|
201
207
|
coords=COORDS,
|
|
202
208
|
method="mean",
|
|
203
209
|
radius=RADIUS,
|
|
204
|
-
on=
|
|
205
|
-
masks="compute_brain_mask",
|
|
210
|
+
on=[DataType.VBM_GM],
|
|
211
|
+
masks=["compute_brain_mask"],
|
|
206
212
|
)
|
|
207
213
|
sphere_agg_vbm_gm_data = marker.fit_transform(element_data)["VBM_GM"][
|
|
208
214
|
"aggregation"
|
|
@@ -245,7 +251,7 @@ def test_SphereAggregation_4D_agg_time() -> None:
|
|
|
245
251
|
method="mean",
|
|
246
252
|
radius=RADIUS,
|
|
247
253
|
time_method="mean",
|
|
248
|
-
on=
|
|
254
|
+
on=DataType.BOLD,
|
|
249
255
|
)
|
|
250
256
|
sphere_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
|
|
251
257
|
"aggregation"
|
|
@@ -281,7 +287,7 @@ def test_SphereAggregation_4D_agg_time() -> None:
|
|
|
281
287
|
radius=RADIUS,
|
|
282
288
|
time_method="select",
|
|
283
289
|
time_method_params={"pick": [0]},
|
|
284
|
-
on=
|
|
290
|
+
on=DataType.BOLD,
|
|
285
291
|
)
|
|
286
292
|
sphere_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
|
|
287
293
|
"aggregation"
|
|
@@ -305,7 +311,7 @@ def test_SphereAggregation_errors() -> None:
|
|
|
305
311
|
radius=RADIUS,
|
|
306
312
|
time_method="pick",
|
|
307
313
|
time_method_params={"pick": [0]},
|
|
308
|
-
on=
|
|
314
|
+
on=[DataType.VBM_GM],
|
|
309
315
|
)
|
|
310
316
|
|
|
311
317
|
with pytest.raises(
|
|
@@ -316,7 +322,7 @@ def test_SphereAggregation_errors() -> None:
|
|
|
316
322
|
method="mean",
|
|
317
323
|
radius=RADIUS,
|
|
318
324
|
time_method_params={"pick": [0]},
|
|
319
|
-
on=
|
|
325
|
+
on=[DataType.VBM_GM],
|
|
320
326
|
)
|
|
321
327
|
|
|
322
328
|
|
|
@@ -333,7 +339,7 @@ def test_SphereAggregation_warning() -> None:
|
|
|
333
339
|
radius=RADIUS,
|
|
334
340
|
time_method="select",
|
|
335
341
|
time_method_params={"pick": [0]},
|
|
336
|
-
on=
|
|
342
|
+
on=DataType.BOLD,
|
|
337
343
|
)
|
|
338
344
|
element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
|
|
339
345
|
..., 0:1
|
junifer/markers/utils.py
CHANGED
|
@@ -8,19 +8,86 @@
|
|
|
8
8
|
# Amir Omidvarnia <a.omidvarnia@fz-juelich.de>
|
|
9
9
|
# License: AGPL
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
import hashlib
|
|
12
|
+
import zlib
|
|
13
|
+
from collections.abc import Callable
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
12
16
|
|
|
17
|
+
import nibabel as nib
|
|
13
18
|
import numpy as np
|
|
14
19
|
import pandas as pd
|
|
20
|
+
from nibabel.spatialimages import SpatialImage
|
|
15
21
|
from scipy.stats import zscore
|
|
16
22
|
|
|
23
|
+
from ..pipeline import WorkDirManager
|
|
17
24
|
from ..utils import raise_error
|
|
18
25
|
|
|
19
26
|
|
|
27
|
+
def _save_mask(mask_img: SpatialImage, prefix: str) -> Path:
|
|
28
|
+
"""Save mask to the element directory, named by its content.
|
|
29
|
+
|
|
30
|
+
The same mask always gets the same path within an element, so that the
|
|
31
|
+
cached computations (e.g., ReHo or ALFF) can be reused by markers using
|
|
32
|
+
the same mask. The element directory is deleted after the element is
|
|
33
|
+
processed.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
mask_img : Niimg-like object
|
|
38
|
+
The mask to save.
|
|
39
|
+
prefix : str
|
|
40
|
+
The prefix of the file name.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
pathlib.Path
|
|
45
|
+
The path to the saved mask.
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
mask_data = np.squeeze(np.asarray(mask_img.dataobj)) != 0
|
|
49
|
+
digest = hashlib.sha256()
|
|
50
|
+
digest.update(str(mask_data.shape).encode())
|
|
51
|
+
digest.update(np.packbits(mask_data).tobytes())
|
|
52
|
+
digest.update(mask_img.affine.tobytes())
|
|
53
|
+
mask_path = (
|
|
54
|
+
WorkDirManager().get_elementdir()
|
|
55
|
+
/ f"{prefix}_{digest.hexdigest()[:16]}.nii"
|
|
56
|
+
)
|
|
57
|
+
if not mask_path.exists():
|
|
58
|
+
nib.save(
|
|
59
|
+
nib.Nifti1Image(
|
|
60
|
+
mask_data.astype(np.uint8), mask_img.affine, mask_img.header
|
|
61
|
+
),
|
|
62
|
+
mask_path,
|
|
63
|
+
)
|
|
64
|
+
return mask_path
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _has_data(data: np.ndarray) -> np.ndarray:
|
|
68
|
+
"""Get the columns with data.
|
|
69
|
+
|
|
70
|
+
Regions that are lost when resampling or warping the parcellation to the
|
|
71
|
+
target image have no voxels, so their time series are all NaN.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
data : np.ndarray
|
|
76
|
+
The data (time x columns).
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
np.ndarray
|
|
81
|
+
Boolean mask of the columns that are not all NaN.
|
|
82
|
+
|
|
83
|
+
"""
|
|
84
|
+
return ~np.all(np.isnan(data), axis=0)
|
|
85
|
+
|
|
86
|
+
|
|
20
87
|
def _ets(
|
|
21
88
|
bold_ts: np.ndarray,
|
|
22
|
-
roi_names:
|
|
23
|
-
) -> tuple[np.ndarray,
|
|
89
|
+
roi_names: list[str] | None = None,
|
|
90
|
+
) -> tuple[np.ndarray, list[str] | None]:
|
|
24
91
|
"""Compute the edge-wise time series based on BOLD time series.
|
|
25
92
|
|
|
26
93
|
Take a timeseries of brain areas, and calculate timeseries for each
|
|
@@ -73,7 +140,8 @@ def _ets(
|
|
|
73
140
|
)
|
|
74
141
|
_roi_names = np.array(roi_names)
|
|
75
142
|
edge_names = [
|
|
76
|
-
"~".join([x, y])
|
|
143
|
+
"~".join([x, y])
|
|
144
|
+
for x, y in zip(_roi_names[u], _roi_names[v], strict=False)
|
|
77
145
|
]
|
|
78
146
|
return ets, edge_names
|
|
79
147
|
|
|
@@ -81,7 +149,7 @@ def _ets(
|
|
|
81
149
|
def _correlate_dataframes(
|
|
82
150
|
df1: pd.DataFrame,
|
|
83
151
|
df2: pd.DataFrame,
|
|
84
|
-
method:
|
|
152
|
+
method: str | Callable = "pearson",
|
|
85
153
|
) -> pd.DataFrame:
|
|
86
154
|
"""Column-wise correlations between two dataframes.
|
|
87
155
|
|
|
@@ -118,3 +186,197 @@ def _correlate_dataframes(
|
|
|
118
186
|
.corr(method=method) # type: ignore
|
|
119
187
|
.loc["df2", "df1"]
|
|
120
188
|
)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _checksum(array: np.ndarray) -> tuple:
|
|
192
|
+
"""Get the checksum of an array.
|
|
193
|
+
|
|
194
|
+
Parameters
|
|
195
|
+
----------
|
|
196
|
+
array : numpy.ndarray
|
|
197
|
+
The array.
|
|
198
|
+
|
|
199
|
+
Returns
|
|
200
|
+
-------
|
|
201
|
+
tuple
|
|
202
|
+
The shape, the dtype and the CRC-32 of the bytes of the array (None
|
|
203
|
+
for arrays of objects).
|
|
204
|
+
|
|
205
|
+
"""
|
|
206
|
+
crc = None
|
|
207
|
+
if not array.dtype.hasobject:
|
|
208
|
+
# The transpose of an array in Fortran order (e.g., the data of a
|
|
209
|
+
# NIfTI image) is in C order, so it is not copied
|
|
210
|
+
if array.flags.f_contiguous and not array.flags.c_contiguous:
|
|
211
|
+
array = array.T
|
|
212
|
+
crc = zlib.crc32(memoryview(np.ascontiguousarray(array)).cast("B"))
|
|
213
|
+
return (array.shape, array.dtype.str, crc)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _image_data(img: SpatialImage) -> tuple:
|
|
217
|
+
"""Get the data of an image in memory.
|
|
218
|
+
|
|
219
|
+
The data read from the file of an image is not loaded, as it cannot be
|
|
220
|
+
changed (unless it is cached) and it would be kept in memory.
|
|
221
|
+
|
|
222
|
+
Parameters
|
|
223
|
+
----------
|
|
224
|
+
img : nibabel.spatialimages.SpatialImage
|
|
225
|
+
The image.
|
|
226
|
+
|
|
227
|
+
Returns
|
|
228
|
+
-------
|
|
229
|
+
tuple
|
|
230
|
+
The data of the image if it is in memory (the data of an image
|
|
231
|
+
created from an array, or the data cached by nilearn, e.g., with
|
|
232
|
+
``nilearn.image.get_data``) and the data cached by nibabel's
|
|
233
|
+
``get_fdata``, or None.
|
|
234
|
+
|
|
235
|
+
"""
|
|
236
|
+
data = img.dataobj
|
|
237
|
+
if not isinstance(data, np.ndarray):
|
|
238
|
+
data = getattr(img, "_data_cache", None)
|
|
239
|
+
return data, getattr(img, "_fdata_cache", None)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _checksums(value: Any) -> tuple:
|
|
243
|
+
"""Get the checksums of an array, data frame, image or set.
|
|
244
|
+
|
|
245
|
+
Parameters
|
|
246
|
+
----------
|
|
247
|
+
value : Any
|
|
248
|
+
The value.
|
|
249
|
+
|
|
250
|
+
Returns
|
|
251
|
+
-------
|
|
252
|
+
tuple
|
|
253
|
+
The checksums, empty for other values. For data frames and series:
|
|
254
|
+
the values and index, and the column labels or name. For images: the
|
|
255
|
+
affine and the data in memory (see :func:`_image_data`, None if not in
|
|
256
|
+
memory). For sets: their contents.
|
|
257
|
+
|
|
258
|
+
"""
|
|
259
|
+
if isinstance(value, np.ndarray):
|
|
260
|
+
return (_checksum(value),)
|
|
261
|
+
if isinstance(value, pd.DataFrame | pd.Series):
|
|
262
|
+
labels = (
|
|
263
|
+
tuple(value.columns)
|
|
264
|
+
if isinstance(value, pd.DataFrame)
|
|
265
|
+
else value.name
|
|
266
|
+
)
|
|
267
|
+
return (
|
|
268
|
+
_checksum(pd.util.hash_pandas_object(value).to_numpy()),
|
|
269
|
+
labels,
|
|
270
|
+
)
|
|
271
|
+
if isinstance(value, SpatialImage):
|
|
272
|
+
return (
|
|
273
|
+
_checksum(value.affine),
|
|
274
|
+
*(
|
|
275
|
+
None if data is None else _checksum(data)
|
|
276
|
+
for data in _image_data(value)
|
|
277
|
+
),
|
|
278
|
+
)
|
|
279
|
+
if isinstance(value, set | frozenset):
|
|
280
|
+
return (frozenset(value),)
|
|
281
|
+
return ()
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def _fingerprint(data: Any, path: tuple = ()) -> dict[tuple, tuple]:
|
|
285
|
+
"""Get a fingerprint of the data, to check whether it is changed.
|
|
286
|
+
|
|
287
|
+
Parameters
|
|
288
|
+
----------
|
|
289
|
+
data : Any
|
|
290
|
+
The data.
|
|
291
|
+
path : tuple, optional
|
|
292
|
+
The keys (or indices) leading to ``data`` (default ()).
|
|
293
|
+
|
|
294
|
+
Returns
|
|
295
|
+
-------
|
|
296
|
+
dict
|
|
297
|
+
For each path, the value (to check it is not replaced) and its
|
|
298
|
+
checksums (to check it is not changed in place).
|
|
299
|
+
|
|
300
|
+
"""
|
|
301
|
+
out = {path: (data, _checksums(data))}
|
|
302
|
+
if isinstance(data, dict):
|
|
303
|
+
items = data.items()
|
|
304
|
+
elif isinstance(data, list | tuple):
|
|
305
|
+
items = enumerate(data)
|
|
306
|
+
else:
|
|
307
|
+
items = ()
|
|
308
|
+
for key, value in items:
|
|
309
|
+
out.update(_fingerprint(value, (*path, key)))
|
|
310
|
+
return out
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def _is_changed(old: tuple, new: tuple) -> bool:
|
|
314
|
+
"""Check whether a value is changed.
|
|
315
|
+
|
|
316
|
+
Parameters
|
|
317
|
+
----------
|
|
318
|
+
old : tuple
|
|
319
|
+
The value and its checksums before.
|
|
320
|
+
new : tuple
|
|
321
|
+
The value and its checksums after.
|
|
322
|
+
|
|
323
|
+
Returns
|
|
324
|
+
-------
|
|
325
|
+
bool
|
|
326
|
+
Whether the value was replaced or changed in place.
|
|
327
|
+
|
|
328
|
+
"""
|
|
329
|
+
(old_value, old_sums), (new_value, new_sums) = old, new
|
|
330
|
+
if new_value is not old_value:
|
|
331
|
+
return True
|
|
332
|
+
if isinstance(new_value, SpatialImage):
|
|
333
|
+
# The affine must be the same
|
|
334
|
+
if old_sums[0] != new_sums[0]:
|
|
335
|
+
return True
|
|
336
|
+
for old_data, new_data, data in zip(
|
|
337
|
+
old_sums[1:], new_sums[1:], _image_data(new_value), strict=True
|
|
338
|
+
):
|
|
339
|
+
if new_data is None:
|
|
340
|
+
# Not in memory (or no longer cached)
|
|
341
|
+
continue
|
|
342
|
+
if old_data is not None and old_data[1] == new_data[1]:
|
|
343
|
+
# Same dtype: the data in memory must be the same
|
|
344
|
+
if old_data != new_data:
|
|
345
|
+
return True
|
|
346
|
+
else:
|
|
347
|
+
# The data was cached during the computation, possibly with
|
|
348
|
+
# another dtype: compare it with the data read from the file
|
|
349
|
+
expected = np.asanyarray(new_value.dataobj, dtype=data.dtype)
|
|
350
|
+
if not np.array_equal(data, expected, equal_nan=True):
|
|
351
|
+
return True
|
|
352
|
+
return False
|
|
353
|
+
return old_sums != new_sums
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def _changed_paths(
|
|
357
|
+
before: dict[tuple, tuple], after: dict[tuple, tuple]
|
|
358
|
+
) -> list[str]:
|
|
359
|
+
"""Get the paths of the data that are changed.
|
|
360
|
+
|
|
361
|
+
Parameters
|
|
362
|
+
----------
|
|
363
|
+
before : dict
|
|
364
|
+
The fingerprint of the data before (see :func:`_fingerprint`).
|
|
365
|
+
after : dict
|
|
366
|
+
The fingerprint of the data after.
|
|
367
|
+
|
|
368
|
+
Returns
|
|
369
|
+
-------
|
|
370
|
+
list of str
|
|
371
|
+
The paths (keys joined by ".") that were added, removed, replaced or
|
|
372
|
+
changed in place.
|
|
373
|
+
|
|
374
|
+
"""
|
|
375
|
+
changed = [
|
|
376
|
+
path
|
|
377
|
+
for path in sorted(before.keys() | after.keys(), key=str)
|
|
378
|
+
if path not in before
|
|
379
|
+
or path not in after
|
|
380
|
+
or _is_changed(before[path], after[path])
|
|
381
|
+
]
|
|
382
|
+
return [".".join(str(key) for key in path) for path in changed]
|
junifer/onthefly/__init__.py
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
|
4
4
|
# License: AGPL
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
from . import _brainprint as brainprint
|
|
6
|
+
import lazy_loader as lazy
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
__all__ =
|
|
9
|
+
__getattr__, __dir__, __all__ = lazy.attach_stub(__name__, __file__)
|
junifer/onthefly/_brainprint.py
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
|
4
4
|
# License: AGPL
|
|
5
5
|
|
|
6
|
-
from typing import Optional
|
|
7
|
-
|
|
8
6
|
import numpy as np
|
|
9
7
|
import pandas as pd
|
|
10
8
|
|
|
@@ -17,7 +15,7 @@ __all__ = ["normalize", "reweight"]
|
|
|
17
15
|
|
|
18
16
|
def normalize(
|
|
19
17
|
storage: StorageLike,
|
|
20
|
-
features: dict[str, dict[str,
|
|
18
|
+
features: dict[str, dict[str, str | None]],
|
|
21
19
|
kind: str,
|
|
22
20
|
) -> pd.DataFrame: # pragma: no cover
|
|
23
21
|
"""Read stored brainprint data and normalize either surfaces or volumes.
|
|
@@ -87,8 +85,8 @@ def normalize(
|
|
|
87
85
|
|
|
88
86
|
def reweight(
|
|
89
87
|
storage: StorageLike,
|
|
90
|
-
feature_name:
|
|
91
|
-
feature_md5:
|
|
88
|
+
feature_name: str | None = None,
|
|
89
|
+
feature_md5: str | None = None,
|
|
92
90
|
) -> pd.DataFrame: # pragma: no cover
|
|
93
91
|
"""Read stored brainprint data and reweight eigenvalues.
|
|
94
92
|
|
|
File without changes
|
|
@@ -3,33 +3,35 @@
|
|
|
3
3
|
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
|
|
4
4
|
# License: AGPL
|
|
5
5
|
|
|
6
|
-
from typing import Optional
|
|
7
|
-
|
|
8
6
|
import numpy as np
|
|
9
7
|
import pandas as pd
|
|
8
|
+
import structlog
|
|
10
9
|
|
|
11
10
|
from ..typing import StorageLike
|
|
12
|
-
from ..utils import
|
|
11
|
+
from ..utils import raise_error, warn_with_log
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
__all__ = ["read_transform"]
|
|
16
15
|
|
|
16
|
+
_log = structlog.get_logger("junifer")
|
|
17
|
+
logger = _log.bind(pkg="onthefly")
|
|
18
|
+
|
|
17
19
|
|
|
18
20
|
def read_transform(
|
|
19
21
|
storage: StorageLike,
|
|
20
22
|
transform: str,
|
|
21
|
-
feature_name:
|
|
22
|
-
feature_md5:
|
|
23
|
-
nan_policy:
|
|
24
|
-
transform_args:
|
|
25
|
-
transform_kw_args:
|
|
23
|
+
feature_name: str | None = None,
|
|
24
|
+
feature_md5: str | None = None,
|
|
25
|
+
nan_policy: str | None = "bypass",
|
|
26
|
+
transform_args: tuple | None = None,
|
|
27
|
+
transform_kw_args: dict | None = None,
|
|
26
28
|
) -> pd.DataFrame:
|
|
27
29
|
"""Read stored feature and transform to specific statistical output.
|
|
28
30
|
|
|
29
31
|
Parameters
|
|
30
32
|
----------
|
|
31
33
|
storage : storage-like
|
|
32
|
-
The storage class, for example,
|
|
34
|
+
The storage class, for example, HDF5FeatureStorage.
|
|
33
35
|
transform : str
|
|
34
36
|
The kind of transform formatted as ``<package>_<function>``,
|
|
35
37
|
for example, ``bctpy_degrees_und``.
|
|
@@ -10,7 +10,7 @@ import numpy as np
|
|
|
10
10
|
import pytest
|
|
11
11
|
|
|
12
12
|
from junifer.onthefly import read_transform
|
|
13
|
-
from junifer.storage
|
|
13
|
+
from junifer.storage import HDF5FeatureStorage, StorageType
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
@pytest.fixture
|
|
@@ -23,9 +23,9 @@ def vector_storage(tmp_path: Path) -> HDF5FeatureStorage:
|
|
|
23
23
|
The path to the test directory.
|
|
24
24
|
|
|
25
25
|
"""
|
|
26
|
-
storage = HDF5FeatureStorage(tmp_path / "vector_store.hdf5")
|
|
26
|
+
storage = HDF5FeatureStorage(uri=tmp_path / "vector_store.hdf5")
|
|
27
27
|
storage.store(
|
|
28
|
-
kind=
|
|
28
|
+
kind=StorageType.Vector,
|
|
29
29
|
meta={
|
|
30
30
|
"element": {"subject": "test"},
|
|
31
31
|
"dependencies": [],
|
|
@@ -48,9 +48,9 @@ def matrix_storage(tmp_path: Path) -> HDF5FeatureStorage:
|
|
|
48
48
|
The path to the test directory.
|
|
49
49
|
|
|
50
50
|
"""
|
|
51
|
-
storage = HDF5FeatureStorage(tmp_path / "matrix_store.hdf5")
|
|
51
|
+
storage = HDF5FeatureStorage(uri=tmp_path / "matrix_store.hdf5")
|
|
52
52
|
storage.store(
|
|
53
|
-
kind=
|
|
53
|
+
kind=StorageType.Matrix,
|
|
54
54
|
meta={
|
|
55
55
|
"element": {"subject": "test"},
|
|
56
56
|
"dependencies": [],
|
|
@@ -74,13 +74,13 @@ def matrix_storage_with_nan(tmp_path: Path) -> HDF5FeatureStorage:
|
|
|
74
74
|
The path to the test directory.
|
|
75
75
|
|
|
76
76
|
"""
|
|
77
|
-
storage = HDF5FeatureStorage(tmp_path / "matrix_store_nan.hdf5")
|
|
77
|
+
storage = HDF5FeatureStorage(uri=tmp_path / "matrix_store_nan.hdf5")
|
|
78
78
|
data = np.arange(36).reshape(3, 3, 4).astype(float)
|
|
79
79
|
data[1, 1, 2] = np.nan
|
|
80
80
|
data[1, 2, 2] = np.nan
|
|
81
81
|
for i in range(4):
|
|
82
82
|
storage.store(
|
|
83
|
-
kind=
|
|
83
|
+
kind=StorageType.Matrix,
|
|
84
84
|
meta={
|
|
85
85
|
"element": {"subject": f"test{i + 1}"},
|
|
86
86
|
"dependencies": [],
|