junifer 0.0.3.dev186__py3-none-any.whl → 0.0.4__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 (178) hide show
  1. junifer/_version.py +14 -2
  2. junifer/api/cli.py +162 -17
  3. junifer/api/functions.py +87 -419
  4. junifer/api/parser.py +24 -0
  5. junifer/api/queue_context/__init__.py +8 -0
  6. junifer/api/queue_context/gnu_parallel_local_adapter.py +258 -0
  7. junifer/api/queue_context/htcondor_adapter.py +365 -0
  8. junifer/api/queue_context/queue_context_adapter.py +60 -0
  9. junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py +192 -0
  10. junifer/api/queue_context/tests/test_htcondor_adapter.py +257 -0
  11. junifer/api/res/afni/run_afni_docker.sh +6 -6
  12. junifer/api/res/ants/ResampleImage +3 -0
  13. junifer/api/res/ants/antsApplyTransforms +3 -0
  14. junifer/api/res/ants/antsApplyTransformsToPoints +3 -0
  15. junifer/api/res/ants/run_ants_docker.sh +39 -0
  16. junifer/api/res/fsl/applywarp +3 -0
  17. junifer/api/res/fsl/flirt +3 -0
  18. junifer/api/res/fsl/img2imgcoord +3 -0
  19. junifer/api/res/fsl/run_fsl_docker.sh +39 -0
  20. junifer/api/res/fsl/std2imgcoord +3 -0
  21. junifer/api/res/run_conda.sh +4 -4
  22. junifer/api/res/run_venv.sh +22 -0
  23. junifer/api/tests/data/partly_cloudy_agg_mean_tian.yml +16 -0
  24. junifer/api/tests/test_api_utils.py +21 -3
  25. junifer/api/tests/test_cli.py +232 -9
  26. junifer/api/tests/test_functions.py +211 -439
  27. junifer/api/tests/test_parser.py +1 -1
  28. junifer/configs/juseless/datagrabbers/aomic_id1000_vbm.py +6 -1
  29. junifer/configs/juseless/datagrabbers/camcan_vbm.py +6 -1
  30. junifer/configs/juseless/datagrabbers/ixi_vbm.py +6 -1
  31. junifer/configs/juseless/datagrabbers/tests/test_ucla.py +8 -8
  32. junifer/configs/juseless/datagrabbers/ucla.py +44 -26
  33. junifer/configs/juseless/datagrabbers/ukb_vbm.py +6 -1
  34. junifer/data/VOIs/meta/AutobiographicalMemory_VOIs.txt +23 -0
  35. junifer/data/VOIs/meta/Power2013_MNI_VOIs.tsv +264 -0
  36. junifer/data/__init__.py +4 -0
  37. junifer/data/coordinates.py +298 -31
  38. junifer/data/masks.py +360 -28
  39. junifer/data/parcellations.py +621 -188
  40. junifer/data/template_spaces.py +190 -0
  41. junifer/data/tests/test_coordinates.py +34 -3
  42. junifer/data/tests/test_data_utils.py +1 -0
  43. junifer/data/tests/test_masks.py +202 -86
  44. junifer/data/tests/test_parcellations.py +266 -55
  45. junifer/data/tests/test_template_spaces.py +104 -0
  46. junifer/data/utils.py +4 -2
  47. junifer/datagrabber/__init__.py +1 -0
  48. junifer/datagrabber/aomic/id1000.py +111 -70
  49. junifer/datagrabber/aomic/piop1.py +116 -53
  50. junifer/datagrabber/aomic/piop2.py +116 -53
  51. junifer/datagrabber/aomic/tests/test_id1000.py +27 -27
  52. junifer/datagrabber/aomic/tests/test_piop1.py +27 -27
  53. junifer/datagrabber/aomic/tests/test_piop2.py +27 -27
  54. junifer/datagrabber/base.py +62 -10
  55. junifer/datagrabber/datalad_base.py +0 -2
  56. junifer/datagrabber/dmcc13_benchmark.py +372 -0
  57. junifer/datagrabber/hcp1200/datalad_hcp1200.py +5 -0
  58. junifer/datagrabber/hcp1200/hcp1200.py +30 -13
  59. junifer/datagrabber/pattern.py +133 -27
  60. junifer/datagrabber/pattern_datalad.py +111 -13
  61. junifer/datagrabber/tests/test_base.py +57 -6
  62. junifer/datagrabber/tests/test_datagrabber_utils.py +204 -76
  63. junifer/datagrabber/tests/test_datalad_base.py +0 -6
  64. junifer/datagrabber/tests/test_dmcc13_benchmark.py +256 -0
  65. junifer/datagrabber/tests/test_multiple.py +43 -10
  66. junifer/datagrabber/tests/test_pattern.py +125 -178
  67. junifer/datagrabber/tests/test_pattern_datalad.py +44 -25
  68. junifer/datagrabber/utils.py +151 -16
  69. junifer/datareader/default.py +36 -10
  70. junifer/external/nilearn/junifer_nifti_spheres_masker.py +6 -0
  71. junifer/markers/base.py +25 -16
  72. junifer/markers/collection.py +35 -16
  73. junifer/markers/complexity/__init__.py +27 -0
  74. junifer/markers/complexity/complexity_base.py +149 -0
  75. junifer/markers/complexity/hurst_exponent.py +136 -0
  76. junifer/markers/complexity/multiscale_entropy_auc.py +140 -0
  77. junifer/markers/complexity/perm_entropy.py +132 -0
  78. junifer/markers/complexity/range_entropy.py +136 -0
  79. junifer/markers/complexity/range_entropy_auc.py +145 -0
  80. junifer/markers/complexity/sample_entropy.py +134 -0
  81. junifer/markers/complexity/tests/test_complexity_base.py +19 -0
  82. junifer/markers/complexity/tests/test_hurst_exponent.py +69 -0
  83. junifer/markers/complexity/tests/test_multiscale_entropy_auc.py +68 -0
  84. junifer/markers/complexity/tests/test_perm_entropy.py +68 -0
  85. junifer/markers/complexity/tests/test_range_entropy.py +69 -0
  86. junifer/markers/complexity/tests/test_range_entropy_auc.py +69 -0
  87. junifer/markers/complexity/tests/test_sample_entropy.py +68 -0
  88. junifer/markers/complexity/tests/test_weighted_perm_entropy.py +68 -0
  89. junifer/markers/complexity/weighted_perm_entropy.py +133 -0
  90. junifer/markers/falff/_afni_falff.py +153 -0
  91. junifer/markers/falff/_junifer_falff.py +142 -0
  92. junifer/markers/falff/falff_base.py +91 -84
  93. junifer/markers/falff/falff_parcels.py +61 -45
  94. junifer/markers/falff/falff_spheres.py +64 -48
  95. junifer/markers/falff/tests/test_falff_parcels.py +89 -121
  96. junifer/markers/falff/tests/test_falff_spheres.py +92 -127
  97. junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +1 -0
  98. junifer/markers/functional_connectivity/edge_functional_connectivity_parcels.py +1 -0
  99. junifer/markers/functional_connectivity/functional_connectivity_base.py +1 -0
  100. junifer/markers/functional_connectivity/tests/test_crossparcellation_functional_connectivity.py +46 -44
  101. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_parcels.py +34 -39
  102. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_spheres.py +40 -52
  103. junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +62 -70
  104. junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +99 -85
  105. junifer/markers/parcel_aggregation.py +60 -38
  106. junifer/markers/reho/_afni_reho.py +192 -0
  107. junifer/markers/reho/_junifer_reho.py +281 -0
  108. junifer/markers/reho/reho_base.py +69 -34
  109. junifer/markers/reho/reho_parcels.py +26 -16
  110. junifer/markers/reho/reho_spheres.py +23 -9
  111. junifer/markers/reho/tests/test_reho_parcels.py +93 -92
  112. junifer/markers/reho/tests/test_reho_spheres.py +88 -86
  113. junifer/markers/sphere_aggregation.py +54 -9
  114. junifer/markers/temporal_snr/temporal_snr_base.py +1 -0
  115. junifer/markers/temporal_snr/tests/test_temporal_snr_parcels.py +38 -37
  116. junifer/markers/temporal_snr/tests/test_temporal_snr_spheres.py +34 -38
  117. junifer/markers/tests/test_collection.py +43 -42
  118. junifer/markers/tests/test_ets_rss.py +29 -37
  119. junifer/markers/tests/test_parcel_aggregation.py +587 -468
  120. junifer/markers/tests/test_sphere_aggregation.py +209 -157
  121. junifer/markers/utils.py +2 -40
  122. junifer/onthefly/read_transform.py +13 -6
  123. junifer/pipeline/__init__.py +1 -0
  124. junifer/pipeline/pipeline_step_mixin.py +105 -41
  125. junifer/pipeline/registry.py +17 -0
  126. junifer/pipeline/singleton.py +45 -0
  127. junifer/pipeline/tests/test_pipeline_step_mixin.py +139 -51
  128. junifer/pipeline/tests/test_update_meta_mixin.py +1 -0
  129. junifer/pipeline/tests/test_workdir_manager.py +104 -0
  130. junifer/pipeline/update_meta_mixin.py +8 -2
  131. junifer/pipeline/utils.py +154 -15
  132. junifer/pipeline/workdir_manager.py +246 -0
  133. junifer/preprocess/__init__.py +3 -0
  134. junifer/preprocess/ants/__init__.py +4 -0
  135. junifer/preprocess/ants/ants_apply_transforms_warper.py +185 -0
  136. junifer/preprocess/ants/tests/test_ants_apply_transforms_warper.py +56 -0
  137. junifer/preprocess/base.py +96 -69
  138. junifer/preprocess/bold_warper.py +265 -0
  139. junifer/preprocess/confounds/fmriprep_confound_remover.py +91 -134
  140. junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +106 -111
  141. junifer/preprocess/fsl/__init__.py +4 -0
  142. junifer/preprocess/fsl/apply_warper.py +179 -0
  143. junifer/preprocess/fsl/tests/test_apply_warper.py +45 -0
  144. junifer/preprocess/tests/test_bold_warper.py +159 -0
  145. junifer/preprocess/tests/test_preprocess_base.py +6 -6
  146. junifer/preprocess/warping/__init__.py +6 -0
  147. junifer/preprocess/warping/_ants_warper.py +167 -0
  148. junifer/preprocess/warping/_fsl_warper.py +109 -0
  149. junifer/preprocess/warping/space_warper.py +213 -0
  150. junifer/preprocess/warping/tests/test_space_warper.py +198 -0
  151. junifer/stats.py +18 -4
  152. junifer/storage/base.py +9 -1
  153. junifer/storage/hdf5.py +8 -3
  154. junifer/storage/pandas_base.py +2 -1
  155. junifer/storage/sqlite.py +1 -0
  156. junifer/storage/tests/test_hdf5.py +2 -1
  157. junifer/storage/tests/test_sqlite.py +8 -8
  158. junifer/storage/tests/test_utils.py +6 -6
  159. junifer/storage/utils.py +1 -0
  160. junifer/testing/datagrabbers.py +11 -7
  161. junifer/testing/utils.py +1 -0
  162. junifer/tests/test_stats.py +2 -0
  163. junifer/utils/__init__.py +1 -0
  164. junifer/utils/helpers.py +53 -0
  165. junifer/utils/logging.py +14 -3
  166. junifer/utils/tests/test_helpers.py +35 -0
  167. {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/METADATA +59 -28
  168. junifer-0.0.4.dist-info/RECORD +257 -0
  169. {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/WHEEL +1 -1
  170. junifer/markers/falff/falff_estimator.py +0 -334
  171. junifer/markers/falff/tests/test_falff_estimator.py +0 -238
  172. junifer/markers/reho/reho_estimator.py +0 -515
  173. junifer/markers/reho/tests/test_reho_estimator.py +0 -260
  174. junifer-0.0.3.dev186.dist-info/RECORD +0 -199
  175. {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/AUTHORS.rst +0 -0
  176. {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/LICENSE.md +0 -0
  177. {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/entry_points.txt +0 -0
  178. {junifer-0.0.3.dev186.dist-info → junifer-0.0.4.dist-info}/top_level.txt +0 -0
@@ -32,32 +32,50 @@ def test_get_python_information() -> None:
32
32
  def test_get_dependency_information_short() -> None:
33
33
  """Test short version of _get_dependency_information()."""
34
34
  dependency_information = _get_dependency_information(long_=False)
35
- assert list(dependency_information.keys()) == [
35
+ dependency_list = [
36
36
  "click",
37
37
  "numpy",
38
+ "scipy",
38
39
  "datalad",
39
40
  "pandas",
40
41
  "nibabel",
41
42
  "nilearn",
42
43
  "sqlalchemy",
43
44
  "ruamel.yaml",
45
+ "httpx",
46
+ "tqdm",
47
+ "templateflow",
48
+ "looseversion",
44
49
  ]
45
50
 
51
+ python_minor_version = int(pl.python_version_tuple()[1])
52
+ if python_minor_version < 10:
53
+ dependency_list.append("importlib_metadata")
54
+
55
+ assert frozenset(dependency_information.keys()) == frozenset(
56
+ dependency_list
57
+ )
58
+
46
59
 
47
60
  def test_get_dependency_information_long() -> None:
48
61
  """Test long version of _get_dependency_information()."""
49
62
  dependency_information = _get_dependency_information(long_=True)
50
63
  dependency_information_keys = list(dependency_information.keys())
51
- for key in [
64
+ dependency_list = [
52
65
  "click",
53
66
  "numpy",
67
+ "scipy",
54
68
  "datalad",
55
69
  "pandas",
56
70
  "nibabel",
57
71
  "nilearn",
58
72
  "sqlalchemy",
59
73
  "ruamel.yaml",
60
- ]:
74
+ "httpx",
75
+ "tqdm",
76
+ "templateflow",
77
+ ]
78
+ for key in dependency_list:
61
79
  assert key in dependency_information_keys
62
80
 
63
81
 
@@ -5,13 +5,21 @@
5
5
  # License: AGPL
6
6
 
7
7
  from pathlib import Path
8
- from typing import Tuple
8
+ from typing import Callable, List, Tuple
9
9
 
10
10
  import pytest
11
11
  from click.testing import CliRunner
12
12
  from ruamel.yaml import YAML
13
13
 
14
- from junifer.api.cli import collect, run, selftest, wtf
14
+ from junifer.api.cli import (
15
+ _parse_elements_file,
16
+ collect,
17
+ queue,
18
+ reset,
19
+ run,
20
+ selftest,
21
+ wtf,
22
+ )
15
23
 
16
24
 
17
25
  # Configure YAML class
@@ -35,18 +43,24 @@ runner = CliRunner()
35
43
  def test_run_and_collect_commands(
36
44
  tmp_path: Path, elements: Tuple[str, ...]
37
45
  ) -> None:
38
- """Test run and collect commands."""
46
+ """Test run and collect commands.
47
+
48
+ Parameters
49
+ ----------
50
+ tmp_path : pathlib.Path
51
+ The path to the test directory.
52
+ elements : tuple of str
53
+ The parametrized elements to operate on.
54
+
55
+ """
39
56
  # Get test config
40
- infile = Path(__file__).parent / "data" / "gmd_mean.yaml"
57
+ infile = Path(__file__).parent / "data" / "partly_cloudy_agg_mean_tian.yml"
41
58
  # Read test config
42
59
  contents = yaml.load(infile)
43
60
  # Working directory
44
- workdir = tmp_path / "workdir"
45
- contents["workdir"] = str(workdir.resolve())
46
- # Output directory
47
- outdir = tmp_path / "outdir"
61
+ contents["workdir"] = str(tmp_path.resolve())
48
62
  # Storage
49
- contents["storage"]["uri"] = str(outdir.resolve())
63
+ contents["storage"]["uri"] = str((tmp_path / "out.hdf5").resolve())
50
64
  # Write new test config
51
65
  outfile = tmp_path / "in.yaml"
52
66
  yaml.dump(contents, stream=outfile)
@@ -74,6 +88,215 @@ def test_run_and_collect_commands(
74
88
  assert collect_result.exit_code == 0
75
89
 
76
90
 
91
+ @pytest.mark.parametrize(
92
+ "elements",
93
+ [
94
+ "sub-01",
95
+ "sub-01\nsub-02",
96
+ " sub-01 ",
97
+ "sub-01\n sub-02",
98
+ ],
99
+ )
100
+ def test_run_using_element_file(tmp_path: Path, elements: str) -> None:
101
+ """Test run command using element file.
102
+
103
+ Parameters
104
+ ----------
105
+ tmp_path : pathlib.Path
106
+ The path to the test directory.
107
+ elements : str
108
+ The parametrized elements to write to the element file.
109
+
110
+ """
111
+ # Create test file
112
+ test_file_path = tmp_path / "elements.txt"
113
+ with open(test_file_path, "w") as f:
114
+ f.write(elements)
115
+
116
+ # Get test config
117
+ infile = Path(__file__).parent / "data" / "partly_cloudy_agg_mean_tian.yml"
118
+ # Read test config
119
+ contents = yaml.load(infile)
120
+ # Working directory
121
+ contents["workdir"] = str(tmp_path.resolve())
122
+ # Storage
123
+ contents["storage"]["uri"] = str((tmp_path / "out.hdf5").resolve())
124
+ # Write new test config
125
+ outfile = tmp_path / "in.yaml"
126
+ yaml.dump(contents, stream=outfile)
127
+ # Run command arguments
128
+ run_args = [
129
+ str(outfile.absolute()),
130
+ "--verbose",
131
+ "debug",
132
+ "--element",
133
+ str(test_file_path.resolve()),
134
+ ]
135
+ # Invoke run command
136
+ run_result = runner.invoke(run, run_args)
137
+ # Check
138
+ assert run_result.exit_code == 0
139
+
140
+
141
+ @pytest.mark.parametrize(
142
+ "elements, expected_list",
143
+ [
144
+ ("sub-01,ses-01", [("sub-01", "ses-01")]),
145
+ (
146
+ "sub-01,ses-01\nsub-02,ses-01",
147
+ [("sub-01", "ses-01"), ("sub-02", "ses-01")],
148
+ ),
149
+ ("sub-01, ses-01", [("sub-01", "ses-01")]),
150
+ (
151
+ "sub-01, ses-01\nsub-02, ses-01",
152
+ [("sub-01", "ses-01"), ("sub-02", "ses-01")],
153
+ ),
154
+ (" sub-01 , ses-01 ", [("sub-01", "ses-01")]),
155
+ (
156
+ " sub-01 , ses-01 \n sub-02, ses-01 ",
157
+ [("sub-01", "ses-01"), ("sub-02", "ses-01")],
158
+ ),
159
+ ("001,01", [("001", "01")]),
160
+ (
161
+ "001,01\n002,02",
162
+ [("001", "01"), ("002", "02")],
163
+ ),
164
+ ("001, 01", [("001", "01")]),
165
+ (
166
+ "001, 01\n002, 02",
167
+ [("001", "01"), ("002", "02")],
168
+ ),
169
+ (" 001 , 01 ", [("001", "01")]),
170
+ (
171
+ " 001 , 01 \n 002, 02 ",
172
+ [("001", "01"), ("002", "02")],
173
+ ),
174
+ ],
175
+ )
176
+ def test_multi_element_access(
177
+ tmp_path: Path, elements: str, expected_list: List[Tuple[str, ...]]
178
+ ) -> None:
179
+ """Test mulit-element parsing.
180
+
181
+ Parameters
182
+ ----------
183
+ tmp_path : pathlib.Path
184
+ The path to the test directory.
185
+ elements : str
186
+ The parametrized elements to write to the element file.
187
+ expected_list : list of tuple of str
188
+ The parametrized list of element tuples to expect.
189
+
190
+ """
191
+ # Create test file
192
+ test_file_path = tmp_path / "elements_multi.txt"
193
+ with open(test_file_path, "w") as f:
194
+ f.write(elements)
195
+ # Load element file
196
+ read_elements = _parse_elements_file(test_file_path)
197
+ # Check
198
+ assert read_elements == expected_list
199
+
200
+
201
+ def test_queue(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
202
+ """Test queue command.
203
+
204
+ Parameters
205
+ ----------
206
+ tmp_path : pathlib.Path
207
+ The path to the test directory.
208
+ monkeypatch : pytest.MonkeyPatch
209
+ The pytest.MonkeyPatch object.
210
+
211
+ """
212
+ with monkeypatch.context() as m:
213
+ m.chdir(tmp_path)
214
+ # Get test config
215
+ infile = Path(__file__).parent / "data" / "gmd_mean_htcondor.yaml"
216
+ # Read test config
217
+ contents = yaml.load(infile)
218
+ # Working directory
219
+ contents["workdir"] = str(tmp_path.resolve())
220
+ # Storage
221
+ contents["storage"]["uri"] = str((tmp_path / "out.sqlite").resolve())
222
+ # Write new test config
223
+ outfile = tmp_path / "in.yaml"
224
+ yaml.dump(contents, stream=outfile)
225
+ # Queue command arguments
226
+ queue_args = [
227
+ str(outfile.resolve()),
228
+ "--verbose",
229
+ "debug",
230
+ ]
231
+ # Invoke queue command
232
+ queue_result = runner.invoke(queue, queue_args)
233
+ # Check
234
+ assert queue_result.exit_code == 0
235
+
236
+
237
+ @pytest.mark.parametrize(
238
+ "action, action_file",
239
+ [
240
+ (run, "partly_cloudy_agg_mean_tian.yml"),
241
+ (queue, "gmd_mean_htcondor.yaml"),
242
+ ],
243
+ )
244
+ def test_reset(
245
+ tmp_path: Path,
246
+ monkeypatch: pytest.MonkeyPatch,
247
+ action: Callable,
248
+ action_file: str,
249
+ ) -> None:
250
+ """Test reset command.
251
+
252
+ Parameters
253
+ ----------
254
+ tmp_path : pathlib.Path
255
+ The path to the test directory.
256
+ monkeypatch : pytest.MonkeyPatch
257
+ The pytest.MonkeyPatch object.
258
+ action : callable
259
+ The parametrized action to perform.
260
+ action_file : str
261
+ The parametrized file for the action.
262
+
263
+ """
264
+ with monkeypatch.context() as m:
265
+ m.chdir(tmp_path)
266
+ # Get test config
267
+ infile = Path(__file__).parent / "data" / action_file
268
+ # Read test config
269
+ contents = yaml.load(infile)
270
+ # Working directory
271
+ contents["workdir"] = str(tmp_path.resolve())
272
+ # Storage
273
+ contents["storage"]["uri"] = str((tmp_path / "out.sqlite").resolve())
274
+ # Write new test config
275
+ outfile = tmp_path / "in.yaml"
276
+ yaml.dump(contents, stream=outfile)
277
+ # Command arguments
278
+ action_args = [
279
+ str(outfile.resolve()),
280
+ "--verbose",
281
+ "debug",
282
+ ]
283
+ # Invoke command
284
+ result = runner.invoke(action, action_args)
285
+ # Check
286
+ assert result.exit_code == 0
287
+
288
+ # Reset arguments
289
+ reset_args = [
290
+ str(outfile.resolve()),
291
+ "--verbose",
292
+ "debug",
293
+ ]
294
+ # Run reset
295
+ reset_result = runner.invoke(reset, reset_args)
296
+ # Check
297
+ assert reset_result.exit_code == 0
298
+
299
+
77
300
  def test_wtf_short() -> None:
78
301
  """Test short version of wtf command."""
79
302
  # Invoke wtf command