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.
Files changed (293) hide show
  1. junifer/_version.py +9 -19
  2. junifer/api/__init__.pyi +17 -2
  3. junifer/api/functions.py +222 -39
  4. junifer/api/queue_context/__init__.pyi +11 -3
  5. junifer/api/queue_context/gnu_parallel_local_adapter.py +81 -120
  6. junifer/api/queue_context/htcondor_adapter.py +118 -181
  7. junifer/api/queue_context/queue_context_adapter.py +51 -7
  8. junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +10 -35
  9. junifer/api/queue_context/tests/test_htcondor_adapter.py +13 -50
  10. junifer/api/res/fsl/run_fsl_docker.sh +4 -0
  11. junifer/api/tests/test_functions.py +863 -36
  12. junifer/cli/__init__.py +1 -7
  13. junifer/cli/cli.py +41 -22
  14. junifer/cli/parser.py +23 -147
  15. junifer/cli/tests/data/gmd_mean.yaml +6 -6
  16. junifer/cli/tests/data/gmd_mean_htcondor.yaml +6 -5
  17. junifer/cli/tests/data/partly_cloudy_agg_mean_tian.yml +1 -0
  18. junifer/cli/tests/test_cli.py +120 -4
  19. junifer/cli/tests/test_cli_utils.py +23 -6
  20. junifer/cli/utils.py +14 -9
  21. junifer/configs/__init__.py +5 -0
  22. junifer/configs/__init__.pyi +0 -0
  23. junifer/configs/juseless/datagrabbers/__init__.pyi +4 -2
  24. junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +18 -24
  25. junifer/configs/juseless/datagrabbers/camcan_vbm.py +20 -27
  26. junifer/configs/juseless/datagrabbers/ixi_vbm.py +44 -52
  27. junifer/configs/juseless/datagrabbers/tests/test_ixi_vbm.py +0 -7
  28. junifer/configs/juseless/datagrabbers/tests/test_ucla.py +2 -19
  29. junifer/configs/juseless/datagrabbers/ucla.py +111 -104
  30. junifer/configs/juseless/datagrabbers/ukb_vbm.py +19 -25
  31. junifer/configs/py.typed +0 -0
  32. junifer/conftest.py +63 -24
  33. junifer/data/_dispatch.py +9 -19
  34. junifer/data/coordinates/_ants_coordinates_warper.py +4 -1
  35. junifer/data/coordinates/_coordinates.py +51 -6
  36. junifer/data/coordinates/_fsl_coordinates_warper.py +4 -1
  37. junifer/data/coordinates/tests/test_coordinates.py +15 -3
  38. junifer/data/coordinates/tests/test_coordinates_names.py +37 -0
  39. junifer/data/maps/_ants_maps_warper.py +18 -12
  40. junifer/data/maps/_fsl_maps_warper.py +7 -3
  41. junifer/data/maps/_maps.py +12 -8
  42. junifer/data/maps/tests/test_maps.py +13 -21
  43. junifer/data/masks/_ants_mask_warper.py +18 -12
  44. junifer/data/masks/_fsl_mask_warper.py +7 -3
  45. junifer/data/masks/_masks.py +15 -12
  46. junifer/data/masks/tests/test_masks.py +20 -17
  47. junifer/data/parcellations/_ants_parcellation_warper.py +18 -12
  48. junifer/data/parcellations/_fsl_parcellation_warper.py +7 -5
  49. junifer/data/parcellations/_parcellations.py +125 -91
  50. junifer/data/parcellations/tests/test_parcellations.py +122 -1
  51. junifer/data/template_spaces.py +117 -50
  52. junifer/data/tests/test_template_spaces.py +10 -7
  53. junifer/data/utils.py +10 -8
  54. junifer/datagrabber/__init__.pyi +38 -5
  55. junifer/datagrabber/aomic/__init__.pyi +8 -1
  56. junifer/datagrabber/aomic/_types.py +22 -0
  57. junifer/datagrabber/aomic/id1000.py +193 -183
  58. junifer/datagrabber/aomic/piop1.py +215 -259
  59. junifer/datagrabber/aomic/piop2.py +211 -244
  60. junifer/datagrabber/aomic/tests/test_id1000.py +70 -53
  61. junifer/datagrabber/aomic/tests/test_piop1.py +98 -102
  62. junifer/datagrabber/aomic/tests/test_piop2.py +88 -85
  63. junifer/datagrabber/base.py +253 -79
  64. junifer/datagrabber/datalad_base.py +127 -76
  65. junifer/datagrabber/dmcc13_benchmark.py +204 -289
  66. junifer/datagrabber/hcp1200/__init__.pyi +7 -2
  67. junifer/datagrabber/hcp1200/datalad_hcp1200.py +61 -40
  68. junifer/datagrabber/hcp1200/hcp1200.py +151 -164
  69. junifer/datagrabber/hcp1200/tests/test_hcp1200.py +116 -128
  70. junifer/datagrabber/multiple.py +183 -63
  71. junifer/datagrabber/pattern.py +358 -227
  72. junifer/datagrabber/pattern_datalad.py +84 -124
  73. junifer/datagrabber/pattern_validation_mixin.py +22 -50
  74. junifer/datagrabber/tests/test_base.py +17 -4
  75. junifer/datagrabber/tests/test_datalad_base.py +20 -27
  76. junifer/datagrabber/tests/test_dmcc13_benchmark.py +110 -122
  77. junifer/datagrabber/tests/test_multiple.py +293 -31
  78. junifer/datagrabber/tests/test_pattern.py +577 -18
  79. junifer/datagrabber/tests/test_pattern_datalad.py +177 -107
  80. junifer/datagrabber/tests/test_pattern_validation_mixin.py +9 -51
  81. junifer/datareader/default.py +8 -5
  82. junifer/datareader/tests/test_default_reader.py +1 -1
  83. junifer/external/BrainPrint/.codecov.yml +2 -0
  84. junifer/external/BrainPrint/.codespellignore +2 -0
  85. junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/bug-report.md +45 -0
  86. junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/documentation.md +12 -0
  87. junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/feature-request.md +24 -0
  88. junifer/external/BrainPrint/.github/ISSUE_TEMPLATE/questions-help-support.md +28 -0
  89. junifer/external/BrainPrint/.github/dependabot.yml +6 -0
  90. junifer/external/BrainPrint/.github/workflows/build.yml +53 -0
  91. junifer/external/BrainPrint/.github/workflows/code-style.yml +44 -0
  92. junifer/external/BrainPrint/.github/workflows/doc.yml +65 -0
  93. junifer/external/BrainPrint/.github/workflows/publish.yml +31 -0
  94. junifer/external/BrainPrint/.github/workflows/pytest.yml +54 -0
  95. junifer/external/BrainPrint/.gitignore +123 -0
  96. junifer/external/BrainPrint/LICENSE +21 -0
  97. junifer/external/BrainPrint/README.md +108 -0
  98. junifer/external/BrainPrint/brainprint/cli/__init__.py +11 -0
  99. junifer/external/BrainPrint/brainprint/cli/help_text.py +169 -0
  100. junifer/external/BrainPrint/brainprint/cli/parser.py +150 -0
  101. junifer/external/BrainPrint/brainprint/cli/utils.py +14 -0
  102. junifer/external/BrainPrint/brainprint/commands/__init__.py +0 -0
  103. junifer/external/BrainPrint/brainprint/commands/sys_info.py +18 -0
  104. junifer/external/BrainPrint/brainprint/utils/tests/__init__.py +0 -0
  105. junifer/external/BrainPrint/brainprint/utils/tests/test_config.py +33 -0
  106. junifer/external/BrainPrint/doc/Makefile +20 -0
  107. junifer/external/BrainPrint/doc/_static/.gitkeep +0 -0
  108. junifer/external/BrainPrint/doc/_templates/autosummary/class.rst +10 -0
  109. junifer/external/BrainPrint/doc/_templates/autosummary/function.rst +8 -0
  110. junifer/external/BrainPrint/doc/_templates/autosummary/module.rst +6 -0
  111. junifer/external/BrainPrint/doc/api/index.rst +11 -0
  112. junifer/external/BrainPrint/doc/conf.py +272 -0
  113. junifer/external/BrainPrint/doc/index.rst +140 -0
  114. junifer/external/BrainPrint/doc/links.inc +36 -0
  115. junifer/external/BrainPrint/doc/make.bat +35 -0
  116. junifer/external/BrainPrint/doc/references.bib +23 -0
  117. junifer/external/BrainPrint/pyproject.toml +170 -0
  118. junifer/external/BrainPrint/setup.py +3 -0
  119. junifer/external/__init__.py +5 -0
  120. junifer/external/__init__.pyi +0 -0
  121. junifer/external/nilearn/junifer_connectivity_measure.py +95 -39
  122. junifer/external/nilearn/junifer_nifti_spheres_masker.py +226 -67
  123. junifer/external/nilearn/tests/test_junifer_connectivity_measure.py +39 -27
  124. junifer/external/nilearn/tests/test_junifer_nifti_spheres_masker.py +231 -21
  125. junifer/external/py.typed +0 -0
  126. junifer/markers/__init__.pyi +6 -3
  127. junifer/markers/base.py +126 -76
  128. junifer/markers/brainprint.py +30 -39
  129. junifer/markers/complexity/__init__.py +20 -3
  130. junifer/markers/complexity/complexity_base.py +40 -41
  131. junifer/markers/complexity/hurst_exponent.py +22 -35
  132. junifer/markers/complexity/multiscale_entropy_auc.py +53 -41
  133. junifer/markers/complexity/perm_entropy.py +22 -36
  134. junifer/markers/complexity/range_entropy.py +22 -35
  135. junifer/markers/complexity/range_entropy_auc.py +27 -36
  136. junifer/markers/complexity/sample_entropy.py +22 -36
  137. junifer/markers/complexity/tests/test_complexity_registry.py +48 -0
  138. junifer/markers/complexity/tests/test_hurst_exponent.py +47 -36
  139. junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +50 -36
  140. junifer/markers/complexity/tests/test_perm_entropy.py +48 -36
  141. junifer/markers/complexity/tests/test_range_entropy.py +47 -36
  142. junifer/markers/complexity/tests/test_range_entropy_auc.py +47 -36
  143. junifer/markers/complexity/tests/test_sample_entropy.py +48 -36
  144. junifer/markers/complexity/tests/test_weighted_perm_entropy.py +50 -36
  145. junifer/markers/complexity/weighted_perm_entropy.py +22 -36
  146. junifer/markers/ets_rss.py +35 -31
  147. junifer/markers/falff/__init__.pyi +7 -1
  148. junifer/markers/falff/_afni_falff.py +22 -9
  149. junifer/markers/falff/_junifer_falff.py +47 -31
  150. junifer/markers/falff/falff_base.py +80 -60
  151. junifer/markers/falff/falff_maps.py +17 -41
  152. junifer/markers/falff/falff_parcels.py +26 -51
  153. junifer/markers/falff/falff_spheres.py +34 -61
  154. junifer/markers/falff/tests/test_falff_maps.py +20 -23
  155. junifer/markers/falff/tests/test_falff_mask.py +99 -0
  156. junifer/markers/falff/tests/test_falff_parcels.py +14 -10
  157. junifer/markers/falff/tests/test_falff_spheres.py +14 -10
  158. junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +32 -34
  159. junifer/markers/functional_connectivity/edge_functional_connectivity_maps.py +12 -25
  160. junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +19 -34
  161. junifer/markers/functional_connectivity/edge_functional_connectivity_spheres.py +24 -44
  162. junifer/markers/functional_connectivity/functional_connectivity_base.py +50 -40
  163. junifer/markers/functional_connectivity/functional_connectivity_maps.py +12 -25
  164. junifer/markers/functional_connectivity/functional_connectivity_parcels.py +19 -34
  165. junifer/markers/functional_connectivity/functional_connectivity_spheres.py +24 -45
  166. junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +21 -22
  167. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_maps.py +8 -7
  168. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +8 -4
  169. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +8 -4
  170. junifer/markers/functional_connectivity/tests/test_functional_connectivity_maps.py +8 -7
  171. junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +9 -5
  172. junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +8 -12
  173. junifer/markers/maps_aggregation.py +77 -55
  174. junifer/markers/parcel_aggregation.py +91 -70
  175. junifer/markers/reho/__init__.pyi +7 -1
  176. junifer/markers/reho/_afni_reho.py +23 -14
  177. junifer/markers/reho/_junifer_reho.py +112 -123
  178. junifer/markers/reho/reho_base.py +115 -37
  179. junifer/markers/reho/reho_maps.py +18 -32
  180. junifer/markers/reho/reho_parcels.py +26 -41
  181. junifer/markers/reho/reho_spheres.py +33 -54
  182. junifer/markers/reho/tests/test_junifer_reho.py +178 -0
  183. junifer/markers/reho/tests/test_reho_maps.py +27 -25
  184. junifer/markers/reho/tests/test_reho_parcels.py +28 -22
  185. junifer/markers/reho/tests/test_reho_spheres.py +16 -12
  186. junifer/markers/sphere_aggregation.py +88 -72
  187. junifer/markers/temporal_snr/temporal_snr_base.py +32 -30
  188. junifer/markers/temporal_snr/temporal_snr_maps.py +9 -18
  189. junifer/markers/temporal_snr/temporal_snr_parcels.py +19 -27
  190. junifer/markers/temporal_snr/temporal_snr_spheres.py +27 -41
  191. junifer/markers/temporal_snr/tests/test_temporal_snr_base.py +2 -2
  192. junifer/markers/temporal_snr/tests/test_temporal_snr_maps.py +17 -22
  193. junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +11 -3
  194. junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +9 -9
  195. junifer/markers/tests/test_brainprint.py +10 -9
  196. junifer/markers/tests/test_ets_rss.py +7 -3
  197. junifer/markers/tests/test_lost_regions.py +279 -0
  198. junifer/markers/tests/test_maps_aggregation.py +67 -114
  199. junifer/markers/tests/test_marker_utils.py +40 -1
  200. junifer/markers/tests/test_markers_base.py +275 -6
  201. junifer/markers/tests/test_parcel_aggregation.py +91 -53
  202. junifer/markers/tests/test_sphere_aggregation.py +53 -47
  203. junifer/markers/utils.py +267 -5
  204. junifer/onthefly/__init__.py +2 -3
  205. junifer/onthefly/__init__.pyi +4 -0
  206. junifer/onthefly/_brainprint.py +3 -5
  207. junifer/onthefly/py.typed +0 -0
  208. junifer/onthefly/read_transform.py +11 -9
  209. junifer/onthefly/tests/test_read_transform.py +7 -7
  210. junifer/pipeline/__init__.pyi +4 -2
  211. junifer/pipeline/marker_collection.py +14 -10
  212. junifer/pipeline/pipeline_component_registry.py +25 -6
  213. junifer/pipeline/pipeline_step_mixin.py +5 -12
  214. junifer/pipeline/tests/test_data_object_dumper.py +10 -10
  215. junifer/pipeline/tests/test_marker_collection.py +145 -168
  216. junifer/pipeline/tests/test_pipeline_component_registry.py +52 -8
  217. junifer/pipeline/tests/test_pipeline_step_mixin.py +12 -26
  218. junifer/pipeline/tests/test_update_meta_mixin.py +4 -5
  219. junifer/pipeline/tests/test_workdir_manager.py +39 -0
  220. junifer/pipeline/update_meta_mixin.py +13 -10
  221. junifer/pipeline/utils.py +22 -17
  222. junifer/pipeline/workdir_manager.py +41 -32
  223. junifer/preprocess/__init__.pyi +9 -4
  224. junifer/preprocess/_temporal_filter.py +34 -33
  225. junifer/preprocess/_temporal_slicer.py +17 -30
  226. junifer/preprocess/base.py +99 -55
  227. junifer/preprocess/confounds/__init__.pyi +10 -2
  228. junifer/preprocess/confounds/fmriprep_confound_remover.py +87 -109
  229. junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +64 -45
  230. junifer/preprocess/smoothing/__init__.pyi +2 -2
  231. junifer/preprocess/smoothing/_afni_smoothing.py +8 -7
  232. junifer/preprocess/smoothing/_fsl_smoothing.py +6 -4
  233. junifer/preprocess/smoothing/_nilearn_smoothing.py +7 -5
  234. junifer/preprocess/smoothing/smoothing.py +59 -40
  235. junifer/preprocess/smoothing/tests/test_smoothing.py +28 -8
  236. junifer/preprocess/tests/test_preprocess_base.py +17 -9
  237. junifer/preprocess/tests/test_temporal_filter.py +37 -16
  238. junifer/preprocess/tests/test_temporal_slicer.py +12 -12
  239. junifer/preprocess/warping/__init__.pyi +2 -2
  240. junifer/preprocess/warping/_ants_warper.py +56 -40
  241. junifer/preprocess/warping/_fsl_warper.py +49 -36
  242. junifer/preprocess/warping/_utils.py +106 -0
  243. junifer/preprocess/warping/space_warper.py +99 -98
  244. junifer/preprocess/warping/tests/test_space_warper.py +46 -41
  245. junifer/preprocess/warping/tests/test_warping_utils.py +163 -0
  246. junifer/stats.py +46 -34
  247. junifer/storage/__init__.pyi +8 -4
  248. junifer/storage/base.py +129 -64
  249. junifer/storage/hdf5.py +307 -199
  250. junifer/storage/pandas_base.py +46 -24
  251. junifer/storage/sqlite.py +99 -62
  252. junifer/storage/tests/data/collected_h5io_fork.hdf5 +0 -0
  253. junifer/storage/tests/test_hdf5.py +147 -12
  254. junifer/storage/tests/test_repeated_storage.py +293 -0
  255. junifer/storage/tests/test_sqlite.py +9 -20
  256. junifer/storage/tests/test_storage_base.py +18 -21
  257. junifer/storage/tests/test_utils.py +83 -22
  258. junifer/storage/utils.py +58 -38
  259. junifer/testing/__init__.pyi +2 -2
  260. junifer/testing/datagrabbers.py +480 -44
  261. junifer/testing/registry.py +12 -0
  262. junifer/testing/tests/test_adhdtesting_datagrabber.py +24 -0
  263. junifer/testing/tests/test_oasisvmbtesting_datagrabber.py +5 -0
  264. junifer/testing/tests/test_partlycloudytesting_datagrabber.py +52 -0
  265. junifer/testing/tests/test_spmauditory_datagrabber.py +16 -0
  266. junifer/testing/tests/test_testing_registry.py +31 -0
  267. junifer/testing/tests/test_testing_utils.py +35 -0
  268. junifer/testing/tests/test_uclacnpvbmtesting_datagrabber.py +81 -0
  269. junifer/testing/utils.py +33 -1
  270. junifer/tests/test_stats.py +1 -5
  271. junifer/typing/__init__.pyi +2 -0
  272. junifer/typing/_typing.py +34 -19
  273. junifer/typing/py.typed +0 -0
  274. junifer/utils/__init__.pyi +10 -1
  275. junifer/utils/_config.py +1 -2
  276. junifer/utils/helpers.py +68 -2
  277. junifer/utils/logging.py +31 -7
  278. junifer/utils/tests/test_helpers.py +36 -1
  279. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/METADATA +43 -35
  280. junifer-0.0.8.dist-info/RECORD +402 -0
  281. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/WHEEL +1 -1
  282. junifer/cli/tests/test_parser.py +0 -280
  283. junifer/external/h5io/h5io/__init__.py +0 -15
  284. junifer/external/h5io/h5io/_h5io.py +0 -767
  285. junifer/external/h5io/h5io/_version.py +0 -1
  286. junifer/external/h5io/h5io/chunked_array.py +0 -94
  287. junifer/external/h5io/h5io/chunked_list.py +0 -65
  288. junifer/markers/complexity/__init__.pyi +0 -17
  289. junifer-0.0.7.dev332.dist-info/RECORD +0 -353
  290. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/entry_points.txt +0 -0
  291. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/licenses/AUTHORS.rst +0 -0
  292. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/licenses/LICENSE.md +0 -0
  293. {junifer-0.0.7.dev332.dist-info → junifer-0.0.8.dist-info}/top_level.txt +0 -0
@@ -3,16 +3,92 @@
3
3
  # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
4
  # License: AGPL
5
5
 
6
- from itertools import product
7
- from pathlib import Path
8
- from typing import Union
6
+ from enum import StrEnum
7
+ from typing import Annotated, ClassVar, Literal
8
+
9
+ from pydantic import AnyUrl, BeforeValidator
9
10
 
10
11
  from ..api.decorators import register_datagrabber
11
- from ..utils import raise_error
12
+ from ..typing import DataGrabberPatterns
13
+ from ..utils import ensure_list
14
+ from .base import DataType
15
+ from .pattern import ConfoundsFormat
12
16
  from .pattern_datalad import PatternDataladDataGrabber
13
17
 
14
18
 
15
- __all__ = ["DMCC13Benchmark"]
19
+ __all__ = [
20
+ "DMCC13Benchmark",
21
+ "DMCCPhaseEncoding",
22
+ "DMCCRun",
23
+ "DMCCSession",
24
+ "DMCCTask",
25
+ ]
26
+
27
+
28
+ class DMCCSession(StrEnum):
29
+ """Accepted DMCC sessions."""
30
+
31
+ Wave1Bas = "ses-wave1bas"
32
+ Wave1Pro = "ses-wave1pro"
33
+ Wave1Rea = "ses-wave1rea"
34
+
35
+
36
+ class DMCCTask(StrEnum):
37
+ """Accepted DMCC tasks."""
38
+
39
+ Rest = "Rest"
40
+ Axcpt = "Axcpt"
41
+ Cuedts = "Cuedts"
42
+ Stern = "Stern"
43
+ Stroop = "Stroop"
44
+
45
+
46
+ class DMCCPhaseEncoding(StrEnum):
47
+ """Accepted DMCC phase encoding directions."""
48
+
49
+ AP = "AP"
50
+ PA = "PA"
51
+
52
+
53
+ class DMCCRun(StrEnum):
54
+ """Accepted DMCC runs."""
55
+
56
+ One = "1"
57
+ Two = "2"
58
+
59
+
60
+ _types = Literal[
61
+ DataType.BOLD,
62
+ DataType.T1w,
63
+ DataType.VBM_CSF,
64
+ DataType.VBM_GM,
65
+ DataType.VBM_WM,
66
+ DataType.Warp,
67
+ ]
68
+
69
+ _sessions = Literal[
70
+ DMCCSession.Wave1Bas,
71
+ DMCCSession.Wave1Pro,
72
+ DMCCSession.Wave1Rea,
73
+ ]
74
+
75
+ _tasks = Literal[
76
+ DMCCTask.Rest,
77
+ DMCCTask.Axcpt,
78
+ DMCCTask.Cuedts,
79
+ DMCCTask.Stern,
80
+ DMCCTask.Stroop,
81
+ ]
82
+
83
+ _phase_encodings = Literal[
84
+ DMCCPhaseEncoding.AP,
85
+ DMCCPhaseEncoding.PA,
86
+ ]
87
+
88
+ _runs = Literal[
89
+ DMCCRun.One,
90
+ DMCCRun.Two,
91
+ ]
16
92
 
17
93
 
18
94
  @register_datagrabber
@@ -21,191 +97,149 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
21
97
 
22
98
  Parameters
23
99
  ----------
24
- datadir : str or Path or None, optional
25
- The directory where the datalad dataset will be cloned. If None,
26
- the datalad dataset will be cloned into a temporary directory
27
- (default None).
28
- types: {"BOLD", "T1w", "VBM_CSF", "VBM_GM", "VBM_WM"} or \
29
- list of the options, optional
30
- DMCC data types. If None, all available data types are selected.
31
- (default None).
32
- sessions: {"ses-wave1bas", "ses-wave1pro", "ses-wave1rea"} or \
33
- list of the options, optional
34
- DMCC sessions. If None, all available sessions are selected
35
- (default None).
36
- tasks: {"Rest", "Axcpt", "Cuedts", "Stern", "Stroop"} or \
37
- list of the options, optional
38
- DMCC task sessions. If None, all available task sessions are selected
39
- (default None).
100
+ types : {"BOLD", "T1w", "VBM_CSF", "VBM_GM", "VBM_WM", "Warp"} or \
101
+ list of the options, optional
102
+ The data type(s) to grab.
103
+ datadir : pathlib.Path, optional
104
+ That path where the datalad dataset will be cloned.
105
+ If not specified, the datalad dataset will be cloned into a temporary
106
+ directory.
107
+ sessions : {"ses-wave1bas", "ses-wave1pro", "ses-wave1rea"} or \
108
+ list of the options, optional
109
+ DMCC sessions.
110
+ By default, all available sessions are selected.
111
+ tasks : {"Rest", "Axcpt", "Cuedts", "Stern", "Stroop"} or \
112
+ list of the options, optional
113
+ DMCC tasks.
114
+ By default, all available tasks are selected.
40
115
  phase_encodings : {"AP", "PA"} or list of the options, optional
41
- DMCC phase encoding directions. If None, all available phase encodings
42
- are selected (default None).
116
+ DMCC phase encoding directions.
117
+ By default, all available phase encodings are selected.
43
118
  runs : {"1", "2"} or list of the options, optional
44
- DMCC runs. If None, all available runs are selected (default None).
119
+ DMCC runs.
120
+ By default, all available runs are selected.
45
121
  native_t1w : bool, optional
46
122
  Whether to use T1w in native space (default False).
47
123
 
48
- Raises
49
- ------
50
- ValueError
51
- If invalid value is passed for:
52
- * ``sessions``
53
- * ``tasks``
54
- * ``phase_encodings``
55
- * ``runs``
56
-
57
124
  """
58
125
 
59
- def __init__(
60
- self,
61
- datadir: Union[str, Path, None] = None,
62
- types: Union[str, list[str], None] = None,
63
- sessions: Union[str, list[str], None] = None,
64
- tasks: Union[str, list[str], None] = None,
65
- phase_encodings: Union[str, list[str], None] = None,
66
- runs: Union[str, list[str], None] = None,
67
- native_t1w: bool = False,
68
- ) -> None:
69
- # Declare all sessions
70
- all_sessions = [
71
- "ses-wave1bas",
72
- "ses-wave1pro",
73
- "ses-wave1rea",
74
- ]
75
- # Set default sessions
76
- if sessions is None:
77
- sessions = all_sessions
78
- else:
79
- # Convert single session into list
80
- if isinstance(sessions, str):
81
- sessions = [sessions]
82
- # Verify valid sessions
83
- for s in sessions:
84
- if s not in all_sessions:
85
- raise_error(
86
- f"{s} is not a valid session in the DMCC dataset"
87
- )
88
- self.sessions = sessions
89
- # Declare all tasks
90
- all_tasks = [
91
- "Rest",
92
- "Axcpt",
93
- "Cuedts",
94
- "Stern",
95
- "Stroop",
96
- ]
97
- # Set default tasks
98
- if tasks is None:
99
- tasks = all_tasks
100
- else:
101
- # Convert single task into list
102
- if isinstance(tasks, str):
103
- tasks = [tasks]
104
- # Verify valid tasks
105
- for t in tasks:
106
- if t not in all_tasks:
107
- raise_error(f"{t} is not a valid task in the DMCC dataset")
108
- self.tasks = tasks
109
- # Declare all phase encodings
110
- all_phase_encodings = ["AP", "PA"]
111
- # Set default phase encodings
112
- if phase_encodings is None:
113
- phase_encodings = all_phase_encodings
114
- else:
115
- # Convert single phase encoding into list
116
- if isinstance(phase_encodings, str):
117
- phase_encodings = [phase_encodings]
118
- # Verify valid phase encodings
119
- for p in phase_encodings:
120
- if p not in all_phase_encodings:
121
- raise_error(
122
- f"{p} is not a valid phase encoding in the DMCC "
123
- "dataset"
124
- )
125
- self.phase_encodings = phase_encodings
126
- # Declare all runs
127
- all_runs = ["1", "2"]
128
- # Set default runs
129
- if runs is None:
130
- runs = all_runs
131
- else:
132
- # Convert single run into list
133
- if isinstance(runs, str):
134
- runs = [runs]
135
- # Verify valid runs
136
- for r in runs:
137
- if r not in all_runs:
138
- raise_error(f"{r} is not a valid run in the DMCC dataset")
139
- self.runs = runs
140
- # The patterns
141
- patterns = {
142
- "BOLD": {
126
+ uri: AnyUrl = AnyUrl("https://github.com/OpenNeuroDatasets/ds003452.git")
127
+ types: Annotated[_types | list[_types], BeforeValidator(ensure_list)] = [ # noqa: RUF012
128
+ DataType.BOLD,
129
+ DataType.T1w,
130
+ DataType.VBM_CSF,
131
+ DataType.VBM_GM,
132
+ DataType.VBM_WM,
133
+ ]
134
+ sessions: Annotated[
135
+ _sessions | list[_sessions], BeforeValidator(ensure_list)
136
+ ] = [ # noqa: RUF012
137
+ DMCCSession.Wave1Bas,
138
+ DMCCSession.Wave1Pro,
139
+ DMCCSession.Wave1Rea,
140
+ ]
141
+ tasks: Annotated[_tasks | list[_tasks], BeforeValidator(ensure_list)] = [ # noqa: RUF012
142
+ DMCCTask.Rest,
143
+ DMCCTask.Axcpt,
144
+ DMCCTask.Cuedts,
145
+ DMCCTask.Stern,
146
+ DMCCTask.Stroop,
147
+ ]
148
+ phase_encodings: Annotated[
149
+ _phase_encodings | list[_phase_encodings],
150
+ BeforeValidator(ensure_list),
151
+ ] = [ # noqa: RUF012
152
+ DMCCPhaseEncoding.AP,
153
+ DMCCPhaseEncoding.PA,
154
+ ]
155
+ runs: Annotated[_runs | list[_runs], BeforeValidator(ensure_list)] = [ # noqa: RUF012
156
+ DMCCRun.One,
157
+ DMCCRun.Two,
158
+ ]
159
+ native_t1w: bool = False
160
+ patterns: DataGrabberPatterns = { # noqa: RUF012
161
+ "BOLD": {
162
+ "pattern": (
163
+ "derivatives/fmriprep-1.3.2/{subject}/{session}/"
164
+ "func/{subject}_{session}_task-{task}_acq-mb4"
165
+ "{phase_encoding}_run-{run}_"
166
+ "space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz"
167
+ ),
168
+ "space": "MNI152NLin2009cAsym",
169
+ "mask": {
143
170
  "pattern": (
144
171
  "derivatives/fmriprep-1.3.2/{subject}/{session}/"
145
172
  "func/{subject}_{session}_task-{task}_acq-mb4"
146
173
  "{phase_encoding}_run-{run}_"
147
- "space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz"
174
+ "space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
148
175
  ),
149
176
  "space": "MNI152NLin2009cAsym",
150
- "mask": {
151
- "pattern": (
152
- "derivatives/fmriprep-1.3.2/{subject}/{session}/"
153
- "func/{subject}_{session}_task-{task}_acq-mb4"
154
- "{phase_encoding}_run-{run}_"
155
- "space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
156
- ),
157
- "space": "MNI152NLin2009cAsym",
158
- },
159
- "confounds": {
160
- "pattern": (
161
- "derivatives/fmriprep-1.3.2/{subject}/{session}/"
162
- "func/{subject}_{session}_task-{task}_acq-mb4"
163
- "{phase_encoding}_run-{run}_desc-confounds_regressors.tsv"
164
- ),
165
- "format": "fmriprep",
166
- },
167
177
  },
168
- "T1w": {
178
+ "confounds": {
169
179
  "pattern": (
170
- "derivatives/fmriprep-1.3.2/{subject}/anat/"
171
- "{subject}_space-MNI152NLin2009cAsym_desc-preproc_T1w.nii.gz"
172
- ),
173
- "space": "MNI152NLin2009cAsym",
174
- "mask": {
175
- "pattern": (
176
- "derivatives/fmriprep-1.3.2/{subject}/anat/"
177
- "{subject}_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
178
- ),
179
- "space": "MNI152NLin2009cAsym",
180
- },
181
- },
182
- "VBM_CSF": {
183
- "pattern": (
184
- "derivatives/fmriprep-1.3.2/{subject}/anat/"
185
- "{subject}_space-MNI152NLin2009cAsym_label-CSF_probseg.nii.gz"
180
+ "derivatives/fmriprep-1.3.2/{subject}/{session}/"
181
+ "func/{subject}_{session}_task-{task}_acq-mb4"
182
+ "{phase_encoding}_run-{run}_desc-confounds_regressors.tsv"
186
183
  ),
187
- "space": "MNI152NLin2009cAsym",
184
+ "format": "fmriprep",
188
185
  },
189
- "VBM_GM": {
186
+ },
187
+ "T1w": {
188
+ "pattern": (
189
+ "derivatives/fmriprep-1.3.2/{subject}/anat/"
190
+ "{subject}_space-MNI152NLin2009cAsym_desc-preproc_T1w.nii.gz"
191
+ ),
192
+ "space": "MNI152NLin2009cAsym",
193
+ "mask": {
190
194
  "pattern": (
191
195
  "derivatives/fmriprep-1.3.2/{subject}/anat/"
192
- "{subject}_space-MNI152NLin2009cAsym_label-GM_probseg.nii.gz"
196
+ "{subject}_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
193
197
  ),
194
198
  "space": "MNI152NLin2009cAsym",
195
199
  },
196
- "VBM_WM": {
197
- "pattern": (
198
- "derivatives/fmriprep-1.3.2/{subject}/anat/"
199
- "{subject}_space-MNI152NLin2009cAsym_label-WM_probseg.nii.gz"
200
- ),
201
- "space": "MNI152NLin2009cAsym",
202
- },
203
- }
204
- # Use native T1w assets
205
- self.native_t1w = False
206
- if native_t1w:
207
- self.native_t1w = True
208
- patterns.update(
200
+ },
201
+ "VBM_CSF": {
202
+ "pattern": (
203
+ "derivatives/fmriprep-1.3.2/{subject}/anat/"
204
+ "{subject}_space-MNI152NLin2009cAsym_label-CSF_probseg.nii.gz"
205
+ ),
206
+ "space": "MNI152NLin2009cAsym",
207
+ },
208
+ "VBM_GM": {
209
+ "pattern": (
210
+ "derivatives/fmriprep-1.3.2/{subject}/anat/"
211
+ "{subject}_space-MNI152NLin2009cAsym_label-GM_probseg.nii.gz"
212
+ ),
213
+ "space": "MNI152NLin2009cAsym",
214
+ },
215
+ "VBM_WM": {
216
+ "pattern": (
217
+ "derivatives/fmriprep-1.3.2/{subject}/anat/"
218
+ "{subject}_space-MNI152NLin2009cAsym_label-WM_probseg.nii.gz"
219
+ ),
220
+ "space": "MNI152NLin2009cAsym",
221
+ },
222
+ }
223
+ replacements: list[str] = [ # noqa: RUF012
224
+ "subject",
225
+ "session",
226
+ "task",
227
+ "phase_encoding",
228
+ "run",
229
+ ]
230
+ # Only grab the specified sessions, tasks, phase encodings and runs
231
+ _REPLACEMENT_FIELDS: ClassVar[dict[str, str]] = {
232
+ "session": "sessions",
233
+ "task": "tasks",
234
+ "phase_encoding": "phase_encodings",
235
+ "run": "runs",
236
+ }
237
+ confounds_format: ConfoundsFormat = ConfoundsFormat.FMRIPrep
238
+
239
+ def validate_datagrabber_params(self) -> None:
240
+ """Run extra logical validation for datagrabber."""
241
+ if self.native_t1w:
242
+ self.patterns.update(
209
243
  {
210
244
  "T1w": {
211
245
  "pattern": (
@@ -245,124 +279,5 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
245
279
  ],
246
280
  }
247
281
  )
248
- # Set default types
249
- if types is None:
250
- types = list(patterns.keys())
251
- # Convert single type into list
252
- else:
253
- if not isinstance(types, list):
254
- types = [types]
255
- # The replacements
256
- replacements = ["subject", "session", "task", "phase_encoding", "run"]
257
- uri = "https://github.com/OpenNeuroDatasets/ds003452.git"
258
- super().__init__(
259
- types=types,
260
- datadir=datadir,
261
- uri=uri,
262
- patterns=patterns,
263
- replacements=replacements,
264
- confounds_format="fmriprep",
265
- )
266
-
267
- def get_item(
268
- self,
269
- subject: str,
270
- session: str,
271
- task: str,
272
- phase_encoding: str,
273
- run: str,
274
- ) -> dict:
275
- """Index one element in the dataset.
276
-
277
- Parameters
278
- ----------
279
- subject : str
280
- The subject ID.
281
- session : {"ses-wave1bas", "ses-wave1pro", "ses-wave1rea"}
282
- The session to get.
283
- task : {"Rest", "Axcpt", "Cuedts", "Stern", "Stroop"}
284
- The task to get.
285
- phase_encoding : {"AP", "PA"}
286
- The phase encoding to get.
287
- run : {"1", "2"}
288
- The run to get.
289
-
290
- Returns
291
- -------
292
- out : dict
293
- Dictionary of paths for each type of data required for the
294
- specified element.
295
-
296
- """
297
- # Format run
298
- if phase_encoding == "AP":
299
- run = "1"
300
- else:
301
- run = "2"
302
- # Fetch item
303
- out = super().get_item(
304
- subject=subject,
305
- session=session,
306
- task=task,
307
- phase_encoding=phase_encoding,
308
- run=run,
309
- )
310
- return out
311
-
312
- def get_elements(self) -> list:
313
- """Implement fetching list of subjects in the dataset.
314
-
315
- Returns
316
- -------
317
- list of str
318
- The list of subjects in the dataset.
319
-
320
- """
321
- subjects = [
322
- "sub-f1031ax",
323
- "sub-f1552xo",
324
- "sub-f1659oa",
325
- "sub-f1670rz",
326
- "sub-f1951tt",
327
- "sub-f3300jh",
328
- "sub-f3720ca",
329
- "sub-f5004cr",
330
- "sub-f5407sl",
331
- "sub-f5416zj",
332
- "sub-f8113do",
333
- "sub-f8570ui",
334
- "sub-f9057kp",
335
- ]
336
- elems = []
337
- # For wave1bas session
338
- for subject, session, task, phase_encoding in product(
339
- subjects,
340
- ["ses-wave1bas"],
341
- self.tasks,
342
- self.phase_encodings,
343
- ):
344
- if phase_encoding == "AP":
345
- run = "1"
346
- else:
347
- run = "2"
348
- # Bypass for f1951tt not having run 2 for Rest
349
- if subject == "sub-f1951tt" and task == "Rest" and run == "2":
350
- continue
351
- elems.append((subject, session, task, phase_encoding, run))
352
- # For other sessions
353
- for subject, session, task, phase_encoding in product(
354
- subjects,
355
- ["ses-wave1pro", "ses-wave1rea"],
356
- ["Rest"],
357
- self.phase_encodings,
358
- ):
359
- if phase_encoding == "AP":
360
- run = "1"
361
- else:
362
- run = "2"
363
- # Bypass for f5416zj for not having wave1rea session
364
- if subject == "sub-f5416zj" and session == "ses-wave1rea":
365
- continue
366
- elems.append((subject, session, task, phase_encoding, run))
367
-
368
- return elems
282
+ self.types.append(DataType.Warp)
283
+ super().validate_datagrabber_params()
@@ -1,4 +1,9 @@
1
- __all__ = ["HCP1200", "DataladHCP1200"]
1
+ __all__ = [
2
+ "HCP1200",
3
+ "HCP1200Task",
4
+ "HCP1200PhaseEncoding",
5
+ "DataladHCP1200",
6
+ ]
2
7
 
3
- from .hcp1200 import HCP1200
8
+ from .hcp1200 import HCP1200, HCP1200Task, HCP1200PhaseEncoding
4
9
  from .datalad_hcp1200 import DataladHCP1200
@@ -5,68 +5,63 @@
5
5
  # Synchon Mandal <s.mandal@fz-juelich.de>
6
6
  # License: AGPL
7
7
 
8
+ from itertools import product
8
9
  from pathlib import Path
9
- from typing import Union
10
+ from typing import Annotated, Literal
10
11
 
11
- from junifer.datagrabber.datalad_base import DataladDataGrabber
12
+ from pydantic import AnyUrl, BeforeValidator
12
13
 
13
14
  from ...api.decorators import register_datagrabber
15
+ from ...typing import Elements
16
+ from ...utils import ensure_list
17
+ from ..base import DataType
18
+ from ..datalad_base import DataladDataGrabber
14
19
  from .hcp1200 import HCP1200
15
20
 
16
21
 
17
22
  __all__ = ["DataladHCP1200"]
18
23
 
19
24
 
25
+ _types = Literal[DataType.BOLD, DataType.T1w, DataType.Warp]
26
+
27
+
20
28
  @register_datagrabber
21
29
  class DataladHCP1200(DataladDataGrabber, HCP1200):
22
30
  """Concrete implementation for datalad-based data fetching of HCP1200.
23
31
 
24
32
  Parameters
25
33
  ----------
26
- datadir : str or Path or None, optional
27
- The directory where the datalad dataset will be cloned. If None,
28
- the datalad dataset will be cloned into a temporary directory
29
- (default None).
34
+ types : {"BOLD", "T1w", "Warp"} or list of the options, optional
35
+ The data type(s) to grab.
36
+ datadir : pathlib.Path, optional
37
+ That path where the datalad dataset will be cloned.
38
+ If not specified, the datalad dataset will be cloned into a temporary
39
+ directory.
30
40
  tasks : {"REST1", "REST2", "SOCIAL", "WM", "RELATIONAL", "EMOTION", \
31
- "LANGUAGE", "GAMBLING", "MOTOR"} or list of the options or None \
32
- , optional
33
- HCP task sessions. If None, all available task sessions are selected
34
- (default None).
35
- phase_encodings : {"LR", "RL"} or list of the options or None, optional
36
- HCP phase encoding directions. If None, both will be used
37
- (default None).
41
+ "LANGUAGE", "GAMBLING", "MOTOR"} or list of the options, optional
42
+ HCP task sessions.
43
+ By default, all available task sessions are selected.
44
+ phase_encodings : {"LR", "RL"} or list of the options, optional
45
+ HCP phase encoding directions.
46
+ By default, all are used.
38
47
  ica_fix : bool, optional
39
48
  Whether to retrieve data that was processed with ICA+FIX.
40
- Only "REST1" and "REST2" tasks are available with ICA+FIX (default
41
- False).
42
-
43
- Raises
44
- ------
45
- ValueError
46
- If invalid value is passed for ``tasks`` or ``phase_encodings``.
49
+ Only ``HCP1200Task.REST1`` and ``HCP1200Task.REST2`` tasks
50
+ are available with ICA+FIX
51
+ (default False).
47
52
 
48
53
  """
49
54
 
50
- def __init__(
51
- self,
52
- datadir: Union[str, Path, None] = None,
53
- tasks: Union[str, list[str], None] = None,
54
- phase_encodings: Union[str, list[str], None] = None,
55
- ica_fix: bool = False,
56
- ) -> None:
57
- uri = (
58
- "https://github.com/datalad-datasets/"
59
- "human-connectome-project-openaccess.git"
60
- )
61
- rootdir = "HCP1200"
62
- super().__init__(
63
- datadir=datadir,
64
- tasks=tasks,
65
- phase_encodings=phase_encodings,
66
- uri=uri,
67
- rootdir=rootdir,
68
- ica_fix=ica_fix,
69
- )
55
+ uri: AnyUrl = AnyUrl(
56
+ "https://github.com/datalad-datasets/"
57
+ "human-connectome-project-openaccess.git"
58
+ )
59
+ types: Annotated[_types | list[_types], BeforeValidator(ensure_list)] = [ # noqa: RUF012
60
+ DataType.BOLD,
61
+ DataType.T1w,
62
+ DataType.Warp,
63
+ ]
64
+ rootdir: Path = Path("HCP1200")
70
65
 
71
66
  # Needed here as HCP1200's subjects are sub-datasets, so will not be
72
67
  # found when elements are checked.
@@ -74,3 +69,29 @@ class DataladHCP1200(DataladDataGrabber, HCP1200):
74
69
  def skip_file_check(self) -> bool:
75
70
  """Skip file check existence."""
76
71
  return True
72
+
73
+ def get_elements(self) -> Elements:
74
+ """Implement fetching list of elements in the dataset.
75
+
76
+ The subjects are sub-datasets, whose files are only there once they
77
+ are installed, so the files are not searched: the elements are all
78
+ the subjects (the directories of the dataset) with the tasks and
79
+ phase encodings to grab, even if some of them have no data.
80
+
81
+ Returns
82
+ -------
83
+ list
84
+ The list of elements that can be grabbed in the dataset.
85
+
86
+ """
87
+ subjects = sorted(
88
+ x.name
89
+ for x in self.fulldir.iterdir()
90
+ if x.is_dir() and not x.name.startswith(".")
91
+ )
92
+ values = {"subject": subjects, **self.get_replacement_values()}
93
+ element_keys = self.get_element_keys()
94
+ elements = list(product(*(values[k] for k in element_keys)))
95
+ if len(element_keys) == 1:
96
+ return [element[0] for element in elements]
97
+ return elements