junifer 0.0.6.dev154__py3-none-any.whl → 0.0.6.dev194__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/__init__.pyi +2 -0
- junifer/_version.py +2 -2
- junifer/api/decorators.py +6 -11
- junifer/api/functions.py +74 -62
- junifer/api/tests/test_functions.py +2 -2
- junifer/data/__init__.pyi +17 -31
- junifer/data/_dispatch.py +251 -0
- junifer/data/coordinates/__init__.py +9 -0
- junifer/data/coordinates/__init__.pyi +5 -0
- junifer/data/coordinates/_ants_coordinates_warper.py +96 -0
- junifer/data/coordinates/_coordinates.py +356 -0
- junifer/data/coordinates/_fsl_coordinates_warper.py +83 -0
- junifer/data/{tests → coordinates/tests}/test_coordinates.py +25 -31
- junifer/data/masks/__init__.py +9 -0
- junifer/data/masks/__init__.pyi +6 -0
- junifer/data/masks/_ants_mask_warper.py +144 -0
- junifer/data/masks/_fsl_mask_warper.py +87 -0
- junifer/data/masks/_masks.py +624 -0
- junifer/data/{tests → masks/tests}/test_masks.py +63 -58
- junifer/data/parcellations/__init__.py +9 -0
- junifer/data/parcellations/__init__.pyi +6 -0
- junifer/data/parcellations/_ants_parcellation_warper.py +154 -0
- junifer/data/parcellations/_fsl_parcellation_warper.py +91 -0
- junifer/data/{parcellations.py → parcellations/_parcellations.py} +450 -473
- junifer/data/{tests → parcellations/tests}/test_parcellations.py +73 -81
- junifer/data/pipeline_data_registry_base.py +74 -0
- junifer/data/utils.py +4 -0
- junifer/datagrabber/aomic/piop2.py +1 -1
- junifer/markers/complexity/hurst_exponent.py +2 -2
- junifer/markers/complexity/multiscale_entropy_auc.py +2 -2
- junifer/markers/complexity/perm_entropy.py +2 -2
- junifer/markers/complexity/range_entropy.py +2 -2
- junifer/markers/complexity/range_entropy_auc.py +2 -2
- junifer/markers/complexity/sample_entropy.py +2 -2
- junifer/markers/complexity/weighted_perm_entropy.py +2 -2
- junifer/markers/ets_rss.py +2 -2
- junifer/markers/falff/falff_parcels.py +2 -2
- junifer/markers/falff/falff_spheres.py +2 -2
- junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +1 -1
- junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +1 -1
- junifer/markers/functional_connectivity/functional_connectivity_parcels.py +1 -1
- junifer/markers/functional_connectivity/functional_connectivity_spheres.py +1 -1
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +3 -3
- junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +2 -2
- junifer/markers/parcel_aggregation.py +11 -7
- junifer/markers/reho/reho_parcels.py +2 -2
- junifer/markers/reho/reho_spheres.py +2 -2
- junifer/markers/sphere_aggregation.py +11 -7
- junifer/markers/temporal_snr/temporal_snr_parcels.py +2 -2
- junifer/markers/temporal_snr/temporal_snr_spheres.py +2 -2
- junifer/markers/tests/test_ets_rss.py +3 -3
- junifer/markers/tests/test_parcel_aggregation.py +24 -24
- junifer/markers/tests/test_sphere_aggregation.py +6 -6
- junifer/pipeline/__init__.pyi +2 -2
- junifer/pipeline/pipeline_component_registry.py +299 -0
- junifer/pipeline/tests/test_pipeline_component_registry.py +201 -0
- junifer/preprocess/confounds/fmriprep_confound_remover.py +6 -3
- junifer/testing/__init__.pyi +2 -2
- junifer/testing/registry.py +4 -7
- junifer/testing/tests/test_testing_registry.py +9 -17
- {junifer-0.0.6.dev154.dist-info → junifer-0.0.6.dev194.dist-info}/METADATA +1 -1
- {junifer-0.0.6.dev154.dist-info → junifer-0.0.6.dev194.dist-info}/RECORD +86 -72
- {junifer-0.0.6.dev154.dist-info → junifer-0.0.6.dev194.dist-info}/WHEEL +1 -1
- junifer/data/coordinates.py +0 -408
- junifer/data/masks.py +0 -670
- junifer/pipeline/registry.py +0 -245
- junifer/pipeline/tests/test_registry.py +0 -150
- /junifer/data/{VOIs → coordinates/VOIs}/meta/AutobiographicalMemory_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/CogAC_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/CogAR_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/DMNBuckner_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Dosenbach2010_MNI_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Empathy_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Motor_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/MultiTask_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/PhysioStress_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Power2011_MNI_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Power2013_MNI_VOIs.tsv +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Rew_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/Somatosensory_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/ToM_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/VigAtt_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/WM_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/eMDN_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/eSAD_VOIs.txt +0 -0
- /junifer/data/{VOIs → coordinates/VOIs}/meta/extDMN_VOIs.txt +0 -0
- {junifer-0.0.6.dev154.dist-info → junifer-0.0.6.dev194.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.6.dev154.dist-info → junifer-0.0.6.dev194.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.6.dev154.dist-info → junifer-0.0.6.dev194.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.6.dev154.dist-info → junifer-0.0.6.dev194.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,299 @@
|
|
1
|
+
"""Provide a class for centralized pipeline component registry."""
|
2
|
+
|
3
|
+
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
|
4
|
+
# Leonard Sasse <l.sasse@fz-juelich.de>
|
5
|
+
# Synchon Mandal <s.mandal@fz-juelich.de>
|
6
|
+
# License: AGPL
|
7
|
+
|
8
|
+
import importlib
|
9
|
+
from typing import TYPE_CHECKING, Dict, List, Mapping, Optional, Union
|
10
|
+
|
11
|
+
from ..utils import logger, raise_error
|
12
|
+
from .singleton import singleton
|
13
|
+
|
14
|
+
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from ..datagrabber import BaseDataGrabber
|
17
|
+
from ..storage import BaseFeatureStorage
|
18
|
+
from .pipeline_step_mixin import PipelineStepMixin
|
19
|
+
|
20
|
+
|
21
|
+
__all__ = ["PipelineComponentRegistry"]
|
22
|
+
|
23
|
+
|
24
|
+
@singleton
|
25
|
+
class PipelineComponentRegistry:
|
26
|
+
"""Class for pipeline component registry.
|
27
|
+
|
28
|
+
This class is a singleton and is used for managing pipeline components.
|
29
|
+
It serves as a centralized registry for built-in and third-party pipeline
|
30
|
+
components like datagrabbers, datareaders, preprocessors, markers and
|
31
|
+
storage.
|
32
|
+
|
33
|
+
Attributes
|
34
|
+
----------
|
35
|
+
steps : list of str
|
36
|
+
Valid pipeline steps.
|
37
|
+
components : dict
|
38
|
+
Registered components for valid pipeline steps.
|
39
|
+
|
40
|
+
"""
|
41
|
+
|
42
|
+
def __init__(self) -> None:
|
43
|
+
"""Initialize the class."""
|
44
|
+
# Valid steps for operation
|
45
|
+
self._steps = [
|
46
|
+
"datagrabber",
|
47
|
+
"datareader",
|
48
|
+
"preprocessing",
|
49
|
+
"marker",
|
50
|
+
"storage",
|
51
|
+
]
|
52
|
+
# Step to sub-package mapping
|
53
|
+
self._step_to_subpkg_mappings = {
|
54
|
+
"datagrabber": "datagrabber",
|
55
|
+
"datareader": "datareader",
|
56
|
+
"preprocessing": "preprocess",
|
57
|
+
"marker": "markers",
|
58
|
+
"storage": "storage",
|
59
|
+
}
|
60
|
+
# Component registry for valid steps
|
61
|
+
self._components = {
|
62
|
+
"datagrabber": {
|
63
|
+
"HCP1200": "HCP1200",
|
64
|
+
"BaseDataGrabber": "BaseDataGrabber",
|
65
|
+
"DataladAOMICID1000": "DataladAOMICID1000",
|
66
|
+
"DataladAOMICPIOP1": "DataladAOMICPIOP1",
|
67
|
+
"DataladAOMICPIOP2": "DataladAOMICPIOP2",
|
68
|
+
"DataladDataGrabber": "DataladDataGrabber",
|
69
|
+
"DataladHCP1200": "DataladHCP1200",
|
70
|
+
"DMCC13Benchmark": "DMCC13Benchmark",
|
71
|
+
"MultipleDataGrabber": "MultipleDataGrabber",
|
72
|
+
"PatternDataGrabber": "PatternDataGrabber",
|
73
|
+
"PatternDataladDataGrabber": "PatternDataladDataGrabber",
|
74
|
+
},
|
75
|
+
"datareader": {
|
76
|
+
"DefaultDataReader": "DefaultDataReader",
|
77
|
+
},
|
78
|
+
"preprocessing": {
|
79
|
+
"BasePreprocessor": "BasePreprocessor",
|
80
|
+
"Smoothing": "Smoothing",
|
81
|
+
"SpaceWarper": "SpaceWarper",
|
82
|
+
"fMRIPrepConfoundRemover": "fMRIPrepConfoundRemover",
|
83
|
+
},
|
84
|
+
"marker": {
|
85
|
+
"ALFFParcels": "ALFFParcels",
|
86
|
+
"ALFFSpheres": "ALFFSpheres",
|
87
|
+
"BaseMarker": "BaseMarker",
|
88
|
+
"BrainPrint": "BrainPrint",
|
89
|
+
"CrossParcellationFC": "CrossParcellationFC",
|
90
|
+
"EdgeCentricFCParcels": "EdgeCentricFCParcels",
|
91
|
+
"EdgeCentricFCSpheres": "EdgeCentricFCSpheres",
|
92
|
+
"FunctionalConnectivityParcels": (
|
93
|
+
"FunctionalConnectivityParcels"
|
94
|
+
),
|
95
|
+
"FunctionalConnectivitySpheres": (
|
96
|
+
"FunctionalConnectivitySpheres"
|
97
|
+
),
|
98
|
+
"ParcelAggregation": "ParcelAggregation",
|
99
|
+
"ReHoParcels": "ReHoParcels",
|
100
|
+
"ReHoSpheres": "ReHoSpheres",
|
101
|
+
"RSSETSMarker": "RSSETSMarker",
|
102
|
+
"SphereAggregation": "SphereAggregation",
|
103
|
+
"TemporalSNRParcels": "TemporalSNRParcels",
|
104
|
+
"TemporalSNRSpheres": "TemporalSNRSpheres",
|
105
|
+
},
|
106
|
+
"storage": {
|
107
|
+
"BaseFeatureStorage": "BaseFeatureStorage",
|
108
|
+
"HDF5FeatureStorage": "HDF5FeatureStorage",
|
109
|
+
"PandasBaseFeatureStorage": "PandasBaseFeatureStorage",
|
110
|
+
"SQLiteFeatureStorage": "SQLiteFeatureStorage",
|
111
|
+
},
|
112
|
+
}
|
113
|
+
|
114
|
+
def _check_valid_step(self, step: str) -> None:
|
115
|
+
"""Check if ``step`` is valid."""
|
116
|
+
if step not in self._steps:
|
117
|
+
raise_error(msg=f"Invalid step: {step}", klass=ValueError)
|
118
|
+
|
119
|
+
@property
|
120
|
+
def steps(self) -> List[str]:
|
121
|
+
"""Get valid pipeline steps."""
|
122
|
+
return self._steps
|
123
|
+
|
124
|
+
@property
|
125
|
+
def components(self) -> Mapping[str, Mapping[str, Union[str, type]]]:
|
126
|
+
"""Get registered components for valid pipeline steps."""
|
127
|
+
return self._components
|
128
|
+
|
129
|
+
def register(self, step: str, klass: type) -> None:
|
130
|
+
"""Register ``klass`` under ``step``.
|
131
|
+
|
132
|
+
Parameters
|
133
|
+
----------
|
134
|
+
step : str
|
135
|
+
Name of the pipeline step. For valid steps, check :meth:`.steps`.
|
136
|
+
klass : class
|
137
|
+
Class to be registered.
|
138
|
+
|
139
|
+
Raises
|
140
|
+
------
|
141
|
+
ValueError
|
142
|
+
If the ``step`` is invalid.
|
143
|
+
|
144
|
+
"""
|
145
|
+
# Verify step
|
146
|
+
self._check_valid_step(step)
|
147
|
+
# Log and register
|
148
|
+
name = klass.__name__
|
149
|
+
logger.info(f"Registering {name} in {step}")
|
150
|
+
self._components[step][name] = klass
|
151
|
+
|
152
|
+
def deregister(self, step: str, klass: type) -> None:
|
153
|
+
"""De-register ``klass`` under ``step``.
|
154
|
+
|
155
|
+
Parameters
|
156
|
+
----------
|
157
|
+
step : str
|
158
|
+
Name of the pipeline step. For valid steps, check :meth:`.steps`.
|
159
|
+
klass : class
|
160
|
+
Class to be de-registered.
|
161
|
+
|
162
|
+
Raises
|
163
|
+
------
|
164
|
+
ValueError
|
165
|
+
If the ``step`` is invalid.
|
166
|
+
|
167
|
+
"""
|
168
|
+
# Verify step
|
169
|
+
self._check_valid_step(step)
|
170
|
+
# Log and de-register
|
171
|
+
name = klass.__name__
|
172
|
+
logger.info(f"De-registering {name} in {step}")
|
173
|
+
_ = self._components[step].pop(name)
|
174
|
+
|
175
|
+
def step_components(self, step: str) -> List[str]:
|
176
|
+
"""Get registered components for ``step``.
|
177
|
+
|
178
|
+
Parameters
|
179
|
+
----------
|
180
|
+
step : str
|
181
|
+
Name of the pipeline step.
|
182
|
+
|
183
|
+
Returns
|
184
|
+
-------
|
185
|
+
list of str
|
186
|
+
List of registered component classes.
|
187
|
+
|
188
|
+
Raises
|
189
|
+
------
|
190
|
+
ValueError
|
191
|
+
If the ``step`` is invalid.
|
192
|
+
|
193
|
+
"""
|
194
|
+
# Verify step
|
195
|
+
self._check_valid_step(step)
|
196
|
+
|
197
|
+
return list(self._components[step].keys())
|
198
|
+
|
199
|
+
def get_class(self, step: str, name: str) -> type:
|
200
|
+
"""Get the class registered under ``name`` for ``step``.
|
201
|
+
|
202
|
+
Parameters
|
203
|
+
----------
|
204
|
+
step : str
|
205
|
+
Name of the pipeline step.
|
206
|
+
name : str
|
207
|
+
Name of the component.
|
208
|
+
|
209
|
+
Returns
|
210
|
+
-------
|
211
|
+
class
|
212
|
+
Registered class.
|
213
|
+
|
214
|
+
Raises
|
215
|
+
------
|
216
|
+
ValueError
|
217
|
+
If the ``step`` or ``name`` is invalid.
|
218
|
+
|
219
|
+
"""
|
220
|
+
# Verify step
|
221
|
+
self._check_valid_step(step)
|
222
|
+
# Verify step name
|
223
|
+
if name not in self._components[step]:
|
224
|
+
raise_error(msg=f"Invalid name: {name}", klass=ValueError)
|
225
|
+
|
226
|
+
# Check if first-time import, then import it
|
227
|
+
if isinstance(self._components[step][name], str):
|
228
|
+
klass = getattr(
|
229
|
+
importlib.import_module(
|
230
|
+
f"junifer.{self._step_to_subpkg_mappings[step]}"
|
231
|
+
),
|
232
|
+
name,
|
233
|
+
)
|
234
|
+
else:
|
235
|
+
klass = self._components[step][name]
|
236
|
+
|
237
|
+
return klass
|
238
|
+
|
239
|
+
def build_component_instance(
|
240
|
+
self,
|
241
|
+
step: str,
|
242
|
+
name: str,
|
243
|
+
baseclass: type,
|
244
|
+
init_params: Optional[Dict] = None,
|
245
|
+
) -> Union["BaseDataGrabber", "PipelineStepMixin", "BaseFeatureStorage"]:
|
246
|
+
"""Build an instance of class registered as ``name``.
|
247
|
+
|
248
|
+
Parameters
|
249
|
+
----------
|
250
|
+
step : str
|
251
|
+
Name of the pipeline step.
|
252
|
+
name : str
|
253
|
+
Name of the component.
|
254
|
+
baseclass : class
|
255
|
+
Base class to be checked against.
|
256
|
+
init_params : dict or None, optional
|
257
|
+
Parameters to pass to the class constructor (default None).
|
258
|
+
|
259
|
+
Returns
|
260
|
+
-------
|
261
|
+
object
|
262
|
+
An instance of the class registered as ``name`` under ``step``.
|
263
|
+
|
264
|
+
Raises
|
265
|
+
------
|
266
|
+
RuntimeError
|
267
|
+
If there is a problem creating the instance.
|
268
|
+
ValueError
|
269
|
+
If the created object with the given name is not a subclass of the
|
270
|
+
base class ``baseclass``.
|
271
|
+
|
272
|
+
"""
|
273
|
+
# Set default init parameters
|
274
|
+
if init_params is None:
|
275
|
+
init_params = {}
|
276
|
+
# Get registered class
|
277
|
+
logger.debug(f"Building {step}/{name}")
|
278
|
+
klass = self.get_class(step=step, name=name)
|
279
|
+
logger.debug(f"\tClass: {klass.__name__}")
|
280
|
+
logger.debug(f"\tInit params: {init_params}")
|
281
|
+
try:
|
282
|
+
# Create instance of the class
|
283
|
+
object_ = klass(**init_params)
|
284
|
+
except (ValueError, TypeError) as e:
|
285
|
+
raise_error(
|
286
|
+
msg=f"Failed to create {step} ({name}). Error: {e}",
|
287
|
+
klass=RuntimeError,
|
288
|
+
exception=e,
|
289
|
+
)
|
290
|
+
# Verify created instance belongs to the base class
|
291
|
+
if not isinstance(object_, baseclass):
|
292
|
+
raise_error(
|
293
|
+
msg=(
|
294
|
+
f"Invalid {step} ({object_.__class__.__name__}). "
|
295
|
+
f"Must inherit from {baseclass.__name__}"
|
296
|
+
),
|
297
|
+
klass=ValueError,
|
298
|
+
)
|
299
|
+
return object_
|
@@ -0,0 +1,201 @@
|
|
1
|
+
"""Provide tests for PipelineComponentRegistry."""
|
2
|
+
|
3
|
+
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
|
4
|
+
# Leonard Sasse <l.sasse@fz-juelich.de>
|
5
|
+
# Synchon Mandal <s.mandal@fz-juelich.de>
|
6
|
+
# License: AGPL
|
7
|
+
|
8
|
+
import logging
|
9
|
+
from abc import ABC
|
10
|
+
from typing import Type
|
11
|
+
|
12
|
+
import pytest
|
13
|
+
|
14
|
+
from junifer.datagrabber.pattern import PatternDataGrabber
|
15
|
+
from junifer.pipeline.pipeline_component_registry import (
|
16
|
+
PipelineComponentRegistry,
|
17
|
+
)
|
18
|
+
from junifer.storage import SQLiteFeatureStorage
|
19
|
+
|
20
|
+
|
21
|
+
def test_pipeline_component_registry_singleton() -> None:
|
22
|
+
"""Test that PipelineComponentRegistry is a singleton."""
|
23
|
+
registry_1 = PipelineComponentRegistry()
|
24
|
+
registry_2 = PipelineComponentRegistry()
|
25
|
+
assert id(registry_1) == id(registry_2)
|
26
|
+
|
27
|
+
|
28
|
+
def test_pipeline_component_registry_register_invalid_step():
|
29
|
+
"""Test invalid step name during component registration."""
|
30
|
+
with pytest.raises(ValueError, match="Invalid step:"):
|
31
|
+
PipelineComponentRegistry().register(step="foo", klass=str)
|
32
|
+
|
33
|
+
|
34
|
+
def test_pipeline_component_registry_steps():
|
35
|
+
"""Test steps for PipelineComponentRegistry."""
|
36
|
+
assert set(PipelineComponentRegistry().steps) == {
|
37
|
+
"datagrabber",
|
38
|
+
"datareader",
|
39
|
+
"preprocessing",
|
40
|
+
"marker",
|
41
|
+
"storage",
|
42
|
+
}
|
43
|
+
|
44
|
+
|
45
|
+
def test_pipeline_component_registry_components():
|
46
|
+
"""Test components for PipelineComponentRegistry."""
|
47
|
+
assert set(PipelineComponentRegistry().steps) == {
|
48
|
+
"datagrabber",
|
49
|
+
"datareader",
|
50
|
+
"preprocessing",
|
51
|
+
"marker",
|
52
|
+
"storage",
|
53
|
+
}
|
54
|
+
|
55
|
+
|
56
|
+
@pytest.mark.parametrize(
|
57
|
+
"step, klass",
|
58
|
+
[
|
59
|
+
("datagrabber", PatternDataGrabber),
|
60
|
+
("storage", SQLiteFeatureStorage),
|
61
|
+
],
|
62
|
+
)
|
63
|
+
def test_pipeline_component_registry_register(
|
64
|
+
caplog: pytest.LogCaptureFixture, step: str, klass: Type
|
65
|
+
) -> None:
|
66
|
+
"""Test register for PipelineComponentRegistry.
|
67
|
+
|
68
|
+
Parameters
|
69
|
+
----------
|
70
|
+
caplog : pytest.LogCaptureFixture
|
71
|
+
The pytest.LogCaptureFixture object.
|
72
|
+
step : str
|
73
|
+
The parametrized name of the step.
|
74
|
+
klass : str
|
75
|
+
The parametrized name of the class.
|
76
|
+
|
77
|
+
"""
|
78
|
+
with caplog.at_level(logging.INFO):
|
79
|
+
# Register
|
80
|
+
PipelineComponentRegistry().register(step=step, klass=klass)
|
81
|
+
# Check logging message
|
82
|
+
assert "Registering" in caplog.text
|
83
|
+
|
84
|
+
|
85
|
+
@pytest.mark.parametrize(
|
86
|
+
"step, klass",
|
87
|
+
[
|
88
|
+
("datagrabber", PatternDataGrabber),
|
89
|
+
("storage", SQLiteFeatureStorage),
|
90
|
+
],
|
91
|
+
)
|
92
|
+
def test_pipeline_component_registry_deregister(
|
93
|
+
caplog: pytest.LogCaptureFixture, step: str, klass: Type
|
94
|
+
) -> None:
|
95
|
+
"""Test de-register for PipelineComponentRegistry.
|
96
|
+
|
97
|
+
Parameters
|
98
|
+
----------
|
99
|
+
caplog : pytest.LogCaptureFixture
|
100
|
+
The pytest.LogCaptureFixture object.
|
101
|
+
step : str
|
102
|
+
The parametrized name of the step.
|
103
|
+
klass : str
|
104
|
+
The parametrized name of the class.
|
105
|
+
|
106
|
+
"""
|
107
|
+
with caplog.at_level(logging.INFO):
|
108
|
+
# Register
|
109
|
+
PipelineComponentRegistry().deregister(step=step, klass=klass)
|
110
|
+
# Check logging message
|
111
|
+
assert "De-registering" in caplog.text
|
112
|
+
|
113
|
+
|
114
|
+
def test_pipeline_component_registry_step_components() -> None:
|
115
|
+
"""Test step components for PipelineComponentRegistry."""
|
116
|
+
# Check absent name
|
117
|
+
assert "fizz" not in PipelineComponentRegistry().step_components(
|
118
|
+
step="datagrabber"
|
119
|
+
)
|
120
|
+
|
121
|
+
# Create new class
|
122
|
+
class fizz(str):
|
123
|
+
pass
|
124
|
+
|
125
|
+
# Register datagrabber
|
126
|
+
PipelineComponentRegistry().register(step="datagrabber", klass=fizz)
|
127
|
+
# Check registered component
|
128
|
+
assert "fizz" in PipelineComponentRegistry().step_components(
|
129
|
+
step="datagrabber"
|
130
|
+
)
|
131
|
+
|
132
|
+
|
133
|
+
def test_pipeline_component_registry_get_class_invalid_name() -> None:
|
134
|
+
"""Test get class invalid name for PipelineComponentRegistry."""
|
135
|
+
with pytest.raises(ValueError, match="Invalid name:"):
|
136
|
+
PipelineComponentRegistry().get_class(step="datagrabber", name="foo")
|
137
|
+
|
138
|
+
|
139
|
+
def test_pipeline_component_registry_get_class():
|
140
|
+
"""Test get class for PipelineComponentRegistry."""
|
141
|
+
|
142
|
+
# Create new class
|
143
|
+
class bar(str):
|
144
|
+
pass
|
145
|
+
|
146
|
+
# Register datagrabber
|
147
|
+
PipelineComponentRegistry().register(step="datagrabber", klass=bar)
|
148
|
+
# Get class
|
149
|
+
obj = PipelineComponentRegistry().get_class(step="datagrabber", name="bar")
|
150
|
+
assert isinstance(obj, type(bar))
|
151
|
+
|
152
|
+
|
153
|
+
def test_pipeline_component_registry_build():
|
154
|
+
"""Test component instance building for PipelineComponentRegistry."""
|
155
|
+
import numpy as np
|
156
|
+
|
157
|
+
# Define abstract base class
|
158
|
+
class SuperClass(ABC):
|
159
|
+
pass
|
160
|
+
|
161
|
+
# Define concrete class
|
162
|
+
class ConcreteClass(SuperClass):
|
163
|
+
def __init__(self, value=1):
|
164
|
+
self.value = value
|
165
|
+
|
166
|
+
# Register
|
167
|
+
PipelineComponentRegistry().register(
|
168
|
+
step="datagrabber", klass=ConcreteClass
|
169
|
+
)
|
170
|
+
|
171
|
+
# Build
|
172
|
+
obj = PipelineComponentRegistry().build_component_instance(
|
173
|
+
step="datagrabber", name="ConcreteClass", baseclass=SuperClass
|
174
|
+
)
|
175
|
+
assert isinstance(obj, ConcreteClass)
|
176
|
+
assert obj.value == 1
|
177
|
+
|
178
|
+
# Build
|
179
|
+
obj = PipelineComponentRegistry().build_component_instance(
|
180
|
+
step="datagrabber",
|
181
|
+
name="ConcreteClass",
|
182
|
+
baseclass=SuperClass,
|
183
|
+
init_params={"value": 2},
|
184
|
+
)
|
185
|
+
assert isinstance(obj, ConcreteClass)
|
186
|
+
assert obj.value == 2
|
187
|
+
|
188
|
+
# Check error
|
189
|
+
with pytest.raises(ValueError, match="Must inherit"):
|
190
|
+
PipelineComponentRegistry().build_component_instance(
|
191
|
+
step="datagrabber", name="ConcreteClass", baseclass=np.ndarray
|
192
|
+
)
|
193
|
+
|
194
|
+
# Check error
|
195
|
+
with pytest.raises(RuntimeError, match="Failed to create"):
|
196
|
+
PipelineComponentRegistry().build_component_instance(
|
197
|
+
step="datagrabber",
|
198
|
+
name="ConcreteClass",
|
199
|
+
baseclass=SuperClass,
|
200
|
+
init_params={"wrong": 2},
|
201
|
+
)
|
@@ -22,7 +22,7 @@ from nilearn import image as nimg
|
|
22
22
|
from nilearn._utils.niimg_conversions import check_niimg_4d
|
23
23
|
|
24
24
|
from ...api.decorators import register_preprocessor
|
25
|
-
from ...data import
|
25
|
+
from ...data import get_data
|
26
26
|
from ...utils import logger, raise_error
|
27
27
|
from ..base import BasePreprocessor
|
28
28
|
|
@@ -546,8 +546,11 @@ class fMRIPrepConfoundRemover(BasePreprocessor):
|
|
546
546
|
mask_img = None
|
547
547
|
if self.masks is not None:
|
548
548
|
logger.debug(f"Masking with {self.masks}")
|
549
|
-
mask_img =
|
550
|
-
|
549
|
+
mask_img = get_data(
|
550
|
+
kind="mask",
|
551
|
+
names=self.masks,
|
552
|
+
target_data=input,
|
553
|
+
extra_input=extra_input,
|
551
554
|
)
|
552
555
|
# Return the BOLD mask and link it to the BOLD data type dict;
|
553
556
|
# this allows to use "inherit" down the pipeline
|
junifer/testing/__init__.pyi
CHANGED
junifer/testing/registry.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
5
5
|
# License: AGPL
|
6
6
|
|
7
|
-
from ..pipeline
|
7
|
+
from ..pipeline import PipelineComponentRegistry
|
8
8
|
from .datagrabbers import (
|
9
9
|
OasisVBMTestingDataGrabber,
|
10
10
|
PartlyCloudyTestingDataGrabber,
|
@@ -13,20 +13,17 @@ from .datagrabbers import (
|
|
13
13
|
|
14
14
|
|
15
15
|
# Register testing DataGrabbers
|
16
|
-
register(
|
16
|
+
PipelineComponentRegistry().register(
|
17
17
|
step="datagrabber",
|
18
|
-
name="OasisVBMTestingDataGrabber",
|
19
18
|
klass=OasisVBMTestingDataGrabber,
|
20
19
|
)
|
21
20
|
|
22
|
-
register(
|
21
|
+
PipelineComponentRegistry().register(
|
23
22
|
step="datagrabber",
|
24
|
-
name="SPMAuditoryTestingDataGrabber",
|
25
23
|
klass=SPMAuditoryTestingDataGrabber,
|
26
24
|
)
|
27
25
|
|
28
|
-
register(
|
26
|
+
PipelineComponentRegistry().register(
|
29
27
|
step="datagrabber",
|
30
|
-
name="PartlyCloudyTestingDataGrabber",
|
31
28
|
klass=PartlyCloudyTestingDataGrabber,
|
32
29
|
)
|
@@ -1,24 +1,16 @@
|
|
1
1
|
"""Provide tests for testing registry."""
|
2
2
|
|
3
|
-
|
3
|
+
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
|
4
|
+
# Synchon Mandal <s.mandal@fz-juelich.de>
|
5
|
+
# License: AGPL
|
4
6
|
|
5
|
-
from junifer.pipeline
|
7
|
+
from junifer.pipeline import PipelineComponentRegistry
|
6
8
|
|
7
9
|
|
8
10
|
def test_testing_registry() -> None:
|
9
11
|
"""Test testing registry."""
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
assert "OasisVBMTestingDataGrabber" not in get_step_names("datagrabber")
|
16
|
-
assert "SPMAuditoryTestingDataGrabber" not in get_step_names("datagrabber")
|
17
|
-
assert "PartlyCloudyTestingDataGrabber" not in get_step_names(
|
18
|
-
"datagrabber"
|
19
|
-
)
|
20
|
-
importlib.reload(junifer.testing.registry) # type: ignore
|
21
|
-
|
22
|
-
assert "OasisVBMTestingDataGrabber" in get_step_names("datagrabber")
|
23
|
-
assert "SPMAuditoryTestingDataGrabber" in get_step_names("datagrabber")
|
24
|
-
assert "PartlyCloudyTestingDataGrabber" in get_step_names("datagrabber")
|
12
|
+
assert {
|
13
|
+
"OasisVBMTestingDataGrabber",
|
14
|
+
"SPMAuditoryTestingDataGrabber",
|
15
|
+
"PartlyCloudyTestingDataGrabber",
|
16
|
+
}.issubset(set(PipelineComponentRegistry().step_components("datagrabber")))
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: junifer
|
3
|
-
Version: 0.0.6.
|
3
|
+
Version: 0.0.6.dev194
|
4
4
|
Summary: JUelich NeuroImaging FEature extractoR
|
5
5
|
Author-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
|
6
6
|
Maintainer-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
|