Skip to content

Commit 9c98d0c

Browse files
committed
fixed:hmc should not perform registration of ref volume
1 parent cf912a5 commit 9c98d0c

File tree

3 files changed

+144
-63
lines changed

3 files changed

+144
-63
lines changed

examples/dmri_preprocessing.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# @Author: oesteban
44
# @Date: 2014-08-31 20:32:22
55
# @Last Modified by: oesteban
6-
# @Last Modified time: 2014-09-02 13:12:12
6+
# @Last Modified time: 2014-09-04 10:55:15
77
"""
88
===================
99
dMRI: Preprocessing
@@ -175,4 +175,3 @@
175175
if __name__ == '__main__':
176176
wf.run()
177177
wf.write_graph()
178-

nipype/workflows/dmri/preprocess/epi.py

Lines changed: 66 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def all_peb_pipeline(name='hmc_sdc_ecc',
127127
('in_bval', 'inputnode.in_bval')])
128128
,(inputnode, avg_b0_0, [('in_file', 'in_dwi'),
129129
('in_bval', 'in_bval')])
130-
,(avg_b0_0, bet_dwi0, [('out_file','in_file')])
130+
,(avg_b0_0, bet_dwi0, [('out_file', 'in_file')])
131131
,(bet_dwi0, hmc, [('mask_file', 'inputnode.in_mask')])
132132
,(hmc, sdc, [('outputnode.out_file', 'inputnode.in_file')])
133133
,(bet_dwi0, sdc, [('mask_file', 'inputnode.in_mask')])
@@ -138,7 +138,7 @@ def all_peb_pipeline(name='hmc_sdc_ecc',
138138
,(bet_dwi0, ecc, [('mask_file', 'inputnode.in_mask')])
139139
,(ecc, avg_b0_1, [('outputnode.out_file', 'in_dwi')])
140140
,(inputnode, avg_b0_1, [('in_bval', 'in_bval')])
141-
,(avg_b0_1, bet_dwi1, [('out_file','in_file')])
141+
,(avg_b0_1, bet_dwi1, [('out_file', 'in_file')])
142142

143143

144144
,(inputnode, unwarp, [('in_file', 'inputnode.in_dwi')])
@@ -189,17 +189,21 @@ def _gen_index(in_file):
189189
return out_file
190190

191191
avg_b0_0 = pe.Node(niu.Function(input_names=['in_dwi', 'in_bval'],
192-
output_names=['out_file'], function=b0_average), name='b0_avg_pre')
193-
bet_dwi0 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True), name='bet_dwi_pre')
192+
output_names=['out_file'], function=b0_average),
193+
name='b0_avg_pre')
194+
bet_dwi0 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True),
195+
name='bet_dwi_pre')
194196

195197
sdc = sdc_peb(epi_params=epi_params, altepi_params=altepi_params)
196198
ecc = pe.Node(fsl.Eddy(method='jac'), name='fsl_eddy')
197199
rot_bvec = pe.Node(niu.Function(input_names=['in_bvec', 'eddy_params'],
198200
output_names=['out_file'], function=eddy_rotate_bvecs),
199201
name='Rotate_Bvec')
200202
avg_b0_1 = pe.Node(niu.Function(input_names=['in_dwi', 'in_bval'],
201-
output_names=['out_file'], function=b0_average), name='b0_avg_post')
202-
bet_dwi1 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True), name='bet_dwi_post')
203+
output_names=['out_file'], function=b0_average),
204+
name='b0_avg_post')
205+
bet_dwi1 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True),
206+
name='bet_dwi_post')
203207

204208
wf = pe.Workflow('dMRI_Artifacts_FSL')
205209
wf.connect([
@@ -235,30 +239,37 @@ def hmc_pipeline(name='motion_correct'):
235239
"""
236240
HMC stands for head-motion correction.
237241
238-
Creates a pipeline that corrects for head motion artifacts in dMRI sequences.
242+
Creates a pipeline that corrects for head motion artifacts in dMRI
243+
sequences.
239244
It takes a series of diffusion weighted images and rigidly co-registers
240-
them to one reference image. Finally, the `b`-matrix is rotated accordingly [Leemans09]_
241-
making use of the rotation matrix obtained by FLIRT.
245+
them to one reference image. Finally, the `b`-matrix is rotated accordingly
246+
[Leemans09]_ making use of the rotation matrix obtained by FLIRT.
242247
243-
Search angles have been limited to 4 degrees, based on results in [Yendiki13]_.
248+
Search angles have been limited to 4 degrees, based on results in
249+
[Yendiki13]_.
244250
245-
A list of rigid transformation matrices is provided, so that transforms can be
246-
chained. This is useful to correct for artifacts with only one interpolation process (as
247-
previously discussed `here <https://github.com/nipy/nipype/pull/530#issuecomment-14505042>`_),
251+
A list of rigid transformation matrices is provided, so that transforms
252+
can be chained.
253+
This is useful to correct for artifacts with only one interpolation process
254+
(as previously discussed `here
255+
<https://github.com/nipy/nipype/pull/530#issuecomment-14505042>`_),
248256
and also to compute nuisance regressors as proposed by [Yendiki13]_.
249257
250258
.. warning:: This workflow rotates the `b`-vectors, so please be advised
251-
that not all the dicom converters ensure the consistency between the resulting
252-
nifti orientation and the gradients table (e.g. dcm2nii checks it).
259+
that not all the dicom converters ensure the consistency between the
260+
resulting nifti orientation and the gradients table (e.g. dcm2nii
261+
checks it).
253262
254263
.. admonition:: References
255264
256-
.. [Leemans09] Leemans A, and Jones DK, `The B-matrix must be rotated when correcting
257-
for subject motion in DTI data <http://dx.doi.org/10.1002/mrm.21890>`_,
265+
.. [Leemans09] Leemans A, and Jones DK, `The B-matrix must be rotated
266+
when correcting for subject motion in DTI data
267+
<http://dx.doi.org/10.1002/mrm.21890>`_,
258268
Magn Reson Med. 61(6):1336-49. 2009. doi: 10.1002/mrm.21890.
259269
260-
.. [Yendiki13] Yendiki A et al., `Spurious group differences due to head motion in
261-
a diffusion MRI study <http://dx.doi.org/10.1016/j.neuroimage.2013.11.027>`_.
270+
.. [Yendiki13] Yendiki A et al., `Spurious group differences due to head
271+
motion in a diffusion MRI study
272+
<http://dx.doi.org/10.1016/j.neuroimage.2013.11.027>`_.
262273
Neuroimage. 21(88C):79-90. 2013. doi: 10.1016/j.neuroimage.2013.11.027
263274
264275
Example
@@ -288,15 +299,23 @@ def hmc_pipeline(name='motion_correct'):
288299
outputnode.out_xfms - list of transformation matrices
289300
290301
"""
291-
params = dict(interp='spline', cost='normmi',
292-
cost_func='normmi', dof=6, bins=64, save_log=True,
293-
searchr_x=[-4, 4], searchr_y=[-4, 4], searchr_z=[-4, 4],
294-
fine_search=1, coarse_search=10, padding_size=1)
302+
params = dict(dof=6, interp='spline', padding_size=10, save_log=True,
303+
searchr_x=[-3, 3], searchr_y=[-3, 3], searchr_z=[-3, 3],
304+
fine_search=1, coarse_search=2)
305+
# cost='normmi', cost_func='normmi', bins=64,
295306

296307
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'ref_num',
297308
'in_bvec', 'in_bval', 'in_mask']), name='inputnode')
298-
pick_ref = pe.Node(fsl.ExtractROI(t_size=1), name='GetB0')
309+
refid = pe.Node(niu.IdentityInterface(fields=['ref_num']),
310+
name='RefVolume')
311+
pick_ref = pe.Node(fsl.ExtractROI(t_size=1), name='GetRef')
312+
pick_mov = pe.Node(niu.Function(input_names=['in_file', 'volid'],
313+
output_names=['out_file'], function=remove_comp),
314+
name='GetMovingDWs')
299315
flirt = dwi_flirt(flirt_param=params)
316+
insmat = pe.Node(niu.Function(input_names=['inlist', 'volid'],
317+
output_names=['out'], function=insert_mat),
318+
name='InsertRefmat')
300319
rot_bvec = pe.Node(niu.Function(input_names=['in_bvec', 'in_matrix'],
301320
output_names=['out_file'], function=rotate_bvecs),
302321
name='Rotate_Bvec')
@@ -306,17 +325,22 @@ def hmc_pipeline(name='motion_correct'):
306325

307326
wf = pe.Workflow(name=name)
308327
wf.connect([
309-
(inputnode, pick_ref, [('in_file', 'in_file'),
310-
(('ref_num', _checkrnum), 't_min')])
328+
(inputnode, refid, [(('ref_num', _checkrnum), 'ref_num')])
329+
,(inputnode, pick_ref, [('in_file', 'in_file')])
330+
,(refid, pick_ref, [('ref_num', 't_min')])
331+
,(inputnode, pick_mov, [('in_file', 'in_file')])
332+
,(refid, pick_mov, [('ref_num', 'volid')])
311333
,(inputnode, flirt, [('in_file', 'inputnode.in_file'),
312334
('in_mask', 'inputnode.ref_mask'),
313335
('in_bval', 'inputnode.in_bval')])
314336
,(pick_ref, flirt, [('roi_file', 'inputnode.reference')])
337+
,(flirt, insmat, [('outputnode.out_xfms', 'inlist')])
338+
,(refid, insmat, [('ref_num', 'volid')])
315339
,(inputnode, rot_bvec, [('in_bvec', 'in_bvec')])
316-
,(flirt, rot_bvec, [('outputnode.out_xfms', 'in_matrix')])
340+
,(insmat, rot_bvec, [('out', 'in_matrix')])
317341
,(rot_bvec, outputnode, [('out_file', 'out_bvec')])
318-
,(flirt, outputnode, [('outputnode.out_xfms', 'out_xfms'),
319-
('outputnode.out_file', 'out_file')])
342+
,(flirt, outputnode, [('outputnode.out_file', 'out_file')])
343+
,(insmat, outputnode, [('out', 'out_xfms')])
320344
])
321345
return wf
322346

@@ -375,9 +399,8 @@ def ecc_pipeline(name='eddy_correct'):
375399
outputnode.out_file - corrected dwi file
376400
outputnode.out_xfms - list of transformation matrices
377401
"""
378-
params = dict(no_search=True, interp='spline', cost='normmi',
379-
cost_func='normmi', dof=12, bins=64,
380-
padding_size=1)
402+
params = dict(dof=12, no_search=True, interp='spline', padding_size=1, save_log=True)
403+
# cost='normmi', cost_func='normmi', bins=64,
381404

382405
inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'in_bval',
383406
'in_mask', 'in_xfms']), name='inputnode')
@@ -638,17 +661,20 @@ def sdc_peb(name='peb_correction',
638661
topup = pe.Node(fsl.TOPUP(), name='topup')
639662
topup.inputs.encoding_direction = [epi_params['enc_dir'],
640663
altepi_params['enc_dir']]
641-
topup.inputs.readout_times = [compute_readout(epi_params),
664+
665+
readout = compute_readout(epi_params)
666+
topup.inputs.readout_times = [readout,
642667
compute_readout(altepi_params)]
643668

644669
unwarp = pe.Node(fsl.ApplyTOPUP(in_index=[1], method='jac'), name='unwarp')
645670

646-
scaling = pe.Node(niu.Function(input_names=['in_file', 'enc_dir'],
647-
output_names=['factor'], function=_get_zoom),
648-
name='GetZoom')
649-
scaling.inputs.enc_dir = epi_params['enc_dir']
671+
#scaling = pe.Node(niu.Function(input_names=['in_file', 'enc_dir'],
672+
# output_names=['factor'], function=_get_zoom),
673+
# name='GetZoom')
674+
#scaling.inputs.enc_dir = epi_params['enc_dir']
650675
vsm2dfm = vsm2warp()
651676
vsm2dfm.inputs.inputnode.enc_dir = epi_params['enc_dir']
677+
vsm2dfm.inputs.inputnode.scaling = readout
652678

653679
wf = pe.Workflow(name=name)
654680
wf.connect([
@@ -666,9 +692,9 @@ def sdc_peb(name='peb_correction',
666692
,(inputnode, unwarp, [('in_file', 'in_files')])
667693
,(unwarp, outputnode, [('out_corrected', 'out_file')])
668694

669-
,(b0_ref, scaling, [('roi_file', 'in_file')])
695+
#,(b0_ref, scaling, [('roi_file', 'in_file')])
696+
#,(scaling, vsm2dfm, [('factor', 'inputnode.scaling')])
670697
,(b0_ref, vsm2dfm, [('roi_file', 'inputnode.in_ref')])
671-
,(scaling, vsm2dfm, [('factor', 'inputnode.scaling')])
672698
,(topup, vsm2dfm, [('out_field', 'inputnode.in_vsm')])
673699
,(topup, outputnode, [('out_field', 'out_vsm')])
674700
,(vsm2dfm, outputnode, [('outputnode.out_warp', 'out_warp')])
@@ -745,7 +771,7 @@ def _xfm_jacobian(in_xfm):
745771
def _get_zoom(in_file, enc_dir):
746772
import nibabel as nb
747773

748-
zooms = nb.load(in_file).get_zooms()
774+
zooms = nb.load(in_file).get_header().get_zooms()
749775

750776
if 'y' in enc_dir:
751777
return zooms[1]

0 commit comments

Comments
 (0)