junifer 0.0.6.dev219__py3-none-any.whl → 0.0.6.dev248__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/__init__.pyi +2 -0
- junifer/_version.py +2 -2
- junifer/api/decorators.py +5 -4
- junifer/api/functions.py +9 -8
- junifer/data/coordinates/_ants_coordinates_warper.py +4 -6
- junifer/data/coordinates/_coordinates.py +28 -15
- junifer/data/coordinates/_fsl_coordinates_warper.py +4 -6
- junifer/data/masks/_ants_mask_warper.py +16 -9
- junifer/data/masks/_fsl_mask_warper.py +4 -6
- junifer/data/masks/_masks.py +21 -25
- junifer/data/parcellations/_ants_parcellation_warper.py +16 -9
- junifer/data/parcellations/_fsl_parcellation_warper.py +4 -6
- junifer/data/parcellations/_parcellations.py +20 -24
- junifer/data/utils.py +67 -3
- junifer/datagrabber/aomic/id1000.py +22 -9
- junifer/datagrabber/aomic/piop1.py +22 -9
- junifer/datagrabber/aomic/piop2.py +22 -9
- junifer/datagrabber/base.py +6 -1
- junifer/datagrabber/datalad_base.py +15 -8
- junifer/datagrabber/dmcc13_benchmark.py +23 -10
- junifer/datagrabber/hcp1200/hcp1200.py +18 -7
- junifer/datagrabber/multiple.py +2 -1
- junifer/datagrabber/pattern.py +65 -35
- junifer/datagrabber/pattern_validation_mixin.py +197 -87
- junifer/datagrabber/tests/test_dmcc13_benchmark.py +26 -9
- junifer/markers/base.py +4 -7
- junifer/markers/brainprint.py +4 -4
- junifer/markers/complexity/complexity_base.py +3 -3
- junifer/markers/ets_rss.py +4 -3
- junifer/markers/falff/_afni_falff.py +3 -5
- junifer/markers/falff/_junifer_falff.py +3 -3
- junifer/markers/falff/falff_base.py +4 -6
- junifer/markers/functional_connectivity/crossparcellation_functional_connectivity.py +4 -3
- junifer/markers/functional_connectivity/functional_connectivity_base.py +4 -3
- junifer/markers/parcel_aggregation.py +4 -3
- junifer/markers/reho/_afni_reho.py +3 -5
- junifer/markers/reho/_junifer_reho.py +3 -3
- junifer/markers/reho/reho_base.py +4 -6
- junifer/markers/sphere_aggregation.py +4 -3
- junifer/markers/temporal_snr/temporal_snr_base.py +4 -3
- junifer/onthefly/_brainprint.py +4 -7
- junifer/onthefly/read_transform.py +3 -6
- junifer/pipeline/marker_collection.py +6 -12
- junifer/pipeline/pipeline_component_registry.py +3 -8
- junifer/pipeline/pipeline_step_mixin.py +8 -4
- junifer/pipeline/tests/test_pipeline_step_mixin.py +18 -19
- junifer/pipeline/tests/test_workdir_manager.py +1 -0
- junifer/pipeline/update_meta_mixin.py +21 -17
- junifer/preprocess/confounds/fmriprep_confound_remover.py +2 -2
- junifer/preprocess/smoothing/_afni_smoothing.py +4 -6
- junifer/preprocess/smoothing/_fsl_smoothing.py +4 -7
- junifer/preprocess/smoothing/_nilearn_smoothing.py +3 -3
- junifer/preprocess/smoothing/smoothing.py +3 -2
- junifer/preprocess/warping/_ants_warper.py +26 -7
- junifer/preprocess/warping/_fsl_warper.py +22 -8
- junifer/preprocess/warping/space_warper.py +34 -6
- junifer/preprocess/warping/tests/test_space_warper.py +4 -7
- junifer/typing/__init__.py +9 -0
- junifer/typing/__init__.pyi +23 -0
- junifer/typing/_typing.py +61 -0
- {junifer-0.0.6.dev219.dist-info → junifer-0.0.6.dev248.dist-info}/METADATA +2 -1
- {junifer-0.0.6.dev219.dist-info → junifer-0.0.6.dev248.dist-info}/RECORD +67 -64
- {junifer-0.0.6.dev219.dist-info → junifer-0.0.6.dev248.dist-info}/WHEEL +1 -1
- {junifer-0.0.6.dev219.dist-info → junifer-0.0.6.dev248.dist-info}/AUTHORS.rst +0 -0
- {junifer-0.0.6.dev219.dist-info → junifer-0.0.6.dev248.dist-info}/LICENSE.md +0 -0
- {junifer-0.0.6.dev219.dist-info → junifer-0.0.6.dev248.dist-info}/entry_points.txt +0 -0
- {junifer-0.0.6.dev219.dist-info → junifer-0.0.6.dev248.dist-info}/top_level.txt +0 -0
junifer/data/utils.py
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# Synchon Mandal <s.mandal@fz-juelich.de>
|
5
5
|
# License: AGPL
|
6
6
|
|
7
|
-
from typing import List, Optional, Union
|
7
|
+
from typing import Dict, List, MutableMapping, Optional, Union
|
8
8
|
|
9
9
|
import numpy as np
|
10
10
|
|
11
|
-
from ..utils
|
11
|
+
from ..utils import logger, raise_error
|
12
12
|
|
13
13
|
|
14
|
-
__all__ = ["closest_resolution"]
|
14
|
+
__all__ = ["closest_resolution", "get_native_warper"]
|
15
15
|
|
16
16
|
|
17
17
|
def closest_resolution(
|
@@ -49,3 +49,67 @@ def closest_resolution(
|
|
49
49
|
closest = np.min(valid_resolution)
|
50
50
|
|
51
51
|
return closest
|
52
|
+
|
53
|
+
|
54
|
+
def get_native_warper(
|
55
|
+
target_data: MutableMapping,
|
56
|
+
other_data: MutableMapping,
|
57
|
+
inverse: bool = False,
|
58
|
+
) -> Dict:
|
59
|
+
"""Get correct warping specification for native space.
|
60
|
+
|
61
|
+
Parameters
|
62
|
+
----------
|
63
|
+
target_data : dict
|
64
|
+
The target data from the pipeline data object.
|
65
|
+
other_data : dict
|
66
|
+
The other data in the pipeline data object.
|
67
|
+
inverse : bool, optional
|
68
|
+
Whether to get the inverse warping specification (default False).
|
69
|
+
|
70
|
+
Returns
|
71
|
+
-------
|
72
|
+
dict
|
73
|
+
The correct warping specification.
|
74
|
+
|
75
|
+
Raises
|
76
|
+
------
|
77
|
+
RuntimeError
|
78
|
+
If no warper or multiple possible warpers are found.
|
79
|
+
|
80
|
+
"""
|
81
|
+
# Get possible warpers
|
82
|
+
possible_warpers = []
|
83
|
+
for entry in other_data["Warp"]:
|
84
|
+
if not inverse:
|
85
|
+
if (
|
86
|
+
entry["src"] == target_data["prewarp_space"]
|
87
|
+
and entry["dst"] == "native"
|
88
|
+
):
|
89
|
+
possible_warpers.append(entry)
|
90
|
+
else:
|
91
|
+
if (
|
92
|
+
entry["dst"] == target_data["prewarp_space"]
|
93
|
+
and entry["src"] == "native"
|
94
|
+
):
|
95
|
+
possible_warpers.append(entry)
|
96
|
+
|
97
|
+
# Check for no warper
|
98
|
+
if not possible_warpers:
|
99
|
+
raise_error(
|
100
|
+
klass=RuntimeError,
|
101
|
+
msg="Could not find correct warping specification",
|
102
|
+
)
|
103
|
+
|
104
|
+
# Check for multiple possible warpers
|
105
|
+
if len(possible_warpers) > 1:
|
106
|
+
raise_error(
|
107
|
+
klass=RuntimeError,
|
108
|
+
msg=(
|
109
|
+
"Cannot proceed as multiple warping specification found, "
|
110
|
+
"adjust either the DataGrabber or the working space: "
|
111
|
+
f"{possible_warpers}"
|
112
|
+
),
|
113
|
+
)
|
114
|
+
|
115
|
+
return possible_warpers[0]
|
@@ -169,15 +169,28 @@ class DataladAOMICID1000(PatternDataladDataGrabber):
|
|
169
169
|
"space": "native",
|
170
170
|
},
|
171
171
|
},
|
172
|
-
"Warp":
|
173
|
-
|
174
|
-
"
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
172
|
+
"Warp": [
|
173
|
+
{
|
174
|
+
"pattern": (
|
175
|
+
"derivatives/fmriprep/{subject}/anat/"
|
176
|
+
"{subject}_from-MNI152NLin2009cAsym_to-T1w_"
|
177
|
+
"mode-image_xfm.h5"
|
178
|
+
),
|
179
|
+
"src": "MNI152NLin2009cAsym",
|
180
|
+
"dst": "native",
|
181
|
+
"warper": "ants",
|
182
|
+
},
|
183
|
+
{
|
184
|
+
"pattern": (
|
185
|
+
"derivatives/fmriprep/{subject}/anat/"
|
186
|
+
"{subject}_from-T1w_to-MNI152NLin2009cAsym_"
|
187
|
+
"mode-image_xfm.h5"
|
188
|
+
),
|
189
|
+
"src": "native",
|
190
|
+
"dst": "MNI152NLin2009cAsym",
|
191
|
+
"warper": "ants",
|
192
|
+
},
|
193
|
+
],
|
181
194
|
}
|
182
195
|
)
|
183
196
|
# Set default types
|
@@ -204,15 +204,28 @@ class DataladAOMICPIOP1(PatternDataladDataGrabber):
|
|
204
204
|
"space": "native",
|
205
205
|
},
|
206
206
|
},
|
207
|
-
"Warp":
|
208
|
-
|
209
|
-
"
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
207
|
+
"Warp": [
|
208
|
+
{
|
209
|
+
"pattern": (
|
210
|
+
"derivatives/fmriprep/{subject}/anat/"
|
211
|
+
"{subject}_from-MNI152NLin2009cAsym_to-T1w_"
|
212
|
+
"mode-image_xfm.h5"
|
213
|
+
),
|
214
|
+
"src": "MNI152NLin2009cAsym",
|
215
|
+
"dst": "native",
|
216
|
+
"warper": "ants",
|
217
|
+
},
|
218
|
+
{
|
219
|
+
"pattern": (
|
220
|
+
"derivatives/fmriprep/{subject}/anat/"
|
221
|
+
"{subject}_from-T1w_to-MNI152NLin2009cAsym_"
|
222
|
+
"mode-image_xfm.h5"
|
223
|
+
),
|
224
|
+
"src": "native",
|
225
|
+
"dst": "MNI152NLin2009cAsym",
|
226
|
+
"warper": "ants",
|
227
|
+
},
|
228
|
+
],
|
216
229
|
}
|
217
230
|
)
|
218
231
|
# Set default types
|
@@ -202,15 +202,28 @@ class DataladAOMICPIOP2(PatternDataladDataGrabber):
|
|
202
202
|
"space": "native",
|
203
203
|
},
|
204
204
|
},
|
205
|
-
"Warp":
|
206
|
-
|
207
|
-
"
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
205
|
+
"Warp": [
|
206
|
+
{
|
207
|
+
"pattern": (
|
208
|
+
"derivatives/fmriprep/{subject}/anat/"
|
209
|
+
"{subject}_from-MNI152NLin2009cAsym_to-T1w_"
|
210
|
+
"mode-image_xfm.h5"
|
211
|
+
),
|
212
|
+
"src": "MNI152NLin2009cAsym",
|
213
|
+
"dst": "native",
|
214
|
+
"warper": "ants",
|
215
|
+
},
|
216
|
+
{
|
217
|
+
"pattern": (
|
218
|
+
"derivatives/fmriprep/{subject}/anat/"
|
219
|
+
"{subject}_from-T1w_to-MNI152NLin2009cAsym_"
|
220
|
+
"mode-image_xfm.h5"
|
221
|
+
),
|
222
|
+
"src": "native",
|
223
|
+
"dst": "MNI152NLin2009cAsym",
|
224
|
+
"warper": "ants",
|
225
|
+
},
|
226
|
+
],
|
214
227
|
}
|
215
228
|
)
|
216
229
|
# Set default types
|
junifer/datagrabber/base.py
CHANGED
@@ -96,7 +96,12 @@ class BaseDataGrabber(ABC, UpdateMetaMixin):
|
|
96
96
|
# Update metadata
|
97
97
|
for _, t_val in out.items():
|
98
98
|
self.update_meta(t_val, "datagrabber")
|
99
|
-
|
99
|
+
# Conditional for list dtype vals like Warp
|
100
|
+
if isinstance(t_val, list):
|
101
|
+
for entry in t_val:
|
102
|
+
entry["meta"]["element"] = named_element
|
103
|
+
else:
|
104
|
+
t_val["meta"]["element"] = named_element
|
100
105
|
|
101
106
|
return out
|
102
107
|
|
@@ -181,14 +181,21 @@ class DataladDataGrabber(BaseDataGrabber):
|
|
181
181
|
"""
|
182
182
|
to_get = []
|
183
183
|
for type_val in out.values():
|
184
|
-
#
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
184
|
+
# Conditional for list dtype vals like Warp
|
185
|
+
if isinstance(type_val, list):
|
186
|
+
for entry in type_val:
|
187
|
+
for k, v in entry.items():
|
188
|
+
if k == "path":
|
189
|
+
to_get.append(v)
|
190
|
+
else:
|
191
|
+
# Iterate to check for nested "types" like mask
|
192
|
+
for k, v in type_val.items():
|
193
|
+
# Add base data type path
|
194
|
+
if k == "path":
|
195
|
+
to_get.append(v)
|
196
|
+
# Add nested data type path
|
197
|
+
if isinstance(v, dict) and "path" in v:
|
198
|
+
to_get.append(v["path"])
|
192
199
|
|
193
200
|
if len(to_get) > 0:
|
194
201
|
logger.debug(f"Getting {len(to_get)} files using datalad:")
|
@@ -150,7 +150,7 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
|
|
150
150
|
"mask": {
|
151
151
|
"pattern": (
|
152
152
|
"derivatives/fmriprep-1.3.2/{subject}/{session}/"
|
153
|
-
"
|
153
|
+
"func/{subject}_{session}_task-{task}_acq-mb4"
|
154
154
|
"{phase_encoding}_run-{run}_"
|
155
155
|
"space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz"
|
156
156
|
),
|
@@ -221,15 +221,28 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
|
|
221
221
|
"space": "native",
|
222
222
|
},
|
223
223
|
},
|
224
|
-
"Warp":
|
225
|
-
|
226
|
-
"
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
224
|
+
"Warp": [
|
225
|
+
{
|
226
|
+
"pattern": (
|
227
|
+
"derivatives/fmriprep-1.3.2/{subject}/anat/"
|
228
|
+
"{subject}_from-MNI152NLin2009cAsym_to-T1w_"
|
229
|
+
"mode-image_xfm.h5"
|
230
|
+
),
|
231
|
+
"src": "MNI152NLin2009cAsym",
|
232
|
+
"dst": "native",
|
233
|
+
"warper": "ants",
|
234
|
+
},
|
235
|
+
{
|
236
|
+
"pattern": (
|
237
|
+
"derivatives/fmriprep-1.3.2/{subject}/anat/"
|
238
|
+
"{subject}_from-T1w_to-MNI152NLin2009cAsym_"
|
239
|
+
"mode-image_xfm.h5"
|
240
|
+
),
|
241
|
+
"src": "native",
|
242
|
+
"dst": "MNI152NLin2009cAsym",
|
243
|
+
"warper": "ants",
|
244
|
+
},
|
245
|
+
],
|
233
246
|
}
|
234
247
|
)
|
235
248
|
# Set default types
|
@@ -122,13 +122,24 @@ class HCP1200(PatternDataGrabber):
|
|
122
122
|
"pattern": "{subject}/T1w/T1w_acpc_dc_restore.nii.gz",
|
123
123
|
"space": "native",
|
124
124
|
},
|
125
|
-
"Warp":
|
126
|
-
|
127
|
-
"
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
125
|
+
"Warp": [
|
126
|
+
{
|
127
|
+
"pattern": (
|
128
|
+
"{subject}/MNINonLinear/xfms/standard2acpc_dc.nii.gz"
|
129
|
+
),
|
130
|
+
"src": "MNI152NLin6Asym",
|
131
|
+
"dst": "native",
|
132
|
+
"warper": "fsl",
|
133
|
+
},
|
134
|
+
{
|
135
|
+
"pattern": (
|
136
|
+
"{subject}/MNINonLinear/xfms/acpc_dc2standard.nii.gz"
|
137
|
+
),
|
138
|
+
"src": "native",
|
139
|
+
"dst": "MNI152NLin6Asym",
|
140
|
+
"warper": "fsl",
|
141
|
+
},
|
142
|
+
],
|
132
143
|
}
|
133
144
|
# The replacements
|
134
145
|
replacements = ["subject", "task", "phase_encoding"]
|
junifer/datagrabber/multiple.py
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
from typing import Dict, List, Tuple, Union
|
9
9
|
|
10
10
|
from ..api.decorators import register_datagrabber
|
11
|
+
from ..typing import DataGrabberLike
|
11
12
|
from ..utils import deep_update, raise_error
|
12
13
|
from .base import BaseDataGrabber
|
13
14
|
|
@@ -37,7 +38,7 @@ class MultipleDataGrabber(BaseDataGrabber):
|
|
37
38
|
|
38
39
|
"""
|
39
40
|
|
40
|
-
def __init__(self, datagrabbers: List[
|
41
|
+
def __init__(self, datagrabbers: List[DataGrabberLike], **kwargs) -> None:
|
41
42
|
# Check datagrabbers consistency
|
42
43
|
# Check for same element keys
|
43
44
|
first_keys = datagrabbers[0].get_element_keys()
|
junifer/datagrabber/pattern.py
CHANGED
@@ -89,7 +89,7 @@ class PatternDataGrabber(BaseDataGrabber, PatternValidationMixin):
|
|
89
89
|
.. code-block:: none
|
90
90
|
|
91
91
|
{
|
92
|
-
"mandatory": ["pattern", "src", "dst"],
|
92
|
+
"mandatory": ["pattern", "src", "dst", "warper"],
|
93
93
|
"optional": []
|
94
94
|
}
|
95
95
|
|
@@ -127,11 +127,22 @@ class PatternDataGrabber(BaseDataGrabber, PatternValidationMixin):
|
|
127
127
|
"pattern": "...",
|
128
128
|
"space": "...",
|
129
129
|
},
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
130
|
+
}
|
131
|
+
|
132
|
+
except ``Warp``, which needs to be a list of dictionaries as there can
|
133
|
+
be multiple spaces to warp (for example, with fMRIPrep):
|
134
|
+
|
135
|
+
.. code-block:: none
|
136
|
+
|
137
|
+
{
|
138
|
+
"Warp": [
|
139
|
+
{
|
140
|
+
"pattern": "...",
|
141
|
+
"src": "...",
|
142
|
+
"dst": "...",
|
143
|
+
"warper": "...",
|
144
|
+
},
|
145
|
+
],
|
135
146
|
}
|
136
147
|
|
137
148
|
taken from :class:`.HCP1200`.
|
@@ -380,42 +391,61 @@ class PatternDataGrabber(BaseDataGrabber, PatternValidationMixin):
|
|
380
391
|
t_pattern = self.patterns[t_type]
|
381
392
|
# Copy data type dictionary in output
|
382
393
|
out[t_type] = deepcopy(t_pattern)
|
383
|
-
#
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
394
|
+
# Conditional for list dtype vals like Warp
|
395
|
+
if isinstance(t_pattern, list):
|
396
|
+
for idx, entry in enumerate(t_pattern):
|
397
|
+
logger.info(
|
398
|
+
f"Resolving path from pattern for {t_type}.{idx}"
|
399
|
+
)
|
388
400
|
# Resolve pattern
|
389
|
-
|
401
|
+
dtype_pattern_path = self._get_path_from_patterns(
|
390
402
|
element=element,
|
391
|
-
pattern=
|
392
|
-
data_type=t_type,
|
403
|
+
pattern=entry["pattern"],
|
404
|
+
data_type=f"{t_type}.{idx}",
|
393
405
|
)
|
394
406
|
# Remove pattern key
|
395
|
-
out[t_type].pop("pattern")
|
407
|
+
out[t_type][idx].pop("pattern")
|
396
408
|
# Add path key
|
397
|
-
out[t_type].update({"path":
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
self._get_path_from_patterns(
|
409
|
+
out[t_type][idx].update({"path": dtype_pattern_path})
|
410
|
+
else:
|
411
|
+
# Iterate to check for nested "types" like mask
|
412
|
+
for k, v in t_pattern.items():
|
413
|
+
# Resolve pattern for base data type
|
414
|
+
if k == "pattern":
|
415
|
+
logger.info(
|
416
|
+
f"Resolving path from pattern for {t_type}"
|
417
|
+
)
|
418
|
+
# Resolve pattern
|
419
|
+
base_dtype_pattern_path = self._get_path_from_patterns(
|
408
420
|
element=element,
|
409
|
-
pattern=v
|
410
|
-
data_type=
|
421
|
+
pattern=v,
|
422
|
+
data_type=t_type,
|
423
|
+
)
|
424
|
+
# Remove pattern key
|
425
|
+
out[t_type].pop("pattern")
|
426
|
+
# Add path key
|
427
|
+
out[t_type].update({"path": base_dtype_pattern_path})
|
428
|
+
# Resolve pattern for nested data type
|
429
|
+
if isinstance(v, dict) and "pattern" in v:
|
430
|
+
# Set nested type key for easier access
|
431
|
+
t_nested_type = f"{t_type}.{k}"
|
432
|
+
logger.info(
|
433
|
+
f"Resolving path from pattern for {t_nested_type}"
|
434
|
+
)
|
435
|
+
# Resolve pattern
|
436
|
+
nested_dtype_pattern_path = (
|
437
|
+
self._get_path_from_patterns(
|
438
|
+
element=element,
|
439
|
+
pattern=v["pattern"],
|
440
|
+
data_type=t_nested_type,
|
441
|
+
)
|
442
|
+
)
|
443
|
+
# Remove pattern key
|
444
|
+
out[t_type][k].pop("pattern")
|
445
|
+
# Add path key
|
446
|
+
out[t_type][k].update(
|
447
|
+
{"path": nested_dtype_pattern_path}
|
411
448
|
)
|
412
|
-
)
|
413
|
-
# Remove pattern key
|
414
|
-
out[t_type][k].pop("pattern")
|
415
|
-
# Add path key
|
416
|
-
out[t_type][k].update(
|
417
|
-
{"path": nested_data_type_pattern_path}
|
418
|
-
)
|
419
449
|
|
420
450
|
return out
|
421
451
|
|