junifer 0.0.5.dev240__py3-none-any.whl → 0.0.6__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 (279) hide show
  1. junifer/__init__.py +2 -31
  2. junifer/__init__.pyi +37 -0
  3. junifer/_version.py +9 -4
  4. junifer/api/__init__.py +3 -5
  5. junifer/api/__init__.pyi +4 -0
  6. junifer/api/decorators.py +14 -19
  7. junifer/api/functions.py +165 -109
  8. junifer/api/py.typed +0 -0
  9. junifer/api/queue_context/__init__.py +2 -4
  10. junifer/api/queue_context/__init__.pyi +5 -0
  11. junifer/api/queue_context/gnu_parallel_local_adapter.py +22 -6
  12. junifer/api/queue_context/htcondor_adapter.py +23 -6
  13. junifer/api/queue_context/py.typed +0 -0
  14. junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +3 -3
  15. junifer/api/queue_context/tests/test_htcondor_adapter.py +3 -3
  16. junifer/api/tests/test_functions.py +168 -74
  17. junifer/cli/__init__.py +24 -0
  18. junifer/cli/__init__.pyi +3 -0
  19. junifer/{api → cli}/cli.py +141 -125
  20. junifer/cli/parser.py +235 -0
  21. junifer/cli/py.typed +0 -0
  22. junifer/{api → cli}/tests/test_cli.py +8 -8
  23. junifer/{api/tests/test_api_utils.py → cli/tests/test_cli_utils.py} +5 -4
  24. junifer/{api → cli}/tests/test_parser.py +2 -2
  25. junifer/{api → cli}/utils.py +6 -16
  26. junifer/configs/juseless/__init__.py +2 -2
  27. junifer/configs/juseless/__init__.pyi +3 -0
  28. junifer/configs/juseless/datagrabbers/__init__.py +2 -12
  29. junifer/configs/juseless/datagrabbers/__init__.pyi +13 -0
  30. junifer/configs/juseless/datagrabbers/ixi_vbm.py +2 -2
  31. junifer/configs/juseless/datagrabbers/py.typed +0 -0
  32. junifer/configs/juseless/datagrabbers/tests/test_ucla.py +2 -2
  33. junifer/configs/juseless/datagrabbers/ucla.py +4 -4
  34. junifer/configs/juseless/py.typed +0 -0
  35. junifer/conftest.py +25 -0
  36. junifer/data/__init__.py +2 -42
  37. junifer/data/__init__.pyi +29 -0
  38. junifer/data/_dispatch.py +248 -0
  39. junifer/data/coordinates/__init__.py +9 -0
  40. junifer/data/coordinates/__init__.pyi +5 -0
  41. junifer/data/coordinates/_ants_coordinates_warper.py +104 -0
  42. junifer/data/coordinates/_coordinates.py +385 -0
  43. junifer/data/coordinates/_fsl_coordinates_warper.py +81 -0
  44. junifer/data/{tests → coordinates/tests}/test_coordinates.py +26 -33
  45. junifer/data/masks/__init__.py +9 -0
  46. junifer/data/masks/__init__.pyi +6 -0
  47. junifer/data/masks/_ants_mask_warper.py +177 -0
  48. junifer/data/masks/_fsl_mask_warper.py +106 -0
  49. junifer/data/masks/_masks.py +802 -0
  50. junifer/data/{tests → masks/tests}/test_masks.py +67 -63
  51. junifer/data/parcellations/__init__.py +9 -0
  52. junifer/data/parcellations/__init__.pyi +6 -0
  53. junifer/data/parcellations/_ants_parcellation_warper.py +166 -0
  54. junifer/data/parcellations/_fsl_parcellation_warper.py +89 -0
  55. junifer/data/parcellations/_parcellations.py +1388 -0
  56. junifer/data/{tests → parcellations/tests}/test_parcellations.py +165 -295
  57. junifer/data/pipeline_data_registry_base.py +76 -0
  58. junifer/data/py.typed +0 -0
  59. junifer/data/template_spaces.py +44 -79
  60. junifer/data/tests/test_data_utils.py +1 -2
  61. junifer/data/tests/test_template_spaces.py +8 -4
  62. junifer/data/utils.py +109 -4
  63. junifer/datagrabber/__init__.py +2 -26
  64. junifer/datagrabber/__init__.pyi +27 -0
  65. junifer/datagrabber/aomic/__init__.py +2 -4
  66. junifer/datagrabber/aomic/__init__.pyi +5 -0
  67. junifer/datagrabber/aomic/id1000.py +81 -52
  68. junifer/datagrabber/aomic/piop1.py +83 -55
  69. junifer/datagrabber/aomic/piop2.py +85 -56
  70. junifer/datagrabber/aomic/py.typed +0 -0
  71. junifer/datagrabber/aomic/tests/test_id1000.py +19 -12
  72. junifer/datagrabber/aomic/tests/test_piop1.py +52 -18
  73. junifer/datagrabber/aomic/tests/test_piop2.py +50 -17
  74. junifer/datagrabber/base.py +22 -18
  75. junifer/datagrabber/datalad_base.py +71 -34
  76. junifer/datagrabber/dmcc13_benchmark.py +31 -18
  77. junifer/datagrabber/hcp1200/__init__.py +2 -3
  78. junifer/datagrabber/hcp1200/__init__.pyi +4 -0
  79. junifer/datagrabber/hcp1200/datalad_hcp1200.py +3 -3
  80. junifer/datagrabber/hcp1200/hcp1200.py +26 -15
  81. junifer/datagrabber/hcp1200/py.typed +0 -0
  82. junifer/datagrabber/hcp1200/tests/test_hcp1200.py +8 -2
  83. junifer/datagrabber/multiple.py +14 -9
  84. junifer/datagrabber/pattern.py +132 -96
  85. junifer/datagrabber/pattern_validation_mixin.py +206 -94
  86. junifer/datagrabber/py.typed +0 -0
  87. junifer/datagrabber/tests/test_datalad_base.py +27 -12
  88. junifer/datagrabber/tests/test_dmcc13_benchmark.py +28 -11
  89. junifer/datagrabber/tests/test_multiple.py +48 -2
  90. junifer/datagrabber/tests/test_pattern_datalad.py +1 -1
  91. junifer/datagrabber/tests/test_pattern_validation_mixin.py +6 -6
  92. junifer/datareader/__init__.py +2 -2
  93. junifer/datareader/__init__.pyi +3 -0
  94. junifer/datareader/default.py +6 -6
  95. junifer/datareader/py.typed +0 -0
  96. junifer/external/nilearn/__init__.py +2 -3
  97. junifer/external/nilearn/__init__.pyi +4 -0
  98. junifer/external/nilearn/junifer_connectivity_measure.py +25 -17
  99. junifer/external/nilearn/junifer_nifti_spheres_masker.py +4 -4
  100. junifer/external/nilearn/py.typed +0 -0
  101. junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +17 -16
  102. junifer/external/nilearn/tests/test_junifer_nifti_spheres_masker.py +2 -3
  103. junifer/markers/__init__.py +2 -38
  104. junifer/markers/__init__.pyi +37 -0
  105. junifer/markers/base.py +11 -14
  106. junifer/markers/brainprint.py +12 -14
  107. junifer/markers/complexity/__init__.py +2 -18
  108. junifer/markers/complexity/__init__.pyi +17 -0
  109. junifer/markers/complexity/complexity_base.py +9 -11
  110. junifer/markers/complexity/hurst_exponent.py +7 -7
  111. junifer/markers/complexity/multiscale_entropy_auc.py +7 -7
  112. junifer/markers/complexity/perm_entropy.py +7 -7
  113. junifer/markers/complexity/py.typed +0 -0
  114. junifer/markers/complexity/range_entropy.py +7 -7
  115. junifer/markers/complexity/range_entropy_auc.py +7 -7
  116. junifer/markers/complexity/sample_entropy.py +7 -7
  117. junifer/markers/complexity/tests/test_complexity_base.py +1 -1
  118. junifer/markers/complexity/tests/test_hurst_exponent.py +5 -5
  119. junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +5 -5
  120. junifer/markers/complexity/tests/test_perm_entropy.py +5 -5
  121. junifer/markers/complexity/tests/test_range_entropy.py +5 -5
  122. junifer/markers/complexity/tests/test_range_entropy_auc.py +5 -5
  123. junifer/markers/complexity/tests/test_sample_entropy.py +5 -5
  124. junifer/markers/complexity/tests/test_weighted_perm_entropy.py +5 -5
  125. junifer/markers/complexity/weighted_perm_entropy.py +7 -7
  126. junifer/markers/ets_rss.py +12 -11
  127. junifer/markers/falff/__init__.py +2 -3
  128. junifer/markers/falff/__init__.pyi +4 -0
  129. junifer/markers/falff/_afni_falff.py +38 -45
  130. junifer/markers/falff/_junifer_falff.py +16 -19
  131. junifer/markers/falff/falff_base.py +7 -11
  132. junifer/markers/falff/falff_parcels.py +9 -9
  133. junifer/markers/falff/falff_spheres.py +8 -8
  134. junifer/markers/falff/py.typed +0 -0
  135. junifer/markers/falff/tests/test_falff_spheres.py +3 -1
  136. junifer/markers/functional_connectivity/__init__.py +2 -12
  137. junifer/markers/functional_connectivity/__init__.pyi +13 -0
  138. junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +9 -8
  139. junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +8 -8
  140. junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +7 -7
  141. junifer/markers/functional_connectivity/functional_connectivity_base.py +13 -12
  142. junifer/markers/functional_connectivity/functional_connectivity_parcels.py +8 -8
  143. junifer/markers/functional_connectivity/functional_connectivity_spheres.py +7 -7
  144. junifer/markers/functional_connectivity/py.typed +0 -0
  145. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +1 -2
  146. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +1 -2
  147. junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +6 -6
  148. junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +5 -5
  149. junifer/markers/parcel_aggregation.py +22 -17
  150. junifer/markers/py.typed +0 -0
  151. junifer/markers/reho/__init__.py +2 -3
  152. junifer/markers/reho/__init__.pyi +4 -0
  153. junifer/markers/reho/_afni_reho.py +29 -35
  154. junifer/markers/reho/_junifer_reho.py +13 -14
  155. junifer/markers/reho/py.typed +0 -0
  156. junifer/markers/reho/reho_base.py +7 -11
  157. junifer/markers/reho/reho_parcels.py +10 -10
  158. junifer/markers/reho/reho_spheres.py +9 -9
  159. junifer/markers/sphere_aggregation.py +22 -17
  160. junifer/markers/temporal_snr/__init__.py +2 -3
  161. junifer/markers/temporal_snr/__init__.pyi +4 -0
  162. junifer/markers/temporal_snr/py.typed +0 -0
  163. junifer/markers/temporal_snr/temporal_snr_base.py +11 -10
  164. junifer/markers/temporal_snr/temporal_snr_parcels.py +8 -8
  165. junifer/markers/temporal_snr/temporal_snr_spheres.py +7 -7
  166. junifer/markers/tests/test_ets_rss.py +3 -3
  167. junifer/markers/tests/test_parcel_aggregation.py +24 -24
  168. junifer/markers/tests/test_sphere_aggregation.py +6 -6
  169. junifer/markers/utils.py +3 -3
  170. junifer/onthefly/__init__.py +2 -1
  171. junifer/onthefly/_brainprint.py +138 -0
  172. junifer/onthefly/read_transform.py +5 -8
  173. junifer/pipeline/__init__.py +2 -10
  174. junifer/pipeline/__init__.pyi +13 -0
  175. junifer/{markers/collection.py → pipeline/marker_collection.py} +8 -14
  176. junifer/pipeline/pipeline_component_registry.py +294 -0
  177. junifer/pipeline/pipeline_step_mixin.py +15 -11
  178. junifer/pipeline/py.typed +0 -0
  179. junifer/{markers/tests/test_collection.py → pipeline/tests/test_marker_collection.py} +2 -3
  180. junifer/pipeline/tests/test_pipeline_component_registry.py +200 -0
  181. junifer/pipeline/tests/test_pipeline_step_mixin.py +36 -37
  182. junifer/pipeline/tests/test_update_meta_mixin.py +4 -4
  183. junifer/pipeline/tests/test_workdir_manager.py +43 -0
  184. junifer/pipeline/update_meta_mixin.py +21 -17
  185. junifer/pipeline/utils.py +6 -6
  186. junifer/pipeline/workdir_manager.py +19 -5
  187. junifer/preprocess/__init__.py +2 -10
  188. junifer/preprocess/__init__.pyi +11 -0
  189. junifer/preprocess/base.py +10 -10
  190. junifer/preprocess/confounds/__init__.py +2 -2
  191. junifer/preprocess/confounds/__init__.pyi +3 -0
  192. junifer/preprocess/confounds/fmriprep_confound_remover.py +243 -64
  193. junifer/preprocess/confounds/py.typed +0 -0
  194. junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +121 -14
  195. junifer/preprocess/py.typed +0 -0
  196. junifer/preprocess/smoothing/__init__.py +2 -2
  197. junifer/preprocess/smoothing/__init__.pyi +3 -0
  198. junifer/preprocess/smoothing/_afni_smoothing.py +40 -40
  199. junifer/preprocess/smoothing/_fsl_smoothing.py +22 -32
  200. junifer/preprocess/smoothing/_nilearn_smoothing.py +35 -14
  201. junifer/preprocess/smoothing/py.typed +0 -0
  202. junifer/preprocess/smoothing/smoothing.py +11 -13
  203. junifer/preprocess/warping/__init__.py +2 -2
  204. junifer/preprocess/warping/__init__.pyi +3 -0
  205. junifer/preprocess/warping/_ants_warper.py +136 -32
  206. junifer/preprocess/warping/_fsl_warper.py +73 -22
  207. junifer/preprocess/warping/py.typed +0 -0
  208. junifer/preprocess/warping/space_warper.py +39 -11
  209. junifer/preprocess/warping/tests/test_space_warper.py +5 -9
  210. junifer/py.typed +0 -0
  211. junifer/stats.py +5 -5
  212. junifer/storage/__init__.py +2 -10
  213. junifer/storage/__init__.pyi +11 -0
  214. junifer/storage/base.py +47 -13
  215. junifer/storage/hdf5.py +95 -33
  216. junifer/storage/pandas_base.py +12 -11
  217. junifer/storage/py.typed +0 -0
  218. junifer/storage/sqlite.py +11 -11
  219. junifer/storage/tests/test_hdf5.py +86 -4
  220. junifer/storage/tests/test_sqlite.py +2 -2
  221. junifer/storage/tests/test_storage_base.py +5 -2
  222. junifer/storage/tests/test_utils.py +33 -7
  223. junifer/storage/utils.py +95 -9
  224. junifer/testing/__init__.py +2 -3
  225. junifer/testing/__init__.pyi +4 -0
  226. junifer/testing/datagrabbers.py +10 -11
  227. junifer/testing/py.typed +0 -0
  228. junifer/testing/registry.py +4 -7
  229. junifer/testing/tests/test_testing_registry.py +9 -17
  230. junifer/tests/test_stats.py +2 -2
  231. junifer/typing/__init__.py +9 -0
  232. junifer/typing/__init__.pyi +31 -0
  233. junifer/typing/_typing.py +68 -0
  234. junifer/utils/__init__.py +2 -12
  235. junifer/utils/__init__.pyi +18 -0
  236. junifer/utils/_config.py +110 -0
  237. junifer/utils/_yaml.py +16 -0
  238. junifer/utils/helpers.py +6 -6
  239. junifer/utils/logging.py +117 -8
  240. junifer/utils/py.typed +0 -0
  241. junifer/{pipeline → utils}/singleton.py +19 -14
  242. junifer/utils/tests/test_config.py +59 -0
  243. {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info}/METADATA +43 -38
  244. junifer-0.0.6.dist-info/RECORD +350 -0
  245. {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info}/WHEEL +1 -1
  246. junifer-0.0.6.dist-info/entry_points.txt +2 -0
  247. junifer/api/parser.py +0 -118
  248. junifer/data/coordinates.py +0 -408
  249. junifer/data/masks.py +0 -670
  250. junifer/data/parcellations.py +0 -1828
  251. junifer/pipeline/registry.py +0 -177
  252. junifer/pipeline/tests/test_registry.py +0 -150
  253. junifer-0.0.5.dev240.dist-info/RECORD +0 -275
  254. junifer-0.0.5.dev240.dist-info/entry_points.txt +0 -2
  255. /junifer/{api → cli}/tests/data/gmd_mean.yaml +0 -0
  256. /junifer/{api → cli}/tests/data/gmd_mean_htcondor.yaml +0 -0
  257. /junifer/{api → cli}/tests/data/partly_cloudy_agg_mean_tian.yml +0 -0
  258. /junifer/data/{VOIs → coordinates/VOIs}/meta/AutobiographicalMemory_VOIs.txt +0 -0
  259. /junifer/data/{VOIs → coordinates/VOIs}/meta/CogAC_VOIs.txt +0 -0
  260. /junifer/data/{VOIs → coordinates/VOIs}/meta/CogAR_VOIs.txt +0 -0
  261. /junifer/data/{VOIs → coordinates/VOIs}/meta/DMNBuckner_VOIs.txt +0 -0
  262. /junifer/data/{VOIs → coordinates/VOIs}/meta/Dosenbach2010_MNI_VOIs.txt +0 -0
  263. /junifer/data/{VOIs → coordinates/VOIs}/meta/Empathy_VOIs.txt +0 -0
  264. /junifer/data/{VOIs → coordinates/VOIs}/meta/Motor_VOIs.txt +0 -0
  265. /junifer/data/{VOIs → coordinates/VOIs}/meta/MultiTask_VOIs.txt +0 -0
  266. /junifer/data/{VOIs → coordinates/VOIs}/meta/PhysioStress_VOIs.txt +0 -0
  267. /junifer/data/{VOIs → coordinates/VOIs}/meta/Power2011_MNI_VOIs.txt +0 -0
  268. /junifer/data/{VOIs → coordinates/VOIs}/meta/Power2013_MNI_VOIs.tsv +0 -0
  269. /junifer/data/{VOIs → coordinates/VOIs}/meta/Rew_VOIs.txt +0 -0
  270. /junifer/data/{VOIs → coordinates/VOIs}/meta/Somatosensory_VOIs.txt +0 -0
  271. /junifer/data/{VOIs → coordinates/VOIs}/meta/ToM_VOIs.txt +0 -0
  272. /junifer/data/{VOIs → coordinates/VOIs}/meta/VigAtt_VOIs.txt +0 -0
  273. /junifer/data/{VOIs → coordinates/VOIs}/meta/WM_VOIs.txt +0 -0
  274. /junifer/data/{VOIs → coordinates/VOIs}/meta/eMDN_VOIs.txt +0 -0
  275. /junifer/data/{VOIs → coordinates/VOIs}/meta/eSAD_VOIs.txt +0 -0
  276. /junifer/data/{VOIs → coordinates/VOIs}/meta/extDMN_VOIs.txt +0 -0
  277. {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info/licenses}/AUTHORS.rst +0 -0
  278. {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info/licenses}/LICENSE.md +0 -0
  279. {junifer-0.0.5.dev240.dist-info → junifer-0.0.6.dist-info}/top_level.txt +0 -0
junifer/__init__.py CHANGED
@@ -4,36 +4,7 @@
4
4
  # Synchon Mandal <s.mandal@fz-juelich.de>
5
5
  # License: AGPL
6
6
 
7
- from . import (
8
- api,
9
- configs,
10
- data,
11
- datagrabber,
12
- datareader,
13
- markers,
14
- pipeline,
15
- preprocess,
16
- stats,
17
- storage,
18
- utils,
19
- external,
20
- onthefly,
21
- )
22
- from ._version import __version__
7
+ import lazy_loader as lazy
23
8
 
24
9
 
25
- __all__ = [
26
- "api",
27
- "configs",
28
- "data",
29
- "datagrabber",
30
- "datareader",
31
- "markers",
32
- "pipeline",
33
- "preprocess",
34
- "stats",
35
- "storage",
36
- "utils",
37
- "external",
38
- "onthefly",
39
- ]
10
+ __getattr__, __dir__, __all__ = lazy.attach_stub(__name__, __file__)
junifer/__init__.pyi ADDED
@@ -0,0 +1,37 @@
1
+ __all__ = [
2
+ "api",
3
+ "configs",
4
+ "data",
5
+ "datagrabber",
6
+ "datareader",
7
+ "markers",
8
+ "pipeline",
9
+ "preprocess",
10
+ "stats",
11
+ "storage",
12
+ "utils",
13
+ "external",
14
+ "onthefly",
15
+ "testing",
16
+ "typing",
17
+ "__version__",
18
+ ]
19
+
20
+ from . import (
21
+ api,
22
+ configs,
23
+ data,
24
+ datagrabber,
25
+ datareader,
26
+ markers,
27
+ pipeline,
28
+ preprocess,
29
+ stats,
30
+ storage,
31
+ utils,
32
+ external,
33
+ testing,
34
+ typing,
35
+ onthefly,
36
+ )
37
+ from ._version import __version__
junifer/_version.py CHANGED
@@ -1,8 +1,13 @@
1
- # file generated by setuptools_scm
1
+ # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
3
6
  TYPE_CHECKING = False
4
7
  if TYPE_CHECKING:
5
- from typing import Tuple, Union
8
+ from typing import Tuple
9
+ from typing import Union
10
+
6
11
  VERSION_TUPLE = Tuple[Union[int, str], ...]
7
12
  else:
8
13
  VERSION_TUPLE = object
@@ -12,5 +17,5 @@ __version__: str
12
17
  __version_tuple__: VERSION_TUPLE
13
18
  version_tuple: VERSION_TUPLE
14
19
 
15
- __version__ = version = '0.0.5.dev240'
16
- __version_tuple__ = version_tuple = (0, 0, 5, 'dev240')
20
+ __version__ = version = '0.0.6'
21
+ __version_tuple__ = version_tuple = (0, 0, 6)
junifer/api/__init__.py CHANGED
@@ -1,12 +1,10 @@
1
- """Public API and CLI components."""
1
+ """Public API components."""
2
2
 
3
3
  # Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
4
4
  # Synchon Mandal <s.mandal@fz-juelich.de>
5
5
  # License: AGPL
6
6
 
7
- from . import decorators
8
- from .cli import cli
9
- from .functions import collect, queue, run
7
+ import lazy_loader as lazy
10
8
 
11
9
 
12
- __all__ = ["decorators", "cli", "collect", "queue", "run"]
10
+ __getattr__, __dir__, __all__ = lazy.attach_stub(__name__, __file__)
@@ -0,0 +1,4 @@
1
+ __all__ = ["decorators", "collect", "queue", "run", "reset", "list_elements"]
2
+
3
+ from . import decorators
4
+ from .functions import collect, list_elements, reset, run, queue
junifer/api/decorators.py CHANGED
@@ -1,25 +1,25 @@
1
- """Provide decorators for api."""
1
+ """Provide API decorators."""
2
2
 
3
3
  # Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
4
4
  # Leonard Sasse <l.sasse@fz-juelich.de>
5
5
  # Synchon Mandal <s.mandal@fz-juelich.de>
6
6
  # License: AGPL
7
7
 
8
- from typing import Type
9
8
 
10
- from ..pipeline.registry import register
9
+ from ..pipeline import PipelineComponentRegistry
10
+ from ..typing import DataGrabberLike, MarkerLike, PreprocessorLike, StorageLike
11
11
 
12
12
 
13
13
  __all__ = [
14
14
  "register_datagrabber",
15
15
  "register_datareader",
16
- "register_preprocessor",
17
16
  "register_marker",
17
+ "register_preprocessor",
18
18
  "register_storage",
19
19
  ]
20
20
 
21
21
 
22
- def register_datagrabber(klass: Type) -> Type:
22
+ def register_datagrabber(klass: DataGrabberLike) -> DataGrabberLike:
23
23
  """Register DataGrabber.
24
24
 
25
25
  Registers the DataGrabber so it can be used by name.
@@ -39,15 +39,14 @@ def register_datagrabber(klass: Type) -> Type:
39
39
  It should only be used as a decorator.
40
40
 
41
41
  """
42
- register(
42
+ PipelineComponentRegistry().register(
43
43
  step="datagrabber",
44
- name=klass.__name__,
45
44
  klass=klass,
46
45
  )
47
46
  return klass
48
47
 
49
48
 
50
- def register_datareader(klass: Type) -> Type:
49
+ def register_datareader(klass: type) -> type:
51
50
  """Register DataReader.
52
51
 
53
52
  Registers the DataReader so it can be used by name.
@@ -67,15 +66,14 @@ def register_datareader(klass: Type) -> Type:
67
66
  It should only be used as a decorator.
68
67
 
69
68
  """
70
- register(
69
+ PipelineComponentRegistry().register(
71
70
  step="datareader",
72
- name=klass.__name__,
73
71
  klass=klass,
74
72
  )
75
73
  return klass
76
74
 
77
75
 
78
- def register_preprocessor(klass: Type) -> Type:
76
+ def register_preprocessor(klass: PreprocessorLike) -> PreprocessorLike:
79
77
  """Preprocessor registration decorator.
80
78
 
81
79
  Registers the preprocessor so it can be used by name.
@@ -91,15 +89,14 @@ def register_preprocessor(klass: Type) -> Type:
91
89
  The unmodified input class.
92
90
 
93
91
  """
94
- register(
92
+ PipelineComponentRegistry().register(
95
93
  step="preprocessing",
96
- name=klass.__name__,
97
94
  klass=klass,
98
95
  )
99
96
  return klass
100
97
 
101
98
 
102
- def register_marker(klass: Type) -> Type:
99
+ def register_marker(klass: MarkerLike) -> MarkerLike:
103
100
  """Marker registration decorator.
104
101
 
105
102
  Registers the marker so it can be used by name.
@@ -115,15 +112,14 @@ def register_marker(klass: Type) -> Type:
115
112
  The unmodified input class.
116
113
 
117
114
  """
118
- register(
115
+ PipelineComponentRegistry().register(
119
116
  step="marker",
120
- name=klass.__name__,
121
117
  klass=klass,
122
118
  )
123
119
  return klass
124
120
 
125
121
 
126
- def register_storage(klass: Type) -> Type:
122
+ def register_storage(klass: StorageLike) -> StorageLike:
127
123
  """Storage registration decorator.
128
124
 
129
125
  Registers the storage so it can be used by name.
@@ -139,9 +135,8 @@ def register_storage(klass: Type) -> Type:
139
135
  The unmodified input class.
140
136
 
141
137
  """
142
- register(
138
+ PipelineComponentRegistry().register(
143
139
  step="storage",
144
- name=klass.__name__,
145
140
  klass=klass,
146
141
  )
147
142
  return klass
junifer/api/functions.py CHANGED
@@ -1,4 +1,4 @@
1
- """Provide functions for cli."""
1
+ """Provide API functions."""
2
2
 
3
3
  # Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
4
4
  # Leonard Sasse <l.sasse@fz-juelich.de>
@@ -7,26 +7,33 @@
7
7
 
8
8
  import os
9
9
  import shutil
10
- import typing
11
10
  from pathlib import Path
12
- from typing import Dict, List, Optional, Tuple, Union
13
-
14
- from ..datagrabber.base import BaseDataGrabber
15
- from ..markers.base import BaseMarker
16
- from ..markers.collection import MarkerCollection
17
- from ..pipeline import WorkDirManager
18
- from ..pipeline.registry import build
19
- from ..preprocess.base import BasePreprocessor
20
- from ..storage.base import BaseFeatureStorage
21
- from ..utils import logger, raise_error
22
- from .queue_context import GnuParallelLocalAdapter, HTCondorAdapter
23
- from .utils import yaml
24
-
25
-
26
- __all__ = ["run", "collect", "queue", "reset", "list_elements"]
27
-
28
-
29
- def _get_datagrabber(datagrabber_config: Dict) -> BaseDataGrabber:
11
+ from typing import Optional, Union
12
+
13
+ from ..api.queue_context import GnuParallelLocalAdapter, HTCondorAdapter
14
+ from ..datagrabber import BaseDataGrabber
15
+ from ..markers import BaseMarker
16
+ from ..pipeline import (
17
+ MarkerCollection,
18
+ PipelineComponentRegistry,
19
+ WorkDirManager,
20
+ )
21
+ from ..preprocess import BasePreprocessor
22
+ from ..storage import BaseFeatureStorage
23
+ from ..typing import (
24
+ DataGrabberLike,
25
+ Elements,
26
+ MarkerLike,
27
+ PreprocessorLike,
28
+ StorageLike,
29
+ )
30
+ from ..utils import logger, raise_error, warn_with_log, yaml
31
+
32
+
33
+ __all__ = ["collect", "list_elements", "queue", "reset", "run"]
34
+
35
+
36
+ def _get_datagrabber(datagrabber_config: dict) -> DataGrabberLike:
30
37
  """Get DataGrabber.
31
38
 
32
39
  Parameters
@@ -40,57 +47,93 @@ def _get_datagrabber(datagrabber_config: Dict) -> BaseDataGrabber:
40
47
  The DataGrabber.
41
48
 
42
49
  """
43
- datagrabber_params = datagrabber_config.copy()
44
- datagrabber_kind = datagrabber_params.pop("kind")
45
- datagrabber = build(
50
+ return PipelineComponentRegistry().build_component_instance(
46
51
  step="datagrabber",
47
- name=datagrabber_kind,
52
+ name=datagrabber_config.pop("kind"),
48
53
  baseclass=BaseDataGrabber,
49
- init_params=datagrabber_params,
54
+ init_params=datagrabber_config,
50
55
  )
51
- datagrabber = typing.cast(BaseDataGrabber, datagrabber)
52
- return datagrabber
53
56
 
54
57
 
55
- def _get_preprocessor(preprocessing_config: Dict) -> BasePreprocessor:
56
- """Get preprocessor.
58
+ def _get_preprocessor(preprocessing_config: dict) -> PreprocessorLike:
59
+ """Get Preprocessor.
57
60
 
58
61
  Parameters
59
62
  ----------
60
63
  preprocessing_config : dict
61
- The config to get the preprocessor using.
64
+ The config to get the Preprocessor using.
62
65
 
63
66
  Returns
64
67
  -------
65
68
  dict
66
- The preprocessor.
69
+ The Preprocessor.
67
70
 
68
71
  """
69
- preprocessor_params = preprocessing_config.copy()
70
- preprocessor_kind = preprocessor_params.pop("kind")
71
- preprocessor = build(
72
+ return PipelineComponentRegistry().build_component_instance(
72
73
  step="preprocessing",
73
- name=preprocessor_kind,
74
+ name=preprocessing_config.pop("kind"),
74
75
  baseclass=BasePreprocessor,
75
- init_params=preprocessor_params,
76
+ init_params=preprocessing_config,
77
+ )
78
+
79
+
80
+ def _get_marker(marker_config: dict) -> MarkerLike:
81
+ """Get Marker.
82
+
83
+ Parameters
84
+ ----------
85
+ marker_config : dict
86
+ The config to get the Marker using.
87
+
88
+ Returns
89
+ -------
90
+ object
91
+ The Marker.
92
+
93
+ """
94
+ return PipelineComponentRegistry().build_component_instance(
95
+ step="marker",
96
+ name=marker_config.pop("kind"),
97
+ baseclass=BaseMarker,
98
+ init_params=marker_config,
99
+ )
100
+
101
+
102
+ def _get_storage(storage_config: dict) -> StorageLike:
103
+ """Get Storage.
104
+
105
+ Parameters
106
+ ----------
107
+ storage_config : dict
108
+ The config to get the Storage using.
109
+
110
+ Returns
111
+ -------
112
+ dict
113
+ The Storage.
114
+
115
+ """
116
+ return PipelineComponentRegistry().build_component_instance(
117
+ step="storage",
118
+ name=storage_config.pop("kind"),
119
+ baseclass=BaseFeatureStorage,
120
+ init_params=storage_config,
76
121
  )
77
- preprocessor = typing.cast(BasePreprocessor, preprocessor)
78
- return preprocessor
79
122
 
80
123
 
81
124
  def run(
82
- workdir: Union[str, Path],
83
- datagrabber: Dict,
84
- markers: List[Dict],
85
- storage: Dict,
86
- preprocessors: Optional[List[Dict]] = None,
87
- elements: Union[str, List[Union[str, Tuple]], Tuple, None] = None,
125
+ workdir: Union[str, Path, dict],
126
+ datagrabber: dict,
127
+ markers: list[dict],
128
+ storage: dict,
129
+ preprocessors: Optional[list[dict]] = None,
130
+ elements: Optional[Elements] = None,
88
131
  ) -> None:
89
132
  """Run the pipeline on the selected element.
90
133
 
91
134
  Parameters
92
135
  ----------
93
- workdir : str or pathlib.Path
136
+ workdir : str or pathlib.Path or dict
94
137
  Directory where the pipeline will be executed.
95
138
  datagrabber : dict
96
139
  DataGrabber to use. Must have a key ``kind`` with the kind of
@@ -106,60 +149,58 @@ def run(
106
149
  Storage to use. Must have a key ``kind`` with the kind of
107
150
  storage to use. All other keys are passed to the storage
108
151
  constructor.
109
- preprocessors : list of dict, optional
152
+ preprocessors : list of dict or None, optional
110
153
  List of preprocessors to use. Each preprocessor is a dict with at
111
154
  least a key ``kind`` specifying the preprocessor to use. All other keys
112
155
  are passed to the preprocessor constructor (default None).
113
- elements : str or tuple or list of str or tuple, optional
156
+ elements : list or None, optional
114
157
  Element(s) to process. Will be used to index the DataGrabber
115
158
  (default None).
116
159
 
160
+ Raises
161
+ ------
162
+ ValueError
163
+ If ``workdir.cleanup=False`` when ``len(elements) > 1``.
164
+ RuntimeError
165
+ If invalid element selectors are found.
166
+
117
167
  """
118
- # Convert str to Path
119
- if isinstance(workdir, str):
120
- workdir = Path(workdir)
121
- # Initiate working directory manager
122
- WorkDirManager(workdir)
168
+ # Conditional to handle workdir config
169
+ if isinstance(workdir, (str, Path)):
170
+ if isinstance(workdir, str):
171
+ workdir = {"workdir": Path(workdir), "cleanup": True}
172
+ else:
173
+ workdir = {"workdir": workdir, "cleanup": True}
174
+ elif isinstance(workdir, dict):
175
+ workdir["workdir"] = workdir.pop("path")
123
176
 
124
- if not isinstance(elements, list) and elements is not None:
125
- elements = [elements]
177
+ # Initiate working directory manager with correct variation
178
+ if not workdir["cleanup"]:
179
+ if elements is None or len(elements) > 1:
180
+ raise_error(
181
+ "Cannot disable `workdir.cleanup` as "
182
+ f"{len(elements) if elements is not None else 'all'} "
183
+ "elements will be processed"
184
+ )
185
+ WorkDirManager(**workdir)
126
186
 
127
187
  # Get datagrabber to use
128
- datagrabber_object = _get_datagrabber(datagrabber)
188
+ datagrabber_object = _get_datagrabber(datagrabber.copy())
129
189
 
130
- # Copy to avoid changing the original dict
131
- _markers = [x.copy() for x in markers]
132
- built_markers = []
133
- for t_marker in _markers:
134
- kind = t_marker.pop("kind")
135
- t_m = build(
136
- step="marker",
137
- name=kind,
138
- baseclass=BaseMarker,
139
- init_params=t_marker,
140
- )
141
- built_markers.append(t_m)
190
+ # Get markers to use
191
+ built_markers = [_get_marker(marker) for marker in markers.copy()]
142
192
 
143
193
  # Get storage engine to use
144
- storage_params = storage.copy()
145
- storage_kind = storage_params.pop("kind")
146
- if "single_output" not in storage_params:
147
- storage_params["single_output"] = False
148
- storage_object = build(
149
- step="storage",
150
- name=storage_kind,
151
- baseclass=BaseFeatureStorage,
152
- init_params=storage_params,
153
- )
154
- storage_object = typing.cast(BaseFeatureStorage, storage_object)
194
+ if "single_output" not in storage:
195
+ storage["single_output"] = False
196
+ storage_object = _get_storage(storage.copy())
155
197
 
156
198
  # Get preprocessor to use (if provided)
157
199
  if preprocessors is not None:
158
- _preprocessors = [x.copy() for x in preprocessors]
159
- built_preprocessors = []
160
- for preprocessor in _preprocessors:
161
- preprocessor_object = _get_preprocessor(preprocessor)
162
- built_preprocessors.append(preprocessor_object)
200
+ built_preprocessors = [
201
+ _get_preprocessor(preprocessor)
202
+ for preprocessor in preprocessors.copy()
203
+ ]
163
204
  else:
164
205
  built_preprocessors = None
165
206
 
@@ -169,21 +210,34 @@ def run(
169
210
  preprocessors=built_preprocessors,
170
211
  storage=storage_object,
171
212
  )
213
+ # Validate the marker collection for the datagrabber
172
214
  mc.validate(datagrabber_object)
173
215
 
174
216
  # Fit elements
175
217
  with datagrabber_object:
176
218
  if elements is not None:
177
- for t_element in datagrabber_object.filter(
178
- elements # type: ignore
179
- ):
219
+ # Keep track of valid selectors
220
+ valid_elements = []
221
+ for t_element in datagrabber_object.filter(elements):
222
+ valid_elements.append(t_element)
180
223
  mc.fit(datagrabber_object[t_element])
224
+ # Compute invalid selectors
225
+ invalid_elements = set(elements) - set(valid_elements)
226
+ # Report if invalid selectors are found
227
+ if invalid_elements:
228
+ raise_error(
229
+ msg=(
230
+ "The following element selectors are invalid:\n"
231
+ f"{invalid_elements}"
232
+ ),
233
+ klass=RuntimeError,
234
+ )
181
235
  else:
182
236
  for t_element in datagrabber_object:
183
237
  mc.fit(datagrabber_object[t_element])
184
238
 
185
239
 
186
- def collect(storage: Dict) -> None:
240
+ def collect(storage: dict) -> None:
187
241
  """Collect and store data.
188
242
 
189
243
  Parameters
@@ -194,31 +248,23 @@ def collect(storage: Dict) -> None:
194
248
  constructor.
195
249
 
196
250
  """
197
- storage_params = storage.copy()
198
- storage_kind = storage_params.pop("kind")
199
- logger.info(f"Collecting data using {storage_kind}")
200
- logger.debug(f"\tStorage params: {storage_params}")
201
- if "single_output" not in storage_params:
202
- storage_params["single_output"] = False
203
- storage_object = build(
204
- step="storage",
205
- name=storage_kind,
206
- baseclass=BaseFeatureStorage,
207
- init_params=storage_params,
208
- )
209
- storage_object = typing.cast(BaseFeatureStorage, storage_object)
251
+ logger.info(f"Collecting data using {storage['kind']}")
252
+ logger.debug(f"\tStorage params: {storage}")
253
+ if "single_output" not in storage:
254
+ storage["single_output"] = False
255
+ storage_object = _get_storage(storage.copy())
210
256
  logger.debug("Running storage.collect()")
211
257
  storage_object.collect()
212
258
  logger.info("Collect done")
213
259
 
214
260
 
215
261
  def queue(
216
- config: Dict,
262
+ config: dict,
217
263
  kind: str,
218
264
  jobname: str = "junifer_job",
219
265
  overwrite: bool = False,
220
- elements: Union[str, List[Union[str, Tuple]], Tuple, None] = None,
221
- **kwargs: Union[str, int, bool, Dict, Tuple, List],
266
+ elements: Optional[Elements] = None,
267
+ **kwargs: Union[str, int, bool, dict, tuple, list],
222
268
  ) -> None:
223
269
  """Queue a job to be executed later.
224
270
 
@@ -232,7 +278,7 @@ def queue(
232
278
  The name of the job (default "junifer_job").
233
279
  overwrite : bool, optional
234
280
  Whether to overwrite if job directory already exists (default False).
235
- elements : str or tuple or list of str or tuple, optional
281
+ elements : list or None, optional
236
282
  Element(s) to process. Will be used to index the DataGrabber
237
283
  (default None).
238
284
  **kwargs : dict
@@ -271,6 +317,16 @@ def queue(
271
317
  shutil.rmtree(jobdir)
272
318
  jobdir.mkdir(exist_ok=True, parents=True)
273
319
 
320
+ # Check workdir config
321
+ if "workdir" in config:
322
+ if isinstance(config["workdir"], dict):
323
+ if not config["workdir"]["cleanup"]:
324
+ warn_with_log(
325
+ "`workdir.cleanup` will be set to True when queueing"
326
+ )
327
+ # Set cleanup
328
+ config["workdir"]["cleanup"] = True
329
+
274
330
  # Load modules
275
331
  if "with" in config:
276
332
  to_load = config["with"]
@@ -305,7 +361,7 @@ def queue(
305
361
  elements = dg.get_elements()
306
362
  # Listify elements
307
363
  if not isinstance(elements, list):
308
- elements: List[Union[str, Tuple]] = [elements]
364
+ elements: Elements = [elements]
309
365
 
310
366
  # Check job queueing system
311
367
  adapter = None
@@ -330,7 +386,7 @@ def queue(
330
386
  logger.info("Queue done")
331
387
 
332
388
 
333
- def reset(config: Dict) -> None:
389
+ def reset(config: dict) -> None:
334
390
  """Reset the storage and jobs directory.
335
391
 
336
392
  Parameters
@@ -369,8 +425,8 @@ def reset(config: Dict) -> None:
369
425
 
370
426
 
371
427
  def list_elements(
372
- datagrabber: Dict,
373
- elements: Union[str, List[Union[str, Tuple]], Tuple, None] = None,
428
+ datagrabber: dict,
429
+ elements: Optional[Elements] = None,
374
430
  ) -> str:
375
431
  """List elements of the datagrabber filtered using `elements`.
376
432
 
@@ -380,7 +436,7 @@ def list_elements(
380
436
  DataGrabber to index. Must have a key ``kind`` with the kind of
381
437
  DataGrabber to use. All other keys are passed to the DataGrabber
382
438
  constructor.
383
- elements : str or tuple or list of str or tuple, optional
439
+ elements : list or None, optional
384
440
  Element(s) to filter using. Will be used to index the DataGrabber
385
441
  (default None).
386
442
 
junifer/api/py.typed ADDED
File without changes
@@ -3,9 +3,7 @@
3
3
  # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
4
  # License: AGPL
5
5
 
6
- from .queue_context_adapter import QueueContextAdapter
7
- from .htcondor_adapter import HTCondorAdapter
8
- from .gnu_parallel_local_adapter import GnuParallelLocalAdapter
6
+ import lazy_loader as lazy
9
7
 
10
8
 
11
- __all__ = ["QueueContextAdapter", "HTCondorAdapter", "GnuParallelLocalAdapter"]
9
+ __getattr__, __dir__, __all__ = lazy.attach_stub(__name__, __file__)
@@ -0,0 +1,5 @@
1
+ __all__ = ["QueueContextAdapter", "HTCondorAdapter", "GnuParallelLocalAdapter"]
2
+
3
+ from .queue_context_adapter import QueueContextAdapter
4
+ from .htcondor_adapter import HTCondorAdapter
5
+ from .gnu_parallel_local_adapter import GnuParallelLocalAdapter