def ecc_pipeline(name='eddy_correct'): """ ECC stands for Eddy currents correction. Creates a pipeline that corrects for artifacts induced by Eddy currents in dMRI sequences. It takes a series of diffusion weighted images and linearly co-registers them to one reference image (the average of all b0s in the dataset). DWIs are also modulated by the determinant of the Jacobian as indicated by [Jones10]_ and [Rohde04]_. A list of rigid transformation matrices can be provided, sourcing from a :func:`.hmc_pipeline` workflow, to initialize registrations in a *motion free* framework. A list of affine transformation matrices is available as output, so that transforms can be chained (discussion `here <https://github.com/nipy/nipype/pull/530#issuecomment-14505042>`_). .. admonition:: References .. [Jones10] Jones DK, `The signal intensity must be modulated by the determinant of the Jacobian when correcting for eddy currents in diffusion MRI <http://cds.ismrm.org/protected/10MProceedings/files/1644_129.pdf>`_, Proc. ISMRM 18th Annual Meeting, (2010). .. [Rohde04] Rohde et al., `Comprehensive Approach for Correction of Motion and Distortion in Diffusion-Weighted MRI <http://stbb.nichd.nih.gov/pdf/com_app_cor_mri04.pdf>`_, MRM 51:103-114 (2004). Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import ecc_pipeline >>> ecc = ecc_pipeline() >>> ecc.inputs.inputnode.in_file = 'diffusion.nii' >>> ecc.inputs.inputnode.in_bval = 'diffusion.bval' >>> ecc.inputs.inputnode.in_mask = 'mask.nii' >>> ecc.run() # doctest: +SKIP Inputs:: inputnode.in_file - input dwi file inputnode.in_mask - weights mask of reference image (a file with data \ range sin [0.0, 1.0], indicating the weight of each voxel when computing the \ metric. inputnode.in_bval - b-values table inputnode.in_xfms - list of matrices to initialize registration (from \ head-motion correction) Outputs:: outputnode.out_file - corrected dwi file outputnode.out_xfms - list of transformation matrices """ from nipype.workflows.data import get_flirt_schedule params = dict(dof=12, no_search=True, interp='spline', bgvalue=0, schedule=get_flirt_schedule('ecc')) # cost='normmi', cost_func='normmi', bins=64, inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bval', 'in_mask', 'in_xfms']), name='inputnode') avg_b0 = pe.Node(niu.Function(input_names=['in_dwi', 'in_bval'], output_names=['out_file'], function=b0_average), name='b0_avg') pick_dws = pe.Node(niu.Function(input_names=['in_dwi', 'in_bval', 'b'], output_names=['out_file'], function=extract_bval), name='ExtractDWI') pick_dws.inputs.b = 'diff' flirt = dwi_flirt(flirt_param=params, excl_nodiff=True) mult = pe.MapNode(fsl.BinaryMaths(operation='mul'), name='ModulateDWIs', iterfield=['in_file', 'operand_value']) thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'], name='RemoveNegative') split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs') get_mat = pe.Node(niu.Function(input_names=['in_bval', 'in_xfms'], output_names=['out_files'], function=recompose_xfm), name='GatherMatrices') merge = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval', 'in_corrected'], output_names=['out_file'], function=recompose_dwi), name='MergeDWIs') outputnode = pe.Node( niu.IdentityInterface(fields=['out_file', 'out_xfms']), name='outputnode') wf = pe.Workflow(name=name) wf.connect([(inputnode, avg_b0, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, pick_dws, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, merge, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, flirt, [('in_mask', 'inputnode.ref_mask'), ('in_xfms', 'inputnode.in_xfms'), ('in_bval', 'inputnode.in_bval')]), (inputnode, get_mat, [('in_bval', 'in_bval')]), (avg_b0, flirt, [('out_file', 'inputnode.reference')]), (pick_dws, flirt, [('out_file', 'inputnode.in_file')]), (flirt, get_mat, [('outputnode.out_xfms', 'in_xfms')]), (flirt, mult, [(('outputnode.out_xfms', _xfm_jacobian), 'operand_value')]), (flirt, split, [('outputnode.out_file', 'in_file')]), (split, mult, [('out_files', 'in_file')]), (mult, thres, [('out_file', 'in_file')]), (thres, merge, [('out_file', 'in_corrected')]), (get_mat, outputnode, [('out_files', 'out_xfms')]), (merge, outputnode, [('out_file', 'out_file')])]) return wf
def hmc_pipeline(name='motion_correct'): """ HMC stands for head-motion correction. Creates a pipeline that corrects for head motion artifacts in dMRI sequences. It takes a series of diffusion weighted images and rigidly co-registers them to one reference image. Finally, the `b`-matrix is rotated accordingly [Leemans09]_ making use of the rotation matrix obtained by FLIRT. Search angles have been limited to 4 degrees, based on results in [Yendiki13]_. A list of rigid transformation matrices is provided, so that transforms can be chained. This is useful to correct for artifacts with only one interpolation process (as previously discussed `here <https://github.com/nipy/nipype/pull/530#issuecomment-14505042>`_), and also to compute nuisance regressors as proposed by [Yendiki13]_. .. warning:: This workflow rotates the `b`-vectors, so please be advised that not all the dicom converters ensure the consistency between the resulting nifti orientation and the gradients table (e.g. dcm2nii checks it). .. admonition:: References .. [Leemans09] Leemans A, and Jones DK, `The B-matrix must be rotated when correcting for subject motion in DTI data <http://dx.doi.org/10.1002/mrm.21890>`_, Magn Reson Med. 61(6):1336-49. 2009. doi: 10.1002/mrm.21890. .. [Yendiki13] Yendiki A et al., `Spurious group differences due to head motion in a diffusion MRI study <http://dx.doi.org/10.1016/j.neuroimage.2013.11.027>`_. Neuroimage. 21(88C):79-90. 2013. doi: 10.1016/j.neuroimage.2013.11.027 Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import hmc_pipeline >>> hmc = hmc_pipeline() >>> hmc.inputs.inputnode.in_file = 'diffusion.nii' >>> hmc.inputs.inputnode.in_bvec = 'diffusion.bvec' >>> hmc.inputs.inputnode.in_bval = 'diffusion.bval' >>> hmc.inputs.inputnode.in_mask = 'mask.nii' >>> hmc.run() # doctest: +SKIP Inputs:: inputnode.in_file - input dwi file inputnode.in_mask - weights mask of reference image (a file with data \ range in [0.0, 1.0], indicating the weight of each voxel when computing the \ metric. inputnode.in_bvec - gradients file (b-vectors) inputnode.ref_num (optional, default=0) index of the b0 volume that \ should be taken as reference Outputs:: outputnode.out_file - corrected dwi file outputnode.out_bvec - rotated gradient vectors table outputnode.out_xfms - list of transformation matrices """ from nipype.workflows.data import get_flirt_schedule params = dict( dof=6, bgvalue=0, save_log=True, no_search=True, # cost='mutualinfo', cost_func='mutualinfo', bins=64, schedule=get_flirt_schedule('hmc')) inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'ref_num', 'in_bvec', 'in_bval', 'in_mask']), name='inputnode') split = pe.Node(niu.Function( output_names=['out_ref', 'out_mov', 'out_bval', 'volid'], input_names=['in_file', 'in_bval', 'ref_num'], function=hmc_split), name='SplitDWI') flirt = dwi_flirt(flirt_param=params) insmat = pe.Node(niu.Function(input_names=['inlist', 'volid'], output_names=['out'], function=insert_mat), name='InsertRefmat') rot_bvec = pe.Node(niu.Function(function=rotate_bvecs, input_names=['in_bvec', 'in_matrix'], output_names=['out_file']), name='Rotate_Bvec') outputnode = pe.Node( niu.IdentityInterface(fields=['out_file', 'out_bvec', 'out_xfms']), name='outputnode') wf = pe.Workflow(name=name) wf.connect([(inputnode, split, [('in_file', 'in_file'), ('in_bval', 'in_bval'), ('ref_num', 'ref_num')]), (inputnode, flirt, [('in_mask', 'inputnode.ref_mask')]), (split, flirt, [('out_ref', 'inputnode.reference'), ('out_mov', 'inputnode.in_file'), ('out_bval', 'inputnode.in_bval')]), (flirt, insmat, [('outputnode.out_xfms', 'inlist')]), (split, insmat, [('volid', 'volid')]), (inputnode, rot_bvec, [('in_bvec', 'in_bvec')]), (insmat, rot_bvec, [('out', 'in_matrix')]), (rot_bvec, outputnode, [('out_file', 'out_bvec')]), (flirt, outputnode, [('outputnode.out_file', 'out_file')]), (insmat, outputnode, [('out', 'out_xfms')])]) return wf
def ecc_pipeline(name='eddy_correct'): """ ECC stands for Eddy currents correction. Creates a pipeline that corrects for artifacts induced by Eddy currents in dMRI sequences. It takes a series of diffusion weighted images and linearly co-registers them to one reference image (the average of all b0s in the dataset). DWIs are also modulated by the determinant of the Jacobian as indicated by [Jones10]_ and [Rohde04]_. A list of rigid transformation matrices can be provided, sourcing from a :func:`.hmc_pipeline` workflow, to initialize registrations in a *motion free* framework. A list of affine transformation matrices is available as output, so that transforms can be chained (discussion `here <https://github.com/nipy/nipype/pull/530#issuecomment-14505042>`_). .. admonition:: References .. [Jones10] Jones DK, `The signal intensity must be modulated by the determinant of the Jacobian when correcting for eddy currents in diffusion MRI <http://cds.ismrm.org/protected/10MProceedings/files/1644_129.pdf>`_, Proc. ISMRM 18th Annual Meeting, (2010). .. [Rohde04] Rohde et al., `Comprehensive Approach for Correction of Motion and Distortion in Diffusion-Weighted MRI <http://stbb.nichd.nih.gov/pdf/com_app_cor_mri04.pdf>`_, MRM 51:103-114 (2004). Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import ecc_pipeline >>> ecc = ecc_pipeline() >>> ecc.inputs.inputnode.in_file = 'diffusion.nii' >>> ecc.inputs.inputnode.in_bval = 'diffusion.bval' >>> ecc.inputs.inputnode.in_mask = 'mask.nii' >>> ecc.run() # doctest: +SKIP Inputs:: inputnode.in_file - input dwi file inputnode.in_mask - weights mask of reference image (a file with data \ range sin [0.0, 1.0], indicating the weight of each voxel when computing the \ metric. inputnode.in_bval - b-values table inputnode.in_xfms - list of matrices to initialize registration (from \ head-motion correction) Outputs:: outputnode.out_file - corrected dwi file outputnode.out_xfms - list of transformation matrices """ from nipype.workflows.data import get_flirt_schedule params = dict(dof=12, no_search=True, interp='spline', bgvalue=0, schedule=get_flirt_schedule('ecc')) # cost='normmi', cost_func='normmi', bins=64, inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bval', 'in_mask', 'in_xfms']), name='inputnode') avg_b0 = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval'], output_names=['out_file'], function=b0_average), name='b0_avg') pick_dws = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval', 'b'], output_names=['out_file'], function=extract_bval), name='ExtractDWI') pick_dws.inputs.b = 'diff' flirt = dwi_flirt(flirt_param=params, excl_nodiff=True) mult = pe.MapNode(fsl.BinaryMaths(operation='mul'), name='ModulateDWIs', iterfield=['in_file', 'operand_value']) thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'], name='RemoveNegative') split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs') get_mat = pe.Node(niu.Function( input_names=['in_bval', 'in_xfms'], output_names=['out_files'], function=recompose_xfm), name='GatherMatrices') merge = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval', 'in_corrected'], output_names=['out_file'], function=recompose_dwi), name='MergeDWIs') outputnode = pe.Node(niu.IdentityInterface( fields=['out_file', 'out_xfms']), name='outputnode') wf = pe.Workflow(name=name) wf.connect([ (inputnode, avg_b0, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, pick_dws, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, merge, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, flirt, [('in_mask', 'inputnode.ref_mask'), ('in_xfms', 'inputnode.in_xfms'), ('in_bval', 'inputnode.in_bval')]), (inputnode, get_mat, [('in_bval', 'in_bval')]), (avg_b0, flirt, [('out_file', 'inputnode.reference')]), (pick_dws, flirt, [('out_file', 'inputnode.in_file')]), (flirt, get_mat, [('outputnode.out_xfms', 'in_xfms')]), (flirt, mult, [(('outputnode.out_xfms', _xfm_jacobian), 'operand_value')]), (flirt, split, [('outputnode.out_file', 'in_file')]), (split, mult, [('out_files', 'in_file')]), (mult, thres, [('out_file', 'in_file')]), (thres, merge, [('out_file', 'in_corrected')]), (get_mat, outputnode, [('out_files', 'out_xfms')]), (merge, outputnode, [('out_file', 'out_file')]) ]) return wf
def hmc_pipeline(name='motion_correct'): """ HMC stands for head-motion correction. Creates a pipeline that corrects for head motion artifacts in dMRI sequences. It takes a series of diffusion weighted images and rigidly co-registers them to one reference image. Finally, the `b`-matrix is rotated accordingly [Leemans09]_ making use of the rotation matrix obtained by FLIRT. Search angles have been limited to 4 degrees, based on results in [Yendiki13]_. A list of rigid transformation matrices is provided, so that transforms can be chained. This is useful to correct for artifacts with only one interpolation process (as previously discussed `here <https://github.com/nipy/nipype/pull/530#issuecomment-14505042>`_), and also to compute nuisance regressors as proposed by [Yendiki13]_. .. warning:: This workflow rotates the `b`-vectors, so please be advised that not all the dicom converters ensure the consistency between the resulting nifti orientation and the gradients table (e.g. dcm2nii checks it). .. admonition:: References .. [Leemans09] Leemans A, and Jones DK, `The B-matrix must be rotated when correcting for subject motion in DTI data <http://dx.doi.org/10.1002/mrm.21890>`_, Magn Reson Med. 61(6):1336-49. 2009. doi: 10.1002/mrm.21890. .. [Yendiki13] Yendiki A et al., `Spurious group differences due to head motion in a diffusion MRI study <http://dx.doi.org/10.1016/j.neuroimage.2013.11.027>`_. Neuroimage. 21(88C):79-90. 2013. doi: 10.1016/j.neuroimage.2013.11.027 Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import hmc_pipeline >>> hmc = hmc_pipeline() >>> hmc.inputs.inputnode.in_file = 'diffusion.nii' >>> hmc.inputs.inputnode.in_bvec = 'diffusion.bvec' >>> hmc.inputs.inputnode.in_bval = 'diffusion.bval' >>> hmc.inputs.inputnode.in_mask = 'mask.nii' >>> hmc.run() # doctest: +SKIP Inputs:: inputnode.in_file - input dwi file inputnode.in_mask - weights mask of reference image (a file with data \ range in [0.0, 1.0], indicating the weight of each voxel when computing the \ metric. inputnode.in_bvec - gradients file (b-vectors) inputnode.ref_num (optional, default=0) index of the b0 volume that \ should be taken as reference Outputs:: outputnode.out_file - corrected dwi file outputnode.out_bvec - rotated gradient vectors table outputnode.out_xfms - list of transformation matrices """ from nipype.workflows.data import get_flirt_schedule params = dict(dof=6, bgvalue=0, save_log=True, no_search=True, # cost='mutualinfo', cost_func='mutualinfo', bins=64, schedule=get_flirt_schedule('hmc')) inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'ref_num', 'in_bvec', 'in_bval', 'in_mask']), name='inputnode') split = pe.Node(niu.Function( output_names=['out_ref', 'out_mov', 'out_bval', 'volid'], input_names=['in_file', 'in_bval', 'ref_num'], function=hmc_split), name='SplitDWI') flirt = dwi_flirt(flirt_param=params) insmat = pe.Node(niu.Function(input_names=['inlist', 'volid'], output_names=['out'], function=insert_mat), name='InsertRefmat') rot_bvec = pe.Node(niu.Function( function=rotate_bvecs, input_names=['in_bvec', 'in_matrix'], output_names=['out_file']), name='Rotate_Bvec') outputnode = pe.Node(niu.IdentityInterface( fields=['out_file', 'out_bvec', 'out_xfms']), name='outputnode') wf = pe.Workflow(name=name) wf.connect([ (inputnode, split, [('in_file', 'in_file'), ('in_bval', 'in_bval'), ('ref_num', 'ref_num')]), (inputnode, flirt, [('in_mask', 'inputnode.ref_mask')]), (split, flirt, [('out_ref', 'inputnode.reference'), ('out_mov', 'inputnode.in_file'), ('out_bval', 'inputnode.in_bval')]), (flirt, insmat, [('outputnode.out_xfms', 'inlist')]), (split, insmat, [('volid', 'volid')]), (inputnode, rot_bvec, [('in_bvec', 'in_bvec')]), (insmat, rot_bvec, [('out', 'in_matrix')]), (rot_bvec, outputnode, [('out_file', 'out_bvec')]), (flirt, outputnode, [('outputnode.out_file', 'out_file')]), (insmat, outputnode, [('out', 'out_xfms')]) ]) return wf
def ecc_pipeline(name="eddy_correct"): """ ECC stands for Eddy currents correction. Creates a pipelines that corrects for artifacts induced by Eddy currents in dMRI sequences. It takes a series of diffusion weighted images and linearly co-registers them to one reference image (the average of all b0s in the dataset). DWIs are also modulated by the determinant of the Jacobian as indicated by [Jones10]_ and [Rohde04]_. A list of rigid transformation matrices can be provided, sourcing from a :func:`.hmc_pipeline` workflow, to initialize registrations in a *motion free* framework. A list of affine transformation matrices is available as output, so that transforms can be chained (discussion `here <https://github.com/nipy/nipype/pull/530#issuecomment-14505042>`_). .. admonition:: References .. [Jones10] Jones DK, `The signal intensity must be modulated by the determinant of the Jacobian when correcting for eddy currents in diffusion MRI <http://cds.ismrm.org/protected/10MProceedings/files/1644_129.pdf>`_, Proc. ISMRM 18th Annual Meeting, (2010). .. [Rohde04] Rohde et al., `Comprehensive Approach for Correction of Motion and Distortion in Diffusion-Weighted MRI <http://stbb.nichd.nih.gov/pdf/com_app_cor_mri04.pdf>`_, MRM 51:103-114 (2004). Example ------- from nipype.workflows.dmri.fsl.artifacts import ecc_pipeline ecc = ecc_pipeline() ecc.inputs.inputnode.in_file = 'diffusion.nii' ecc.inputs.inputnode.in_bval = 'diffusion.bval' ecc.inputs.inputnode.in_mask = 'mask.nii' ecc.run() # doctest: +SKIP Inputs:: inputnode.in_file - input dwi file inputnode.in_mask - weights mask of reference image (a file with data \ range sin [0.0, 1.0], indicating the weight of each voxel when computing the \ metric. inputnode.in_bval - b-values table inputnode.in_xfms - list of matrices to initialize registration (from \ head-motion correction) Outputs:: outputnode.out_file - corrected dwi file outputnode.out_xfms - list of transformation matrices """ import nipype.interfaces.fsl as fsl import nipype.interfaces.utility as niu import nipype.pipeline.engine as pe from nipype.workflows.data import get_flirt_schedule from nipype.workflows.dmri.fsl.artifacts import _xfm_jacobian from nipype.workflows.dmri.fsl.utils import ( extract_bval, recompose_dwi, recompose_xfm, ) from clinica.utils.dwi import merge_volumes_tdim from clinica.workflows.dwi_preprocessing import dwi_flirt params = dict( dof=12, no_search=True, interp="spline", bgvalue=0, schedule=get_flirt_schedule("ecc"), ) inputnode = pe.Node( niu.IdentityInterface( fields=["in_file", "in_bval", "in_mask", "in_xfms"]), name="inputnode", ) getb0 = pe.Node(fsl.ExtractROI(t_min=0, t_size=1), name="get_b0") pick_dws = pe.Node( niu.Function( input_names=["in_dwi", "in_bval", "b"], output_names=["out_file"], function=extract_bval, ), name="extract_dwi", ) pick_dws.inputs.b = "diff" flirt = dwi_flirt(flirt_param=params, excl_nodiff=True) mult = pe.MapNode( fsl.BinaryMaths(operation="mul"), name="ModulateDWIs", iterfield=["in_file", "operand_value"], ) thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=["in_file"], name="RemoveNegative") split = pe.Node(fsl.Split(dimension="t"), name="SplitDWIs") get_mat = pe.Node( niu.Function( input_names=["in_bval", "in_xfms"], output_names=["out_files"], function=recompose_xfm, ), name="GatherMatrices", ) merge = pe.Node( niu.Function( input_names=["in_dwi", "in_bval", "in_corrected"], output_names=["out_file"], function=recompose_dwi, ), name="MergeDWIs", ) merged_volumes = pe.Node( niu.Function( input_names=["in_file1", "in_file2"], output_names=["out_file"], function=merge_volumes_tdim, ), name="merge_enhanced_ref_dwis", ) outputnode = pe.Node( niu.IdentityInterface(fields=["out_file", "out_xfms"]), name="outputnode") wf = pe.Workflow(name=name) wf.connect([ (inputnode, getb0, [("in_file", "in_file")]), (inputnode, pick_dws, [("in_file", "in_dwi"), ("in_bval", "in_bval")]), ( flirt, merged_volumes, [ ("outputnode.out_ref", "in_file1"), ("outputnode.out_file", "in_file2"), ], ), (merged_volumes, merge, [("out_file", "in_dwi")]), (inputnode, merge, [("in_bval", "in_bval")]), ( inputnode, flirt, [ ("in_mask", "inputnode.ref_mask"), ("in_xfms", "inputnode.in_xfms"), ("in_bval", "inputnode.in_bval"), ], ), (inputnode, get_mat, [("in_bval", "in_bval")]), (getb0, flirt, [("roi_file", "inputnode.reference")]), (pick_dws, flirt, [("out_file", "inputnode.in_file")]), (flirt, get_mat, [("outputnode.out_xfms", "in_xfms")]), (flirt, mult, [(("outputnode.out_xfms", _xfm_jacobian), "operand_value")]), (flirt, split, [("outputnode.out_file", "in_file")]), (split, mult, [("out_files", "in_file")]), (mult, thres, [("out_file", "in_file")]), (thres, merge, [("out_file", "in_corrected")]), (get_mat, outputnode, [("out_files", "out_xfms")]), (merge, outputnode, [("out_file", "out_file")]), ]) return wf
def hmc_pipeline(name="motion_correct"): """ HMC stands for head-motion correction. Creates a pipelines that corrects for head motion artifacts in dMRI sequences. It takes a series of diffusion weighted images and rigidly co-registers them to one reference image (FLIRT normalised mutual information). Finally, the `b`-matrix is rotated accordingly [Leemans09]_ making use of the rotation matrix obtained by FLIRT. A list of rigid transformation matrices is provided, so that transforms can be chained. This is useful to correct for artifacts with only one interpolation process and also to compute nuisance regressors as proposed by [Yendiki13]_. .. warning:: This workflow rotates the `b`-vectors, so please be advised that not all the dicom converters ensure the consistency between the resulting nifti orientation and the gradients table (e.g. dcm2nii checks it). .. admonition:: References .. [Leemans09] Leemans A, and Jones DK, `The B-matrix must be rotated when correcting for subject motion in DTI data <http://dx.doi.org/10.1002/mrm.21890>`_, Magn Reson Med. 61(6):1336-49. 2009. doi: 10.1002/mrm.21890. .. [Yendiki13] Yendiki A et al., `Spurious group differences due to head motion in a diffusion MRI study <http://dx.doi.org/10.1016/j.neuroimage.2013.11.027>`_. Neuroimage. 21(88C):79-90. 2013. doi: 10.1016/j.neuroimage.2013.11.027 Inputnode --------- in_file : FILE Mandatory input. Input dwi file. in_bvec : FILE Mandatory input. Vector file of the diffusion directions of the dwi dataset. in_bval : FILE Mandatory input. B values file. in_mask : FILE Mandatory input. Weights mask of reference image (a file with data range in [0.0, 1.0], indicating the weight of each voxel when computing the metric ref_num : INT Optional input. Default=0. Index of the b0 volume that should be taken as reference. Outputnode ---------- outputnode.out_file - corrected dwi file outputnode.out_bvec - rotated gradient vectors table outputnode.out_xfms - list of transformation matrices """ import nipype.interfaces.utility as niu import nipype.pipeline.engine as pe from nipype.workflows.data import get_flirt_schedule from nipype.workflows.dmri.fsl.utils import insert_mat, rotate_bvecs from clinica.utils.dwi import hmc_split, merge_volumes_tdim from clinica.workflows.dwi_preprocessing import dwi_flirt params = dict( dof=6, bgvalue=0, save_log=True, no_search=True, # cost='mutualinfo', cost_func='mutualinfo', bins=64, schedule=get_flirt_schedule("hmc"), ) inputnode = pe.Node( niu.IdentityInterface( fields=["in_file", "in_bvec", "in_bval", "in_mask", "ref_num"]), name="inputnode", ) split = pe.Node( niu.Function( function=hmc_split, input_names=["in_file", "in_bval", "ref_num"], output_names=["out_ref", "out_mov", "out_bval", "volid"], ), name="split_ref_moving", ) flirt = dwi_flirt(flirt_param=params) insmat = pe.Node( niu.Function(input_names=["inlist", "volid"], output_names=["out"], function=insert_mat), name="insert_ref_matrix", ) rot_bvec = pe.Node( niu.Function( input_names=["in_bvec", "in_matrix"], output_names=["out_file"], function=rotate_bvecs, ), name="Rotate_Bvec", ) merged_volumes = pe.Node( niu.Function( input_names=["in_file1", "in_file2"], output_names=["out_file"], function=merge_volumes_tdim, ), name="merge_reference_moving", ) outputnode = pe.Node( niu.IdentityInterface( fields=["out_file", "out_bvec", "out_xfms", "mask_B0"]), name="outputnode", ) wf = pe.Workflow(name=name) wf.connect([ ( inputnode, split, [ ("in_file", "in_file"), ("in_bval", "in_bval"), ("ref_num", "ref_num"), ], ), (inputnode, flirt, [("in_mask", "inputnode.ref_mask")]), ( split, flirt, [ ("out_ref", "inputnode.reference"), ("out_mov", "inputnode.in_file"), ("out_bval", "inputnode.in_bval"), ], ), (flirt, insmat, [("outputnode.out_xfms", "inlist")]), (split, insmat, [("volid", "volid")]), (inputnode, rot_bvec, [("in_bvec", "in_bvec")]), (insmat, rot_bvec, [("out", "in_matrix")]), (rot_bvec, outputnode, [("out_file", "out_bvec")]), ( flirt, merged_volumes, [ ("outputnode.out_ref", "in_file1"), ("outputnode.out_file", "in_file2"), ], ), (merged_volumes, outputnode, [("out_file", "out_file")]), (insmat, outputnode, [("out", "out_xfms")]), (flirt, outputnode, [("outputnode.out_ref", "mask_B0")]), ]) return wf