junifer 0.0.7.dev153__py3-none-any.whl → 0.0.7.dev169__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 (27) hide show
  1. junifer/_version.py +2 -2
  2. junifer/conftest.py +32 -0
  3. junifer/markers/__init__.pyi +12 -2
  4. junifer/markers/falff/__init__.pyi +2 -1
  5. junifer/markers/falff/falff_maps.py +151 -0
  6. junifer/markers/falff/tests/test_falff_maps.py +167 -0
  7. junifer/markers/functional_connectivity/__init__.pyi +4 -0
  8. junifer/markers/functional_connectivity/edge_functional_connectivity_maps.py +115 -0
  9. junifer/markers/functional_connectivity/functional_connectivity_maps.py +95 -0
  10. junifer/markers/functional_connectivity/tests/test_edge_functional_connectivity_maps.py +74 -0
  11. junifer/markers/functional_connectivity/tests/test_functional_connectivity_maps.py +110 -0
  12. junifer/markers/maps_aggregation.py +201 -0
  13. junifer/markers/reho/__init__.pyi +2 -1
  14. junifer/markers/reho/reho_maps.py +161 -0
  15. junifer/markers/reho/tests/test_reho_maps.py +135 -0
  16. junifer/markers/temporal_snr/__init__.pyi +2 -1
  17. junifer/markers/temporal_snr/temporal_snr_maps.py +80 -0
  18. junifer/markers/temporal_snr/tests/test_temporal_snr_maps.py +67 -0
  19. junifer/markers/tests/test_maps_aggregation.py +430 -0
  20. junifer/typing/_typing.py +1 -3
  21. {junifer-0.0.7.dev153.dist-info → junifer-0.0.7.dev169.dist-info}/METADATA +1 -1
  22. {junifer-0.0.7.dev153.dist-info → junifer-0.0.7.dev169.dist-info}/RECORD +27 -15
  23. {junifer-0.0.7.dev153.dist-info → junifer-0.0.7.dev169.dist-info}/WHEEL +0 -0
  24. {junifer-0.0.7.dev153.dist-info → junifer-0.0.7.dev169.dist-info}/entry_points.txt +0 -0
  25. {junifer-0.0.7.dev153.dist-info → junifer-0.0.7.dev169.dist-info}/licenses/AUTHORS.rst +0 -0
  26. {junifer-0.0.7.dev153.dist-info → junifer-0.0.7.dev169.dist-info}/licenses/LICENSE.md +0 -0
  27. {junifer-0.0.7.dev153.dist-info → junifer-0.0.7.dev169.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,80 @@
1
+ """Provide class for temporal SNR using maps."""
2
+
3
+ # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
+ # License: AGPL
5
+
6
+ from typing import Any, Optional, Union
7
+
8
+ from ...api.decorators import register_marker
9
+ from ..maps_aggregation import MapsAggregation
10
+ from .temporal_snr_base import TemporalSNRBase
11
+
12
+
13
+ __all__ = ["TemporalSNRMaps"]
14
+
15
+
16
+ @register_marker
17
+ class TemporalSNRMaps(TemporalSNRBase):
18
+ """Class for temporal signal-to-noise ratio using maps.
19
+
20
+ Parameters
21
+ ----------
22
+ maps : str
23
+ The name of the map(s) to use.
24
+ See :func:`.list_data` for options.
25
+ masks : str, dict or list of dict or str, optional
26
+ The specification of the masks to apply to regions before extracting
27
+ signals. Check :ref:`Using Masks <using_masks>` for more details.
28
+ If None, will not apply any mask (default None).
29
+ name : str, optional
30
+ The name of the marker. If None, will use the class name (default
31
+ None).
32
+
33
+ """
34
+
35
+ def __init__(
36
+ self,
37
+ maps: str,
38
+ masks: Union[str, dict, list[Union[dict, str]], None] = None,
39
+ name: Optional[str] = None,
40
+ ) -> None:
41
+ self.maps = maps
42
+ super().__init__(
43
+ masks=masks,
44
+ name=name,
45
+ )
46
+
47
+ def aggregate(
48
+ self, input: dict[str, Any], extra_input: Optional[dict] = None
49
+ ) -> dict:
50
+ """Perform maps aggregation.
51
+
52
+ Parameters
53
+ ----------
54
+ input : dict
55
+ A single input from the pipeline data object in which the data
56
+ is the voxelwise temporal SNR map.
57
+ extra_input : dict, optional
58
+ The other fields in the pipeline data object. Useful for accessing
59
+ other data kind that needs to be used in the computation. For
60
+ example, the functional connectivity markers can make use of the
61
+ confounds if available (default None).
62
+
63
+ Returns
64
+ -------
65
+ dict
66
+ The computed result as dictionary. This will be either returned
67
+ to the user or stored in the storage by calling the store method
68
+ with this as a parameter. The dictionary has the following keys:
69
+
70
+ * ``aggregation`` : dictionary with the following keys:
71
+
72
+ - ``data`` : ROI-wise tSNR values as ``numpy.ndarray``
73
+ - ``col_names`` : ROI labels as list of str
74
+
75
+ """
76
+ return MapsAggregation(
77
+ maps=self.maps,
78
+ masks=self.masks,
79
+ on="BOLD",
80
+ ).compute(input=input, extra_input=extra_input)
@@ -0,0 +1,67 @@
1
+ """Provide tests for temporal signal-to-noise ratio using maps."""
2
+
3
+ # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
+ # License: AGPL
5
+
6
+ from pathlib import Path
7
+
8
+ from junifer.datagrabber import PatternDataladDataGrabber
9
+ from junifer.datareader import DefaultDataReader
10
+ from junifer.markers import TemporalSNRMaps
11
+ from junifer.storage import HDF5FeatureStorage
12
+
13
+
14
+ def test_TemporalSNRMaps_computation(
15
+ maps_datagrabber: PatternDataladDataGrabber,
16
+ ) -> None:
17
+ """Test TemporalSNRMaps fit-transform.
18
+
19
+ Parameters
20
+ ----------
21
+ maps_datagrabber : PatternDataladDataGrabber
22
+ The testing PatternDataladDataGrabber, as fixture.
23
+
24
+ """
25
+ with maps_datagrabber as dg:
26
+ element = dg[("sub-01", "sub-001", "rest", "1")]
27
+ element_data = DefaultDataReader().fit_transform(element)
28
+ marker = TemporalSNRMaps(maps="Smith_rsn_10")
29
+ # Check correct output
30
+ assert "vector" == marker.get_output_type(
31
+ input_type="BOLD", output_feature="tsnr"
32
+ )
33
+
34
+ # Fit-transform the data
35
+ tsnr_parcels = marker.fit_transform(element_data)
36
+ tsnr_parcels_bold = tsnr_parcels["BOLD"]["tsnr"]
37
+
38
+ assert "data" in tsnr_parcels_bold
39
+ assert "col_names" in tsnr_parcels_bold
40
+ assert tsnr_parcels_bold["data"].shape == (1, 10)
41
+ assert len(set(tsnr_parcels_bold["col_names"])) == 10
42
+
43
+
44
+ def test_TemporalSNRMaps_storage(
45
+ tmp_path: Path, maps_datagrabber: PatternDataladDataGrabber
46
+ ) -> None:
47
+ """Test TemporalSNRMaps store.
48
+
49
+ Parameters
50
+ ----------
51
+ tmp_path : pathlib.Path
52
+ The path to the test directory.
53
+ maps_datagrabber : PatternDataladDataGrabber
54
+ The testing PatternDataladDataGrabber, as fixture.
55
+
56
+ """
57
+ with maps_datagrabber as dg:
58
+ element = dg[("sub-01", "sub-001", "rest", "1")]
59
+ element_data = DefaultDataReader().fit_transform(element)
60
+ marker = TemporalSNRMaps(maps="Smith_rsn_10")
61
+ # Store
62
+ storage = HDF5FeatureStorage(tmp_path / "test_tsnr_maps.hdf5")
63
+ marker.fit_transform(input=element_data, storage=storage)
64
+ features = storage.list_features()
65
+ assert any(
66
+ x["name"] == "BOLD_TemporalSNRMaps_tsnr" for x in features.values()
67
+ )
@@ -0,0 +1,430 @@
1
+ """Provide test for maps aggregation."""
2
+
3
+ # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
4
+ # License: AGPL
5
+
6
+ from copy import deepcopy
7
+ from pathlib import Path
8
+
9
+ import pytest
10
+ from nilearn.maskers import NiftiMapsMasker
11
+ from numpy.testing import assert_array_almost_equal, assert_array_equal
12
+
13
+ from junifer.data import MapsRegistry, MaskRegistry
14
+ from junifer.data.masks import compute_brain_mask
15
+ from junifer.datagrabber import PatternDataladDataGrabber
16
+ from junifer.datareader import DefaultDataReader
17
+ from junifer.markers import MapsAggregation
18
+ from junifer.storage import HDF5FeatureStorage
19
+
20
+
21
+ @pytest.mark.parametrize(
22
+ "input_type, storage_type",
23
+ [
24
+ (
25
+ "T1w",
26
+ "vector",
27
+ ),
28
+ (
29
+ "T2w",
30
+ "vector",
31
+ ),
32
+ (
33
+ "BOLD",
34
+ "timeseries",
35
+ ),
36
+ (
37
+ "VBM_GM",
38
+ "vector",
39
+ ),
40
+ (
41
+ "VBM_WM",
42
+ "vector",
43
+ ),
44
+ (
45
+ "VBM_CSF",
46
+ "vector",
47
+ ),
48
+ (
49
+ "fALFF",
50
+ "vector",
51
+ ),
52
+ (
53
+ "GCOR",
54
+ "vector",
55
+ ),
56
+ (
57
+ "LCOR",
58
+ "vector",
59
+ ),
60
+ ],
61
+ )
62
+ def test_MapsAggregation_input_output(
63
+ input_type: str, storage_type: str
64
+ ) -> None:
65
+ """Test MapsAggregation input and output types.
66
+
67
+ Parameters
68
+ ----------
69
+ input_type : str
70
+ The parametrized input type.
71
+ storage_type : str
72
+ The parametrized storage type.
73
+
74
+ """
75
+ assert storage_type == MapsAggregation(
76
+ maps="Smith_rsn_10", on=input_type
77
+ ).get_output_type(input_type=input_type, output_feature="aggregation")
78
+
79
+
80
+ def test_MapsAggregation_3D(
81
+ maps_datagrabber: PatternDataladDataGrabber,
82
+ ) -> None:
83
+ """Test MapsAggregation on 3D data.
84
+
85
+ Parameters
86
+ ----------
87
+ maps_datagrabber : PatternDataladDataGrabber
88
+ The testing PatternDataladDataGrabber, as fixture.
89
+
90
+ """
91
+ with maps_datagrabber as dg:
92
+ element = dg[("sub-01", "sub-001", "rest", "1")]
93
+ element_data = DefaultDataReader().fit_transform(element)
94
+ # Deepcopy data for later use
95
+ input_data = deepcopy(element_data)
96
+ # Modify for junifer
97
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
98
+ ...,
99
+ 0:1,
100
+ ]
101
+ marker = MapsAggregation(maps="Smith_rsn_10")
102
+ maps_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
103
+ "aggregation"
104
+ ]["data"]
105
+ assert maps_agg_bold_data.ndim == 2
106
+
107
+ # Compare with nilearn
108
+ # Load testing maps
109
+ maps, _ = MapsRegistry().get(
110
+ maps="Smith_rsn_10",
111
+ target_data=element_data["BOLD"],
112
+ )
113
+ # Extract data
114
+ masker = NiftiMapsMasker(maps_img=maps)
115
+ nifti_maps_masked_bold = masker.fit_transform(
116
+ input_data["BOLD"]["data"].slicer[..., 0:1]
117
+ )
118
+
119
+ assert_array_equal(
120
+ nifti_maps_masked_bold.shape, maps_agg_bold_data.shape
121
+ )
122
+ assert_array_equal(nifti_maps_masked_bold, maps_agg_bold_data)
123
+
124
+
125
+ def test_MapsAggregation_4D(
126
+ maps_datagrabber: PatternDataladDataGrabber,
127
+ ) -> None:
128
+ """Test MapsAggregation on 4D data.
129
+
130
+ Parameters
131
+ ----------
132
+ maps_datagrabber : PatternDataladDataGrabber
133
+ The testing PatternDataladDataGrabber, as fixture.
134
+
135
+ """
136
+ with maps_datagrabber as dg:
137
+ element = dg[("sub-01", "sub-001", "rest", "1")]
138
+ element_data = DefaultDataReader().fit_transform(element)
139
+ # Deepcopy data for later use
140
+ input_data = deepcopy(element_data)
141
+ marker = MapsAggregation(maps="Smith_rsn_10")
142
+ maps_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
143
+ "aggregation"
144
+ ]["data"]
145
+ assert maps_agg_bold_data.ndim == 2
146
+
147
+ # Compare with nilearn
148
+ # Load testing maps
149
+ maps, _ = MapsRegistry().get(
150
+ maps="Smith_rsn_10",
151
+ target_data=element_data["BOLD"],
152
+ )
153
+ # Extract data
154
+ masker = NiftiMapsMasker(maps_img=maps)
155
+ nifti_maps_masked_bold = masker.fit_transform(
156
+ input_data["BOLD"]["data"]
157
+ )
158
+
159
+ assert_array_equal(
160
+ nifti_maps_masked_bold.shape, maps_agg_bold_data.shape
161
+ )
162
+ assert_array_equal(nifti_maps_masked_bold, maps_agg_bold_data)
163
+
164
+
165
+ def test_MapsAggregation_storage(
166
+ maps_datagrabber: PatternDataladDataGrabber, tmp_path: Path
167
+ ) -> None:
168
+ """Test MapsAggregation storage.
169
+
170
+ Parameters
171
+ ----------
172
+ maps_datagrabber : PatternDataladDataGrabber
173
+ The testing PatternDataladDataGrabber, as fixture.
174
+ tmp_path : pathlib.Path
175
+ The path to the test directory.
176
+
177
+ """
178
+ # Store 3D
179
+ with maps_datagrabber as dg:
180
+ element = dg[("sub-01", "sub-001", "rest", "1")]
181
+ element_data = DefaultDataReader().fit_transform(element)
182
+ storage = HDF5FeatureStorage(
183
+ uri=tmp_path / "test_maps_storage_3D.hdf5"
184
+ )
185
+ marker = MapsAggregation(
186
+ maps="Smith_rsn_10",
187
+ on="BOLD",
188
+ )
189
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
190
+ ..., 0:1
191
+ ]
192
+ marker.fit_transform(input=element_data, storage=storage)
193
+ features = storage.list_features()
194
+ assert any(
195
+ x["name"] == "BOLD_MapsAggregation_aggregation"
196
+ for x in features.values()
197
+ )
198
+
199
+ # Store 4D
200
+ with maps_datagrabber as dg:
201
+ element = dg[("sub-01", "sub-001", "rest", "1")]
202
+ element_data = DefaultDataReader().fit_transform(element)
203
+ storage = HDF5FeatureStorage(
204
+ uri=tmp_path / "test_maps_storage_4D.sqlite"
205
+ )
206
+ marker = MapsAggregation(
207
+ maps="Smith_rsn_10",
208
+ on="BOLD",
209
+ )
210
+ marker.fit_transform(input=element_data, storage=storage)
211
+ features = storage.list_features()
212
+ assert any(
213
+ x["name"] == "BOLD_MapsAggregation_aggregation"
214
+ for x in features.values()
215
+ )
216
+
217
+
218
+ def test_MapsAggregation_3D_mask(
219
+ maps_datagrabber: PatternDataladDataGrabber,
220
+ ) -> None:
221
+ """Test MapsAggregation on 3D data with mask.
222
+
223
+ Parameters
224
+ ----------
225
+ maps_datagrabber : PatternDataladDataGrabber
226
+ The testing PatternDataladDataGrabber, as fixture.
227
+
228
+ """
229
+ with maps_datagrabber as dg:
230
+ element = dg[("sub-01", "sub-001", "rest", "1")]
231
+ element_data = DefaultDataReader().fit_transform(element)
232
+ # Deepcopy data for later use
233
+ input_data = deepcopy(element_data)
234
+ # Modify for junifer
235
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
236
+ ...,
237
+ 0:1,
238
+ ]
239
+ marker = MapsAggregation(
240
+ maps="Smith_rsn_10",
241
+ on="BOLD",
242
+ masks="compute_brain_mask",
243
+ )
244
+ maps_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
245
+ "aggregation"
246
+ ]["data"]
247
+ assert maps_agg_bold_data.ndim == 2
248
+
249
+ # Compare with nilearn
250
+ # Load testing maps
251
+ maps, _ = MapsRegistry().get(
252
+ maps="Smith_rsn_10",
253
+ target_data=element_data["BOLD"],
254
+ )
255
+ # Load mask
256
+ mask_img = MaskRegistry().get(
257
+ "compute_brain_mask", target_data=element_data["BOLD"]
258
+ )
259
+ # Extract data
260
+ masker = NiftiMapsMasker(maps_img=maps, mask_img=mask_img)
261
+ nifti_maps_masked_bold = masker.fit_transform(
262
+ input_data["BOLD"]["data"].slicer[..., 0:1]
263
+ )
264
+
265
+ assert_array_equal(
266
+ nifti_maps_masked_bold.shape, maps_agg_bold_data.shape
267
+ )
268
+ assert_array_equal(nifti_maps_masked_bold, maps_agg_bold_data)
269
+
270
+
271
+ def test_MapsAggregation_3D_mask_computed(
272
+ maps_datagrabber: PatternDataladDataGrabber,
273
+ ) -> None:
274
+ """Test MapsAggregation on 3D data with computed masks.
275
+
276
+ Parameters
277
+ ----------
278
+ maps_datagrabber : PatternDataladDataGrabber
279
+ The testing PatternDataladDataGrabber, as fixture.
280
+
281
+ """
282
+ with maps_datagrabber as dg:
283
+ element = dg[("sub-01", "sub-001", "rest", "1")]
284
+ element_data = DefaultDataReader().fit_transform(element)
285
+
286
+ # Compare with nilearn
287
+ # Load testing maps
288
+ maps, _ = MapsRegistry().get(
289
+ maps="Smith_rsn_10",
290
+ target_data=element_data["BOLD"],
291
+ )
292
+ # Get a mask
293
+ mask_img = compute_brain_mask(element_data["BOLD"], threshold=0.2)
294
+ # Create NiftiMapsMasker
295
+ masker = NiftiMapsMasker(maps_img=maps, mask_img=mask_img)
296
+ nifti_maps_masked_bold_good = masker.fit_transform(
297
+ element_data["BOLD"]["data"]
298
+ )
299
+
300
+ # Get another mask
301
+ mask_img = compute_brain_mask(element_data["BOLD"], threshold=0.5)
302
+ # Create NiftiMapsMasker
303
+ masker = NiftiMapsMasker(maps_img=maps, mask_img=mask_img)
304
+ nifti_maps_masked_bold_bad = masker.fit_transform(mask_img)
305
+
306
+ # Use the MapsAggregation object
307
+ marker = MapsAggregation(
308
+ maps="Smith_rsn_10",
309
+ masks={"compute_brain_mask": {"threshold": 0.2}},
310
+ on="BOLD",
311
+ )
312
+ maps_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
313
+ "aggregation"
314
+ ]["data"]
315
+
316
+ assert maps_agg_bold_data.ndim == 2
317
+ assert_array_almost_equal(
318
+ nifti_maps_masked_bold_good, maps_agg_bold_data
319
+ )
320
+
321
+ with pytest.raises(AssertionError):
322
+ assert_array_almost_equal(
323
+ maps_agg_bold_data, nifti_maps_masked_bold_bad
324
+ )
325
+
326
+
327
+ def test_MapsAggregation_4D_agg_time(
328
+ maps_datagrabber: PatternDataladDataGrabber,
329
+ ):
330
+ """Test MapsAggregation on 4D data, aggregating time.
331
+
332
+ Parameters
333
+ ----------
334
+ maps_datagrabber : PatternDataladDataGrabber
335
+ The testing PatternDataladDataGrabber, as fixture.
336
+
337
+ """
338
+ with maps_datagrabber as dg:
339
+ element = dg[("sub-01", "sub-001", "rest", "1")]
340
+ element_data = DefaultDataReader().fit_transform(element)
341
+ # Create MapsAggregation object
342
+ marker = MapsAggregation(
343
+ maps="Smith_rsn_10",
344
+ time_method="mean",
345
+ on="BOLD",
346
+ )
347
+ maps_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
348
+ "aggregation"
349
+ ]["data"]
350
+
351
+ # Compare with nilearn
352
+ # Loading testing maps
353
+ maps, _ = MapsRegistry().get(
354
+ maps="Smith_rsn_10",
355
+ target_data=element_data["BOLD"],
356
+ )
357
+ # Extract data
358
+ masker = NiftiMapsMasker(maps_img=maps)
359
+ nifti_maps_masked_bold = masker.fit_transform(
360
+ element_data["BOLD"]["data"]
361
+ )
362
+ nifti_maps_masked_bold_mean = nifti_maps_masked_bold.mean(axis=0)
363
+
364
+ assert maps_agg_bold_data.ndim == 1
365
+ assert_array_equal(
366
+ nifti_maps_masked_bold_mean.shape, maps_agg_bold_data.shape
367
+ )
368
+ assert_array_almost_equal(
369
+ nifti_maps_masked_bold_mean, maps_agg_bold_data, decimal=2
370
+ )
371
+
372
+ # Test picking first time point
373
+ nifti_maps_masked_bold_pick_0 = nifti_maps_masked_bold[:1, :]
374
+ marker = MapsAggregation(
375
+ maps="Smith_rsn_10",
376
+ time_method="select",
377
+ time_method_params={"pick": [0]},
378
+ on="BOLD",
379
+ )
380
+ maps_agg_bold_data = marker.fit_transform(element_data)["BOLD"][
381
+ "aggregation"
382
+ ]["data"]
383
+
384
+ assert maps_agg_bold_data.ndim == 2
385
+ assert_array_equal(
386
+ nifti_maps_masked_bold_pick_0.shape, maps_agg_bold_data.shape
387
+ )
388
+ assert_array_equal(nifti_maps_masked_bold_pick_0, maps_agg_bold_data)
389
+
390
+
391
+ def test_MapsAggregation_errors() -> None:
392
+ """Test errors for MapsAggregation."""
393
+ with pytest.raises(ValueError, match="can only be used with BOLD data"):
394
+ MapsAggregation(
395
+ maps="Smith_rsn_10",
396
+ time_method="select",
397
+ time_method_params={"pick": [0]},
398
+ on="VBM_GM",
399
+ )
400
+
401
+ with pytest.raises(
402
+ ValueError, match="can only be used with `time_method`"
403
+ ):
404
+ MapsAggregation(
405
+ maps="Smith_rsn_10",
406
+ time_method_params={"pick": [0]},
407
+ on="VBM_GM",
408
+ )
409
+
410
+
411
+ def test_MapsAggregation_warning(
412
+ maps_datagrabber: PatternDataladDataGrabber,
413
+ ) -> None:
414
+ """Test warning for MapsAggregation."""
415
+ with maps_datagrabber as dg:
416
+ element = dg[("sub-01", "sub-001", "rest", "1")]
417
+ element_data = DefaultDataReader().fit_transform(element)
418
+ with pytest.warns(
419
+ RuntimeWarning, match="No time dimension to aggregate"
420
+ ):
421
+ marker = MapsAggregation(
422
+ maps="Smith_rsn_10",
423
+ time_method="select",
424
+ time_method_params={"pick": [0]},
425
+ on="BOLD",
426
+ )
427
+ element_data["BOLD"]["data"] = element_data["BOLD"]["data"].slicer[
428
+ ..., 0:1
429
+ ]
430
+ marker.fit_transform(element_data)
junifer/typing/_typing.py CHANGED
@@ -65,9 +65,7 @@ ConditionalDependencies = Sequence[
65
65
  ]
66
66
  ExternalDependencies = Sequence[MutableMapping[str, Union[str, Sequence[str]]]]
67
67
  MarkerInOutMappings = MutableMapping[str, MutableMapping[str, str]]
68
- DataGrabberPatterns = dict[
69
- str, Union[dict[str, str], list[dict[str, str]]]
70
- ]
68
+ DataGrabberPatterns = dict[str, Union[dict[str, str], list[dict[str, str]]]]
71
69
  ConfigVal = Union[bool, int, float, str]
72
70
  Element = Union[str, tuple[str, ...]]
73
71
  Elements = Sequence[Element]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: junifer
3
- Version: 0.0.7.dev153
3
+ Version: 0.0.7.dev169
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>