Skip to content

Commit eedcfcc

Browse files
committed
enh:new all_fmb_pipeline with just 1 interpolation
1 parent dfa8346 commit eedcfcc

File tree

2 files changed

+204
-43
lines changed

2 files changed

+204
-43
lines changed

nipype/workflows/dmri/preprocess/epi.py

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ def all_fmb_pipeline(name='hmc_sdc_ecc'):
1717
Builds a pipeline including three artifact corrections: head-motion correction (HMC),
1818
susceptibility-derived distortion correction (SDC), and Eddy currents-derived distortion
1919
correction (ECC).
20+
21+
The displacement fields from each kind of distortions are combined. Thus,
22+
only one interpolation occurs between input data and result.
23+
24+
.. warning:: this workflow rotates the gradients table (*b*-vectors) [Leemans09]_.
25+
26+
2027
"""
2128
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'in_bvec', 'in_bval',
2229
'bmap_pha', 'bmap_mag']), name='inputnode')
@@ -35,19 +42,16 @@ def all_fmb_pipeline(name='hmc_sdc_ecc'):
3542
hmc = hmc_pipeline()
3643
sdc = sdc_fmb()
3744
ecc = ecc_pipeline()
38-
39-
regrid = pe.Node(fs.MRIConvert(vox_size=(2.0, 2.0, 2.0), out_orientation='RAS'),
40-
name='Reslice')
45+
unwarp = apply_all_corrections()
4146

4247
wf = pe.Workflow('dMRI_Artifacts')
4348
wf.connect([
4449
(inputnode, hmc, [('in_file', 'inputnode.in_file'),
4550
('in_bvec', 'inputnode.in_bvec')])
4651
,(inputnode, avg_b0_0, [('in_file', 'in_dwi'),
4752
('in_bval', 'in_bval')])
48-
,(avg_b0_0, bet_dwi0, [('out_file','in_file')])
53+
,(avg_b0_0, bet_dwi0, [('out_file', 'in_file')])
4954
,(bet_dwi0, hmc, [('mask_file', 'inputnode.in_mask')])
50-
5155
,(hmc, sdc, [('outputnode.out_file', 'inputnode.in_file')])
5256
,(bet_dwi0, sdc, [('mask_file', 'inputnode.in_mask')])
5357
,(inputnode, sdc, [('in_bval', 'inputnode.in_bval'),
@@ -56,12 +60,17 @@ def all_fmb_pipeline(name='hmc_sdc_ecc'):
5660
,(inputnode, ecc, [('in_bval', 'inputnode.in_bval')])
5761
,(bet_dwi0, ecc, [('mask_file', 'inputnode.in_mask')])
5862
,(sdc, ecc, [('outputnode.out_file', 'inputnode.in_file')])
59-
,(hmc, outputnode, [('outputnode.out_bvec', 'out_bvec')])
60-
,(ecc, regrid, [('outputnode.out_file', 'in_file')])
61-
,(regrid, outputnode, [('out_file', 'out_file')])
62-
,(regrid, avg_b0_1, [('out_file', 'in_dwi')])
63+
,(ecc, avg_b0_1, [('outputnode.out_file', 'in_dwi')])
6364
,(inputnode, avg_b0_1, [('in_bval', 'in_bval')])
64-
,(avg_b0_1, bet_dwi1, [('out_file','in_file')])
65+
,(avg_b0_1, bet_dwi1, [('out_file', 'in_file')])
66+
67+
,(inputnode, unwarp, [('in_file', 'inputnode.in_dwi')])
68+
,(hmc, unwarp, [('outputnode.out_xfms', 'inputnode.in_hmc')])
69+
,(ecc, unwarp, [('outputnode.out_xfms', 'inputnode.in_ecc')])
70+
,(sdc, unwarp, [('outputnode.out_warp', 'inputnode.in_sdc')])
71+
72+
,(hmc, outputnode, [('outputnode.out_bvec', 'out_bvec')])
73+
,(unwarp, outputnode, [('outputnode.out_file', 'out_file')])
6574
,(bet_dwi1, outputnode, [('mask_file', 'out_mask')])
6675
])
6776
return wf
@@ -80,6 +89,10 @@ def all_peb_pipeline(name='hmc_sdc_ecc',
8089
Builds a pipeline including three artifact corrections: head-motion correction (HMC),
8190
susceptibility-derived distortion correction (SDC), and Eddy currents-derived distortion
8291
correction (ECC).
92+
93+
.. warning:: this workflow rotates the gradients table (*b*-vectors) [Leemans09]_.
94+
95+
8396
"""
8497
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'in_bvec', 'in_bval',
8598
'alt_file']), name='inputnode')
@@ -98,13 +111,6 @@ def all_peb_pipeline(name='hmc_sdc_ecc',
98111
sdc = sdc_peb(epi_params=epi_params, altepi_params=altepi_params)
99112
ecc = ecc_pipeline()
100113

101-
rot_bvec = pe.Node(niu.Function(input_names=['in_bvec', 'eddy_params'],
102-
output_names=['out_file'], function=eddy_rotate_bvecs),
103-
name='Rotate_Bvec')
104-
105-
regrid = pe.Node(fs.MRIConvert(vox_size=(2.0, 2.0, 2.0), out_orientation='RAS'),
106-
name='Reslice')
107-
108114
wf = pe.Workflow('dMRI_Artifacts')
109115
wf.connect([
110116
(inputnode, hmc, [('in_file', 'inputnode.in_file'),
@@ -120,16 +126,12 @@ def all_peb_pipeline(name='hmc_sdc_ecc',
120126
,(inputnode, ecc, [('in_bval', 'inputnode.in_bval')])
121127
,(bet_dwi0, ecc, [('mask_file', 'inputnode.in_mask')])
122128
,(sdc, ecc, [('outputnode.out_file', 'inputnode.in_file')])
123-
,(hmc, outputnode, [('outputnode.out_bvec', 'out_bvec')])
124-
,(ecc, regrid, [('outputnode.out_file', 'in_file')])
125-
,(regrid, outputnode, [('out_file', 'out_file')])
126-
,(regrid, avg_b0_1, [('out_file', 'in_dwi')])
129+
,(ecc, avg_b0_1, [('outputnode.out_file', 'in_dwi')])
127130
,(inputnode, avg_b0_1, [('in_bval', 'in_bval')])
128131
,(avg_b0_1, bet_dwi1, [('out_file','in_file')])
129-
,(inputnode, rot_bvec, [('in_bvec', 'in_bvec')])
130-
,(ecc, rot_bvec, [('out_parameter', 'eddy_params')])
132+
,(ecc, outputnode, [('outputnode.out_file', 'out_file')])
133+
,(hmc, outputnode, [('outputnode.out_bvec', 'out_bvec')])
131134
,(bet_dwi1, outputnode, [('mask_file', 'out_mask')])
132-
,(rot_bvec, outputnode, [('out_file', 'out_bvec')])
133135
])
134136
return wf
135137

@@ -143,6 +145,15 @@ def all_fsl_pipeline(name='fsl_all_correct',
143145
enc_dir='y')):
144146
"""
145147
Workflow that integrates FSL ``topup`` and ``eddy``.
148+
149+
150+
.. warning:: this workflow rotates the gradients table (*b*-vectors) [Leemans09]_.
151+
152+
153+
.. warning:: this workflow does not perform jacobian modulation of each
154+
*DWI* [Jones10]_.
155+
156+
146157
"""
147158

148159
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'in_bvec', 'in_bval',
@@ -166,9 +177,9 @@ def _gen_index(in_file):
166177

167178
sdc = sdc_peb(epi_params=epi_params, altepi_params=altepi_params)
168179
ecc = pe.Node(fsl.Eddy(method='jac'), name='fsl_eddy')
169-
170-
regrid = pe.Node(fs.MRIConvert(vox_size=(2.0, 2.0, 2.0), out_orientation='RAS'),
171-
name='Reslice')
180+
rot_bvec = pe.Node(niu.Function(input_names=['in_bvec', 'eddy_params'],
181+
output_names=['out_file'], function=eddy_rotate_bvecs),
182+
name='Rotate_Bvec')
172183
avg_b0_1 = pe.Node(niu.Function(input_names=['in_dwi', 'in_bval'],
173184
output_names=['out_file'], function=b0_average), name='b0_avg_post')
174185
bet_dwi1 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True), name='bet_dwi_post')
@@ -191,11 +202,13 @@ def _gen_index(in_file):
191202
(('in_file', _gen_index), 'in_index'),
192203
('in_bval', 'in_bval'),
193204
('in_bvec', 'in_bvec')])
194-
,(ecc, regrid, [('out_corrected', 'in_file')])
195-
,(regrid, outputnode, [('out_file', 'out_file')])
196-
,(regrid, avg_b0_1, [('out_file', 'in_dwi')])
205+
,(inputnode, rot_bvec, [('in_bvec', 'in_bvec')])
206+
,(ecc, rot_bvec, [('out_parameter', 'eddy_params')])
207+
,(ecc, avg_b0_1, [('out_corrected', 'in_dwi')])
197208
,(inputnode, avg_b0_1, [('in_bval', 'in_bval')])
198209
,(avg_b0_1, bet_dwi1, [('out_file','in_file')])
210+
,(ecc, outputnode, [('out_corrected', 'out_file')])
211+
,(rot_bvec, outputnode, [('out_file', 'out_bvec')])
199212
,(bet_dwi1, outputnode, [('mask_file', 'out_mask')])
200213
])
201214
return wf
@@ -444,12 +457,14 @@ def sdc_fmb(name='fmb_correction',
444457
<http://dx.doi.org/10.1002/mrm.10354>`_, MRM 49(1):193-197, 2003, doi: 10.1002/mrm.10354.
445458
446459
"""
447-
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'in_bval', 'in_mask',
448-
'bmap_pha', 'bmap_mag']),
460+
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'in_bval',
461+
'in_mask', 'bmap_pha', 'bmap_mag']),
449462
name='inputnode')
450-
outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_vsm']),
463+
outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_vsm',
464+
'out_warp']),
451465
name='outputnode')
452466

467+
delta_te = epi_params['echospacing'] / (1.0 * epi_params['acc_factor'])
453468

454469
firstmag = pe.Node(fsl.ExtractROI(t_min=0, t_size=1), name='GetFirst')
455470
n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='Bias')
@@ -487,15 +502,18 @@ def sdc_fmb(name='fmb_correction',
487502
vsm = pe.Node(fsl.FUGUE(save_shift=True, **fugue_params),
488503
name="ComputeVSM")
489504
vsm.inputs.asym_se_time = bmap_params['delta_te']
490-
vsm.inputs.dwell_time = epi_params['echospacing'] / (1.0 * epi_params['acc_factor'])
505+
vsm.inputs.dwell_time = delta_te
491506

492507
split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs')
493508
merge = pe.Node(fsl.Merge(dimension='t'), name='MergeDWIs')
494509
unwarp = pe.MapNode(fsl.FUGUE(icorr=True, forward_warping=False),
495510
iterfield=['in_file'], name='UnwarpDWIs')
496-
unwarp.inputs.unwarp_direction=epi_params['enc_dir']
511+
unwarp.inputs.unwarp_direction = epi_params['enc_dir']
497512
thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'],
498513
name='RemoveNegative')
514+
vsm2dfm = vsm2warp()
515+
vsm2dfm.inputs.inputnode.scaling = 1.0
516+
vsm2dfm.inputs.inputnode.enc_dir = epi_params['enc_dir']
499517

500518
wf = pe.Workflow(name=name)
501519
wf.connect([
@@ -531,8 +549,11 @@ def sdc_fmb(name='fmb_correction',
531549
,(vsm, unwarp, [('shift_out_file', 'shift_in_file')])
532550
,(unwarp, thres, [('unwarped_file', 'in_file')])
533551
,(thres, merge, [('out_file', 'in_files')])
552+
,(merge, vsm2dfm, [('merged_file', 'inputnode.in_ref')])
553+
,(vsm, vsm2dfm, [('shift_out_file', 'inputnode.in_vsm')])
534554
,(merge, outputnode, [('merged_file', 'out_file')])
535555
,(vsm, outputnode, [('shift_out_file', 'out_vsm')])
556+
,(vsm2dfm, outputnode, [('outputnode.out_warp', 'out_warp')])
536557
])
537558
return wf
538559

0 commit comments

Comments
 (0)