33
33
echo-planar imaging (EPI) references """
34
34
_PEPOLAR_METHOD = "PEB/PEPOLAR (phase-encoding based / PE-POLARity)"
35
35
36
+
36
37
def init_topup_wf (
37
38
grid_reference = 0 ,
38
39
omp_nthreads = 1 ,
@@ -92,7 +93,11 @@ def init_topup_wf(
92
93
93
94
from ...interfaces .bspline import TOPUPCoeffReorient
94
95
from ...interfaces .epi import GetReadoutTime , SortPEBlips
95
- from ...interfaces .utils import PadSlices , ReorientImageAndMetadata , UniformGrid
96
+ from ...interfaces .utils import (
97
+ PadSlices ,
98
+ ReorientImageAndMetadata ,
99
+ UniformGrid ,
100
+ )
96
101
from ...utils .misc import front as _front
97
102
from ..ancillary import init_brainextraction_wf
98
103
@@ -101,7 +106,9 @@ def init_topup_wf(
101
106
{ _PEPOLAR_DESC } with `topup` (@topup; FSL { TOPUP ().version } ).
102
107
"""
103
108
104
- inputnode = pe .Node (niu .IdentityInterface (fields = INPUT_FIELDS ), name = "inputnode" )
109
+ inputnode = pe .Node (
110
+ niu .IdentityInterface (fields = INPUT_FIELDS ), name = "inputnode"
111
+ )
105
112
outputnode = pe .Node (
106
113
niu .IdentityInterface (
107
114
fields = [
@@ -139,19 +146,23 @@ def init_topup_wf(
139
146
SortPEBlips (), name = "sort_pe_blips" , run_without_submitting = True
140
147
)
141
148
# Merge into one 4D file
142
- concat_blips = pe .Node (MergeSeries (affine_tolerance = 1e-4 ), name = "concat_blips" )
149
+ concat_blips = pe .Node (
150
+ MergeSeries (affine_tolerance = 1e-4 ), name = "concat_blips"
151
+ )
143
152
# Pad dimensions so that they meet TOPUP's expectations
144
153
pad_blip_slices = pe .Node (PadSlices (), name = "pad_blip_slices" )
145
154
# Run 3dVolReg between runs: uses RobustAverage for consistency and to generate
146
155
# debugging artifacts (typically, one wants to look at the average across uncorrected runs)
147
- setwise_avg = pe .Node (RobustAverage (num_threads = omp_nthreads ), name = "setwise_avg" )
156
+ setwise_avg = pe .Node (
157
+ RobustAverage (num_threads = omp_nthreads ), name = "setwise_avg"
158
+ )
148
159
# The core of the implementation
149
160
# Feed the input images in LAS orientation, so FSL does not run funky reorientations
150
- to_las = pe .Node (ReorientImageAndMetadata (target_orientation = "LAS" ), name = "to_las" )
161
+ to_las = pe .Node (
162
+ ReorientImageAndMetadata (target_orientation = "LAS" ), name = "to_las"
163
+ )
151
164
topup = pe .Node (
152
- TOPUP (
153
- config = str (data .load (f"flirtsch/b02b0{ '_quick' * sloppy } .cnf" ))
154
- ),
165
+ TOPUP (config = str (data .load (f"flirtsch/b02b0{ '_quick' * sloppy } .cnf" ))),
155
166
name = "topup" ,
156
167
)
157
168
# "Generalize" topup coefficients and store them in a spatially-correct NIfTI file
@@ -160,7 +171,9 @@ def init_topup_wf(
160
171
)
161
172
162
173
# Average the output
163
- ref_average = pe .Node (RobustAverage (num_threads = omp_nthreads ), name = "ref_average" )
174
+ ref_average = pe .Node (
175
+ RobustAverage (num_threads = omp_nthreads ), name = "ref_average"
176
+ )
164
177
165
178
# Sophisticated brain extraction of fMRIPrep
166
179
brainextraction_wf = init_brainextraction_wf ()
@@ -238,10 +251,8 @@ def init_topup_wf(
238
251
239
252
240
253
def init_3dQwarp_wf (
241
- omp_nthreads = 1 ,
242
- debug = False ,
243
- sloppy = False ,
244
- name = "pepolar_estimate_wf" ):
254
+ omp_nthreads = 1 , debug = False , sloppy = False , name = "pepolar_estimate_wf"
255
+ ):
245
256
"""
246
257
Create the PEPOLAR field estimation workflow based on AFNI's ``3dQwarp``.
247
258
@@ -251,8 +262,8 @@ def init_3dQwarp_wf(
251
262
``3dQwarp`` is used to generate a displacement field and correct
252
263
the reference image. The workflow also returns an estimated fieldmap,
253
264
which is the result of converting the displacement field to a fieldmap
254
- and then regularizing it with a bspline field. This means that the unwarped
255
- image is in general not what one would get by reconstructing the fieldmap
265
+ and then regularizing it with a bspline field. This means that the unwarped
266
+ image is in general not what one would get by reconstructing the fieldmap
256
267
from fmap_coeff and warping the in_data.
257
268
258
269
Workflow Graph
@@ -276,11 +287,11 @@ def init_3dQwarp_wf(
276
287
------
277
288
in_data : :obj:`list` of :obj:`str`
278
289
A list of two EPI files, the first of which will be taken as reference.
279
- The reference PhaseEncodingDirection should match the value for
290
+ The reference PhaseEncodingDirection should match the value for
280
291
in_reference.
281
292
metadata : :obj:`list` of :obj:`dict`
282
- A list with length matching the length of in_data. Each element should be a
283
- dict with keys that are strings and values of any type. One key should be
293
+ A list with length matching the length of in_data. Each element should be a
294
+ dict with keys that are strings and values of any type. One key should be
284
295
PhaseEncodingDirection and the values should be BIDS-valid codings.
285
296
286
297
Outputs
@@ -301,7 +312,9 @@ def init_3dQwarp_wf(
301
312
"""
302
313
from nipype .interfaces import afni
303
314
from niworkflows .func .util import init_enhance_and_skullstrip_bold_wf
304
- from niworkflows .interfaces .fixes import FixHeaderRegistration as Registration
315
+ from niworkflows .interfaces .fixes import (
316
+ FixHeaderRegistration as Registration ,
317
+ )
305
318
from niworkflows .interfaces .freesurfer import StructuralReference
306
319
from niworkflows .interfaces .header import CopyHeader
307
320
@@ -316,7 +329,6 @@ def init_3dQwarp_wf(
316
329
from ...interfaces .utils import ConvertWarp , Flatten
317
330
from ...utils .misc import front , last
318
331
319
-
320
332
workflow = Workflow (name = name )
321
333
workflow .__desc__ = f"""{ _PEPOLAR_DESC } \
322
334
with `3dQwarp` (@afni; AFNI { '' .join (['%02d' % v for v in afni .Info ().version () or []])} ).
@@ -329,13 +341,15 @@ def init_3dQwarp_wf(
329
341
outputnode = pe .Node (
330
342
niu .IdentityInterface (
331
343
fields = [
332
- "fmap" ,
333
- "fmap_ref" ,
334
- "fmap_mask" ,
335
- "fmap_coeff" ,
344
+ "fmap" ,
345
+ "fmap_ref" ,
346
+ "fmap_mask" ,
347
+ "fmap_coeff" ,
336
348
"method" ,
337
- "out_warps" ]),
338
- name = "outputnode"
349
+ "out_warps" ,
350
+ ]
351
+ ),
352
+ name = "outputnode" ,
339
353
)
340
354
outputnode .inputs .method = _PEPOLAR_METHOD
341
355
@@ -347,7 +361,9 @@ def init_3dQwarp_wf(
347
361
348
362
flatten = pe .Node (Flatten (), name = "flatten" )
349
363
sort_pe = pe .Node (
350
- niu .Function (function = _sorted_pe , output_names = ["sorted" , "qwarp_args" ]),
364
+ niu .Function (
365
+ function = _sorted_pe , output_names = ["sorted" , "qwarp_args" ]
366
+ ),
351
367
name = "sort_pe" ,
352
368
run_without_submitting = True ,
353
369
)
@@ -499,11 +515,14 @@ def _sorted_pe(inlist):
499
515
elif pe [0 ] == ref_pe [0 ]:
500
516
out_opp .append (d )
501
517
else :
502
- raise ValueError ("Cannot handle orthogonal PE encodings." )
518
+ msg = "Cannot handle orthogonal PE encodings."
519
+ raise ValueError (msg )
503
520
504
521
return (
505
522
[out_ref , out_opp ],
506
- {"i" : "-noYdis -noZdis" , "j" : "-noXdis -noZdis" , "k" : "-noXdis -noYdis" }[
507
- ref_pe [0 ]
508
- ],
523
+ {
524
+ "i" : "-noYdis -noZdis" ,
525
+ "j" : "-noXdis -noZdis" ,
526
+ "k" : "-noXdis -noYdis" ,
527
+ }[ref_pe [0 ]],
509
528
)
0 commit comments