Пример #1
0
def create_tensor_pipeline():
    """
    Estimate diffusion tensor coefficients and compute FA
    :return:
    """
    # Nodes
    inputnode = pe.Node(
        utility.IdentityInterface(fields=["diffusion_volume", "mask"],
                                  mandatory_inputs=False),
        name="inputnode",
    )
    # tensor coefficients estimation
    diffusion2tensor = pe.Node(interface=mrtrix3.reconst.FitTensor(),
                               name="diffusion2tensor")
    # derived FA contrast (force nifti format to do registration with FSL or Ants)
    tensor2fa = pe.Node(interface=mrtrix3.TensorMetrics(out_fa="fa.nii.gz"),
                        name="tensor2fa")
    outputnode = pe.Node(
        utility.IdentityInterface(fields=["tensor_coeff", "fa"],
                                  mandatory_inputs=False),
        name="outputnode",
    )

    # Workflow structure
    tensor = pe.Workflow(name="tensor")
    tensor.connect(inputnode, "diffusion_volume", diffusion2tensor, "in_file")
    tensor.connect(inputnode, "mask", diffusion2tensor, "in_mask")
    tensor.connect(diffusion2tensor, "out_file", tensor2fa, "in_file")
    tensor.connect(diffusion2tensor, "out_file", outputnode, "tensor_coeff")
    tensor.connect(tensor2fa, "out_fa", outputnode, "fa")

    return tensor
Пример #2
0
def calculate_metrics(in_file: Path, out_files: dict):
    """
    Calculate various DWI metrics based on Diffusion's kurtosis tensor
    estimation.

    Parameters
    ----------
    in_file : Path
        Path to preprocessed DWI series
    out_files : dict
        A dictionary containing paths to various metrics to be calculated
    """
    tensor = out_files.pop("tensor")
    tsr = mrt.FitTensor()
    tsr.inputs.in_file = in_file
    tsr.inputs.out_file = tensor
    tsr.inputs.args = "-quiet"
    if not tensor.exists():
        tsr.run()
    comp = mrt.TensorMetrics()
    comp.inputs.in_file = tensor
    comp_args = ""
    for key, val in out_files.items():
        comp_args += f"-{key} {val} "
    comp.inputs.args = comp_args
    return tsr, comp
Пример #3
0
def fit_tensors(dwi_file: str, mask_file: str, dti_file: str):
    dilated_mask = mask_file.replace(".mif", "_dilated.mif")
    cmd = f"maskfilter {mask_file} dilate {dilated_mask} -npass 3"
    os.system(cmd)
    tsr = mrt.FitTensor()
    tsr.inputs.in_file = dwi_file
    tsr.inputs.in_mask = dilated_mask
    tsr.inputs.out_file = dti_file
    print(tsr.cmdline)
    tsr.run()
    comp = mrt.TensorMetrics()
    comp.inputs.in_file = dti_file
    comp.inputs.out_fa = dti_file.replace("dti", "fa")
    comp.inputs.args = "-force"
    print(comp.cmdline)
    comp.run()
    return comp.inputs.out_fa
Пример #4
0
def fit_tensors(dwi_file: Path, mask_file: Path, dti_file: Path,
                fa_file: Path):
    dilated_mask = mask_file.parent / f"{mask_file.stem}_dilated.mif"
    cmd = f"maskfilter {mask_file} dilate {dilated_mask} -npass 3"
    os.system(cmd)
    tsr = mrt.FitTensor()
    tsr.inputs.in_file = dwi_file
    tsr.inputs.in_mask = dilated_mask
    tsr.inputs.out_file = dti_file
    print(tsr.cmdline)
    tsr.run()
    comp = mrt.TensorMetrics()
    comp.inputs.in_file = dti_file
    comp.inputs.out_fa = fa_file
    print(comp.cmdline)
    comp.run()
    dti_file.unlink()
    return comp.inputs.out_fa
Пример #5
0
# Data conversion from .nii to .mif file (allows to embed diffusion bvals et bvecs)
mrconvert = pe.Node(interface=mrtrix3.MRConvert(), name="mrconvert")

# Bias correction of the diffusion MRI data (for more quantitative approach)
dwibiascorrect = pe.Node(interface=mrtrix3.preprocess.DWIBiasCorrect(),
                         name="dwibiascorrect")
dwibiascorrect.use_ants = True

# gross brain mask stemming from DWI data
dwi2mask = pe.Node(interface=mrtrix3.utils.BrainMask(), name="dwi2mask")

# tensor coefficients estimation
dwi2tensor = pe.Node(interface=mrtrix3.reconst.FitTensor(), name="dwi2tensor")

# derived FA contrast for registration
tensor2fa = pe.Node(interface=mrtrix3.TensorMetrics(), name="tensor2fa")

# Tissue classification from T1 MRI data
tissue_classif = pe.Node(interface=mrtrix3.Generate5tt(),
                         name="tissue_classif")
# rely on FSL for T1 tissue segmentation
tissue_classif.inputs.algorithm = "fsl"

# impulsionnal response estimation
dwi2response = pe.Node(interface=mrtrix3.preprocess.ResponseSD(),
                       name="dwi2response")
dwi2response.inputs.algorithm = "msmt_5tt"

# Multi-shell multi tissue spherical deconvolution of the diffusion MRI data
dwi2fod = pe.Node(
    interface=mrtrix3.reconst.ConstrainedSphericalDeconvolution(),
Пример #6
0
def dholl_preproc_wf(shells=[0, 1000, 2000],
                     lmax=[0, 8, 8],
                     sshell=False,
                     noreorient=False,
                     template_dir=None,
                     template_label=None,
                     wdir=None,
                     nthreads=1,
                     name='dholl_preproc_wf'):
    """
    Set up Dhollander response preproc workflow
    No assumption of registration to T1w space is made
    """

    if template_dir is None or template_label is None:
        print("Missing template info")
        raise IOError

    # Grab template data
    templateGrabber = io.getTemplate(template_dir=template_dir,
                                     template_label=template_label,
                                     wdir=wdir)

    # Convert nii to mif
    dwiConvert = pe.Node(mrt.MRConvert(), name='dwiConvert')
    dwiConvert.base_dir = wdir
    dwiConvert.inputs.nthreads = nthreads
    dwiConvert.interface.num_threads = nthreads

    # dwi2response - included but not used
    dwi2response = pe.Node(mrt.ResponseSD(), name='dwi2response')
    dwi2response.base_dir = wdir
    dwi2response.inputs.algorithm = 'dhollander'
    dwi2response.inputs.wm_file = 'space-dwi_model-CSD_WMResp.txt'
    dwi2response.inputs.gm_file = 'space-dwi_model-CSD_GMResp.txt'
    dwi2response.inputs.csf_file = 'space-dwi_model-CSD_CSFResp.txt'
    dwi2response.inputs.max_sh = lmax
    dwi2response.inputs.shell = shells
    dwi2response.inputs.nthreads = nthreads
    dwi2response.interface.num_threads = nthreads

    # Convert mask (nii) to mif
    maskConvert = pe.Node(mrt.MRConvert(), name='maskConvert')
    maskConvert.base_dir = wdir
    maskConvert.inputs.nthreads = nthreads
    maskConvert.interface.num_threads = nthreads

    # dwi2fod
    dwi2fod = pe.Node(mrt.EstimateFOD(), name='dwi2fod')
    dwi2fod.base_dir = wdir
    dwi2fod.inputs.algorithm = 'msmt_csd'
    dwi2fod.inputs.shell = shells
    dwi2fod.inputs.wm_odf = 'space-dwi_model-CSD_WMFOD.mif'
    if sshell is False:
        dwi2fod.inputs.gm_odf = 'space-dwi_model-CSD_GMFOD.mif'
    dwi2fod.inputs.csf_odf = 'space-dwi_model-CSD_CSFFOD.mif'
    dwi2fod.inputs.nthreads = nthreads
    dwi2fod.interface.num_threads = nthreads

    # mtnormalise
    mtnormalise = pe.Node(mrt.MTNormalise(), name='mtnormalise')
    mtnormalise.base_dir = wdir
    mtnormalise.inputs.out_wm = 'space-dwi_model-CSD_WMFODNorm.mif'
    if sshell is False:
        mtnormalise.inputs.out_gm = 'space-dwi_model-CSD_GMFODNorm.mif'
    mtnormalise.inputs.out_csf = 'space-dwi_model-CSD_CSFFODNorm.mif'
    mtnormalise.inputs.nthreads = nthreads
    mtnormalise.interface.num_threads = nthreads

    # Registration
    MRRegister = pe.Node(mrt.MRRegister(), name='MRRegister')
    MRRegister.base_dir = wdir
    # MRRegister.inputs.ref_file = template
    MRRegister.inputs.nl_warp = [
        'from-dwi_to-Template_xfm.mif', 'from-Template_to-dwi_xfm.mif'
    ]
    if noreorient is not False:
        MRRegister.inputs.noreorientation = noreorient
    MRRegister.inputs.nthreads = nthreads
    MRRegister.interface.num_threads = nthreads

    # Transforms
    WarpSelect1 = pe.Node(niu.Select(), name='WarpSelect1')
    WarpSelect1.base_dir = wdir
    WarpSelect1.inputs.index = [0]
    WarpSelect1.interface.num_threads = nthreads

    WarpSelect2 = pe.Node(niu.Select(), name='WarpSelect2')
    WarpSelect2.base_dir = wdir
    WarpSelect2.inputs.index = [1]
    WarpSelect2.interface.num_threads = nthreads

    # Warp data
    MaskTransform = pe.Node(mrt.MRTransform(), name='MaskTransform')
    MaskTransform.base_dir = wdir
    MaskTransform.inputs.out_file = 'space-Template_brainmask.mif'
    MaskTransform.inputs.nthreads = nthreads
    MaskTransform.interface.num_threads = nthreads

    FODTransform = pe.Node(mrt.MRTransform(), name='FODTransform')
    FODTransform.base_dir = wdir
    FODTransform.inputs.out_file = 'space-Template_model-CSD_WMFODNorm.mif'
    FODTransform.inputs.nthreads = nthreads
    FODTransform.interface.num_threads = nthreads

    # Tensor processing
    DWINormalise = pe.Node(mrt.DWINormalise(), name='DWINormalise')
    DWINormalise.base_dir = wdir
    DWINormalise.inputs.out_file = 'space-dwi_dwiNorm.mif'
    DWINormalise.inputs.nthreads = nthreads
    DWINormalise.interface.num_threads = nthreads

    DWITransform = pe.Node(mrt.MRTransform(), name='DWITransform')
    DWITransform.base_dir = wdir
    DWITransform.inputs.out_file = 'space-Template_dwiNorm.mif'
    DWITransform.inputs.nthreads = nthreads
    DWITransform.interface.num_threads = nthreads

    FitTensor = pe.Node(mrt.FitTensor(), name='FitTensor')
    FitTensor.base_dir = wdir
    FitTensor.inputs.out_file = 'space-Template_desc-WLS_model-DTI_tensor.mif'
    FitTensor.inputs.nthreads = nthreads
    FitTensor.interface.num_threads = nthreads

    TensorMetrics = pe.Node(mrt.TensorMetrics(), name='TensorMetrics')
    TensorMetrics.base_dir = wdir
    TensorMetrics.inputs.out_fa = 'space-Template_model-DTI_FA.mif'
    TensorMetrics.inputs.out_adc = 'space-Template_model-DTI_MD.mif'
    TensorMetrics.inputs.out_ad = 'space-Template_model-DTI_AD.mif'
    TensorMetrics.inputs.out_rd = 'space-Template_model-DTI_RD.mif'
    TensorMetrics.inputs.nthreads = nthreads
    TensorMetrics.interface.num_threads = nthreads

    # Build workflow
    workflow = pe.Workflow(name=name)

    # Single shell
    if sshell is True:
        workflow.connect([
            # Compute FOD
            (dwiConvert, dwi2response, [('out_file', 'in_file')]),
            (dwiConvert, dwi2fod, [('out_file', 'in_file')]),
            (dwi2response, dwi2fod, [('wm_file', 'wm_txt'),
                                     ('csf_file', 'csf_txt')]),
            (dwi2fod, mtnormalise, [('wm_odf', 'in_wm'),
                                    ('csf_odf', 'in_csf')]),
            (maskConvert, dwi2response, [('out_file', 'in_mask')]),
            (maskConvert, dwi2fod, [('out_file', 'mask_file')]),
            (maskConvert, mtnormalise, [('out_file', 'mask')]),
            (maskConvert, MRRegister, [('out_file', 'mask1')]),
            (templateGrabber, MRRegister, [('wm_fod', 'ref_file'),
                                           ('mask', 'mask2')]),
            (mtnormalise, MRRegister, [('out_wm', 'in_file')]),
            (MRRegister, WarpSelect1, [('nl_warp', 'inlist')]),
            (MRRegister, WarpSelect2, [('nl_warp', 'inlist')]),
            (maskConvert, MaskTransform, [('out_file', 'in_file')]),
            (WarpSelect1, MaskTransform, [('out', 'warp')]),
            (mtnormalise, FODTransform, [('out_wm', 'in_file')]),
            (WarpSelect1, FODTransform, [('out', 'warp')]),
            # Compute tensors
            (dwiConvert, DWINormalise, [('out_file', 'in_file')]),
            (maskConvert, DWINormalise, [('out_file', 'in_mask')]),
            (DWINormalise, DWITransform, [('out_file', 'in_file')]),
            (WarpSelect1, DWITransform, [('out', 'warp')]),
            (DWITransform, FitTensor, [('out_file', 'in_file')]),
            (MaskTransform, FitTensor, [('out_file', 'in_mask')]),
            (FitTensor, TensorMetrics, [('out_file', 'in_file')]),
            (MaskTransform, TensorMetrics, [('out_file', 'in_mask')])
        ])

    # For multi-shell
    else:
        workflow.connect([
            # Compute FOD
            (dwiConvert, dwi2response, [('out_file', 'in_file')]),
            (dwiConvert, dwi2fod, [('out_file', 'in_file')]),
            (dwi2response, dwi2fod, [('wm_file', 'wm_txt'),
                                     ('gm_file', 'gm_txt'),
                                     ('csf_file', 'csf_txt')]),
            (dwi2fod, mtnormalise, [('wm_odf', 'in_wm'), ('gm_odf', 'in_gm'),
                                    ('csf_odf', 'in_csf')]),
            (maskConvert, dwi2response, [('out_file', 'in_mask')]),
            (maskConvert, dwi2fod, [('out_file', 'mask_file')]),
            (maskConvert, mtnormalise, [('out_file', 'mask')]),
            (maskConvert, MRRegister, [('out_file', 'mask1')]),
            (templateGrabber, MRRegister, [('wm_fod', 'ref_file'),
                                           ('mask', 'mask2')]),
            (mtnormalise, MRRegister, [('out_wm', 'in_file')]),
            (MRRegister, WarpSelect1, [('nl_warp', 'inlist')]),
            (MRRegister, WarpSelect2, [('nl_warp', 'inlist')]),
            (maskConvert, MaskTransform, [('out_file', 'in_file')]),
            (WarpSelect1, MaskTransform, [('out', 'warp')]),
            (mtnormalise, FODTransform, [('out_wm', 'in_file')]),
            (WarpSelect1, FODTransform, [('out', 'warp')]),
            # Compute tensors
            (dwiConvert, DWINormalise, [('out_file', 'in_file')]),
            (maskConvert, DWINormalise, [('out_file', 'in_mask')]),
            (DWINormalise, DWITransform, [('out_file', 'in_file')]),
            (WarpSelect1, DWITransform, [('out', 'warp')]),
            (DWITransform, FitTensor, [('out_file', 'in_file')]),
            (MaskTransform, FitTensor, [('out_file', 'in_mask')]),
            (FitTensor, TensorMetrics, [('out_file', 'in_file')]),
            (MaskTransform, TensorMetrics, [('out_file', 'in_mask')])
        ])

    return workflow