junifer 0.0.6.dev213__py3-none-any.whl → 0.0.6.dev227__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.
Files changed (46) hide show
  1. junifer/__init__.pyi +2 -0
  2. junifer/_version.py +2 -2
  3. junifer/api/decorators.py +5 -4
  4. junifer/api/functions.py +9 -8
  5. junifer/datagrabber/multiple.py +2 -1
  6. junifer/markers/base.py +4 -7
  7. junifer/markers/brainprint.py +4 -4
  8. junifer/markers/complexity/complexity_base.py +3 -3
  9. junifer/markers/ets_rss.py +4 -3
  10. junifer/markers/falff/_afni_falff.py +3 -5
  11. junifer/markers/falff/_junifer_falff.py +3 -3
  12. junifer/markers/falff/falff_base.py +4 -6
  13. junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +4 -3
  14. junifer/markers/functional_connectivity/functional_connectivity_base.py +4 -3
  15. junifer/markers/parcel_aggregation.py +4 -3
  16. junifer/markers/reho/_afni_reho.py +3 -5
  17. junifer/markers/reho/_junifer_reho.py +3 -3
  18. junifer/markers/reho/reho_base.py +4 -6
  19. junifer/markers/sphere_aggregation.py +4 -3
  20. junifer/markers/temporal_snr/temporal_snr_base.py +4 -3
  21. junifer/onthefly/_brainprint.py +4 -7
  22. junifer/onthefly/read_transform.py +3 -6
  23. junifer/pipeline/marker_collection.py +6 -12
  24. junifer/pipeline/pipeline_component_registry.py +3 -8
  25. junifer/pipeline/tests/test_pipeline_step_mixin.py +18 -19
  26. junifer/pipeline/tests/test_workdir_manager.py +43 -0
  27. junifer/pipeline/workdir_manager.py +17 -2
  28. junifer/preprocess/confounds/fmriprep_confound_remover.py +2 -2
  29. junifer/preprocess/smoothing/_afni_smoothing.py +4 -6
  30. junifer/preprocess/smoothing/_fsl_smoothing.py +4 -7
  31. junifer/preprocess/smoothing/_nilearn_smoothing.py +3 -3
  32. junifer/preprocess/smoothing/smoothing.py +3 -2
  33. junifer/preprocess/warping/_ants_warper.py +3 -5
  34. junifer/preprocess/warping/_fsl_warper.py +3 -5
  35. junifer/preprocess/warping/space_warper.py +3 -2
  36. junifer/preprocess/warping/tests/test_space_warper.py +4 -7
  37. junifer/typing/__init__.py +9 -0
  38. junifer/typing/__init__.pyi +23 -0
  39. junifer/typing/_typing.py +61 -0
  40. {junifer-0.0.6.dev213.dist-info → junifer-0.0.6.dev227.dist-info}/METADATA +2 -1
  41. {junifer-0.0.6.dev213.dist-info → junifer-0.0.6.dev227.dist-info}/RECORD +46 -43
  42. {junifer-0.0.6.dev213.dist-info → junifer-0.0.6.dev227.dist-info}/WHEEL +1 -1
  43. {junifer-0.0.6.dev213.dist-info → junifer-0.0.6.dev227.dist-info}/AUTHORS.rst +0 -0
  44. {junifer-0.0.6.dev213.dist-info → junifer-0.0.6.dev227.dist-info}/LICENSE.md +0 -0
  45. {junifer-0.0.6.dev213.dist-info → junifer-0.0.6.dev227.dist-info}/entry_points.txt +0 -0
  46. {junifer-0.0.6.dev213.dist-info → junifer-0.0.6.dev227.dist-info}/top_level.txt +0 -0
@@ -5,20 +5,14 @@
5
5
  # License: AGPL
6
6
 
7
7
  from collections import Counter
8
- from typing import TYPE_CHECKING, Dict, List, Optional
8
+ from typing import Dict, List, Optional
9
9
 
10
10
  from ..datareader import DefaultDataReader
11
11
  from ..pipeline import PipelineStepMixin, WorkDirManager
12
+ from ..typing import DataGrabberLike, MarkerLike, PreprocessorLike, StorageLike
12
13
  from ..utils import logger, raise_error
13
14
 
14
15
 
15
- if TYPE_CHECKING:
16
- from junifer.datagrabber import BaseDataGrabber
17
- from junifer.markers import BaseMarker
18
- from junifer.preprocess import BasePreprocessor
19
- from junifer.storage import BaseFeatureStorage
20
-
21
-
22
16
  __all__ = ["MarkerCollection"]
23
17
 
24
18
 
@@ -45,10 +39,10 @@ class MarkerCollection:
45
39
 
46
40
  def __init__(
47
41
  self,
48
- markers: List["BaseMarker"],
42
+ markers: List[MarkerLike],
49
43
  datareader: Optional[PipelineStepMixin] = None,
50
- preprocessors: Optional[List["BasePreprocessor"]] = None,
51
- storage: Optional["BaseFeatureStorage"] = None,
44
+ preprocessors: Optional[List[PreprocessorLike]] = None,
45
+ storage: Optional[StorageLike] = None,
52
46
  ):
53
47
  # Check that the markers have different names
54
48
  marker_names = [m.name for m in markers]
@@ -111,7 +105,7 @@ class MarkerCollection:
111
105
 
112
106
  return None if self._storage else out
113
107
 
114
- def validate(self, datagrabber: "BaseDataGrabber") -> None:
108
+ def validate(self, datagrabber: DataGrabberLike) -> None:
115
109
  """Validate the pipeline.
116
110
 
117
111
  Without doing any computation, check if the marker collection can
@@ -6,18 +6,13 @@
6
6
  # License: AGPL
7
7
 
8
8
  import importlib
9
- from typing import TYPE_CHECKING, Dict, List, Mapping, Optional, Union
9
+ from typing import Dict, List, Mapping, Optional, Union
10
10
 
11
+ from ..typing import DataGrabberLike, MarkerLike, PreprocessorLike, StorageLike
11
12
  from ..utils import logger, raise_error
12
13
  from ..utils.singleton import Singleton
13
14
 
14
15
 
15
- if TYPE_CHECKING:
16
- from ..datagrabber import BaseDataGrabber
17
- from ..storage import BaseFeatureStorage
18
- from .pipeline_step_mixin import PipelineStepMixin
19
-
20
-
21
16
  __all__ = ["PipelineComponentRegistry"]
22
17
 
23
18
 
@@ -241,7 +236,7 @@ class PipelineComponentRegistry(metaclass=Singleton):
241
236
  name: str,
242
237
  baseclass: type,
243
238
  init_params: Optional[Dict] = None,
244
- ) -> Union["BaseDataGrabber", "PipelineStepMixin", "BaseFeatureStorage"]:
239
+ ) -> Union[DataGrabberLike, PreprocessorLike, MarkerLike, StorageLike]:
245
240
  """Build an instance of class registered as ``name``.
246
241
 
247
242
  Parameters
@@ -5,12 +5,17 @@
5
5
  # License: AGPL
6
6
 
7
7
  import warnings
8
- from typing import ClassVar, Dict, List, Set, Type, Union
8
+ from typing import ClassVar, Dict, List
9
9
 
10
10
  import pytest
11
11
 
12
12
  from junifer.pipeline.pipeline_step_mixin import PipelineStepMixin
13
13
  from junifer.pipeline.utils import _check_afni
14
+ from junifer.typing import (
15
+ ConditionalDependencies,
16
+ Dependencies,
17
+ ExternalDependencies,
18
+ )
14
19
 
15
20
 
16
21
  def test_PipelineStepMixin_correct_dependencies() -> None:
@@ -19,7 +24,7 @@ def test_PipelineStepMixin_correct_dependencies() -> None:
19
24
  class CorrectMixer(PipelineStepMixin):
20
25
  """Test class for validation."""
21
26
 
22
- _DEPENDENCIES: ClassVar[Set[str]] = {"math"}
27
+ _DEPENDENCIES: ClassVar[Dependencies] = {"math"}
23
28
 
24
29
  def validate_input(self, input: List[str]) -> List[str]:
25
30
  return input
@@ -40,7 +45,7 @@ def test_PipelineStepMixin_incorrect_dependencies() -> None:
40
45
  class IncorrectMixer(PipelineStepMixin):
41
46
  """Test class for validation."""
42
47
 
43
- _DEPENDENCIES: ClassVar[Set[str]] = {"foobar"}
48
+ _DEPENDENCIES: ClassVar[Dependencies] = {"foobar"}
44
49
 
45
50
  def validate_input(self, input: List[str]) -> List[str]:
46
51
  return input
@@ -65,7 +70,7 @@ def test_PipelineStepMixin_correct_ext_dependencies() -> None:
65
70
  class CorrectMixer(PipelineStepMixin):
66
71
  """Test class for validation."""
67
72
 
68
- _EXT_DEPENDENCIES: ClassVar[List[Dict[str, str]]] = [{"name": "afni"}]
73
+ _EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [{"name": "afni"}]
69
74
 
70
75
  def validate_input(self, input: List[str]) -> List[str]:
71
76
  return input
@@ -89,7 +94,7 @@ def test_PipelineStepMixin_ext_deps_correct_commands() -> None:
89
94
  class CorrectMixer(PipelineStepMixin):
90
95
  """Test class for validation."""
91
96
 
92
- _EXT_DEPENDENCIES: ClassVar[List[Dict[str, Union[str, List[str]]]]] = [
97
+ _EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
93
98
  {"name": "afni", "commands": ["3dReHo"]}
94
99
  ]
95
100
 
@@ -117,7 +122,7 @@ def test_PipelineStepMixin_ext_deps_incorrect_commands() -> None:
117
122
  class CorrectMixer(PipelineStepMixin):
118
123
  """Test class for validation."""
119
124
 
120
- _EXT_DEPENDENCIES: ClassVar[List[Dict[str, Union[str, List[str]]]]] = [
125
+ _EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
121
126
  {"name": "afni", "commands": ["3d"]}
122
127
  ]
123
128
 
@@ -141,7 +146,7 @@ def test_PipelineStepMixin_incorrect_ext_dependencies() -> None:
141
146
  class IncorrectMixer(PipelineStepMixin):
142
147
  """Test class for validation."""
143
148
 
144
- _EXT_DEPENDENCIES: ClassVar[List[Dict[str, Union[str, bool]]]] = [
149
+ _EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
145
150
  {"name": "foobar", "optional": True}
146
151
  ]
147
152
 
@@ -163,14 +168,12 @@ def test_PipelineStepMixin_correct_conditional_dependencies() -> None:
163
168
  """Test fit-transform with correct conditional dependencies."""
164
169
 
165
170
  class Dependency:
166
- _DEPENDENCIES: ClassVar[Set[str]] = {"math"}
171
+ _DEPENDENCIES: ClassVar[Dependencies] = {"math"}
167
172
 
168
173
  class CorrectMixer(PipelineStepMixin):
169
174
  """Test class for validation."""
170
175
 
171
- _CONDITIONAL_DEPENDENCIES: ClassVar[
172
- List[Dict[str, Union[str, Type]]]
173
- ] = [
176
+ _CONDITIONAL_DEPENDENCIES: ClassVar[ConditionalDependencies] = [
174
177
  {
175
178
  "using": "math",
176
179
  "depends_on": Dependency,
@@ -196,14 +199,12 @@ def test_PipelineStepMixin_incorrect_conditional_dependencies() -> None:
196
199
  """Test fit-transform with incorrect conditional dependencies."""
197
200
 
198
201
  class Dependency:
199
- _DEPENDENCIES: ClassVar[Set[str]] = {"math"}
202
+ _DEPENDENCIES: ClassVar[Dependencies] = {"math"}
200
203
 
201
204
  class IncorrectMixer(PipelineStepMixin):
202
205
  """Test class for validation."""
203
206
 
204
- _CONDITIONAL_DEPENDENCIES: ClassVar[
205
- List[Dict[str, Union[str, Type]]]
206
- ] = [
207
+ _CONDITIONAL_DEPENDENCIES: ClassVar[ConditionalDependencies] = [
207
208
  {
208
209
  "using": "math",
209
210
  "depends_on": Dependency,
@@ -231,14 +232,12 @@ def test_PipelineStepMixin_correct_conditional_ext_dependencies() -> None:
231
232
  """Test fit-transform with correct conditional external dependencies."""
232
233
 
233
234
  class ExternalDependency:
234
- _EXT_DEPENDENCIES: ClassVar[List[Dict[str, str]]] = [{"name": "afni"}]
235
+ _EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [{"name": "afni"}]
235
236
 
236
237
  class CorrectMixer(PipelineStepMixin):
237
238
  """Test class for validation."""
238
239
 
239
- _CONDITIONAL_DEPENDENCIES: ClassVar[
240
- List[Dict[str, Union[str, Type]]]
241
- ] = [
240
+ _CONDITIONAL_DEPENDENCIES: ClassVar[ConditionalDependencies] = [
242
241
  {
243
242
  "using": "afni",
244
243
  "depends_on": ExternalDependency,
@@ -102,3 +102,46 @@ def test_workdir_manager_get_and_delete_tempdir(tmp_path: Path) -> None:
102
102
  workdir_mgr._cleanup()
103
103
  # Should remove temporary directory
104
104
  assert workdir_mgr.root_tempdir is None
105
+
106
+
107
+ def test_workdir_manager_no_cleanup(tmp_path: Path) -> None:
108
+ """Test WorkDirManager correctly bypasses cleanup.
109
+
110
+ Parameters
111
+ ----------
112
+ tmp_path : pathlib.Path
113
+ The path to the test directory.
114
+
115
+ """
116
+ workdir_mgr = WorkDirManager(cleanup=False)
117
+ workdir_mgr.workdir = tmp_path
118
+ # Check no root temporary directory
119
+ assert workdir_mgr.root_tempdir is None
120
+
121
+ tempdir = workdir_mgr.get_tempdir()
122
+ assert tempdir.exists()
123
+ # Should create a temporary directory
124
+ assert workdir_mgr.root_tempdir is not None
125
+
126
+ workdir_mgr.delete_tempdir(tempdir)
127
+ workdir_mgr._cleanup()
128
+
129
+ # Should remove temporary directory
130
+ assert workdir_mgr.root_tempdir is None
131
+ # But the temporary directory should still exist
132
+ assert tempdir.exists()
133
+
134
+ # Now the same but for the element directory
135
+
136
+ # Check no element directory
137
+ assert workdir_mgr.elementdir is None
138
+
139
+ tempdir = workdir_mgr.get_element_tempdir()
140
+ # Should create a temporary directory
141
+ assert workdir_mgr.elementdir is not None
142
+
143
+ workdir_mgr.cleanup_elementdir()
144
+ # Should remove temporary directory
145
+ assert workdir_mgr.elementdir is None
146
+ # But the temporary directory should still exist
147
+ assert tempdir.exists()
@@ -39,15 +39,20 @@ class WorkDirManager(metaclass=Singleton):
39
39
  The path to the element directory.
40
40
  root_tempdir : pathlib.Path or None
41
41
  The path to the root temporary directory.
42
+ cleanup : bool, optional
43
+ If False, the directories are not cleaned up after the object is
44
+ destroyed. This is useful for debugging purposes (default True).
42
45
 
43
46
  """
44
47
 
45
- def __init__(self, workdir: Optional[Union[str, Path]] = None) -> None:
48
+ def __init__(
49
+ self, workdir: Optional[Union[str, Path]] = None, cleanup=True
50
+ ) -> None:
46
51
  """Initialize the class."""
47
52
  self._workdir = Path(workdir) if isinstance(workdir, str) else workdir
48
53
  self._elementdir = None
49
54
  self._root_tempdir = None
50
-
55
+ self._cleanup_dirs = cleanup
51
56
  self._set_default_workdir()
52
57
 
53
58
  def _set_default_workdir(self) -> None:
@@ -72,6 +77,9 @@ class WorkDirManager(metaclass=Singleton):
72
77
 
73
78
  def _cleanup(self) -> None:
74
79
  """Clean up the element and temporary directories."""
80
+ if self._cleanup_dirs is False:
81
+ self._root_tempdir = None
82
+ return
75
83
  # Remove element directory
76
84
  self.cleanup_elementdir()
77
85
  # Remove root temporary directory
@@ -171,6 +179,8 @@ class WorkDirManager(metaclass=Singleton):
171
179
  The temporary directory path to be deleted.
172
180
 
173
181
  """
182
+ if self._cleanup_dirs is False:
183
+ return
174
184
  logger.debug(f"Deleting element temporary directory at {tempdir}")
175
185
  shutil.rmtree(tempdir, ignore_errors=True)
176
186
 
@@ -182,6 +192,9 @@ class WorkDirManager(metaclass=Singleton):
182
192
  can lead to required intermediate files not being found.
183
193
 
184
194
  """
195
+ if self._cleanup_dirs is False:
196
+ self._elementdir = None
197
+ return
185
198
  if self._elementdir is not None:
186
199
  logger.debug(
187
200
  "Deleting element directory at "
@@ -244,5 +257,7 @@ class WorkDirManager(metaclass=Singleton):
244
257
  The temporary directory path to be deleted.
245
258
 
246
259
  """
260
+ if self._cleanup_dirs is False:
261
+ return
247
262
  logger.debug(f"Deleting temporary directory at {tempdir}")
248
263
  shutil.rmtree(tempdir, ignore_errors=True)
@@ -11,7 +11,6 @@ from typing import (
11
11
  Dict,
12
12
  List,
13
13
  Optional,
14
- Set,
15
14
  Tuple,
16
15
  Union,
17
16
  )
@@ -23,6 +22,7 @@ from nilearn._utils.niimg_conversions import check_niimg_4d
23
22
 
24
23
  from ...api.decorators import register_preprocessor
25
24
  from ...data import get_data
25
+ from ...typing import Dependencies
26
26
  from ...utils import logger, raise_error
27
27
  from ..base import BasePreprocessor
28
28
 
@@ -152,7 +152,7 @@ class fMRIPrepConfoundRemover(BasePreprocessor):
152
152
 
153
153
  """
154
154
 
155
- _DEPENDENCIES: ClassVar[Set[str]] = {"numpy", "nilearn"}
155
+ _DEPENDENCIES: ClassVar[Dependencies] = {"numpy", "nilearn"}
156
156
 
157
157
  def __init__(
158
158
  self,
@@ -6,20 +6,18 @@
6
6
  from typing import (
7
7
  TYPE_CHECKING,
8
8
  ClassVar,
9
- Dict,
10
- List,
11
- Set,
12
9
  Union,
13
10
  )
14
11
 
15
12
  import nibabel as nib
16
13
 
17
14
  from ...pipeline import WorkDirManager
15
+ from ...typing import Dependencies, ExternalDependencies
18
16
  from ...utils import logger, run_ext_cmd
19
17
 
20
18
 
21
19
  if TYPE_CHECKING:
22
- from nibabel import Nifti1Image
20
+ from nibabel.nifti1 import Nifti1Image
23
21
 
24
22
 
25
23
  __all__ = ["AFNISmoothing"]
@@ -32,14 +30,14 @@ class AFNISmoothing:
32
30
 
33
31
  """
34
32
 
35
- _EXT_DEPENDENCIES: ClassVar[List[Dict[str, Union[str, List[str]]]]] = [
33
+ _EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
36
34
  {
37
35
  "name": "afni",
38
36
  "commands": ["3dBlurToFWHM"],
39
37
  },
40
38
  ]
41
39
 
42
- _DEPENDENCIES: ClassVar[Set[str]] = {"nibabel"}
40
+ _DEPENDENCIES: ClassVar[Dependencies] = {"nibabel"}
43
41
 
44
42
  def preprocess(
45
43
  self,
@@ -6,20 +6,17 @@
6
6
  from typing import (
7
7
  TYPE_CHECKING,
8
8
  ClassVar,
9
- Dict,
10
- List,
11
- Set,
12
- Union,
13
9
  )
14
10
 
15
11
  import nibabel as nib
16
12
 
17
13
  from ...pipeline import WorkDirManager
14
+ from ...typing import Dependencies, ExternalDependencies
18
15
  from ...utils import logger, run_ext_cmd
19
16
 
20
17
 
21
18
  if TYPE_CHECKING:
22
- from nibabel import Nifti1Image
19
+ from nibabel.nifti1 import Nifti1Image
23
20
 
24
21
 
25
22
  __all__ = ["FSLSmoothing"]
@@ -32,14 +29,14 @@ class FSLSmoothing:
32
29
 
33
30
  """
34
31
 
35
- _EXT_DEPENDENCIES: ClassVar[List[Dict[str, Union[str, List[str]]]]] = [
32
+ _EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
36
33
  {
37
34
  "name": "fsl",
38
35
  "commands": ["susan"],
39
36
  },
40
37
  ]
41
38
 
42
- _DEPENDENCIES: ClassVar[Set[str]] = {"nibabel"}
39
+ _DEPENDENCIES: ClassVar[Dependencies] = {"nibabel"}
43
40
 
44
41
  def preprocess(
45
42
  self,
@@ -7,18 +7,18 @@ from typing import (
7
7
  TYPE_CHECKING,
8
8
  ClassVar,
9
9
  Literal,
10
- Set,
11
10
  Union,
12
11
  )
13
12
 
14
13
  from nilearn import image as nimg
15
14
  from numpy.typing import ArrayLike
16
15
 
16
+ from ...typing import Dependencies
17
17
  from ...utils import logger
18
18
 
19
19
 
20
20
  if TYPE_CHECKING:
21
- from nibabel import Nifti1Image
21
+ from nibabel.nifti1 import Nifti1Image
22
22
 
23
23
 
24
24
  __all__ = ["NilearnSmoothing"]
@@ -31,7 +31,7 @@ class NilearnSmoothing:
31
31
 
32
32
  """
33
33
 
34
- _DEPENDENCIES: ClassVar[Set[str]] = {"nilearn"}
34
+ _DEPENDENCIES: ClassVar[Dependencies] = {"nilearn"}
35
35
 
36
36
  def preprocess(
37
37
  self,
@@ -3,9 +3,10 @@
3
3
  # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
4
  # License: AGPL
5
5
 
6
- from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type, Union
6
+ from typing import Any, ClassVar, Dict, List, Optional, Tuple, Union
7
7
 
8
8
  from ...api.decorators import register_preprocessor
9
+ from ...typing import ConditionalDependencies
9
10
  from ...utils import logger, raise_error
10
11
  from ..base import BasePreprocessor
11
12
  from ._afni_smoothing import AFNISmoothing
@@ -67,7 +68,7 @@ class Smoothing(BasePreprocessor):
67
68
 
68
69
  """
69
70
 
70
- _CONDITIONAL_DEPENDENCIES: ClassVar[List[Dict[str, Union[str, Type]]]] = [
71
+ _CONDITIONAL_DEPENDENCIES: ClassVar[ConditionalDependencies] = [
71
72
  {
72
73
  "using": "nilearn",
73
74
  "depends_on": NilearnSmoothing,
@@ -7,9 +7,6 @@ from typing import (
7
7
  Any,
8
8
  ClassVar,
9
9
  Dict,
10
- List,
11
- Set,
12
- Union,
13
10
  )
14
11
 
15
12
  import nibabel as nib
@@ -17,6 +14,7 @@ import numpy as np
17
14
 
18
15
  from ...data import get_template, get_xfm
19
16
  from ...pipeline import WorkDirManager
17
+ from ...typing import Dependencies, ExternalDependencies
20
18
  from ...utils import logger, run_ext_cmd
21
19
 
22
20
 
@@ -31,14 +29,14 @@ class ANTsWarper:
31
29
 
32
30
  """
33
31
 
34
- _EXT_DEPENDENCIES: ClassVar[List[Dict[str, Union[str, List[str]]]]] = [
32
+ _EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
35
33
  {
36
34
  "name": "ants",
37
35
  "commands": ["ResampleImage", "antsApplyTransforms"],
38
36
  },
39
37
  ]
40
38
 
41
- _DEPENDENCIES: ClassVar[Set[str]] = {"numpy", "nibabel"}
39
+ _DEPENDENCIES: ClassVar[Dependencies] = {"numpy", "nibabel"}
42
40
 
43
41
  def preprocess(
44
42
  self,
@@ -7,15 +7,13 @@ from typing import (
7
7
  Any,
8
8
  ClassVar,
9
9
  Dict,
10
- List,
11
- Set,
12
- Union,
13
10
  )
14
11
 
15
12
  import nibabel as nib
16
13
  import numpy as np
17
14
 
18
15
  from ...pipeline import WorkDirManager
16
+ from ...typing import Dependencies, ExternalDependencies
19
17
  from ...utils import logger, run_ext_cmd
20
18
 
21
19
 
@@ -30,14 +28,14 @@ class FSLWarper:
30
28
 
31
29
  """
32
30
 
33
- _EXT_DEPENDENCIES: ClassVar[List[Dict[str, Union[str, List[str]]]]] = [
31
+ _EXT_DEPENDENCIES: ClassVar[ExternalDependencies] = [
34
32
  {
35
33
  "name": "fsl",
36
34
  "commands": ["flirt", "applywarp"],
37
35
  },
38
36
  ]
39
37
 
40
- _DEPENDENCIES: ClassVar[Set[str]] = {"numpy", "nibabel"}
38
+ _DEPENDENCIES: ClassVar[Dependencies] = {"numpy", "nibabel"}
41
39
 
42
40
  def preprocess(
43
41
  self,
@@ -3,11 +3,12 @@
3
3
  # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
4
  # License: AGPL
5
5
 
6
- from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type, Union
6
+ from typing import Any, ClassVar, Dict, List, Optional, Tuple, Union
7
7
 
8
8
  from templateflow import api as tflow
9
9
 
10
10
  from ...api.decorators import register_preprocessor
11
+ from ...typing import ConditionalDependencies
11
12
  from ...utils import logger, raise_error
12
13
  from ..base import BasePreprocessor
13
14
  from ._ants_warper import ANTsWarper
@@ -46,7 +47,7 @@ class SpaceWarper(BasePreprocessor):
46
47
 
47
48
  """
48
49
 
49
- _CONDITIONAL_DEPENDENCIES: ClassVar[List[Dict[str, Union[str, Type]]]] = [
50
+ _CONDITIONAL_DEPENDENCIES: ClassVar[ConditionalDependencies] = [
50
51
  {
51
52
  "using": "fsl",
52
53
  "depends_on": FSLWarper,
@@ -4,7 +4,7 @@
4
4
  # License: AGPL
5
5
 
6
6
  import socket
7
- from typing import TYPE_CHECKING, Tuple, Type
7
+ from typing import Tuple, Type
8
8
 
9
9
  import pytest
10
10
  from numpy.testing import assert_array_equal, assert_raises
@@ -14,10 +14,7 @@ from junifer.datareader import DefaultDataReader
14
14
  from junifer.pipeline.utils import _check_ants, _check_fsl
15
15
  from junifer.preprocess import SpaceWarper
16
16
  from junifer.testing.datagrabbers import PartlyCloudyTestingDataGrabber
17
-
18
-
19
- if TYPE_CHECKING:
20
- from junifer.datagrabber import BaseDataGrabber
17
+ from junifer.typing import DataGrabberLike
21
18
 
22
19
 
23
20
  @pytest.mark.parametrize(
@@ -99,7 +96,7 @@ def test_SpaceWarper_errors(
99
96
  reason="only for juseless",
100
97
  )
101
98
  def test_SpaceWarper_native(
102
- datagrabber: "BaseDataGrabber", element: Tuple[str, ...], using: str
99
+ datagrabber: DataGrabberLike, element: Tuple[str, ...], using: str
103
100
  ) -> None:
104
101
  """Test SpaceWarper for native space warping.
105
102
 
@@ -162,7 +159,7 @@ def test_SpaceWarper_native(
162
159
  _check_ants() is False, reason="requires ANTs to be in PATH"
163
160
  )
164
161
  def test_SpaceWarper_multi_mni(
165
- datagrabber: "BaseDataGrabber",
162
+ datagrabber: DataGrabberLike,
166
163
  element: Tuple[str, ...],
167
164
  space: str,
168
165
  ) -> None:
@@ -0,0 +1,9 @@
1
+ """Type hints for internal and external use."""
2
+
3
+ # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
+ # License: AGPL
5
+
6
+ import lazy_loader as lazy
7
+
8
+
9
+ __getattr__, __dir__, __all__ = lazy.attach_stub(__name__, __file__)
@@ -0,0 +1,23 @@
1
+ __all__ = [
2
+ "DataGrabberLike",
3
+ "PreprocessorLike",
4
+ "MarkerLike",
5
+ "StorageLike",
6
+ "PipelineComponent",
7
+ "Dependencies",
8
+ "ConditionalDependencies",
9
+ "ExternalDependencies",
10
+ "MarkerInOutMappings",
11
+ ]
12
+
13
+ from ._typing import (
14
+ DataGrabberLike,
15
+ PreprocessorLike,
16
+ MarkerLike,
17
+ StorageLike,
18
+ PipelineComponent,
19
+ Dependencies,
20
+ ConditionalDependencies,
21
+ ExternalDependencies,
22
+ MarkerInOutMappings,
23
+ )