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
|
@@ -5,16 +5,19 @@
|
|
|
5
5
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
|
6
6
|
# License: AGPL
|
|
7
7
|
|
|
8
|
+
import importlib
|
|
8
9
|
import logging
|
|
10
|
+
import pkgutil
|
|
9
11
|
from abc import ABC
|
|
10
12
|
|
|
11
13
|
import pytest
|
|
12
14
|
|
|
15
|
+
import junifer
|
|
13
16
|
from junifer.datagrabber.pattern import PatternDataGrabber
|
|
14
17
|
from junifer.pipeline.pipeline_component_registry import (
|
|
15
18
|
PipelineComponentRegistry,
|
|
16
19
|
)
|
|
17
|
-
from junifer.storage import
|
|
20
|
+
from junifer.storage import HDF5FeatureStorage
|
|
18
21
|
|
|
19
22
|
|
|
20
23
|
def test_pipeline_component_registry_singleton() -> None:
|
|
@@ -56,7 +59,7 @@ def test_pipeline_component_registry_components():
|
|
|
56
59
|
"step, klass",
|
|
57
60
|
[
|
|
58
61
|
("datagrabber", PatternDataGrabber),
|
|
59
|
-
("storage",
|
|
62
|
+
("storage", HDF5FeatureStorage),
|
|
60
63
|
],
|
|
61
64
|
)
|
|
62
65
|
def test_pipeline_component_registry_register(
|
|
@@ -85,7 +88,7 @@ def test_pipeline_component_registry_register(
|
|
|
85
88
|
"step, klass",
|
|
86
89
|
[
|
|
87
90
|
("datagrabber", PatternDataGrabber),
|
|
88
|
-
("storage",
|
|
91
|
+
("storage", HDF5FeatureStorage),
|
|
89
92
|
],
|
|
90
93
|
)
|
|
91
94
|
def test_pipeline_component_registry_deregister(
|
|
@@ -103,11 +106,16 @@ def test_pipeline_component_registry_deregister(
|
|
|
103
106
|
The parametrized name of the class.
|
|
104
107
|
|
|
105
108
|
"""
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
registry = PipelineComponentRegistry()
|
|
110
|
+
try:
|
|
111
|
+
with caplog.at_level(logging.INFO):
|
|
112
|
+
registry.deregister(step=step, klass=klass)
|
|
113
|
+
# Check logging message
|
|
114
|
+
assert "De-registering" in caplog.text
|
|
115
|
+
assert klass.__name__ not in registry.step_components(step)
|
|
116
|
+
finally:
|
|
117
|
+
# Register again, as the registry is shared by all the tests
|
|
118
|
+
registry.register(step=step, klass=klass)
|
|
111
119
|
|
|
112
120
|
|
|
113
121
|
def test_pipeline_component_registry_step_components() -> None:
|
|
@@ -149,6 +157,42 @@ def test_pipeline_component_registry_get_class():
|
|
|
149
157
|
assert isinstance(obj, type(bar))
|
|
150
158
|
|
|
151
159
|
|
|
160
|
+
def test_pipeline_component_registry_get_class_builtin() -> None:
|
|
161
|
+
"""Test get class for the built-in components of the registry."""
|
|
162
|
+
# A new registry, with the built-in components not imported yet (the
|
|
163
|
+
# singleton might have imported some of them)
|
|
164
|
+
registry = object.__new__(PipelineComponentRegistry)
|
|
165
|
+
registry.__init__()
|
|
166
|
+
for step in registry.steps:
|
|
167
|
+
for name in registry.step_components(step=step):
|
|
168
|
+
assert isinstance(registry.components[step][name], str)
|
|
169
|
+
klass = registry.get_class(step=step, name=name)
|
|
170
|
+
assert klass.__name__ == name
|
|
171
|
+
# Import all the components of the sub-packages of the steps, which
|
|
172
|
+
# registers them, and check that they are all built-in components, except
|
|
173
|
+
# the ones with optional dependencies, which are registered by importing
|
|
174
|
+
# their sub-package (e.g., with ``with:`` in the YAML)
|
|
175
|
+
optional = ("junifer.markers.complexity",)
|
|
176
|
+
for module in pkgutil.walk_packages(junifer.__path__, "junifer."):
|
|
177
|
+
if ".tests" in module.name:
|
|
178
|
+
continue
|
|
179
|
+
try:
|
|
180
|
+
importlib.import_module(module.name)
|
|
181
|
+
except ImportError:
|
|
182
|
+
# Only if the optional dependencies are not installed
|
|
183
|
+
assert module.name.startswith(optional)
|
|
184
|
+
for step, subpkg in registry._step_to_subpkg_mappings.items():
|
|
185
|
+
for name, klass in (
|
|
186
|
+
PipelineComponentRegistry().components[step].items()
|
|
187
|
+
):
|
|
188
|
+
if isinstance(klass, str):
|
|
189
|
+
continue
|
|
190
|
+
if klass.__module__.startswith(optional):
|
|
191
|
+
assert name not in registry.components[step]
|
|
192
|
+
elif klass.__module__.startswith(f"junifer.{subpkg}."):
|
|
193
|
+
assert name in registry.components[step]
|
|
194
|
+
|
|
195
|
+
|
|
152
196
|
def test_pipeline_component_registry_build():
|
|
153
197
|
"""Test component instance building for PipelineComponentRegistry."""
|
|
154
198
|
import numpy as np
|
|
@@ -9,7 +9,7 @@ from typing import ClassVar
|
|
|
9
9
|
|
|
10
10
|
import pytest
|
|
11
11
|
|
|
12
|
-
from junifer.pipeline
|
|
12
|
+
from junifer.pipeline import ExtDep, PipelineStepMixin
|
|
13
13
|
from junifer.pipeline.utils import _check_afni
|
|
14
14
|
from junifer.typing import (
|
|
15
15
|
ConditionalDependencies,
|
|
@@ -18,6 +18,9 @@ from junifer.typing import (
|
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
|
|
21
|
+
pytestmark = pytest.mark.external
|
|
22
|
+
|
|
23
|
+
|
|
21
24
|
def test_PipelineStepMixin_correct_dependencies() -> None:
|
|
22
25
|
"""Test fit-transform with correct dependencies."""
|
|
23
26
|
|
|
@@ -64,7 +67,9 @@ def test_PipelineStepMixin_correct_ext_dependencies() -> None:
|
|
|
64
67
|
class CorrectMixer(PipelineStepMixin):
|
|
65
68
|
"""Test class for validation."""
|
|
66
69
|
|
|
67
|
-
_EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
|
|
70
|
+
_EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
|
|
71
|
+
{"name": ExtDep.AFNI}
|
|
72
|
+
]
|
|
68
73
|
|
|
69
74
|
def validate_input(self, input: list[str]) -> list[str]:
|
|
70
75
|
return input
|
|
@@ -86,7 +91,7 @@ def test_PipelineStepMixin_ext_deps_correct_commands() -> None:
|
|
|
86
91
|
"""Test class for validation."""
|
|
87
92
|
|
|
88
93
|
_EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
|
|
89
|
-
{"name":
|
|
94
|
+
{"name": ExtDep.AFNI, "commands": ["3dReHo"]}
|
|
90
95
|
]
|
|
91
96
|
|
|
92
97
|
def validate_input(self, input: list[str]) -> list[str]:
|
|
@@ -111,7 +116,7 @@ def test_PipelineStepMixin_ext_deps_incorrect_commands() -> None:
|
|
|
111
116
|
"""Test class for validation."""
|
|
112
117
|
|
|
113
118
|
_EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
|
|
114
|
-
{"name":
|
|
119
|
+
{"name": ExtDep.AFNI, "commands": ["3d"]}
|
|
115
120
|
]
|
|
116
121
|
|
|
117
122
|
def validate_input(self, input: list[str]) -> list[str]:
|
|
@@ -125,27 +130,6 @@ def test_PipelineStepMixin_ext_deps_incorrect_commands() -> None:
|
|
|
125
130
|
mixer.fit_transform({})
|
|
126
131
|
|
|
127
132
|
|
|
128
|
-
def test_PipelineStepMixin_incorrect_ext_dependencies() -> None:
|
|
129
|
-
"""Test fit-transform with incorrect external dependencies."""
|
|
130
|
-
|
|
131
|
-
class IncorrectMixer(PipelineStepMixin):
|
|
132
|
-
"""Test class for validation."""
|
|
133
|
-
|
|
134
|
-
_EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
|
|
135
|
-
{"name": "foobar", "optional": True}
|
|
136
|
-
]
|
|
137
|
-
|
|
138
|
-
def validate_input(self, input: list[str]) -> list[str]:
|
|
139
|
-
return input
|
|
140
|
-
|
|
141
|
-
def _fit_transform(self, input: dict[str, dict]) -> dict[str, dict]:
|
|
142
|
-
return {"input": input}
|
|
143
|
-
|
|
144
|
-
mixer = IncorrectMixer()
|
|
145
|
-
with pytest.raises(ValueError, match="Invalid value"):
|
|
146
|
-
mixer.fit_transform({})
|
|
147
|
-
|
|
148
|
-
|
|
149
133
|
def test_PipelineStepMixin_correct_conditional_dependencies() -> None:
|
|
150
134
|
"""Test fit-transform with correct conditional dependencies."""
|
|
151
135
|
|
|
@@ -208,7 +192,9 @@ def test_PipelineStepMixin_correct_conditional_ext_dependencies() -> None:
|
|
|
208
192
|
"""Test fit-transform with correct conditional external dependencies."""
|
|
209
193
|
|
|
210
194
|
class ExternalDependency:
|
|
211
|
-
_EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
|
|
195
|
+
_EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
|
|
196
|
+
{"name": ExtDep.AFNI}
|
|
197
|
+
]
|
|
212
198
|
|
|
213
199
|
class CorrectMixer(PipelineStepMixin):
|
|
214
200
|
"""Test class for validation."""
|
|
@@ -4,11 +4,10 @@
|
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
|
5
5
|
# License: AGPL
|
|
6
6
|
|
|
7
|
-
from typing import Union
|
|
8
|
-
|
|
9
7
|
import pytest
|
|
8
|
+
from pydantic import BaseModel
|
|
10
9
|
|
|
11
|
-
from junifer.pipeline
|
|
10
|
+
from junifer.pipeline import UpdateMetaMixin
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
@pytest.mark.parametrize(
|
|
@@ -23,7 +22,7 @@ from junifer.pipeline.update_meta_mixin import UpdateMetaMixin
|
|
|
23
22
|
def test_UpdateMetaMixin(
|
|
24
23
|
input: dict,
|
|
25
24
|
step_name: str,
|
|
26
|
-
dependencies:
|
|
25
|
+
dependencies: set | list | str | None,
|
|
27
26
|
expected: set,
|
|
28
27
|
) -> None:
|
|
29
28
|
"""Test UpdateMetaMixin.
|
|
@@ -41,7 +40,7 @@ def test_UpdateMetaMixin(
|
|
|
41
40
|
|
|
42
41
|
"""
|
|
43
42
|
|
|
44
|
-
class TestUpdateMetaMixin(UpdateMetaMixin):
|
|
43
|
+
class TestUpdateMetaMixin(BaseModel, UpdateMetaMixin):
|
|
45
44
|
"""Test UpdateMetaMixin."""
|
|
46
45
|
|
|
47
46
|
_DEPENDENCIES = dependencies
|
|
@@ -29,6 +29,21 @@ def test_workdir_manager_workdir(tmp_path: Path) -> None:
|
|
|
29
29
|
assert workdir_mgr.workdir == tmp_path
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
def test_workdir_manager_create_workdir(tmp_path: Path) -> None:
|
|
33
|
+
"""Test WorkDirManager creates the workdir if it does not exist.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
tmp_path : pathlib.Path
|
|
38
|
+
The path to the test directory.
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
workdir = tmp_path / "new" / "workdir"
|
|
42
|
+
workdir_mgr = WorkDirManager(workdir=workdir)
|
|
43
|
+
assert workdir_mgr.workdir == workdir
|
|
44
|
+
assert workdir.is_dir()
|
|
45
|
+
|
|
46
|
+
|
|
32
47
|
def test_workdir_manager_get_and_delete_element_tempdir(
|
|
33
48
|
tmp_path: Path,
|
|
34
49
|
) -> None:
|
|
@@ -80,6 +95,30 @@ def test_workdir_manager_cleanup_elementdir(
|
|
|
80
95
|
assert workdir_mgr.elementdir is None
|
|
81
96
|
|
|
82
97
|
|
|
98
|
+
def test_workdir_manager_get_elementdir(tmp_path: Path) -> None:
|
|
99
|
+
"""Test WorkDirManager gets the element directory correctly.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
tmp_path : pathlib.Path
|
|
104
|
+
The path to the test directory.
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
workdir_mgr = WorkDirManager()
|
|
108
|
+
workdir_mgr.workdir = tmp_path
|
|
109
|
+
assert workdir_mgr.elementdir is None
|
|
110
|
+
# Created on the first call, and the same afterwards
|
|
111
|
+
elementdir = workdir_mgr.get_elementdir()
|
|
112
|
+
assert elementdir.is_dir()
|
|
113
|
+
assert elementdir.parent == tmp_path
|
|
114
|
+
assert workdir_mgr.get_elementdir() == elementdir
|
|
115
|
+
# The element temporary directories are in it
|
|
116
|
+
assert workdir_mgr.get_element_tempdir().parent == elementdir
|
|
117
|
+
workdir_mgr.cleanup_elementdir()
|
|
118
|
+
assert not elementdir.exists()
|
|
119
|
+
assert workdir_mgr.elementdir is None
|
|
120
|
+
|
|
121
|
+
|
|
83
122
|
def test_workdir_manager_get_and_delete_tempdir(tmp_path: Path) -> None:
|
|
84
123
|
"""Test WorkDirManager gets and deletes temporary directories correctly.
|
|
85
124
|
|
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
|
5
5
|
# License: AGPL
|
|
6
6
|
|
|
7
|
-
from typing import Union
|
|
8
|
-
|
|
9
|
-
|
|
10
7
|
__all__ = ["UpdateMetaMixin"]
|
|
11
8
|
|
|
12
9
|
|
|
@@ -15,8 +12,9 @@ class UpdateMetaMixin:
|
|
|
15
12
|
|
|
16
13
|
def update_meta(
|
|
17
14
|
self,
|
|
18
|
-
input:
|
|
15
|
+
input: dict | list[dict],
|
|
19
16
|
step_name: str,
|
|
17
|
+
append: bool = False,
|
|
20
18
|
) -> None:
|
|
21
19
|
"""Update metadata.
|
|
22
20
|
|
|
@@ -26,16 +24,18 @@ class UpdateMetaMixin:
|
|
|
26
24
|
The data object to update.
|
|
27
25
|
step_name : str
|
|
28
26
|
The name of the pipeline step.
|
|
27
|
+
append : bool, optional
|
|
28
|
+
Whether to append the metadata of the step to a list, for the
|
|
29
|
+
steps that can be several (e.g., the preprocessors), instead of
|
|
30
|
+
replacing the metadata of the previous step (default False).
|
|
29
31
|
|
|
30
32
|
"""
|
|
31
33
|
# Initialize empty dictionary for the step's metadata
|
|
32
34
|
t_meta = {}
|
|
33
35
|
# Set class name for the step
|
|
34
36
|
t_meta["class"] = self.__class__.__name__
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
if not k.startswith("_"):
|
|
38
|
-
t_meta[k] = v
|
|
37
|
+
# Dump model
|
|
38
|
+
t_meta.update(self.model_dump(mode="json"))
|
|
39
39
|
# Conditional for list dtype vals like Warp
|
|
40
40
|
if not isinstance(input, list):
|
|
41
41
|
input = [input]
|
|
@@ -44,13 +44,16 @@ class UpdateMetaMixin:
|
|
|
44
44
|
if "meta" not in entry:
|
|
45
45
|
entry["meta"] = {}
|
|
46
46
|
# Add step name
|
|
47
|
-
|
|
47
|
+
if append:
|
|
48
|
+
entry["meta"].setdefault(step_name, []).append(t_meta)
|
|
49
|
+
else:
|
|
50
|
+
entry["meta"][step_name] = t_meta
|
|
48
51
|
# Add step dependencies
|
|
49
52
|
if "dependencies" not in entry["meta"]:
|
|
50
53
|
entry["meta"]["dependencies"] = set()
|
|
51
54
|
# Update step dependencies
|
|
52
55
|
dependencies = getattr(self, "_DEPENDENCIES", set())
|
|
53
56
|
if dependencies is not None:
|
|
54
|
-
if not isinstance(dependencies,
|
|
57
|
+
if not isinstance(dependencies, set | list):
|
|
55
58
|
dependencies = {dependencies}
|
|
56
59
|
entry["meta"]["dependencies"].update(dependencies)
|
junifer/pipeline/utils.py
CHANGED
|
@@ -5,22 +5,35 @@
|
|
|
5
5
|
# License: AGPL
|
|
6
6
|
|
|
7
7
|
import subprocess
|
|
8
|
-
from
|
|
8
|
+
from enum import StrEnum
|
|
9
|
+
from typing import Any
|
|
9
10
|
|
|
10
|
-
from
|
|
11
|
+
from pydantic import validate_call
|
|
11
12
|
|
|
13
|
+
from ..utils import raise_error, warn_with_log
|
|
12
14
|
|
|
13
|
-
__all__ = ["check_ext_dependencies"]
|
|
14
15
|
|
|
16
|
+
__all__ = ["ExtDep", "check_ext_dependencies"]
|
|
15
17
|
|
|
18
|
+
|
|
19
|
+
class ExtDep(StrEnum):
|
|
20
|
+
"""Accepted external dependencies."""
|
|
21
|
+
|
|
22
|
+
AFNI = "afni"
|
|
23
|
+
FSL = "fsl"
|
|
24
|
+
ANTs = "ants"
|
|
25
|
+
FreeSurfer = "freesurfer"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@validate_call
|
|
16
29
|
def check_ext_dependencies(
|
|
17
|
-
name:
|
|
30
|
+
name: ExtDep, optional: bool = False, **kwargs: Any
|
|
18
31
|
) -> bool:
|
|
19
32
|
"""Check if external dependency `name` is found if mandatory.
|
|
20
33
|
|
|
21
34
|
Parameters
|
|
22
35
|
----------
|
|
23
|
-
name :
|
|
36
|
+
name : :enum:`.ExtDep`
|
|
24
37
|
The name of the dependency.
|
|
25
38
|
optional : bool, optional
|
|
26
39
|
Whether the dependency is optional (default False).
|
|
@@ -34,18 +47,10 @@ def check_ext_dependencies(
|
|
|
34
47
|
|
|
35
48
|
Raises
|
|
36
49
|
------
|
|
37
|
-
ValueError
|
|
38
|
-
If ``name`` is invalid.
|
|
39
50
|
RuntimeError
|
|
40
51
|
If ``name`` is mandatory and is not found.
|
|
41
52
|
|
|
42
53
|
"""
|
|
43
|
-
valid_ext_dependencies = ("afni", "fsl", "ants", "freesurfer")
|
|
44
|
-
if name not in valid_ext_dependencies:
|
|
45
|
-
raise_error(
|
|
46
|
-
"Invalid value for `name`, should be one of: "
|
|
47
|
-
f"{valid_ext_dependencies}"
|
|
48
|
-
)
|
|
49
54
|
# Check for afni
|
|
50
55
|
if name == "afni":
|
|
51
56
|
found = _check_afni(**kwargs)
|
|
@@ -71,7 +76,7 @@ def check_ext_dependencies(
|
|
|
71
76
|
return found
|
|
72
77
|
|
|
73
78
|
|
|
74
|
-
def _check_afni(commands:
|
|
79
|
+
def _check_afni(commands: list[str] | None = None) -> bool:
|
|
75
80
|
"""Check if AFNI is present in the system.
|
|
76
81
|
|
|
77
82
|
Parameters
|
|
@@ -131,7 +136,7 @@ def _check_afni(commands: Optional[list[str]] = None) -> bool:
|
|
|
131
136
|
return afni_found
|
|
132
137
|
|
|
133
138
|
|
|
134
|
-
def _check_fsl(commands:
|
|
139
|
+
def _check_fsl(commands: list[str] | None = None) -> bool:
|
|
135
140
|
"""Check if FSL is present in the system.
|
|
136
141
|
|
|
137
142
|
Parameters
|
|
@@ -195,7 +200,7 @@ def _check_fsl(commands: Optional[list[str]] = None) -> bool:
|
|
|
195
200
|
return fsl_found
|
|
196
201
|
|
|
197
202
|
|
|
198
|
-
def _check_ants(commands:
|
|
203
|
+
def _check_ants(commands: list[str] | None = None) -> bool:
|
|
199
204
|
"""Check if ANTs is present in the system.
|
|
200
205
|
|
|
201
206
|
Parameters
|
|
@@ -255,7 +260,7 @@ def _check_ants(commands: Optional[list[str]] = None) -> bool:
|
|
|
255
260
|
return ants_found
|
|
256
261
|
|
|
257
262
|
|
|
258
|
-
def _check_freesurfer(commands:
|
|
263
|
+
def _check_freesurfer(commands: list[str] | None = None) -> bool:
|
|
259
264
|
"""Check if FreeSurfer is present in the system.
|
|
260
265
|
|
|
261
266
|
Parameters
|
|
@@ -7,14 +7,17 @@
|
|
|
7
7
|
import shutil
|
|
8
8
|
import tempfile
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Optional, Union
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
import structlog
|
|
12
|
+
|
|
13
13
|
from ..utils.singleton import Singleton
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
__all__ = ["WorkDirManager"]
|
|
17
17
|
|
|
18
|
+
_log = structlog.get_logger("junifer")
|
|
19
|
+
logger = _log.bind(pkg="pipeline")
|
|
20
|
+
|
|
18
21
|
|
|
19
22
|
class WorkDirManager(metaclass=Singleton):
|
|
20
23
|
"""Class for working directory manager.
|
|
@@ -46,7 +49,7 @@ class WorkDirManager(metaclass=Singleton):
|
|
|
46
49
|
"""
|
|
47
50
|
|
|
48
51
|
def __init__(
|
|
49
|
-
self, workdir:
|
|
52
|
+
self, workdir: str | Path | None = None, cleanup: bool = True
|
|
50
53
|
) -> None:
|
|
51
54
|
"""Initialize the class."""
|
|
52
55
|
self._workdir = Path(workdir) if isinstance(workdir, str) else workdir
|
|
@@ -60,20 +63,16 @@ class WorkDirManager(metaclass=Singleton):
|
|
|
60
63
|
# Check and set topmost level directory if not provided
|
|
61
64
|
if self._workdir is None:
|
|
62
65
|
self._workdir = Path(tempfile.gettempdir()) / "junifer"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"Creating working directory at "
|
|
67
|
-
f"{self._workdir.resolve()!s}"
|
|
68
|
-
)
|
|
69
|
-
self._workdir.mkdir(parents=True)
|
|
66
|
+
|
|
67
|
+
# Create directory if not found
|
|
68
|
+
if not self._workdir.is_dir():
|
|
70
69
|
logger.debug(
|
|
71
|
-
f"
|
|
70
|
+
f"Creating working directory at {self._workdir.resolve()!s}"
|
|
72
71
|
)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
self._workdir.mkdir(parents=True)
|
|
73
|
+
logger.debug(
|
|
74
|
+
f"Setting working directory to {self._workdir.resolve()!s}"
|
|
75
|
+
)
|
|
77
76
|
|
|
78
77
|
def _cleanup(self) -> None:
|
|
79
78
|
"""Clean up the element and temporary directories."""
|
|
@@ -97,7 +96,7 @@ class WorkDirManager(metaclass=Singleton):
|
|
|
97
96
|
return self._workdir # type: ignore
|
|
98
97
|
|
|
99
98
|
@workdir.setter
|
|
100
|
-
def workdir(self, path:
|
|
99
|
+
def workdir(self, path: str | Path) -> None:
|
|
101
100
|
"""Set working directory.
|
|
102
101
|
|
|
103
102
|
The directory path is created if it doesn't exist yet.
|
|
@@ -129,8 +128,28 @@ class WorkDirManager(metaclass=Singleton):
|
|
|
129
128
|
"""Get element directory."""
|
|
130
129
|
return self._elementdir # type: ignore
|
|
131
130
|
|
|
131
|
+
def get_elementdir(self) -> Path:
|
|
132
|
+
"""Get the element directory, creating it if needed.
|
|
133
|
+
|
|
134
|
+
This directory should be available only for the lifetime of an
|
|
135
|
+
element.
|
|
136
|
+
|
|
137
|
+
Returns
|
|
138
|
+
-------
|
|
139
|
+
pathlib.Path
|
|
140
|
+
The path to the element directory.
|
|
141
|
+
|
|
142
|
+
"""
|
|
143
|
+
if self._elementdir is None:
|
|
144
|
+
logger.debug(
|
|
145
|
+
"Setting up element directory under "
|
|
146
|
+
f"{self._workdir.resolve()!s}" # type: ignore
|
|
147
|
+
)
|
|
148
|
+
self._elementdir = Path(tempfile.mkdtemp(dir=self._workdir))
|
|
149
|
+
return self._elementdir
|
|
150
|
+
|
|
132
151
|
def get_element_tempdir(
|
|
133
|
-
self, prefix:
|
|
152
|
+
self, prefix: str | None = None, suffix: str | None = None
|
|
134
153
|
) -> Path:
|
|
135
154
|
"""Get an element-scoped temporary directory.
|
|
136
155
|
|
|
@@ -152,22 +171,12 @@ class WorkDirManager(metaclass=Singleton):
|
|
|
152
171
|
The path to the temporary directory.
|
|
153
172
|
|
|
154
173
|
"""
|
|
155
|
-
|
|
156
|
-
if self._elementdir is None:
|
|
157
|
-
logger.debug(
|
|
158
|
-
"Setting up element directory under "
|
|
159
|
-
f"{self._workdir.resolve()!s}" # type: ignore
|
|
160
|
-
)
|
|
161
|
-
self._elementdir = Path(tempfile.mkdtemp(dir=self._workdir))
|
|
162
|
-
|
|
174
|
+
elementdir = self.get_elementdir()
|
|
163
175
|
logger.debug(
|
|
164
|
-
"Creating element temporary directory at "
|
|
165
|
-
f"{self._elementdir.resolve()!s}"
|
|
176
|
+
f"Creating element temporary directory at {elementdir.resolve()!s}"
|
|
166
177
|
)
|
|
167
178
|
return Path(
|
|
168
|
-
tempfile.mkdtemp(
|
|
169
|
-
dir=self._elementdir, prefix=prefix, suffix=suffix
|
|
170
|
-
)
|
|
179
|
+
tempfile.mkdtemp(dir=elementdir, prefix=prefix, suffix=suffix)
|
|
171
180
|
)
|
|
172
181
|
|
|
173
182
|
def delete_element_tempdir(self, tempdir: Path) -> None:
|
|
@@ -203,12 +212,12 @@ class WorkDirManager(metaclass=Singleton):
|
|
|
203
212
|
self._elementdir = None
|
|
204
213
|
|
|
205
214
|
@property
|
|
206
|
-
def root_tempdir(self) ->
|
|
215
|
+
def root_tempdir(self) -> Path | None:
|
|
207
216
|
"""Get root temporary directory."""
|
|
208
217
|
return self._root_tempdir
|
|
209
218
|
|
|
210
219
|
def get_tempdir(
|
|
211
|
-
self, prefix:
|
|
220
|
+
self, prefix: str | None = None, suffix: str | None = None
|
|
212
221
|
) -> Path:
|
|
213
222
|
"""Get a component-scoped temporary directory.
|
|
214
223
|
|
junifer/preprocess/__init__.pyi
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
__all__ = [
|
|
2
2
|
"BasePreprocessor",
|
|
3
3
|
"fMRIPrepConfoundRemover",
|
|
4
|
+
"Confounds",
|
|
5
|
+
"Strategy",
|
|
4
6
|
"SpaceWarper",
|
|
7
|
+
"SpaceWarpingImpl",
|
|
5
8
|
"Smoothing",
|
|
9
|
+
"SmoothingImpl",
|
|
6
10
|
"TemporalSlicer",
|
|
7
11
|
"TemporalFilter",
|
|
12
|
+
"logger",
|
|
8
13
|
]
|
|
9
14
|
|
|
10
|
-
from .base import BasePreprocessor
|
|
11
|
-
from .confounds import fMRIPrepConfoundRemover
|
|
12
|
-
from .warping import SpaceWarper
|
|
13
|
-
from .smoothing import Smoothing
|
|
15
|
+
from .base import BasePreprocessor, logger
|
|
16
|
+
from .confounds import fMRIPrepConfoundRemover, Confounds, Strategy
|
|
17
|
+
from .warping import SpaceWarper, SpaceWarpingImpl
|
|
18
|
+
from .smoothing import Smoothing, SmoothingImpl
|
|
14
19
|
from ._temporal_slicer import TemporalSlicer
|
|
15
20
|
from ._temporal_filter import TemporalFilter
|