junifer 0.0.6.dev380__py3-none-any.whl → 0.0.6.dev389__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
junifer/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.0.6.dev380'
16
- __version_tuple__ = version_tuple = (0, 0, 6, 'dev380')
15
+ __version__ = version = '0.0.6.dev389'
16
+ __version_tuple__ = version_tuple = (0, 0, 6, 'dev389')
junifer/api/functions.py CHANGED
@@ -20,7 +20,13 @@ from ..pipeline import (
20
20
  )
21
21
  from ..preprocess import BasePreprocessor
22
22
  from ..storage import BaseFeatureStorage
23
- from ..typing import DataGrabberLike, MarkerLike, PreprocessorLike, StorageLike
23
+ from ..typing import (
24
+ DataGrabberLike,
25
+ Elements,
26
+ MarkerLike,
27
+ PreprocessorLike,
28
+ StorageLike,
29
+ )
24
30
  from ..utils import logger, raise_error, warn_with_log, yaml
25
31
 
26
32
 
@@ -121,7 +127,7 @@ def run(
121
127
  markers: list[dict],
122
128
  storage: dict,
123
129
  preprocessors: Optional[list[dict]] = None,
124
- elements: Optional[list[tuple[str, ...]]] = None,
130
+ elements: Optional[Elements] = None,
125
131
  ) -> None:
126
132
  """Run the pipeline on the selected element.
127
133
 
@@ -147,7 +153,7 @@ def run(
147
153
  List of preprocessors to use. Each preprocessor is a dict with at
148
154
  least a key ``kind`` specifying the preprocessor to use. All other keys
149
155
  are passed to the preprocessor constructor (default None).
150
- elements : list of tuple or None, optional
156
+ elements : list or None, optional
151
157
  Element(s) to process. Will be used to index the DataGrabber
152
158
  (default None).
153
159
 
@@ -155,6 +161,8 @@ def run(
155
161
  ------
156
162
  ValueError
157
163
  If ``workdir.cleanup=False`` when ``len(elements) > 1``.
164
+ RuntimeError
165
+ If invalid element selectors are found.
158
166
 
159
167
  """
160
168
  # Conditional to handle workdir config
@@ -208,10 +216,22 @@ def run(
208
216
  # Fit elements
209
217
  with datagrabber_object:
210
218
  if elements is not None:
211
- for t_element in datagrabber_object.filter(
212
- elements # type: ignore
213
- ):
219
+ # Keep track of valid selectors
220
+ valid_elements = []
221
+ for t_element in datagrabber_object.filter(elements):
222
+ valid_elements.append(t_element)
214
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
+ )
215
235
  else:
216
236
  for t_element in datagrabber_object:
217
237
  mc.fit(datagrabber_object[t_element])
@@ -243,7 +263,7 @@ def queue(
243
263
  kind: str,
244
264
  jobname: str = "junifer_job",
245
265
  overwrite: bool = False,
246
- elements: Optional[list[tuple[str, ...]]] = None,
266
+ elements: Optional[Elements] = None,
247
267
  **kwargs: Union[str, int, bool, dict, tuple, list],
248
268
  ) -> None:
249
269
  """Queue a job to be executed later.
@@ -258,7 +278,7 @@ def queue(
258
278
  The name of the job (default "junifer_job").
259
279
  overwrite : bool, optional
260
280
  Whether to overwrite if job directory already exists (default False).
261
- elements : list of tuple or None, optional
281
+ elements : list or None, optional
262
282
  Element(s) to process. Will be used to index the DataGrabber
263
283
  (default None).
264
284
  **kwargs : dict
@@ -341,7 +361,7 @@ def queue(
341
361
  elements = dg.get_elements()
342
362
  # Listify elements
343
363
  if not isinstance(elements, list):
344
- elements: list[Union[str, tuple]] = [elements]
364
+ elements: Elements = [elements]
345
365
 
346
366
  # Check job queueing system
347
367
  adapter = None
@@ -406,7 +426,7 @@ def reset(config: dict) -> None:
406
426
 
407
427
  def list_elements(
408
428
  datagrabber: dict,
409
- elements: Optional[list[tuple[str, ...]]] = None,
429
+ elements: Optional[Elements] = None,
410
430
  ) -> str:
411
431
  """List elements of the datagrabber filtered using `elements`.
412
432
 
@@ -416,7 +436,7 @@ def list_elements(
416
436
  DataGrabber to index. Must have a key ``kind`` with the kind of
417
437
  DataGrabber to use. All other keys are passed to the DataGrabber
418
438
  constructor.
419
- elements : list of tuple or None, optional
439
+ elements : list or None, optional
420
440
  Element(s) to filter using. Will be used to index the DataGrabber
421
441
  (default None).
422
442
 
@@ -6,8 +6,9 @@
6
6
  import shutil
7
7
  import textwrap
8
8
  from pathlib import Path
9
- from typing import Optional, Union
9
+ from typing import Optional
10
10
 
11
+ from ...typing import Elements
11
12
  from ...utils import logger, make_executable, raise_error, run_ext_cmd
12
13
  from .queue_context_adapter import QueueContextAdapter
13
14
 
@@ -63,7 +64,7 @@ class GnuParallelLocalAdapter(QueueContextAdapter):
63
64
  job_name: str,
64
65
  job_dir: Path,
65
66
  yaml_config_path: Path,
66
- elements: list[Union[str, tuple]],
67
+ elements: Elements,
67
68
  pre_run: Optional[str] = None,
68
69
  pre_collect: Optional[str] = None,
69
70
  env: Optional[dict[str, str]] = None,
@@ -6,8 +6,9 @@
6
6
  import shutil
7
7
  import textwrap
8
8
  from pathlib import Path
9
- from typing import Optional, Union
9
+ from typing import Optional
10
10
 
11
+ from ...typing import Elements
11
12
  from ...utils import logger, make_executable, raise_error, run_ext_cmd
12
13
  from .queue_context_adapter import QueueContextAdapter
13
14
 
@@ -81,7 +82,7 @@ class HTCondorAdapter(QueueContextAdapter):
81
82
  job_name: str,
82
83
  job_dir: Path,
83
84
  yaml_config_path: Path,
84
- elements: list[Union[str, tuple]],
85
+ elements: Elements,
85
86
  pre_run: Optional[str] = None,
86
87
  pre_collect: Optional[str] = None,
87
88
  env: Optional[dict[str, str]] = None,
@@ -6,16 +6,19 @@
6
6
  # License: AGPL
7
7
 
8
8
  import logging
9
+ from contextlib import AbstractContextManager, nullcontext
9
10
  from pathlib import Path
10
- from typing import Optional, Union
11
+ from typing import Any, Optional, Union
11
12
 
12
13
  import pytest
14
+ from nibabel.filebasedimages import ImageFileError
13
15
  from ruamel.yaml import YAML
14
16
 
15
17
  import junifer.testing.registry # noqa: F401
16
18
  from junifer.api import collect, list_elements, queue, reset, run
17
19
  from junifer.datagrabber.base import BaseDataGrabber
18
20
  from junifer.pipeline import PipelineComponentRegistry
21
+ from junifer.typing import Elements
19
22
 
20
23
 
21
24
  # Configure YAML class
@@ -25,12 +28,37 @@ yaml.allow_unicode = True
25
28
  yaml.indent(mapping=2, sequence=4, offset=2)
26
29
 
27
30
 
31
+ # Kept for parametrizing
32
+ _datagrabber = {
33
+ "kind": "PartlyCloudyTestingDataGrabber",
34
+ }
35
+ _bids_ses_datagrabber = {
36
+ "kind": "PatternDataladDataGrabber",
37
+ "uri": "https://gin.g-node.org/juaml/datalad-example-bids-ses",
38
+ "types": ["T1w", "BOLD"],
39
+ "patterns": {
40
+ "T1w": {
41
+ "pattern": (
42
+ "{subject}/{session}/anat/{subject}_{session}_T1w.nii.gz"
43
+ ),
44
+ "space": "MNI152NLin6Asym",
45
+ },
46
+ "BOLD": {
47
+ "pattern": (
48
+ "{subject}/{session}/func/{subject}_{session}_task-rest_bold.nii.gz"
49
+ ),
50
+ "space": "MNI152NLin6Asym",
51
+ },
52
+ },
53
+ "replacements": ["subject", "session"],
54
+ "rootdir": "example_bids_ses",
55
+ }
56
+
57
+
28
58
  @pytest.fixture
29
59
  def datagrabber() -> dict[str, str]:
30
60
  """Return a datagrabber as a dictionary."""
31
- return {
32
- "kind": "PartlyCloudyTestingDataGrabber",
33
- }
61
+ return _datagrabber.copy()
34
62
 
35
63
 
36
64
  @pytest.fixture
@@ -60,11 +88,48 @@ def storage() -> dict[str, str]:
60
88
  }
61
89
 
62
90
 
91
+ @pytest.mark.parametrize(
92
+ "datagrabber, element, expect",
93
+ [
94
+ (
95
+ _datagrabber,
96
+ [("sub-01",)],
97
+ pytest.raises(RuntimeError, match="element selectors are invalid"),
98
+ ),
99
+ (
100
+ _datagrabber,
101
+ ["sub-01"],
102
+ nullcontext(),
103
+ ),
104
+ (
105
+ _bids_ses_datagrabber,
106
+ ["sub-01"],
107
+ pytest.raises(ImageFileError, match="is not a gzip file"),
108
+ ),
109
+ (
110
+ _bids_ses_datagrabber,
111
+ [("sub-01", "ses-01")],
112
+ pytest.raises(ImageFileError, match="is not a gzip file"),
113
+ ),
114
+ (
115
+ _bids_ses_datagrabber,
116
+ [("sub-01", "ses-100")],
117
+ pytest.raises(RuntimeError, match="element selectors are invalid"),
118
+ ),
119
+ (
120
+ _bids_ses_datagrabber,
121
+ [("sub-100", "ses-01")],
122
+ pytest.raises(RuntimeError, match="element selectors are invalid"),
123
+ ),
124
+ ],
125
+ )
63
126
  def test_run_single_element(
64
127
  tmp_path: Path,
65
- datagrabber: dict[str, str],
128
+ datagrabber: dict[str, Any],
66
129
  markers: list[dict[str, str]],
67
130
  storage: dict[str, str],
131
+ element: Elements,
132
+ expect: AbstractContextManager,
68
133
  ) -> None:
69
134
  """Test run function with single element.
70
135
 
@@ -78,21 +143,26 @@ def test_run_single_element(
78
143
  Testing markers as list of dictionary.
79
144
  storage : dict
80
145
  Testing storage as dictionary.
146
+ element : list of str or tuple
147
+ The parametrized element.
148
+ expect : typing.ContextManager
149
+ The parametrized ContextManager object.
81
150
 
82
151
  """
83
152
  # Set storage
84
153
  storage["uri"] = str((tmp_path / "out.sqlite").resolve())
85
154
  # Run operations
86
- run(
87
- workdir=tmp_path,
88
- datagrabber=datagrabber,
89
- markers=markers,
90
- storage=storage,
91
- elements=[("sub-01",)],
92
- )
93
- # Check files
94
- files = list(tmp_path.glob("*.sqlite"))
95
- assert len(files) == 1
155
+ with expect:
156
+ run(
157
+ workdir=tmp_path,
158
+ datagrabber=datagrabber,
159
+ markers=markers,
160
+ storage=storage,
161
+ elements=element,
162
+ )
163
+ # Check files
164
+ files = list(tmp_path.glob("*.sqlite"))
165
+ assert len(files) == 1
96
166
 
97
167
 
98
168
  def test_run_single_element_with_preprocessing(
@@ -128,18 +198,30 @@ def test_run_single_element_with_preprocessing(
128
198
  "kind": "fMRIPrepConfoundRemover",
129
199
  }
130
200
  ],
131
- elements=[("sub-01",)],
201
+ elements=["sub-01"],
132
202
  )
133
203
  # Check files
134
204
  files = list(tmp_path.glob("*.sqlite"))
135
205
  assert len(files) == 1
136
206
 
137
207
 
208
+ @pytest.mark.parametrize(
209
+ "element, expect",
210
+ [
211
+ (
212
+ [("sub-01",), ("sub-03",)],
213
+ pytest.raises(RuntimeError, match="element selectors are invalid"),
214
+ ),
215
+ (["sub-01", "sub-03"], nullcontext()),
216
+ ],
217
+ )
138
218
  def test_run_multi_element_multi_output(
139
219
  tmp_path: Path,
140
220
  datagrabber: dict[str, str],
141
221
  markers: list[dict[str, str]],
142
222
  storage: dict[str, str],
223
+ element: Elements,
224
+ expect: AbstractContextManager,
143
225
  ) -> None:
144
226
  """Test run function with multi element and multi output.
145
227
 
@@ -153,22 +235,27 @@ def test_run_multi_element_multi_output(
153
235
  Testing markers as list of dictionary.
154
236
  storage : dict
155
237
  Testing storage as dictionary.
238
+ element : list of str or tuple
239
+ The parametrized element.
240
+ expect : typing.ContextManager
241
+ The parametrized ContextManager object.
156
242
 
157
243
  """
158
244
  # Set storage
159
245
  storage["uri"] = str((tmp_path / "out.sqlite").resolve())
160
246
  storage["single_output"] = False # type: ignore
161
247
  # Run operations
162
- run(
163
- workdir=tmp_path,
164
- datagrabber=datagrabber,
165
- markers=markers,
166
- storage=storage,
167
- elements=[("sub-01",), ("sub-03",)],
168
- )
169
- # Check files
170
- files = list(tmp_path.glob("*.sqlite"))
171
- assert len(files) == 2
248
+ with expect:
249
+ run(
250
+ workdir=tmp_path,
251
+ datagrabber=datagrabber,
252
+ markers=markers,
253
+ storage=storage,
254
+ elements=element,
255
+ )
256
+ # Check files
257
+ files = list(tmp_path.glob("*.sqlite"))
258
+ assert len(files) == 2
172
259
 
173
260
 
174
261
  def test_run_multi_element_single_output(
@@ -200,7 +287,7 @@ def test_run_multi_element_single_output(
200
287
  datagrabber=datagrabber,
201
288
  markers=markers,
202
289
  storage=storage,
203
- elements=[("sub-01",), ("sub-03",)],
290
+ elements=["sub-01", "sub-03"],
204
291
  )
205
292
  # Check files
206
293
  files = list(tmp_path.glob("*.sqlite"))
@@ -569,7 +656,7 @@ def test_reset_run(
569
656
  datagrabber=datagrabber,
570
657
  markers=markers,
571
658
  storage=storage,
572
- elements=[("sub-01",)],
659
+ elements=["sub-01"],
573
660
  )
574
661
  # Reset operation
575
662
  reset(config={"storage": storage})
junifer/cli/parser.py CHANGED
@@ -12,6 +12,7 @@ from typing import Union
12
12
 
13
13
  import pandas as pd
14
14
 
15
+ from ..typing import Elements
15
16
  from ..utils import logger, raise_error, warn_with_log, yaml
16
17
 
17
18
 
@@ -142,7 +143,7 @@ def parse_yaml(filepath: Union[str, Path]) -> dict: # noqa: C901
142
143
 
143
144
  def parse_elements(
144
145
  element: tuple[str, ...], config: dict
145
- ) -> Union[list[tuple[str, ...]], None]:
146
+ ) -> Union[Elements, None]:
146
147
  """Parse elements from cli.
147
148
 
148
149
  Parameters
@@ -203,7 +204,7 @@ def parse_elements(
203
204
  return elements
204
205
 
205
206
 
206
- def _parse_elements_file(filepath: Path) -> list[tuple[str, ...]]:
207
+ def _parse_elements_file(filepath: Path) -> Elements:
207
208
  """Parse elements from file.
208
209
 
209
210
  Parameters
@@ -213,7 +214,7 @@ def _parse_elements_file(filepath: Path) -> list[tuple[str, ...]]:
213
214
 
214
215
  Returns
215
216
  -------
216
- list of tuple of str
217
+ list
217
218
  The element(s) as list.
218
219
 
219
220
  """
@@ -227,5 +228,8 @@ def _parse_elements_file(filepath: Path) -> list[tuple[str, ...]]:
227
228
  )
228
229
  # Remove trailing whitespace in cell entries
229
230
  csv_df_trimmed = csv_df.apply(lambda x: x.str.strip())
230
- # Convert to list of tuple of str
231
- return list(map(tuple, csv_df_trimmed.to_numpy()))
231
+ # Convert to list of tuple of str if more than one column else flatten
232
+ if len(csv_df_trimmed.columns) == 1:
233
+ return csv_df_trimmed.to_numpy().flatten().tolist()
234
+ else:
235
+ return list(map(tuple, csv_df_trimmed.to_numpy()))
@@ -11,6 +11,7 @@ from pathlib import Path
11
11
  from typing import Union
12
12
 
13
13
  from ..pipeline import UpdateMetaMixin
14
+ from ..typing import Element, Elements
14
15
  from ..utils import logger, raise_error
15
16
 
16
17
 
@@ -67,9 +68,7 @@ class BaseDataGrabber(ABC, UpdateMetaMixin):
67
68
  """
68
69
  yield from self.get_elements()
69
70
 
70
- def __getitem__(
71
- self, element: Union[str, tuple[str, ...]]
72
- ) -> dict[str, dict]:
71
+ def __getitem__(self, element: Element) -> dict[str, dict]:
73
72
  """Enable indexing support.
74
73
 
75
74
  Parameters
@@ -137,13 +136,13 @@ class BaseDataGrabber(ABC, UpdateMetaMixin):
137
136
  """
138
137
  return self._datadir
139
138
 
140
- def filter(self, selection: list[Union[str, tuple[str]]]) -> Iterator:
139
+ def filter(self, selection: Elements) -> Iterator:
141
140
  """Filter elements to be grabbed.
142
141
 
143
142
  Parameters
144
143
  ----------
145
- selection : list of str or tuple
146
- The list of partial element key values to filter using.
144
+ selection : list
145
+ The list of partial or complete element selectors to filter using.
147
146
 
148
147
  Yields
149
148
  ------
@@ -152,7 +151,7 @@ class BaseDataGrabber(ABC, UpdateMetaMixin):
152
151
 
153
152
  """
154
153
 
155
- def filter_func(element: Union[str, tuple[str]]) -> bool:
154
+ def filter_func(element: Element) -> bool:
156
155
  """Filter element based on selection.
157
156
 
158
157
  Parameters
@@ -201,15 +200,14 @@ class BaseDataGrabber(ABC, UpdateMetaMixin):
201
200
  ) # pragma: no cover
202
201
 
203
202
  @abstractmethod
204
- def get_elements(self) -> list[Union[str, tuple[str]]]:
203
+ def get_elements(self) -> Elements:
205
204
  """Get elements.
206
205
 
207
206
  Returns
208
207
  -------
209
208
  list
210
- List of elements that can be grabbed. The elements can be strings,
211
- tuples or any object that will be then used as a key to index the
212
- DataGrabber.
209
+ List of elements that can be grabbed. The elements can be strings
210
+ or tuples of strings to index the DataGrabber.
213
211
 
214
212
  """
215
213
  raise_error(
@@ -17,6 +17,7 @@ from datalad.support.exceptions import IncompleteResultsError
17
17
  from datalad.support.gitrepo import GitRepo
18
18
 
19
19
  from ..pipeline import WorkDirManager
20
+ from ..typing import Element
20
21
  from ..utils import config, logger, raise_error, warn_with_log
21
22
  from .base import BaseDataGrabber
22
23
 
@@ -312,7 +313,7 @@ class DataladDataGrabber(BaseDataGrabber):
312
313
  logger.debug(f"Dropping {f}")
313
314
  self._dataset.drop(f, result_renderer="disabled")
314
315
 
315
- def __getitem__(self, element: Union[str, tuple]) -> dict:
316
+ def __getitem__(self, element: Element) -> dict:
316
317
  """Implement single element indexing in the Datalad database.
317
318
 
318
319
  It will first obtain the paths from the parent class and then
@@ -320,11 +321,11 @@ class DataladDataGrabber(BaseDataGrabber):
320
321
 
321
322
  Parameters
322
323
  ----------
323
- element : str or tuple
324
+ element : str or tuple of str
324
325
  The element to be indexed. If one string is provided, it is
325
326
  assumed to be a tuple with only one item. If a tuple is provided,
326
327
  each item in the tuple is the value for the replacement string
327
- specified in "replacements".
328
+ specified in ``"replacements"``.
328
329
 
329
330
  Returns
330
331
  -------
@@ -13,7 +13,7 @@ from typing import Optional, Union
13
13
  import numpy as np
14
14
 
15
15
  from ..api.decorators import register_datagrabber
16
- from ..typing import DataGrabberPatterns
16
+ from ..typing import DataGrabberPatterns, Elements
17
17
  from ..utils import logger, raise_error
18
18
  from .base import BaseDataGrabber
19
19
  from .pattern_validation_mixin import PatternValidationMixin
@@ -367,7 +367,7 @@ class PatternDataGrabber(BaseDataGrabber, PatternValidationMixin):
367
367
  """
368
368
  return self.replacements
369
369
 
370
- def get_item(self, **element: str) -> dict[str, dict]:
370
+ def get_item(self, **element: dict) -> dict[str, dict]:
371
371
  """Implement single element indexing for the datagrabber.
372
372
 
373
373
  This method constructs a real path to the requested item's data, by
@@ -450,7 +450,7 @@ class PatternDataGrabber(BaseDataGrabber, PatternValidationMixin):
450
450
 
451
451
  return out
452
452
 
453
- def get_elements(self) -> list:
453
+ def get_elements(self) -> Elements:
454
454
  """Implement fetching list of elements in the dataset.
455
455
 
456
456
  It will use regex to search for "replacements" in the "patterns" and
@@ -10,6 +10,8 @@ __all__ = [
10
10
  "MarkerInOutMappings",
11
11
  "DataGrabberPatterns",
12
12
  "ConfigVal",
13
+ "Element",
14
+ "Elements",
13
15
  ]
14
16
 
15
17
  from ._typing import (
@@ -24,4 +26,6 @@ from ._typing import (
24
26
  MarkerInOutMappings,
25
27
  DataGrabberPatterns,
26
28
  ConfigVal,
29
+ Element,
30
+ Elements,
27
31
  )
junifer/typing/_typing.py CHANGED
@@ -24,6 +24,8 @@ __all__ = [
24
24
  "DataGrabberLike",
25
25
  "DataGrabberPatterns",
26
26
  "Dependencies",
27
+ "Element",
28
+ "Elements",
27
29
  "ExternalDependencies",
28
30
  "MarkerInOutMappings",
29
31
  "MarkerLike",
@@ -62,3 +64,5 @@ DataGrabberPatterns = dict[
62
64
  str, Union[dict[str, str], Sequence[dict[str, str]]]
63
65
  ]
64
66
  ConfigVal = Union[bool, int, float]
67
+ Element = Union[str, tuple[str, ...]]
68
+ Elements = Sequence[Element]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: junifer
3
- Version: 0.0.6.dev380
3
+ Version: 0.0.6.dev389
4
4
  Summary: JUelich NeuroImaging FEature extractoR
5
5
  Author-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
6
6
  Maintainer-email: Fede Raimondo <f.raimondo@fz-juelich.de>, Synchon Mandal <s.mandal@fz-juelich.de>
@@ -1,18 +1,18 @@
1
1
  junifer/__init__.py,sha256=2McgH1yNue6Z1V26-uN_mfMjbTcx4CLhym-DMBl5xA4,266
2
2
  junifer/__init__.pyi,sha256=SsTvgq2Dod6UqJN96GH1lCphH6hJQQurEJHGNhHjGUI,508
3
- junifer/_version.py,sha256=mYYbSdr8ZZIWyxeI7ZjX_AQPfym-vU4DP9CpIXFD0FE,428
3
+ junifer/_version.py,sha256=X-yXnQlyg2_EwjCw0n4eAgGDkY1QOoPd1RhBaG_xEes,428
4
4
  junifer/conftest.py,sha256=PWYkkRDU8ly2lYwv7VBKMHje4et6HX7Yey3Md_I2KbA,613
5
5
  junifer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  junifer/stats.py,sha256=e9aaagMGtgpRfW3Wdpz9ocpnYld1IWylCDcjFUgX9Mk,6225
7
7
  junifer/api/__init__.py,sha256=aAXW_KAEGQ8aAP5Eni2G1R4MWBF7UgjKOgM6akLuJco,252
8
8
  junifer/api/__init__.pyi,sha256=UJu55ApMFd43N0xlQyNKrYpCdzqhAxA3Jjaj0ETwCXU,169
9
9
  junifer/api/decorators.py,sha256=xphy55NJHnMZnJ-aNA70UzHUJ3SIgh5Xc8ekcozvj3U,2854
10
- junifer/api/functions.py,sha256=Tq1LKoxJuHHylcCFJ6SrPoPriIsnTLdbQ5K6w8gdTE8,13697
10
+ junifer/api/functions.py,sha256=AeOSWA-U_Z18gtFYpFPvhk9Fip_FPWTW2NOMAzNIrQc,14242
11
11
  junifer/api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  junifer/api/queue_context/__init__.py,sha256=glr8x4aMm4EvVrHywDIlugdNlwD1RzqV2FTDNPqYQZ4,204
13
13
  junifer/api/queue_context/__init__.pyi,sha256=LoDQFGZ9wCDmgx5a1_nhKo4zOSvqViXZ8V882DksF7U,246
14
- junifer/api/queue_context/gnu_parallel_local_adapter.py,sha256=hFeLoqqHiB7JXE5cwkVDRX00tjKyK60xAxvE1uO7OOk,10178
15
- junifer/api/queue_context/htcondor_adapter.py,sha256=9TXtPhBsDdGFgkIhtsySFCi4QUjerUXMq5kMHpxNg90,13878
14
+ junifer/api/queue_context/gnu_parallel_local_adapter.py,sha256=3jynHE7dmKUrJN8KfuzUbUokk2ZtriFE5XdpIk1gz8g,10187
15
+ junifer/api/queue_context/htcondor_adapter.py,sha256=5gPlGbuNpfhcWuVB7BhqXqmtoKy2Wm1sAvaD2qOFpzo,13887
16
16
  junifer/api/queue_context/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  junifer/api/queue_context/queue_context_adapter.py,sha256=a6UE8xavDfuaZbkWYsayVs6l-rwIrbpFSpqSyHsEeYY,1577
18
18
  junifer/api/queue_context/tests/test_gnu_parallel_local_adapter.py,sha256=Nv_0axIW4SOE7-TyQXd_nM_0A_kDiFAgrkQcmQafW_s,6585
@@ -40,11 +40,11 @@ junifer/api/res/fsl/flirt,sha256=tSjiUco8ui8AbHD7mTzChEwbR0Rf_4iJTgzYTPF_WuQ,42
40
40
  junifer/api/res/fsl/img2imgcoord,sha256=Zmaw3oJYrEltcXiPyEubXry9ppAq3SND52tdDWGgeZk,49
41
41
  junifer/api/res/fsl/run_fsl_docker.sh,sha256=pq-fcNdLuvHzVIQePN4GebZGlcE2UF-xj5rBIqAMz4g,1122
42
42
  junifer/api/res/fsl/std2imgcoord,sha256=-X5wRH6XMl0yqnTACJX6MFhO8DFOEWg42MHRxGvimXg,49
43
- junifer/api/tests/test_functions.py,sha256=PPkjs_FqjZZgsEa3a81ulzPxLskVh5HmnaG8TaNCwR0,18084
43
+ junifer/api/tests/test_functions.py,sha256=HcJIBCtcgL1xJlDwtGHrGOWBMjXgCoAFoVxQW6n2Tds,20676
44
44
  junifer/cli/__init__.py,sha256=DS3kZKHeVDxt6d1MLBerZ2fcAwrEBHee5JOBhOLajUI,197
45
45
  junifer/cli/__init__.pyi,sha256=PiV4znUnzSeuSSJGz-RT8N21PiMqoSMwYcypi7nt2Js,40
46
46
  junifer/cli/cli.py,sha256=LvtkFMvnxuoviAhs0bki6P4GMda6ZvNsJi4_QF00va8,15691
47
- junifer/cli/parser.py,sha256=ouVnk4NrOmVMNnQDMsqAjt2BaOT05bNJq0LVRsIakXI,8358
47
+ junifer/cli/parser.py,sha256=jLinKVcZeuyTnxjB2p5sj8555DO5rcPcWKgZCtgFARY,8498
48
48
  junifer/cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  junifer/cli/utils.py,sha256=AbPQC0Kl-tHMNKiPxp_01gLAGD3IGoLbsq3rXyPMM-c,3116
50
50
  junifer/cli/tests/test_cli.py,sha256=AYL4my12GmFRCbI3JV7-rju32heYxAqbXNwnV8PwqVY,10982
@@ -122,11 +122,11 @@ junifer/data/tests/test_data_utils.py,sha256=136iGPjGecCxyqgUwU8VZMHoE6imcYJ0WNC
122
122
  junifer/data/tests/test_template_spaces.py,sha256=ZEicEcLqOJ-NpuBZ5SYh4yZ0xZRkhYHnYXiC_YSxjrY,3219
123
123
  junifer/datagrabber/__init__.py,sha256=EHIK-lbjuvkt0V8ypFvLSt85OAAXSkaxBmVlCbNNz8M,323
124
124
  junifer/datagrabber/__init__.pyi,sha256=zOQE4TaCKXBTHnNqgmECtsszWIOHYiQ1CUEeXXFU9F4,832
125
- junifer/datagrabber/base.py,sha256=a3_fUZIN5Bqhq2f4ldpwk_eWeSVRDpDmx2QGIKzCtkg,6761
126
- junifer/datagrabber/datalad_base.py,sha256=v_qGP66zk1-a-nU_u4qoSRNWYuh8YBdjhKkvzISgJWM,12586
125
+ junifer/datagrabber/base.py,sha256=Llr5bHyHovkySI-bzxoQ1TklEF6WOaNRN9D_srqQvYM,6661
126
+ junifer/datagrabber/datalad_base.py,sha256=52T2DbqDGOxiKSESBESzElrVJ3WihLWrrGlQewSvYOs,12616
127
127
  junifer/datagrabber/dmcc13_benchmark.py,sha256=VMyiwvkr4qSvzBICSksPPKOI2w_WVo06H89Url-hrNs,12819
128
128
  junifer/datagrabber/multiple.py,sha256=4tCOzojs3hoG7daHJJ7HUsx15atWR5nTmyP0S0__aig,6666
129
- junifer/datagrabber/pattern.py,sha256=UwJQ0MObBIS6eHH9FfoM_sBYuNM9n5NAX7DA0HdtL1A,18709
129
+ junifer/datagrabber/pattern.py,sha256=hZxXc59qFGiH710aZkcVgt-JcvVjuR-EMmQ1_QFAoHM,18724
130
130
  junifer/datagrabber/pattern_datalad.py,sha256=QPWXIToYHDU4mvm9lz_hy8BjdqqoCXiGiJKCcATrT-w,4568
131
131
  junifer/datagrabber/pattern_validation_mixin.py,sha256=6IlL5EMbr-XEtiiXs_buD3DJkujjs335BmAgAiWGZ3M,19369
132
132
  junifer/datagrabber/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -326,8 +326,8 @@ junifer/testing/tests/test_testing_registry.py,sha256=MK4a_q4MHieCvYhnhuPm_dH76l
326
326
  junifer/tests/test_main.py,sha256=GMff7jlisGM9_FsiUwWDte43j-KQJGFRYZpwRRqTkd8,373
327
327
  junifer/tests/test_stats.py,sha256=NljoGFu2JOPADbi9W0WeUHwpf8nZSdOkcCgCv-Z1fY4,4149
328
328
  junifer/typing/__init__.py,sha256=e0UbuxozXUIxz8h8pLokMOxZV629Q1lnA7vvgm95WF0,215
329
- junifer/typing/__init__.pyi,sha256=0SBTyWv6jYV2x7UiZO2vJirFeJePTMyVq9lZcHZus44,536
330
- junifer/typing/_typing.py,sha256=TQrKnVqECgLDP1EiI0z-5pkeT9zHPmoha1gG8a2tqs0,1560
329
+ junifer/typing/__init__.pyi,sha256=GRGfrnReP1ROtQM6eT0EpFjmE-v-pCJuBiQZMXCVTsE,594
330
+ junifer/typing/_typing.py,sha256=oKxUUelzxntTzlxyE9G4WV2xq600QaRx5vzNlGWL2dU,1658
331
331
  junifer/utils/__init__.py,sha256=I3tYaePAD_ZEU-36-TJ_OYeqW_aMmi5MZ3jmqie6RfU,260
332
332
  junifer/utils/__init__.pyi,sha256=CMb4rq1VcQ00IRuiBFfAWu07Vb-vA4qtVLAoY0ll-bA,422
333
333
  junifer/utils/_config.py,sha256=cfxyv1bfklID2atQseu6y3J7mZrCXPwnGEfBSImG9CM,3054
@@ -341,10 +341,10 @@ junifer/utils/tests/test_config.py,sha256=7ltIXuwb_W4Mv_1dxQWyiyM10XgUAfsWKV6D_i
341
341
  junifer/utils/tests/test_fs.py,sha256=WQS7cKlKEZ742CIuiOYYpueeAhY9PqlastfDVpVVtvE,923
342
342
  junifer/utils/tests/test_helpers.py,sha256=k5qqfxK8dFyuewTJyR1Qn6-nFaYNuVr0ysc18bfPjyU,929
343
343
  junifer/utils/tests/test_logging.py,sha256=duO4ou365hxwa_kwihFtKPLaL6LC5XHiyhOijrrngbA,8009
344
- junifer-0.0.6.dev380.dist-info/AUTHORS.rst,sha256=rmULKpchpSol4ExWFdm-qu4fkpSZPYqIESVJBZtGb6E,163
345
- junifer-0.0.6.dev380.dist-info/LICENSE.md,sha256=MqCnOBu8uXsEOzRZWh9EBVfVz-kE9NkXcLCrtGXo2yU,34354
346
- junifer-0.0.6.dev380.dist-info/METADATA,sha256=AHzgELy1Qm22BQDL1EvglM-gJvl2FlVW6gNlWrtebrU,8429
347
- junifer-0.0.6.dev380.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
348
- junifer-0.0.6.dev380.dist-info/entry_points.txt,sha256=6O8ru0BP-SP7YMUZiizFNoaZ2HvJpadO2G7nKk4PwjI,48
349
- junifer-0.0.6.dev380.dist-info/top_level.txt,sha256=4bAq1R2QFQ4b3hohjys2JBvxrl0GKk5LNFzYvz9VGcA,8
350
- junifer-0.0.6.dev380.dist-info/RECORD,,
344
+ junifer-0.0.6.dev389.dist-info/AUTHORS.rst,sha256=rmULKpchpSol4ExWFdm-qu4fkpSZPYqIESVJBZtGb6E,163
345
+ junifer-0.0.6.dev389.dist-info/LICENSE.md,sha256=MqCnOBu8uXsEOzRZWh9EBVfVz-kE9NkXcLCrtGXo2yU,34354
346
+ junifer-0.0.6.dev389.dist-info/METADATA,sha256=EmDLVfbOnEGVxZpLIPhK8S9OJt_1RcpGW6ABx12fIRw,8429
347
+ junifer-0.0.6.dev389.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
348
+ junifer-0.0.6.dev389.dist-info/entry_points.txt,sha256=6O8ru0BP-SP7YMUZiizFNoaZ2HvJpadO2G7nKk4PwjI,48
349
+ junifer-0.0.6.dev389.dist-info/top_level.txt,sha256=4bAq1R2QFQ4b3hohjys2JBvxrl0GKk5LNFzYvz9VGcA,8
350
+ junifer-0.0.6.dev389.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.7.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5