Ejemplo n.º 1
0
def extract_timeseries(SinkTag="connectivity",
                       wf_name="extract_timeseries",
                       modularise=True):
    ########################################################################
    # Extract timeseries
    ########################################################################

    import nipype.interfaces.nilearn as learn
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.io as io
    from nipype.interfaces.utility import Function
    import PUMI.utils.globals as globals
    import PUMI.utils.QC as qc
    import os

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Identitiy mapping for input variables
    inputspec = pe.Node(
        utility.IdentityInterface(fields=[
            'std_func',
            'atlas_file',  # nii labelmap (or 4D probmaps)
            'labels',  # list of short names to regions
            'modules'  # list of modules of regions
        ]),
        name='inputspec')
    # re-label atlas, so that regions corresponding to the same modules follow each other
    if modularise:
        relabel_atls = pe.Node(interface=Function(
            input_names=['atlas_file', 'modules', 'labels'],
            output_names=[
                'relabelled_atlas_file', 'reordered_modules',
                'reordered_labels', 'newlabels_file'
            ],
            function=relabel_atlas),
                               name='relabel_atlas')
        # Save outputs which are important
        ds_nii = pe.Node(interface=io.DataSink(), name='ds_relabeled_atlas')
        ds_nii.inputs.base_directory = SinkDir
        ds_nii.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

        # Save outputs which are important
        ds_newlabels = pe.Node(interface=io.DataSink(), name='ds_newlabels')
        ds_newlabels.inputs.base_directory = SinkDir
        ds_newlabels.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".tsv")]

    extract_timesereies = pe.MapNode(
        interface=learn.SignalExtraction(detrend=False),
        iterfield=['in_file'],
        name='extract_timeseries')

    # Save outputs which are important
    ds_txt = pe.Node(interface=io.DataSink(), name='ds_txt')
    ds_txt.inputs.base_directory = SinkDir
    ds_txt.inputs.regexp_substitutions = [("(\/)[^\/]*$", wf_name + ".tsv")]

    #QC
    timeseries_qc = qc.regTimeseriesQC("regional_timeseries", tag=wf_name)

    outputspec = pe.Node(utility.IdentityInterface(fields=[
        'timeseries_file', 'relabelled_atlas_file', 'reordered_modules',
        'reordered_labels'
    ]),
                         name='outputspec')

    # Create workflow
    analysisflow = pe.Workflow(wf_name)
    analysisflow.connect(inputspec, 'std_func', extract_timesereies, 'in_file')
    if modularise:
        analysisflow.connect(inputspec, 'atlas_file', relabel_atls,
                             'atlas_file')
        analysisflow.connect(inputspec, 'modules', relabel_atls, 'modules')
        analysisflow.connect(inputspec, 'labels', relabel_atls, 'labels')

        analysisflow.connect(relabel_atls, 'relabelled_atlas_file',
                             extract_timesereies, 'label_files')
        analysisflow.connect(relabel_atls, 'reordered_labels',
                             extract_timesereies, 'class_labels')
        analysisflow.connect(relabel_atls, 'reordered_modules', timeseries_qc,
                             'inputspec.modules')
        analysisflow.connect(relabel_atls, 'relabelled_atlas_file',
                             timeseries_qc, 'inputspec.atlas')
        analysisflow.connect(relabel_atls, 'relabelled_atlas_file', ds_nii,
                             'atlas_relabeled')
        analysisflow.connect(relabel_atls, 'newlabels_file', ds_newlabels,
                             'atlas_relabeled')
        analysisflow.connect(relabel_atls, 'relabelled_atlas_file', outputspec,
                             'relabelled_atlas_file')
        analysisflow.connect(relabel_atls, 'reordered_labels', outputspec,
                             'reordered_labels')
        analysisflow.connect(relabel_atls, 'reordered_modules', outputspec,
                             'reordered_modules')
    else:
        analysisflow.connect(inputspec, 'atlas_file', extract_timesereies,
                             'label_files')
        analysisflow.connect(inputspec, 'labels', extract_timesereies,
                             'class_labels')
        analysisflow.connect(inputspec, 'modules', timeseries_qc,
                             'inputspec.modules')
        analysisflow.connect(inputspec, 'atlas_file', timeseries_qc,
                             'inputspec.atlas')
        analysisflow.connect(inputspec, 'atlas_file', outputspec,
                             'relabelled_atlas_file')
        analysisflow.connect(inputspec, 'labels', outputspec,
                             'reordered_labels')
        analysisflow.connect(inputspec, 'modules', outputspec,
                             'reordered_modules')

    analysisflow.connect(extract_timesereies, 'out_file', ds_txt,
                         'regional_timeseries')
    analysisflow.connect(extract_timesereies, 'out_file', timeseries_qc,
                         'inputspec.timeseries')

    analysisflow.connect(extract_timesereies, 'out_file', outputspec,
                         'timeseries_file')

    return analysisflow
Ejemplo n.º 2
0
def anat2mni_ants_workflow_harcoded(SinkTag="anat_preproc",
                                    wf_name="anat2mni_ants"):
    """
    Register skull and brain extracted image to MNI space and return the transformation martices.
    Using ANTS, doing it with a hardcoded function, a'la C-PAC.
    This uses brain masks and full head images, as well.

    Workflow inputs:
        :param skull: The reoriented anatomical file.
        :param brain: The brain extracted anat.
        :param ref_skull: MNI152 skull file.
        :param ref_brain: MNI152 brain file.
        :param SinkDir:
        :param SinkTag: The output directiry in which the returned images (see workflow outputs) could be found.

    Workflow outputs:




        :return: anat2mni_workflow - workflow


        anat="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres.nii.gz",
                      brain="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres_brain.nii.gz",


    Tamas Spisak
    [email protected]
    2018


    """
    from nipype.interfaces.utility import Function

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Define inputs of workflow
    inputspec = pe.Node(utility.IdentityInterface(
        fields=['brain', 'skull', 'reference_brain', 'reference_skull']),
                        name='inputspec')

    inputspec.inputs.reference_brain = globals._FSLDIR_ + globals._brainref  #TODO_ready: 1 or 2mm???
    inputspec.inputs.reference_skull = globals._FSLDIR_ + globals._headref

    # Multi-stage registration node with ANTS
    reg = pe.MapNode(interface=Function(input_names=[
        'anatomical_brain', 'reference_brain', 'anatomical_skull',
        'reference_skull'
    ],
                                        output_names=[
                                            'transform_composite',
                                            'transform_inverse_composite',
                                            'warped_image'
                                        ],
                                        function=hardcoded_reg_fast),
                     iterfield=['anatomical_brain', 'anatomical_skull'],
                     name="ANTS_hardcoded",
                     mem_gb=4.1)

    # Calculate linear transformation with FSL. This matrix has to be used in segmentation with fast if priors are set. (the default).
    # Linear registration node
    linear_reg = pe.MapNode(interface=fsl.FLIRT(),
                            iterfield=['in_file'],
                            name='linear_reg_0')
    linear_reg.inputs.cost = 'corratio'

    # Calculate the invers of the linear transformation
    inv_flirt_xfm = pe.MapNode(interface=fsl.utils.ConvertXFM(),
                               iterfield=['in_file'],
                               name='inv_linear_reg0_xfm')
    inv_flirt_xfm.inputs.invert_xfm = True

    #  # or hardcoded_reg_cpac

    # Create png images for quality check
    myqc = qc.vol2png("anat2mni", "ANTS", overlayiterated=False)
    myqc.inputs.inputspec.overlay_image = globals._FSLDIR_ + globals._brainref  #TODO_ready: 1 or 2mm???
    myqc.inputs.slicer.image_width = 500  # 5000 # for the 1mm template
    myqc.inputs.slicer.threshold_edges = 0.1  # 0.1  # for the 1mm template

    # Save outputs which are important
    ds = pe.Node(interface=io.DataSink(), name='ds_nii')
    ds.inputs.base_directory = SinkDir
    ds.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

    # Define outputs of the workflow
    outputspec = pe.Node(utility.IdentityInterface(fields=[
        'output_brain', 'linear_xfm', 'invlinear_xfm', 'nonlinear_xfm',
        'invnonlinear_xfm', 'std_template'
    ]),
                         name='outputspec')

    outputspec.inputs.std_template = inputspec.inputs.reference_brain

    # Create workflow nad connect nodes
    analysisflow = pe.Workflow(name=wf_name)
    # FSL part for the transformation matrix
    analysisflow.connect(inputspec, 'brain', linear_reg, 'in_file')
    analysisflow.connect(inputspec, 'reference_brain', linear_reg, 'reference')
    analysisflow.connect(linear_reg, 'out_matrix_file', inv_flirt_xfm,
                         'in_file')
    analysisflow.connect(inv_flirt_xfm, 'out_file', outputspec,
                         'invlinear_xfm')

    analysisflow.connect(inputspec, 'reference_skull', reg, 'reference_skull')
    analysisflow.connect(inputspec, 'reference_brain', reg, 'reference_brain')
    analysisflow.connect(inputspec, 'skull', reg, 'anatomical_skull')
    analysisflow.connect(inputspec, 'brain', reg, 'anatomical_brain')

    analysisflow.connect(reg, 'transform_composite', outputspec,
                         'nonlinear_xfm')
    analysisflow.connect(reg, 'transform_inverse_composite', outputspec,
                         'invnonlinear_xfm')
    analysisflow.connect(reg, 'warped_image', outputspec, 'output_brain')
    analysisflow.connect(reg, 'warped_image', ds, 'anat2mni_std')
    analysisflow.connect(reg, 'transform_composite', ds, 'anat2mni_warpfield')
    analysisflow.connect(reg, 'warped_image', myqc, 'inputspec.bg_image')

    return analysisflow
Ejemplo n.º 3
0
def fast_workflow(SinkTag="anat_preproc",
                  wf_name="tissue_segmentation",
                  priormap=True):
    """

     Modified version of CPAC.seg_preproc.seg_preproc

     `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/seg_preproc/seg_preproc.html`


        Do the segmentation of a brain extracted T1w image.


        Workflow inputs:
            :param brain: The brain extracted image, the output of the better_workflow.
            :param init_transform: The standard to anat linear transformation matrix (which is calculated in the Anat2MNI.py script). Beware of the resolution of the reference (standard) image, the default value is 2mm.
            :param priorprob: A list of tissue probability maps in the prior (=reference=standard) space. By default it must be 3 element(in T1w images the CSF, GM, WM order is valid)
            :param SinkDir:
            :param SinkTag: The output directiry in which the returned images (see workflow outputs) could be found.

        Workflow outputs:




            :return: fast_workflow - workflow




        Balint Kincses
        [email protected]
        2018


        """

    #This is a Nipype generator. Warning, here be dragons.
    #!/usr/bin/env python
    import sys
    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.io as io
    import PUMI.utils.QC as qc
    import PUMI.utils.globals as globals

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    #Basic interface class generates identity mappings
    inputspec = pe.Node(
        utility.IdentityInterface(fields=[
            'brain',
            'stand2anat_xfm',  # leave empty for no prior
            'priorprob'
        ]),
        name='inputspec')
    # inputspec.inputs.stand2anat_xfm='/home/analyser/Documents/PAINTER/probewith2subj/preprocess_solvetodos/anat2mni_fsl/inv_linear_reg0_xfm/mapflow/_inv_linear_reg0_xfm0/anat_brain_flirt_inv.mat'

    #TODO_ready set standard mask to 2mm

    if priormap:
        inputspec.inputs.priorprob = [
            globals._FSLDIR_ + '/data/standard/tissuepriors/avg152T1_csf.hdr',
            globals._FSLDIR_ + '/data/standard/tissuepriors/avg152T1_gray.hdr',
            globals._FSLDIR_ + '/data/standard/tissuepriors/avg152T1_white.hdr'
        ]

    # TODO_ready: use prior probabilioty maps
    # Wraps command **fast**
    if priormap:
        fast = pe.MapNode(interface=fsl.FAST(),
                          iterfield=['in_files', 'init_transform'],
                          name='fast')
    else:
        fast = pe.MapNode(interface=fsl.FAST(),
                          iterfield=['in_files'],
                          name='fast')

    fast.inputs.img_type = 1
    fast.inputs.segments = True
    fast.inputs.probability_maps = True
    fast.inputs.out_basename = 'fast_'

    myqc = qc.vol2png("tissue_segmentation", overlay=False)
    myqc.inputs.slicer.colour_map = globals._FSLDIR_ + '/etc/luts/renderjet.lut'

    # Basic interface class generates identity mappings
    outputspec = pe.Node(utility.IdentityInterface(fields=[
        'probmap_csf', 'probmap_gm', 'probmap_wm', 'mixeltype', 'parvol_csf',
        'parvol_gm', 'parvol_wm', 'partial_volume_map'
    ]),
                         name='outputspec')

    # Save outputs which are important
    ds = pe.Node(interface=io.DataSink(), name='ds')
    ds.inputs.base_directory = SinkDir
    ds.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

    def pickindex(vec, i):
        #print "************************************************************************************************************************************************"
        #print vec
        #print i
        return [x[i] for x in vec]

    #Create a workflow to connect all those nodes
    analysisflow = nipype.Workflow(wf_name)
    analysisflow.base_dir = '.'
    analysisflow.connect(inputspec, 'brain', fast, 'in_files')
    if priormap:
        analysisflow.connect(inputspec, 'stand2anat_xfm', fast,
                             'init_transform')
        #analysisflow.connect(inputspec, 'priorprob', fast,'other_priors')
        # commented out for compatibility with the original RPN-signature
    # analysisflow.connect(inputspec, 'stand_csf' ,fast,('other_priors', pickindex, 0))
    # analysisflow.connect(inputspec, 'stand_gm' ,fast,('other_priors', pickindex, 1))
    # analysisflow.connect(inputspec, 'stand_wm' ,fast,('other_priors', pickindex, 2))

    #nalysisflow.connect(fast, 'probability_maps', outputspec, 'probability_maps')
    analysisflow.connect(fast, ('probability_maps', pickindex, 0), outputspec,
                         'probmap_csf')
    analysisflow.connect(fast, ('probability_maps', pickindex, 1), outputspec,
                         'probmap_gm')
    analysisflow.connect(fast, ('probability_maps', pickindex, 2), outputspec,
                         'probmap_wm')
    analysisflow.connect(fast, 'mixeltype', outputspec, 'mixeltype')
    #analysisflow.connect(fast, 'partial_volume_files', outputspec, 'partial_volume_files')
    analysisflow.connect(fast, ('partial_volume_files', pickindex, 0),
                         outputspec, 'parvol_csf')
    analysisflow.connect(fast, ('partial_volume_files', pickindex, 0),
                         outputspec, 'parvol_gm')
    analysisflow.connect(fast, ('partial_volume_files', pickindex, 0),
                         outputspec, 'parvol_wm')
    analysisflow.connect(fast, 'partial_volume_map', outputspec,
                         'partial_volume_map')
    analysisflow.connect(fast, ('probability_maps', pickindex, 0), ds,
                         'fast_csf')
    analysisflow.connect(fast, ('probability_maps', pickindex, 1), ds,
                         'fast_gm')
    analysisflow.connect(fast, ('probability_maps', pickindex, 2), ds,
                         'fast_wm')
    analysisflow.connect(fast, 'partial_volume_map', myqc,
                         'inputspec.bg_image')

    return analysisflow
Ejemplo n.º 4
0
def mc_workflow_afni(reference_vol="mid",
                     FD_mode="Power",
                     SinkTag="func_preproc",
                     wf_name="motion_correction_afni"):
    from nipype.interfaces.afni import preprocess
    import sys
    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import PUMI.func_preproc.info.info_get as info_get
    import nipype.interfaces.io as io
    import nipype.algorithms.confounds as conf
    import PUMI.utils.utils_math as utils_math
    import PUMI.utils.utils_convert as utils_convert
    import PUMI.utils.globals as globals
    import PUMI.utils.QC as qc

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)
    QCDir = os.path.abspath(globals._SinkDir_ + "/" + globals._QCDir_)
    if not os.path.exists(QCDir):
        os.makedirs(QCDir)

    # Basic interface class generates identity mappings
    inputspec = pe.Node(utility.IdentityInterface(
        fields=['func', 'ref_vol', 'save_plots', 'stats_imgs']),
                        name='inputspec')
    inputspec.inputs.save_plots = True
    inputspec.inputs.stats_imgs = True
    inputspec.inputs.ref_vol = reference_vol

    # extract reference volume
    refvol = pe.MapNode(utility.Function(input_names=['refvol', 'func'],
                                         output_names=['refvol'],
                                         function=getRefVol),
                        iterfield=['func'],
                        name='getRefVol')

    if (reference_vol == "mean"):
        func_motion_correct1 = pe.MapNode(interface=preprocess.Volreg(),
                                          iterfield=["in_file", "basefile"],
                                          name='mc_afni_init')
        func_motion_correct1.inputs.args = '-Fourier -twopass'
        func_motion_correct1.inputs.zpad = 4
        func_motion_correct1.inputs.outputtype = 'NIFTI_GZ'

        # extract reference volume
        refvol2 = pe.MapNode(utility.Function(input_names=['refvol', 'func'],
                                              output_names=['refvol'],
                                              function=getRefVol),
                             iterfield=['func'],
                             name='getRefVol2')

    func_motion_correct = pe.MapNode(interface=preprocess.Volreg(),
                                     iterfield=["in_file", "basefile"],
                                     name='mc_afni')
    func_motion_correct.inputs.args = '-Fourier -twopass'
    func_motion_correct.inputs.zpad = 4
    func_motion_correct.inputs.outputtype = 'NIFTI_GZ'

    myqc = qc.timecourse2png("timeseries", tag="010_motioncorr")

    # Calculate Friston24 parameters
    calc_friston = pe.MapNode(utility.Function(
        input_names=['in_file'],
        output_names=['out_file'],
        function=calc_friston_twenty_four),
                              iterfield=['in_file'],
                              name='calc_friston')

    if FD_mode == "Power":
        calculate_FD = pe.MapNode(conf.FramewiseDisplacement(
            parameter_source='AFNI', save_plot=True),
                                  iterfield=['in_file'],
                                  name='calculate_FD_Power')
    elif FD_mode == "Jenkinson":
        calculate_FD = pe.MapNode(utility.Function(input_names=['in_file'],
                                                   output_names=['out_file'],
                                                   function=calculate_FD_J),
                                  iterfield=['in_file'],
                                  name='calculate_FD_Jenkinson')

        # compute mean and max FD
        meanFD = pe.MapNode(interface=utils_math.Txt2meanTxt,
                            iterfield=['in_file'],
                            name='meanFD')
        meanFD.inputs.axis = 0  # global mean
        meanFD.inputs.header = True  # global mean

        maxFD = pe.MapNode(interface=utils_math.Txt2maxTxt,
                           iterfield=['in_file'],
                           name='maxFD')
        maxFD.inputs.axis = 0  # global mean
        maxFD.inputs.header = True  # global mean

        pop_FD = pe.Node(interface=utils_convert.List2TxtFileOpen,
                         name='pop_FD')
        pop_FDmax = pe.Node(interface=utils_convert.List2TxtFileOpen,
                            name='pop_FDmax')

    # save data out with Datasink
    ds_fd = pe.Node(interface=io.DataSink(), name='ds_pop_fd')
    ds_fd.inputs.regexp_substitutions = [("(\/)[^\/]*$", "FD.txt")]
    ds_fd.inputs.base_directory = SinkDir

    # save data out with Datasink
    ds_fd_max = pe.Node(interface=io.DataSink(), name='ds_pop_fd_max')
    ds_fd_max.inputs.regexp_substitutions = [("(\/)[^\/]*$", "FD_max.txt")]
    ds_fd_max.inputs.base_directory = SinkDir

    # Save outputs which are important
    ds_qc_fd = pe.Node(interface=io.DataSink(), name='ds_qc_fd')
    ds_qc_fd.inputs.base_directory = QCDir
    ds_qc_fd.inputs.regexp_substitutions = [("(\/)[^\/]*$", "_FD.pdf")]

    # Basic interface class generates identity mappings
    outputspec = pe.Node(utility.IdentityInterface(fields=[
        'func_out_file', 'first24_file', 'mat_file', 'mc_par_file', 'FD_file'
    ]),
                         name='outputspec')

    # save data out with Datasink
    ds_nii = pe.Node(interface=io.DataSink(), name='ds_nii')
    ds_nii.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]
    ds_nii.inputs.base_directory = SinkDir

    # save data out with Datasink
    ds_text = pe.Node(interface=io.DataSink(), name='ds_txt')
    ds_text.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".txt")]
    ds_text.inputs.base_directory = SinkDir

    # TODO_ready set the proper images which has to be saved in a the datasink specified directory
    # Create a workflow to connect all those nodes
    analysisflow = nipype.Workflow(wf_name)

    analysisflow.connect(inputspec, 'func', refvol, 'func')
    analysisflow.connect(inputspec, 'ref_vol', refvol, 'refvol')
    if (reference_vol == "mean"):
        analysisflow.connect(inputspec, 'func', func_motion_correct1,
                             'in_file')
        analysisflow.connect(refvol, 'refvol', func_motion_correct1,
                             'basefile')
        analysisflow.connect(func_motion_correct1, 'out_file', refvol2, 'func')
        analysisflow.connect(inputspec, 'ref_vol', refvol2, 'refvol')
        analysisflow.connect(inputspec, 'func', func_motion_correct, 'in_file')
        analysisflow.connect(refvol2, 'refvol', func_motion_correct,
                             'basefile')
    else:
        analysisflow.connect(inputspec, 'func', func_motion_correct, 'in_file')
        analysisflow.connect(refvol, 'refvol', func_motion_correct, 'basefile')

    analysisflow.connect(func_motion_correct, 'oned_file', calc_friston,
                         'in_file')
    analysisflow.connect(func_motion_correct, 'oned_file', calculate_FD,
                         'in_file')

    analysisflow.connect(func_motion_correct, 'out_file', outputspec,
                         'func_out_file')
    analysisflow.connect(func_motion_correct, 'oned_matrix_save', outputspec,
                         'mat_file')
    analysisflow.connect(func_motion_correct, 'oned_file', outputspec,
                         'mc_par_file')
    analysisflow.connect(func_motion_correct, 'out_file', ds_nii, 'mc_func')
    analysisflow.connect(func_motion_correct, 'oned_file', ds_text, 'mc_par')
    # analysisflow.connect(func_motion_correct, 'variance_img', ds, 'mc.@variance_img')
    analysisflow.connect(calc_friston, 'out_file', outputspec, 'first24_file')
    analysisflow.connect(calc_friston, 'out_file', ds_text, 'mc_first24')
    analysisflow.connect(calculate_FD, 'out_file', outputspec, 'FD_file')
    analysisflow.connect(func_motion_correct, 'out_file', myqc,
                         'inputspec.func')
    # pop-level mean FD
    analysisflow.connect(calculate_FD, 'out_file', meanFD, 'in_file')
    analysisflow.connect(calculate_FD, 'out_file', ds_text, 'mc_fd')
    analysisflow.connect(meanFD, 'mean_file', pop_FD, 'in_list')
    analysisflow.connect(pop_FD, 'txt_file', ds_fd, 'pop')
    analysisflow.connect(calculate_FD, 'out_figure', ds_qc_fd, 'FD')

    analysisflow.connect(calculate_FD, 'out_file', maxFD, 'in_file')
    analysisflow.connect(maxFD, 'max_file', pop_FDmax, 'in_list')
    analysisflow.connect(pop_FDmax, 'txt_file', ds_fd_max, 'pop')

    return analysisflow
Ejemplo n.º 5
0
def anat2mni_ants_workflow_nipype(SinkTag="anat_preproc",
                                  wf_name="anat2mni_ants"):
    """
    Register skull and brain extracted image to MNI space and return the transformation martices.
    Using ANTS, doing it in the nipype way.

    Workflow inputs:
        :param skull: The reoriented anatomical file.
        :param brain: The brain extracted anat.
        :param ref_skull: MNI152 skull file.
        :param ref_brain: MNI152 brain file.
        :param SinkDir:
        :param SinkTag: The output directiry in which the returned images (see workflow outputs) could be found.

    Workflow outputs:




        :return: anat2mni_workflow - workflow


        anat="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres.nii.gz",
                      brain="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres_brain.nii.gz",


    Tamas Spisak
    [email protected]
    2018


    """
    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Define inputs of workflow
    inputspec = pe.Node(utility.IdentityInterface(
        fields=['brain', 'skull', 'reference_brain', 'reference_skull']),
                        name='inputspec')

    inputspec.inputs.reference_brain = globals._FSLDIR_ + globals._brainref  #TODO_ready: 1 or 2mm???
    inputspec.inputs.reference_skull = globals._FSLDIR_ + globals._headref

    # Multi-stage registration node with ANTS
    reg = pe.MapNode(
        interface=Registration(),
        iterfield=['moving_image'],  # 'moving_image_mask'],
        name="ANTS")
    """
    reg.inputs.transforms = ['Affine', 'SyN']
    reg.inputs.transform_parameters = [(2.0,), (0.1, 3.0, 0.0)]
    reg.inputs.number_of_iterations = [[1500, 200], [100, 50, 30]]
    reg.inputs.dimension = 3
    reg.inputs.write_composite_transform = True
    reg.inputs.collapse_output_transforms = False
    reg.inputs.initialize_transforms_per_stage = False
    reg.inputs.metric = ['Mattes', 'Mattes']
    reg.inputs.metric_weight = [1] * 2  # Default (value ignored currently by ANTs)
    reg.inputs.radius_or_number_of_bins = [32] * 2
    reg.inputs.sampling_strategy = ['Random', None]
    reg.inputs.sampling_percentage = [0.05, None]
    reg.inputs.convergence_threshold = [1.e-8, 1.e-9]
    reg.inputs.convergence_window_size = [20] * 2
    reg.inputs.smoothing_sigmas = [[1, 0], [2, 1, 0]]
    reg.inputs.sigma_units = ['vox'] * 2
    reg.inputs.shrink_factors = [[2, 1], [4, 2, 1]]
    reg.inputs.use_estimate_learning_rate_once = [True, True]
    reg.inputs.use_histogram_matching = [True, True]  # This is the default
    reg.inputs.output_warped_image = 'output_warped_image.nii.gz'
    reg.inputs.winsorize_lower_quantile = 0.01
    reg.inputs.winsorize_upper_quantile = 0.99
    """

    #satra says:
    reg.inputs.transforms = ['Rigid', 'Affine', 'SyN']
    reg.inputs.transform_parameters = [(0.1, ), (0.1, ), (0.2, 3.0, 0.0)]
    reg.inputs.number_of_iterations = ([[10000, 111110, 11110]] * 2 +
                                       [[100, 50, 30]])
    reg.inputs.dimension = 3
    reg.inputs.write_composite_transform = True
    reg.inputs.collapse_output_transforms = True
    reg.inputs.initial_moving_transform_com = True
    reg.inputs.metric = ['Mattes'] * 2 + [['Mattes', 'CC']]
    reg.inputs.metric_weight = [1] * 2 + [[0.5, 0.5]]
    reg.inputs.radius_or_number_of_bins = [32] * 2 + [[32, 4]]
    reg.inputs.sampling_strategy = ['Regular'] * 2 + [[None, None]]
    reg.inputs.sampling_percentage = [0.3] * 2 + [[None, None]]
    reg.inputs.convergence_threshold = [1.e-8] * 2 + [-0.01]
    reg.inputs.convergence_window_size = [20] * 2 + [5]
    reg.inputs.smoothing_sigmas = [[4, 2, 1]] * 2 + [[1, 0.5, 0]]
    reg.inputs.sigma_units = ['vox'] * 3
    reg.inputs.shrink_factors = [[3, 2, 1]] * 2 + [[4, 2, 1]]
    reg.inputs.use_estimate_learning_rate_once = [True] * 3
    reg.inputs.use_histogram_matching = [False] * 2 + [True]
    reg.inputs.winsorize_lower_quantile = 0.005
    reg.inputs.winsorize_upper_quantile = 0.995
    reg.inputs.args = '--float'

    # Create png images for quality check
    myqc = qc.vol2png("anat2mni", "ANTS3", overlayiterated=False)
    myqc.inputs.inputspec.overlay_image = globals._FSLDIR_ + globals._brainref  #TODO_ready: 1 or 2mm???
    myqc.inputs.slicer.image_width = 500  # 5000 # for the 1mm template
    myqc.inputs.slicer.threshold_edges = 0.1  # 0.1  # for the 1mm template

    # Save outputs which are important
    ds = pe.Node(interface=io.DataSink(), name='ds_nii')
    ds.inputs.base_directory = SinkDir
    ds.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

    # Define outputs of the workflow
    outputspec = pe.Node(utility.IdentityInterface(fields=[
        'output_brain', 'linear_xfm', 'invlinear_xfm', 'nonlinear_xfm',
        'invnonlinear_xfm', 'std_template'
    ]),
                         name='outputspec')

    outputspec.inputs.std_template = inputspec.inputs.reference_brain

    # Create workflow nad connect nodes
    analysisflow = pe.Workflow(name=wf_name)

    analysisflow.connect(inputspec, 'reference_skull', reg, 'fixed_image')
    #analysisflow.connect(inputspec, 'reference_brain', reg, 'fixed_image_mask')
    analysisflow.connect(inputspec, 'skull', reg, 'moving_image')
    #analysisflow.connect(inputspec, 'brain', reg, 'moving_image_mask')

    analysisflow.connect(reg, 'composite_transform', outputspec,
                         'nonlinear_xfm')
    analysisflow.connect(reg, 'inverse_composite_transform', outputspec,
                         'invnonlinear_xfm')
    analysisflow.connect(reg, 'warped_image', outputspec, 'output_brain')
    analysisflow.connect(reg, 'warped_image', ds, 'anat2mni_std')
    analysisflow.connect(reg, 'composite_transform', ds, 'anat2mni_warpfield')
    analysisflow.connect(reg, 'warped_image', myqc, 'inputspec.bg_image')

    return analysisflow
Ejemplo n.º 6
0
def func2mni(stdreg,
             carpet_plot="",
             wf_name='func2mni',
             SinkTag="func_preproc"):
    """
    stdreg: either globals._RegType_.ANTS or globals._RegType_.FSL (do default value to make sure the user has to decide explicitly)

    Transaform 4D functional image to MNI space.

    carpet_plot: string specifying the tag parameter for carpet plot of the standardized MRI measurement
            (default is "": no carpet plot)
            if not "", inputs atlaslabels and confounds should be defined (it might work with defaults, though)

    Workflow inputs:
    :param func
    :param linear_reg_mtrx
    :param nonlinear_reg_mtrx
    :param reference_brain
    :param atlas (optional)
    :param confounds (optional)
    :param confound_names (optional)


    Workflow outputs:




        :return: anat2mni_workflow - workflow


        anat="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres.nii.gz",
                      brain="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres_brain.nii.gz",


    Balint Kincses
    [email protected]
    2018


    """
    import os
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.ants as ants
    from nipype.interfaces.c3 import C3dAffineTool
    import PUMI.utils.globals as globals
    import PUMI.func_preproc.Onevol as onevol
    import PUMI.utils.QC as qc
    import nipype.interfaces.io as io
    from nipype.interfaces.utility import Function

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    inputspec = pe.Node(
        utility.IdentityInterface(fields=[
            'func',
            'anat',  # only obligatory if stdreg==globals._RegType_.ANTS
            'linear_reg_mtrx',
            'nonlinear_reg_mtrx',
            'reference_brain',
            'atlas',
            'confounds',
            'confound_names'
        ]),
        name='inputspec')

    inputspec.inputs.atlas = globals._FSLDIR_ + '/data/atlases/HarvardOxford/HarvardOxford-cort-maxprob-thr25-2mm.nii.gz'

    inputspec.inputs.reference_brain = globals._FSLDIR_ + "/data/standard/MNI152_T1_3mm_brain.nii.gz"  #3mm by default
    # TODO: this does not work with the iterfiled definition for ref_file below:
    # TODO: it should be sepcified in a function argument, whether it shopuld be iterated
    #TODO_ready: ANTS
    #TODO: make resampling voxel size for func parametrizable

    # apply transformation martices
    if stdreg == globals._RegType_.FSL:
        applywarp = pe.MapNode(interface=fsl.ApplyWarp(interp="spline", ),
                               iterfield=['in_file', 'field_file', 'premat'],
                               name='applywarp')
        myqc = qc.vol2png("func2mni", wf_name + "_FSL", overlayiterated=False)
        myqc.inputs.slicer.image_width = 500  # 500 # for the 2mm template
        myqc.inputs.slicer.threshold_edges = 0.1  # 0.1  # for the 2mm template
    else:  #ANTs
        # source file for C3dAffineToolmust not be 4D, so we extract the one example vol
        myonevol = onevol.onevol_workflow()
        # concat premat and ants transform
        bbr2ants = pe.MapNode(
            interface=C3dAffineTool(fsl2ras=True, itk_transform=True),
            iterfield=['source_file', 'transform_file',
                       'reference_file'],  # output: 'itk_transform'
            name="bbr2ants")
        #concat trfs into a list
        trflist = pe.MapNode(interface=Function(
            input_names=['trf_first', 'trf_second'],
            output_names=['trflist'],
            function=transformlist),
                             iterfield=['trf_first', 'trf_second'],
                             name="collect_trf")

        applywarp = pe.MapNode(interface=ants.ApplyTransforms(
            interpolation="BSpline", input_image_type=3),
                               iterfield=['input_image', 'transforms'],
                               name='applywarp')
        myqc = qc.vol2png("func2mni",
                          wf_name + "_ANTS3",
                          overlayiterated=False)
        myqc.inputs.slicer.image_width = 500  # 500 # for the 2mm template
        myqc.inputs.slicer.threshold_edges = 0.1  # 0.1  # for the 2mm template

    if carpet_plot:
        fmri_qc = qc.fMRI2QC("carpet_plots", tag=carpet_plot)

    outputspec = pe.Node(utility.IdentityInterface(fields=['func_std']),
                         name='outputspec')

    # Save outputs which are important
    ds_nii = pe.Node(interface=io.DataSink(), name='ds_nii')
    ds_nii.inputs.base_directory = SinkDir
    ds_nii.inputs.regexp_substitutions = [("(\/)[^\/]*$", wf_name + ".nii.gz")]

    analysisflow = pe.Workflow(wf_name)
    analysisflow.base_dir = '.'
    if stdreg == globals._RegType_.FSL:
        analysisflow.connect(inputspec, 'func', applywarp, 'in_file')
        analysisflow.connect(inputspec, 'linear_reg_mtrx', applywarp, 'premat')
        analysisflow.connect(inputspec, 'nonlinear_reg_mtrx', applywarp,
                             'field_file')
        analysisflow.connect(inputspec, 'reference_brain', applywarp,
                             'ref_file')
        analysisflow.connect(applywarp, 'out_file', outputspec, 'func_std')
        analysisflow.connect(applywarp, 'out_file', myqc, 'inputspec.bg_image')
        analysisflow.connect(inputspec, 'reference_brain', myqc,
                             'inputspec.overlay_image')
        analysisflow.connect(applywarp, 'out_file', ds_nii, 'func2mni')
    else:  # ANTs
        analysisflow.connect(inputspec, 'func', myonevol, 'inputspec.func')
        analysisflow.connect(myonevol, 'outputspec.func1vol', bbr2ants,
                             'source_file')
        analysisflow.connect(inputspec, 'linear_reg_mtrx', bbr2ants,
                             'transform_file')
        analysisflow.connect(inputspec, 'anat', bbr2ants, 'reference_file')
        analysisflow.connect(bbr2ants, 'itk_transform', trflist, 'trf_first')
        analysisflow.connect(inputspec, 'nonlinear_reg_mtrx', trflist,
                             'trf_second')
        analysisflow.connect(trflist, 'trflist', applywarp, 'transforms')
        analysisflow.connect(inputspec, 'func', applywarp, 'input_image')
        analysisflow.connect(inputspec, 'reference_brain', applywarp,
                             'reference_image')

        analysisflow.connect(applywarp, 'output_image', outputspec, 'func_std')
        analysisflow.connect(applywarp, 'output_image', myqc,
                             'inputspec.bg_image')
        analysisflow.connect(inputspec, 'reference_brain', myqc,
                             'inputspec.overlay_image')
        analysisflow.connect(applywarp, 'output_image', ds_nii, 'func2mni')

    if carpet_plot:
        if stdreg == globals._RegType_.FSL:
            analysisflow.connect(applywarp, 'out_file', fmri_qc,
                                 'inputspec.func')
        else:  # ANTs
            analysisflow.connect(applywarp, 'output_image', fmri_qc,
                                 'inputspec.func')

        analysisflow.connect(inputspec, 'atlas', fmri_qc, 'inputspec.atlas')
        analysisflow.connect(inputspec, 'confounds', fmri_qc,
                             'inputspec.confounds')

    return analysisflow
Ejemplo n.º 7
0
def compcor_workflow(SinkTag="func_preproc", wf_name="compcor"):
    """


               `source: -`


               Component based noise reduction method (Behzadi et al.,2007): Regressing out principal components from noise ROIs.
               Here the aCompCor is used.

               Workflow inputs:
                   :param func_aligned: The reoriented and realigned functional image.
                   :param mask_files: Mask files which determine ROI(s). The default mask is the
                   :param components_file
                   :param num_componenets:
                   :param pre_filter: Detrend time series prior to component extraction.
                   :param TR
                   :param SinkDir:
                   :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found in a subdirectory directory specific for this workflow.

               Workflow outputs:




                   :return: slt_workflow - workflow




               Balint Kincses
               [email protected]
               2018


     """

    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.algorithms.confounds as cnf
    import PUMI.func_preproc.info.info_get as info_get
    import PUMI.utils.utils_convert as utils_convert
    import nipype.interfaces.io as io
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import PUMI.utils.QC as qc
    import PUMI.utils.globals as globals

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Basic interface class generates identity mappings
    inputspec = pe.Node(
        utility.IdentityInterface(fields=['func_aligned', 'mask_file']),
        name='inputspec')

    myqc = qc.vol2png("compcor_noiseroi")

    # Save outputs which are important
    ds_nii = pe.Node(interface=io.DataSink(), name='ds_nii')
    ds_nii.inputs.base_directory = SinkDir
    ds_nii.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

    # standardize timeseries prior to compcor. added by tspisak
    scale = pe.MapNode(interface=utility.Function(input_names=['in_file'],
                                                  output_names=['scaled_file'],
                                                  function=scale_vol),
                       iterfield=['in_file'],
                       name='scale_func')

    # Calculate compcor files
    compcor = pe.MapNode(
        interface=cnf.ACompCor(pre_filter='polynomial',
                               header_prefix="",
                               num_components=5),
        iterfield=['realigned_file', 'repetition_time', 'mask_files'],
        name='compcor')

    # Custom interface wrapping function Float2Str
    func_str2float = pe.MapNode(interface=utils_convert.Str2Float,
                                iterfield=['str'],
                                name='func_str2float')
    # Drop first line of the Acompcor function output
    drop_firstline = pe.MapNode(interface=utils_convert.DropFirstLine,
                                iterfield=['txt'],
                                name='drop_firstline')
    # Custom interface wrapping function TR
    TRvalue = pe.MapNode(interface=info_get.TR,
                         iterfield=['in_file'],
                         name='TRvalue')

    # Basic interface class generates identity mappings
    outputspec = pe.Node(utility.IdentityInterface(fields=['components_file']),
                         name='outputspec')

    # save data out with Datasink
    ds_text = pe.Node(interface=io.DataSink(), name='ds_txt')
    ds_text.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".txt")]
    ds_text.inputs.base_directory = SinkDir

    # Create a workflow to connect all those nodes
    analysisflow = nipype.Workflow(wf_name)
    analysisflow.connect(inputspec, 'func_aligned', scale, 'in_file')
    analysisflow.connect(scale, 'scaled_file', compcor, 'realigned_file')
    analysisflow.connect(inputspec, 'func_aligned', TRvalue, 'in_file')
    analysisflow.connect(TRvalue, 'TR', func_str2float, 'str')
    analysisflow.connect(func_str2float, 'float', compcor, 'repetition_time')
    #analysisflow.connect(TRvalue, 'TR', compcor, 'repetition_time')
    analysisflow.connect(inputspec, 'mask_file', compcor, 'mask_files')
    analysisflow.connect(compcor, 'components_file', drop_firstline, 'txt')
    analysisflow.connect(drop_firstline, 'droppedtxtfloat', outputspec,
                         'components_file')
    analysisflow.connect(compcor, 'components_file', ds_text, 'compcor_noise')

    analysisflow.connect(inputspec, 'func_aligned', myqc, 'inputspec.bg_image')
    analysisflow.connect(inputspec, 'mask_file', myqc,
                         'inputspec.overlay_image')

    analysisflow.connect(inputspec, 'mask_file', ds_nii, 'compcor_noise_mask')

    return analysisflow
Ejemplo n.º 8
0
def aroma_workflow(fwhm=0, # in mm
                SinkTag = "func_preproc", wf_name="ICA_AROMA"):

    """
   ICA AROMA method embedded into PUMI
   https://github.com/rhr-pruim/ICA-AROMA

    function input: fwhm: smoothing FWHM in mm. fwhm=0 means no smoothing

    Workflow inputs:
        :param mc_func: The reoriented and motion-corrected functional file.
        :param mc_params: motion parameters file from mcflirt
        :param SinkDir:
        :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found in a subdirectory directory specific for this workflow..

    Workflow outputs:




        :return: aroma_workflow - workflow

    Tamas Spisak
    [email protected]
    2018


    """
    from nipype.interfaces.fsl import ICA_AROMA
    import nipype.pipeline as pe
    from nipype.interfaces import utility
    import nipype.interfaces.io as io
    import PUMI.utils.QC as qc
    from nipype.interfaces.fsl import Smooth
    import os
    import PUMI.utils.globals as globals

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Define inputs of the workflow
    inputspec = pe.Node(utility.IdentityInterface(fields=['mc_func',
                                                          'mc_par',
                                                          'fnirt_warp_file',
                                                          'mat_file',
                                                          'mask',
                                                          'qc_mask'
                                                          ]),
                            name='inputspec')

    # build the actual pipeline
    if fwhm != 0:
        smoother = pe.MapNode(interface=Smooth(fwhm=fwhm),
                              iterfield=['in_file'],
                              name="smoother")
    myqc_before = qc.timecourse2png("timeseries", tag="1_original")

    aroma = pe.MapNode(interface=ICA_AROMA(denoise_type='both'),
                       iterfield=['in_file',
                                  'motion_parameters',
                                  'mat_file',
                                  'fnirt_warp_file',
                                  'mask'],
                       name="ICA_AROMA")
    aroma.inputs.denoise_type = 'both'
    aroma.inputs.out_dir = 'AROMA_out'

    myqc_after_nonaggr = qc.timecourse2png("timeseries", tag="2_nonaggressive")
    myqc_after_aggr = qc.timecourse2png("timeseries", tag="3_aggressive")  # put these in the same QC dir

    getMotICs=pe.MapNode(interface=Function(input_names=['aroma_dir'],
                                            output_names=['motion_ICs'],
                                            function=extract_motionICs),
                         iterfield=['aroma_dir'],
                         name="get_motion_ICs")

    # Save outputs which are important
    ds_nii = pe.Node(interface=io.DataSink(),
                 name='ds_nii')
    ds_nii.inputs.base_directory = SinkDir
    ds_nii.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

    ds_txt = pe.Node(interface=io.DataSink(),
                     name='ds_txt')
    ds_txt.inputs.base_directory = SinkDir
    ds_txt.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".txt")]

    # Define outputs of the workflow
    outputspec = pe.Node(utility.IdentityInterface(fields=['aggr_denoised_file',
                                                           'nonaggr_denoised_file',
                                                           'motion_ICs',
                                                           'out_dir',
                                                           'fwhm']),
                         name='outputspec')
    outputspec.inputs.fwhm = fwhm

    analysisflow = pe.Workflow(name=wf_name)
    if fwhm != 0:
        analysisflow.connect(inputspec, 'mc_func', smoother, 'in_file')
        analysisflow.connect(smoother, 'smoothed_file', aroma, 'in_file')
        analysisflow.connect(smoother, 'smoothed_file', myqc_before, 'inputspec.func')
    else:
        analysisflow.connect(inputspec, 'mc_func', aroma, 'in_file')
        analysisflow.connect(inputspec, 'mc_func', myqc_before, 'inputspec.func')
    analysisflow.connect(inputspec, 'mc_par', aroma, 'motion_parameters')
    analysisflow.connect(inputspec, 'mat_file', aroma, 'mat_file')
    analysisflow.connect(inputspec, 'fnirt_warp_file', aroma, 'fnirt_warp_file')
    analysisflow.connect(inputspec, 'mask', aroma, 'mask')
    analysisflow.connect(aroma, 'out_dir', getMotICs, 'aroma_dir')
    analysisflow.connect(getMotICs, 'motion_ICs', ds_txt, 'motion_ICs')
    analysisflow.connect(aroma, 'aggr_denoised_file', ds_nii, 'AROMA_aggr_denoised')
    analysisflow.connect(aroma, 'nonaggr_denoised_file', ds_nii, 'AROMA_nonaggr_denoised')

    analysisflow.connect(inputspec, 'qc_mask', myqc_before, 'inputspec.mask')
    analysisflow.connect(aroma, 'aggr_denoised_file', myqc_after_aggr, 'inputspec.func')
    #analysisflow.connect(inputspec, 'qc_mask', myqc_after_aggr, 'inputspec.mask')
    analysisflow.connect(aroma, 'nonaggr_denoised_file', myqc_after_nonaggr, 'inputspec.func')
    #analysisflow.connect(inputspec, 'qc_mask', myqc_after_nonaggr, 'inputspec.mask')

    analysisflow.connect(aroma, 'aggr_denoised_file', outputspec, 'aggr_denoised_file')
    analysisflow.connect(aroma, 'nonaggr_denoised_file', outputspec, 'nonaggr_denoised_file')
    analysisflow.connect(aroma, 'out_dir', outputspec, 'out_dir')
    analysisflow.connect(getMotICs, 'motion_ICs', outputspec, 'motion_ICs')

    return analysisflow
Ejemplo n.º 9
0
def datacens_workflow_threshold(SinkTag="func_preproc",
                                wf_name="data_censoring",
                                ex_before=1,
                                ex_after=2):
    """

        Modified version of CPAC.scrubbing.scrubbing +
                            CPAC.generate_motion_statistics.generate_motion_statistics +
                            CPAC.func_preproc.func_preproc

    `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/scrubbing/scrubbing.html`
    `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/generate_motion_statistics/generate_motion_statistics.html`
    `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/func_preproc/func_preproc.html`

    Description:
        Do the data censoring on the 4D functional data. First, it calculates the framewise displacement according to Power's method. Second, it
        indexes the volumes which FD is in the upper part in percent(determined by the threshold variable which is 5% by default). Thirdly, it excludes those volumes and one volume
        before and 2 volumes after the indexed volume. The workflow returns a 4D scrubbed functional data.

    Workflow inputs:
        :param func: The reoriented,motion occrected, nuissance removed and bandpass filtered functional file.
        :param FD: the frame wise displacement calculated by the MotionCorrecter.py script
        :param threshold: threshold of FD volumes which should be excluded
        :param SinkDir:
        :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found in a subdirectory directory specific for this workflow..

    Workflow outputs:

        :return: datacens_workflow - workflow




    Balint Kincses
    [email protected]
    2018


    References
    ----------

    .. [1] Power, J. D., Barnes, K. A., Snyder, A. Z., Schlaggar, B. L., & Petersen, S. E. (2012). Spurious
           but systematic correlations in functional connectivity MRI networks arise from subject motion. NeuroImage, 59(3),
           2142-2154. doi:10.1016/j.neuroimage.2011.10.018

    .. [2] Power, J. D., Barnes, K. A., Snyder, A. Z., Schlaggar, B. L., & Petersen, S. E. (2012). Steps
           toward optimizing motion artifact removal in functional connectivity MRI; a reply to Carp.
           NeuroImage. doi:10.1016/j.neuroimage.2012.03.017

    .. [3] Jenkinson, M., Bannister, P., Brady, M., Smith, S., 2002. Improved optimization for the robust
           and accurate linear registration and motion correction of brain images. Neuroimage 17, 825-841.

    """

    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.io as io
    import PUMI.utils.utils_convert as utils_convert
    import PUMI.utils.globals as globals
    import PUMI.utils.QC as qc

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Identitiy mapping for input variables
    inputspec = pe.Node(
        utility.IdentityInterface(fields=['func', 'FD', 'threshold']),
        name='inputspec')
    inputspec.inputs.threshold = 0.2  #mm

    #TODO_ready check CPAC.generate_motion_statistics.generate_motion_statistics script. It may use the FD of Jenkinson to index volumes which violate the upper threhold limit, no matter what we set.
    # - we use the power method to calculate FD
    above_thr = pe.MapNode(utility.Function(
        input_names=['in_file', 'threshold', 'frames_before', 'frames_after'],
        output_names=[
            'frames_in_idx', 'frames_out_idx', 'percentFD',
            'percent_scrubbed_file', 'fd_scrubbed_file', 'nvol'
        ],
        function=above_threshold),
                           iterfield=['in_file'],
                           name='above_threshold')
    above_thr.inputs.frames_before = ex_before
    above_thr.inputs.frames_after = ex_after

    # Save outputs which are important
    ds_fd_scrub = pe.Node(interface=io.DataSink(), name='ds_fd_scrub')
    ds_fd_scrub.inputs.base_directory = SinkDir
    ds_fd_scrub.inputs.regexp_substitutions = [("(\/)[^\/]*$",
                                                "FD_scrubbed.csv")]
    pop_perc_scrub = pe.Node(interface=utils_convert.List2TxtFileOpen,
                             name='pop_perc_scrub')

    # save data out with Datasink
    ds_pop_perc_scrub = pe.Node(interface=io.DataSink(),
                                name='ds_pop_perc_scrub')
    ds_pop_perc_scrub.inputs.regexp_substitutions = [
        ("(\/)[^\/]*$", "pop_percent_scrubbed.txt")
    ]
    ds_pop_perc_scrub.inputs.base_directory = SinkDir

    # Generate the weird input for the scrubbing procedure which is done in afni
    craft_scrub_input = pe.MapNode(
        utility.Function(input_names=['scrub_input', 'frames_in_1D_file'],
                         output_names=['scrub_input_string'],
                         function=get_indx),
        iterfield=['scrub_input', 'frames_in_1D_file'],
        name='scrubbing_craft_input_string')
    # Scrub the image
    scrubbed_preprocessed = pe.MapNode(utility.Function(
        input_names=['scrub_input'],
        output_names=['scrubbed_image'],
        function=scrub_image),
                                       iterfield=['scrub_input'],
                                       name='scrubbed_preprocessed')

    myqc = qc.timecourse2png("timeseries", tag="040_censored")

    outputspec = pe.Node(
        utility.IdentityInterface(fields=['scrubbed_image', 'FD_scrubbed']),
        name='outputspec')

    # save data out with Datasink
    ds = pe.Node(interface=io.DataSink(), name='ds')
    ds.inputs.base_directory = SinkDir

    #TODO_ready: some plot for qualitiy checking

    # Create workflow
    analysisflow = pe.Workflow(wf_name)
    ###Calculating mean Framewise Displacement (FD) as Power et al., 2012
    # Calculating frames to exclude and include after scrubbing
    analysisflow.connect(inputspec, 'FD', above_thr, 'in_file')
    analysisflow.connect(inputspec, 'threshold', above_thr, 'threshold')
    # Create the proper format for the scrubbing procedure
    analysisflow.connect(above_thr, 'frames_in_idx', craft_scrub_input,
                         'frames_in_1D_file')
    analysisflow.connect(
        above_thr, 'percent_scrubbed_file', ds,
        'percentFD')  # TODO save this in separate folder for QC
    analysisflow.connect(inputspec, 'func', craft_scrub_input, 'scrub_input')
    # Do the scubbing
    analysisflow.connect(craft_scrub_input, 'scrub_input_string',
                         scrubbed_preprocessed, 'scrub_input')
    # Output
    analysisflow.connect(scrubbed_preprocessed, 'scrubbed_image', outputspec,
                         'scrubbed_image')
    analysisflow.connect(above_thr, 'fd_scrubbed_file', outputspec,
                         'FD_scrubbed')  #TODO_ready: scrub FD file, as well
    analysisflow.connect(above_thr, 'fd_scrubbed_file', ds_fd_scrub,
                         'FD_scrubbed')

    analysisflow.connect(above_thr, 'percent_scrubbed_file', pop_perc_scrub,
                         'in_list')
    analysisflow.connect(pop_perc_scrub, 'txt_file', ds_pop_perc_scrub, 'pop')

    # Save a few files
    analysisflow.connect(scrubbed_preprocessed, 'scrubbed_image', ds,
                         'scrubbed_image')
    #analysisflow.connect(above_thr, 'percentFD', ds, 'scrubbed_image.@numberofvols')
    analysisflow.connect(scrubbed_preprocessed, 'scrubbed_image', myqc,
                         'inputspec.func')

    return analysisflow
Ejemplo n.º 10
0
datagrab.inputs.template = "*"  # do we need this?
datagrab.inputs.field_template = dict(struct=sys.argv[1])  # specified by command line arguments
datagrab.inputs.sort_filelist = True


reorient_struct = pe.MapNode(fsl.utils.Reorient2Std(),
                      iterfield=['in_file'],
                      name="reorient_struct")

bet = pe.MapNode(interface=fsl.BET(),
                     iterfield=['in_file'],
                 iterables=[('vertical_gradient',[-0.2,0,0.2])
                            ],
                  name='bet')

myqc = qc.vol2png("brain_extraction", overlay=True)

totalWorkflow = nipype.Workflow('bet_probe')
totalWorkflow.base_dir = '.'

totalWorkflow.connect([
    (datagrab,reorient_struct,
     [('struct','in_file')]),
    (reorient_struct, bet,
     [('out_file', 'in_file')]),
    (bet,myqc,
     [('out_file', 'inputspec.overlay_image')]),
    (reorient_struct, myqc,
     [('out_file','inputspec.bg_image')])
    ])
Ejemplo n.º 11
0
def FuncProc_despike_afni(stdrefvol="mid",
                          SinkTag="func_preproc",
                          wf_name="func_preproc_dspk_afni",
                          fwhm=0,
                          carpet_plot=""):
    """
        Performs processing of functional (resting-state) images:

        Images should be already reoriented, e.g. with fsl fslreorient2std (see scripts/ex_pipeline.py)

        Workflow inputs:
            :param func: The functional image file.
            :param SinkDir: where to write important ouputs
            :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found.

        Workflow outputs:
            :param



            :return: anatproc_workflow


        Tamas Spisak
        [email protected]
        2018

        """

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)
    wf_mc = nipype.Workflow(wf_name)

    # Basic interface class generates identity mappings
    inputspec = pe.Node(
        utility.IdentityInterface(fields=['func', 'cc_noise_roi']),
        name='inputspec')

    # build the actual pipeline
    #myonevol = onevol.onevol_workflow(SinkDir=SinkDir)
    mybet = bet.bet_workflow(SinkTag="func_preproc",
                             fmri=True,
                             wf_name="brain_extraction_func")

    mymc = mc.mc_workflow_fsl(reference_vol=stdrefvol)

    if carpet_plot:
        # create "atlas"
        add_masks = pe.MapNode(fsl.ImageMaths(op_string=' -add'),
                               iterfield=['in_file', 'in_file2'],
                               name="addimgs")
        wf_mc.connect(inputspec, 'cc_noise_roi', add_masks, 'in_file')
        wf_mc.connect(mybet, 'outputspec.brain_mask', add_masks, 'in_file2')

        fmri_qc_mc = qc.fMRI2QC(carpet_plot, tag="mc", indiv_atlas=True)
        wf_mc.connect(add_masks, 'out_file', fmri_qc_mc, 'inputspec.atlas')
        wf_mc.connect(mymc, 'outputspec.FD_file', fmri_qc_mc,
                      'inputspec.confounds')
        wf_mc.connect(mymc, 'outputspec.func_out_file', fmri_qc_mc,
                      'inputspec.func')

    mydespike = pe.MapNode(
        afni.Despike(
            outputtype="NIFTI_GZ"),  # I do it after motion correction...
        iterfield=['in_file'],
        name="DeSpike")

    if carpet_plot:
        fmri_qc_mc_dspk = qc.fMRI2QC(carpet_plot,
                                     tag="mc_dspk",
                                     indiv_atlas=True)
        wf_mc.connect(add_masks, 'out_file', fmri_qc_mc_dspk,
                      'inputspec.atlas')
        wf_mc.connect(mymc, 'outputspec.FD_file', fmri_qc_mc_dspk,
                      'inputspec.confounds')
        wf_mc.connect(mydespike, 'out_file', fmri_qc_mc_dspk, 'inputspec.func')

    mycmpcor = cmpcor.compcor_workflow()  # to  WM+CSF signal
    myconc = conc.concat_workflow(numconcat=2)
    mynuisscor = nuisscorr.nuissremov_workflow(
    )  # regress out 5 compcor variables and the Friston24

    if carpet_plot:
        fmri_qc_mc_dspk_nuis = qc.fMRI2QC(carpet_plot,
                                          tag="mc_dspk_nuis",
                                          indiv_atlas=True)
        wf_mc.connect(add_masks, 'out_file', fmri_qc_mc_dspk_nuis,
                      'inputspec.atlas')
        wf_mc.connect(mymc, 'outputspec.FD_file', fmri_qc_mc_dspk_nuis,
                      'inputspec.confounds')
        wf_mc.connect(mynuisscor, 'outputspec.out_file', fmri_qc_mc_dspk_nuis,
                      'inputspec.func')

    # optional smoother:
    if fwhm > 0:
        smoother = pe.MapNode(interface=Smooth(fwhm=fwhm),
                              iterfield=['in_file'],
                              name="smoother")
        if carpet_plot:
            fmri_qc_mc_dspk_smooth_nuis_bpf = qc.fMRI2QC(
                carpet_plot, tag="mc_dspk_nuis_smooth", indiv_atlas=True)
            wf_mc.connect(add_masks, 'out_file',
                          fmri_qc_mc_dspk_smooth_nuis_bpf, 'inputspec.atlas')
            wf_mc.connect(mymc, 'outputspec.FD_file',
                          fmri_qc_mc_dspk_smooth_nuis_bpf,
                          'inputspec.confounds')
            wf_mc.connect(smoother, 'smoothed_file',
                          fmri_qc_mc_dspk_smooth_nuis_bpf, 'inputspec.func')

    #mymedangcor = medangcor.mac_workflow() #skip it this time
    mytmpfilt = tmpfilt.tmpfilt_workflow(
        highpass_Hz=0.008, lowpass_Hz=0.08)  #will be done by the masker?

    if carpet_plot:
        fmri_qc_mc_dspk_nuis_bpf = qc.fMRI2QC(carpet_plot,
                                              tag="mc_dspk_nuis_bpf",
                                              indiv_atlas=True)
        wf_mc.connect(add_masks, 'out_file', fmri_qc_mc_dspk_nuis_bpf,
                      'inputspec.atlas')
        wf_mc.connect(mymc, 'outputspec.FD_file', fmri_qc_mc_dspk_nuis_bpf,
                      'inputspec.confounds')
        wf_mc.connect(mytmpfilt, 'outputspec.func_tmplfilt',
                      fmri_qc_mc_dspk_nuis_bpf, 'inputspec.func')

    myscrub = scrub.datacens_workflow_threshold(ex_before=0, ex_after=0)
    # "liberal scrubbing" since despiking was already performed

    if carpet_plot:
        fmri_qc_mc_dspk_nuis_bpf_scrub = qc.fMRI2QC(
            carpet_plot, tag="mc_dspk_nuis_bpf_scrub", indiv_atlas=True)
        wf_mc.connect(add_masks, 'out_file', fmri_qc_mc_dspk_nuis_bpf_scrub,
                      'inputspec.atlas')
        wf_mc.connect(myscrub, 'outputspec.FD_scrubbed',
                      fmri_qc_mc_dspk_nuis_bpf_scrub, 'inputspec.confounds')
        wf_mc.connect(myscrub, 'outputspec.scrubbed_image',
                      fmri_qc_mc_dspk_nuis_bpf_scrub, 'inputspec.func')

    # Basic interface class generates identity mappings
    outputspec = pe.Node(
        utility.IdentityInterface(fields=[
            'func_preprocessed',
            'func_preprocessed_scrubbed',
            # non-image data
            'FD'
        ]),
        name='outputspec')

    wf_mc.connect([
        (inputspec, mybet, [('func', 'inputspec.in_file')]),
        (mybet, mymc, [('outputspec.brain', 'inputspec.func')]),
        (mymc, mydespike, [('outputspec.func_out_file', 'in_file')]),
        (mydespike, mycmpcor, [('out_file', 'inputspec.func_aligned')]),
        (inputspec, mycmpcor, [('cc_noise_roi', 'inputspec.mask_file')]),
        (mycmpcor, myconc, [('outputspec.components_file', 'inputspec.par1')]),
        (mymc, myconc, [('outputspec.first24_file', 'inputspec.par2')]),
        (myconc, mynuisscor, [('outputspec.concat_file',
                               'inputspec.design_file')]),
        (mydespike, mynuisscor, [('out_file', 'inputspec.in_file')])
    ])

    if fwhm > 0:
        wf_mc.connect([
            (mynuisscor, smoother, [('outputspec.out_file', 'in_file')]),
            (smoother, mytmpfilt, [('smoothed_file', 'inputspec.func')]),
            (mytmpfilt, myscrub, [('outputspec.func_tmplfilt',
                                   'inputspec.func')]),
            (mymc, myscrub, [('outputspec.FD_file', 'inputspec.FD')]),
            (mytmpfilt, outputspec, [('outputspec.func_tmplfilt',
                                      'func_preprocessed')])
        ])
    else:
        wf_mc.connect([(mynuisscor, mytmpfilt, [('outputspec.out_file',
                                                 'inputspec.func')]),
                       (mytmpfilt, myscrub, [('outputspec.func_tmplfilt',
                                              'inputspec.func')]),
                       (mymc, myscrub, [('outputspec.FD_file', 'inputspec.FD')
                                        ]),
                       (mytmpfilt, outputspec, [('outputspec.func_tmplfilt',
                                                 'func_preprocessed')])])

    wf_mc.connect([
        # non-image data:
        (mymc, outputspec, [('outputspec.FD_file', 'FD')]),
        (myscrub, outputspec, [('outputspec.scrubbed_image',
                                'func_preprocessed_scrubbed')]),
    ])

    return wf_mc
Ejemplo n.º 12
0
def fieldmapper(TE1=4.9,
                TE2=7.3,
                dwell_time=0.00035,
                unwarp_direction="y-",
                SinkTag="func_fieldmapcorr",
                wf_name="fieldmap_correction"):
    import os
    import PUMI.utils.globals as globals

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)
    ###########################################
    # HERE INSERT PORCUPINE GENERATED CODE
    # MUST DEFINE
    # OutJSON: file path to JSON file contaioning the output strings to be returned
    # variables can (should) use variable SinkDir (defined here as function argument)
    ###########################################
    # To do
    ###########################################
    # adjust number of cores with psutil.cpu_count()
    ###########################################
    # also subtract:
    # analysisflow = nipype.Workflow('FieldMapper')
    # analysisflow.base_dir = '.'
    ###########################################
    # Here comes the generated code
    ###########################################

    # This is a Nipype generator. Warning, here be dragons.
    # !/usr/bin/env python
    import sys
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import PUMI.utils.utils_math as utils_math
    import nipype.interfaces.io as io
    import PUMI.utils.QC as qc
    import PUMI.utils.utils_convert as utils_convert

    OutJSON = SinkDir + "/outputs.JSON"

    # Basic interface class generates identity mappings
    inputspec = pe.Node(utility.IdentityInterface(fields=[
        'in_file', 'magnitude', 'phase', 'TE1', 'TE2', 'dwell_time',
        'unwarp_direction'
    ]),
                        name='inputspec')
    #defaults:
    #inputspec.inputs.func = func
    #inputspec.inputs.magnitude = magnitude
    #inputspec.inputs.phase = phase
    inputspec.inputs.TE1 = TE1
    inputspec.inputs.TE2 = TE2
    inputspec.inputs.dwell_time = dwell_time
    inputspec.inputs.unwarp_direction = unwarp_direction

    # Wraps command **bet**
    bet = pe.MapNode(interface=fsl.BET(), name='bet', iterfield=['in_file'])
    bet.inputs.mask = True

    # Wraps command **fslmaths**
    erode = pe.MapNode(interface=fsl.ErodeImage(),
                       name='erode',
                       iterfield=['in_file'])

    # Wraps command **fslmaths**
    erode2 = pe.MapNode(interface=fsl.ErodeImage(),
                        name='erode2',
                        iterfield=['in_file'])

    # Custom interface wrapping function SubTwo
    subtract = pe.Node(interface=utils_math.SubTwo, name='subtract')

    # Custom interface wrapping function Abs
    abs = pe.Node(interface=utils_math.Abs, name='abs')

    # Wraps command **fsl_prepare_fieldmap**
    preparefm = pe.MapNode(interface=fsl.PrepareFieldmap(),
                           name='preparefm',
                           iterfield=['in_phase', 'in_magnitude'])

    # Wraps command **fugue**
    fugue = pe.MapNode(interface=fsl.FUGUE(),
                       name='fugue',
                       iterfield=['in_file', 'fmap_in_file', 'mask_file'])

    # Generic datasink module to store structured outputs
    outputspec = pe.Node(interface=io.DataSink(), name='outputspec')
    outputspec.inputs.base_directory = SinkDir
    outputspec.inputs.regexp_substitutions = [
        ("func_fieldmapcorr/_NodeName_.{13}", "")
    ]

    # Generic datasink module to store structured outputs
    outputspec2 = pe.Node(interface=io.DataSink(), name='outputspec2')
    outputspec2.inputs.base_directory = SinkDir
    outputspec2.inputs.regexp_substitutions = [("_NodeName_.{13}", "")]

    myqc_orig = qc.vol2png("fielmap_correction", tag="original")
    myqc_unwarp = qc.vol2png("fielmap_correction", tag="unwarped")

    # Create a workflow to connect all those nodes
    analysisflow = nipype.Workflow(wf_name)
    analysisflow.base_dir = '.'
    analysisflow.connect(preparefm, 'out_fieldmap', outputspec2, 'fieldmap')
    analysisflow.connect(abs, 'abs', preparefm, 'delta_TE')
    analysisflow.connect(subtract, 'dif', abs, 'x')
    analysisflow.connect(inputspec, 'unwarp_direction', fugue,
                         'unwarp_direction')
    analysisflow.connect(fugue, 'unwarped_file', outputspec,
                         'func_fieldmapcorr')
    analysisflow.connect(preparefm, 'out_fieldmap', fugue, 'fmap_in_file')
    analysisflow.connect(erode2, 'out_file', fugue, 'mask_file')
    analysisflow.connect(bet, 'mask_file', erode2, 'in_file')
    analysisflow.connect(inputspec, 'dwell_time', fugue, 'dwell_time')
    analysisflow.connect(inputspec, 'in_file', fugue, 'in_file')
    analysisflow.connect(bet, 'out_file', erode, 'in_file')
    analysisflow.connect(inputspec, 'TE2', subtract, 'b')
    analysisflow.connect(inputspec, 'TE1', subtract, 'a')
    analysisflow.connect(inputspec, 'phase', preparefm, 'in_phase')
    analysisflow.connect(erode, 'out_file', preparefm, 'in_magnitude')
    analysisflow.connect(inputspec, 'magnitude', bet, 'in_file')

    analysisflow.connect(inputspec, 'magnitude', myqc_orig,
                         'inputspec.bg_image')
    analysisflow.connect(inputspec, 'in_file', myqc_orig,
                         'inputspec.overlay_image')
    analysisflow.connect(inputspec, 'magnitude', myqc_unwarp,
                         'inputspec.bg_image')
    analysisflow.connect(fugue, 'unwarped_file', myqc_unwarp,
                         'inputspec.overlay_image')

    # Run the workflow
    #plugin = 'MultiProc'  # adjust your desired plugin here
    #plugin_args = {'n_procs': psutil.cpu_count()}  # adjust to your number of cores
    #analysisflow.write_graph(graph2use='flat', format='png', simple_form=False)
    #analysisflow.run(plugin=plugin, plugin_args=plugin_args)

    ####################################################################################################
    # Porcupine generated code ends here
    ####################################################################################################

    #load and return json
    # you have to be aware the keys of the json map here

    #ret = json.load(open(OutJSON))
    #return ret['func_fieldmapcorr'], ret['fieldmap']
    return analysisflow
Ejemplo n.º 13
0
                           iterfield=['in_file'],
                           name='scale')

#todo: parametrize fwhm
myaroma = aroma.aroma_workflow(fwhm=8)

func2std = func2standard.func2mni(stdreg=globals._RegType_.FSL,
                                  wf_name='func2std')
func2std_aroma_nonaggr = func2standard.func2mni(
    stdreg=globals._RegType_.FSL, wf_name='func2std_aroma_nonaggr')
func2std_aroma_nonaggr.inputs.inputspec.reference_brain = globals._FSLDIR_ + "/data/standard/MNI152_T1_3mm_brain.nii.gz"
func2std_aroma_aggr = func2standard.func2mni(stdreg=globals._RegType_.FSL,
                                             wf_name='func2std_aroma_aggr')
func2std_aroma_aggr.inputs.inputspec.reference_brain = globals._FSLDIR_ + "/data/standard/MNI152_T1_3mm_brain.nii.gz"

fmri_qc_original = qc.fMRI2QC("carpet_aroma", tag="1_orinal")
fmri_qc_nonaggr = qc.fMRI2QC("carpet_aroma", tag="2_nonaggressive")
fmri_qc_aggr = qc.fMRI2QC("carpet_aroma", tag="3_aggressive")

# compute mean FD
meanFD = pe.MapNode(interface=utils_math.Txt2meanTxt,
                    iterfield=['in_file'],
                    name='meanFD')
meanFD.inputs.axis = 0  # global mean

pop_FD = pe.Node(interface=utils_convert.List2TxtFileOpen,
                 name='pop_FD')  # TODO  sink this
pop_FD.inputs.rownum = 0
pop_FD.inputs.out_file = "FD.txt"

totalWorkflow = nipype.Workflow('exAROMA')
Ejemplo n.º 14
0
def tmpfilt_workflow(highpass_Hz,
                     lowpass_Hz,
                     SinkTag="func_preproc",
                     wf_name="temporal_filtering"):
    #TODO kivezetni a higpass_inseces lowpass_insec valtozokat egy(esetleg kettto)-vel feljebbi szintekre.
    """
    Modified version of porcupine generated temporal filtering code:

    `source: -`


    Creates a slice time corrected functional image.

    Workflow inputs:
        :param func: The reoriented functional file.
        :param highpass: The highpass filter, which is 100s by default.
        :param lowpass: The lowpass filter, which is 1s by default.
        :param SinkDir:
        :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found in a subdirectory directory specific for this workflow.

    Workflow outputs:




        :return: tmpfilt_workflow - workflow




    Balint Kincses
    [email protected]
    2018


    """

    #This is a Nipype generator. Warning, here be dragons.
    #!/usr/bin/env python
    import sys
    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import PUMI.utils.utils_math as utils_math
    import PUMI.func_preproc.info.info_get as info_get
    import PUMI.utils.utils_convert as utils_convert
    import nipype.interfaces.fsl as fsl
    from nipype.interfaces import afni
    import nipype.interfaces.io as io
    import PUMI.utils.globals as globals
    import PUMI.utils.QC as qc

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    #Basic interface class generates identity mappings
    inputspec = pe.Node(
        utility.IdentityInterface(fields=[
            'func'
            #'highpass_Hz', # TODO: make these available as input
            #'lowpass_Hz'
        ]),
        name='inputspec')
    #nputspec.inputs.highpass_HZ = highpass_Hz
    #inputspec.inputs.lowpass_Hz = lowpass_Hz

    #Custom interface wrapping function Sec2sigmaV
    #func_sec2sigmaV = pe.MapNode(interface = utils_math.Sec2sigmaV,
    #                            iterfield=['TR'],
    #                          name = 'func_sec2sigmaV')
    #Custom interface wrapping function Sec2sigmaV_2
    #func_sec2sigmaV_2 = pe.MapNode(interface = utils_math.Sec2sigmaV,
    #                               iterfield=['TR'],
    #                           name = 'func_sec2sigmaV_2')

    # Custom interface wrapping function Str2Func
    func_str2float = pe.MapNode(interface=utils_convert.Str2Float,
                                iterfield=['str'],
                                name='func_str2float')

    #Wraps command **fslmaths**
    # TODO_done: change highpass filter to AFNI implewmentation:
    # https://neurostars.org/t/bandpass-filtering-different-outputs-from-fsl-and-nipype-custom-function/824
    #tmpfilt = pe.MapNode(interface=fsl.TemporalFilter(),
    #                     iterfield=['in_file','highpass','lowpass'],
    #                           name = 'tmpfilt')

    tmpfilt = pe.MapNode(interface=afni.Bandpass(highpass=highpass_Hz,
                                                 lowpass=lowpass_Hz),
                         iterfield=['in_file', 'tr'],
                         name='tmpfilt')
    tmpfilt.inputs.despike = False
    tmpfilt.inputs.no_detrend = False  #True
    tmpfilt.inputs.notrans = True  # hopefully there are no initial transients in our data
    tmpfilt.inputs.outputtype = 'NIFTI_GZ'
    # Get TR value from header
    TRvalue = pe.MapNode(interface=info_get.TR,
                         iterfield=['in_file'],
                         name='TRvalue')

    myqc = qc.timecourse2png("timeseries",
                             tag="030_filtered_" +
                             str(highpass_Hz).replace('0.', '') + "_" +
                             str(lowpass_Hz).replace('0.', '') + "_Hz")

    #Basic interface class generates identity mappings
    outputspec = pe.Node(utility.IdentityInterface(fields=['func_tmplfilt']),
                         name='outputspec')

    #Generic datasink module to store structured outputs
    ds = pe.Node(interface=io.DataSink(), name='ds')
    ds.inputs.base_directory = SinkDir
    #ds.inputs.regexp_substitutions = [("tmpfilt/_NodeName_.{13}", "")]

    #Create a workflow to connect all those nodes
    analysisflow = nipype.Workflow(wf_name)
    analysisflow.connect(inputspec, 'func', tmpfilt, 'in_file')
    analysisflow.connect(inputspec, 'func', TRvalue, 'in_file')
    analysisflow.connect(TRvalue, 'TR', func_str2float, 'str')
    analysisflow.connect(func_str2float, 'float', tmpfilt, 'tr')
    #analysisflow.connect(inputspec, 'highpass_Hz', tmpfilt, 'highpass')
    #analysisflow.connect(inputspec, 'lowpass_Hz', tmpfilt, 'lowpass')
    analysisflow.connect(tmpfilt, 'out_file', ds, 'tmpfilt')
    analysisflow.connect(tmpfilt, 'out_file', outputspec, 'func_tmplfilt')
    analysisflow.connect(tmpfilt, 'out_file', myqc, 'inputspec.func')

    return analysisflow
Ejemplo n.º 15
0
def extract_timeseries_nativespace(SinkTag="connectivity",
                                   wf_name="extract_timeseries_nativespace",
                                   global_signal=True):
    # this workflow transforms atlas back to native space and uses TsExtractor

    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.io as io
    import nipype.interfaces.utility as utility
    import PUMI.func_preproc.func2standard as transform
    import PUMI.utils.globals as globals
    import PUMI.utils.QC as qc

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)
    wf = nipype.Workflow(wf_name)

    inputspec = pe.Node(
        utility.IdentityInterface(fields=[
            'atlas',
            'labels',
            'modules',
            'anat',  # only obligatory if stdreg==globals._RegType_.ANTS
            'inv_linear_reg_mtrx',
            'inv_nonlinear_reg_mtrx',
            'func',
            'gm_mask',
            'confounds',
            'confound_names'
        ]),
        name="inputspec")

    # transform atlas back to native EPI spaces!
    atlas2native = transform.atlas2func(stdreg=globals._regType_)
    wf.connect(inputspec, 'atlas', atlas2native, 'inputspec.atlas')
    wf.connect(inputspec, 'anat', atlas2native, 'inputspec.anat')
    wf.connect(inputspec, 'inv_linear_reg_mtrx', atlas2native,
               'inputspec.inv_linear_reg_mtrx')
    wf.connect(inputspec, 'inv_nonlinear_reg_mtrx', atlas2native,
               'inputspec.inv_nonlinear_reg_mtrx')
    wf.connect(inputspec, 'func', atlas2native, 'inputspec.func')
    wf.connect(inputspec, 'gm_mask', atlas2native, 'inputspec.example_func')
    wf.connect(inputspec, 'confounds', atlas2native, 'inputspec.confounds')
    wf.connect(inputspec, 'confound_names', atlas2native,
               'inputspec.confound_names')

    # extract timeseries
    extract_timeseries = pe.MapNode(interface=utility.Function(
        input_names=['labels', 'labelmap', 'func', 'mask', 'global_signal'],
        output_names=['out_file', 'labels', 'out_gm_label'],
        function=TsExtractor),
                                    iterfield=['labelmap', 'func', 'mask'],
                                    name='extract_timeseries')
    extract_timeseries.inputs.global_signal = global_signal
    wf.connect(atlas2native, 'outputspec.atlas2func', extract_timeseries,
               'labelmap')
    wf.connect(inputspec, 'labels', extract_timeseries, 'labels')
    wf.connect(inputspec, 'gm_mask', extract_timeseries, 'mask')
    wf.connect(inputspec, 'func', extract_timeseries, 'func')

    # Save outputs which are important
    ds_regts = pe.Node(interface=io.DataSink(), name='ds_regts')
    ds_regts.inputs.base_directory = globals._SinkDir_
    ds_regts.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".tsv")]
    wf.connect(extract_timeseries, 'out_file', ds_regts, 'regional_timeseries')

    # QC
    timeseries_qc = qc.regTimeseriesQC("regional_timeseries", tag=wf_name)
    wf.connect(inputspec, 'modules', timeseries_qc, 'inputspec.modules')
    wf.connect(inputspec, 'atlas', timeseries_qc, 'inputspec.atlas')
    wf.connect(extract_timeseries, 'out_file', timeseries_qc,
               'inputspec.timeseries')

    # Basic interface class generates identity mappings
    outputspec = pe.Node(
        utility.IdentityInterface(fields=['timeseries', 'out_gm_label']),
        name='outputspec')
    wf.connect(extract_timeseries, 'out_file', outputspec, 'timeseries')
    wf.connect(extract_timeseries, 'out_gm_label', outputspec, 'out_gm_label')

    return wf
Ejemplo n.º 16
0
def mac_workflow(target_angle=90,
                 SinkTag="func_preproc",
                 wf_name="median_angle_correction"):
    """

     Modified version of CPAC.median_angle.median_angle:

    `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/median_angle/median_angle.html`


    Do the data censoring on the 4D functional data.

    Workflow inputs:
        :param func: The reoriented functional file.
        :param target angle: the default is 90.
        :param SinkDir:
        :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found in a subdirectory directory specific for this workflow..

    Workflow outputs:




        :return: datacens_workflow - workflow




    Balint Kincses
    [email protected]
    2018
    Median Angle Correction

    Parameters
    ----------
    name : string, optional
        Name of the workflow.

    Returns
    -------
    median_angle_correction : nipype.pipeline.engine.Workflow
        Median Angle Correction workflow.

    Notes
    -----

    Workflow Inputs::

        inputspec.subject : string (nifti file)
            Realigned nifti file of a subject
        inputspec.target_angle : integer
            Target angle in degrees to correct the median angle to

    Workflow Outputs::

        outputspec.subject : string (nifti file)
            Median angle corrected nifti file of the given subject
        outputspec.pc_angles : string (.npy file)
            Numpy file (.npy file) containing the angles (in radians) of all voxels with
            the 5 largest principal components.

    Median Angle Correction Procedure:

    1. Compute the median angle with respect to the first principal component of the subject
    2. Shift the angle of every voxel so that the new median angle equals the target angle

    Workflow Graph:

    .. image:: ../images/median_angle_correction.dot.png
        :width: 500

    Detailed Workflow Graph:

    .. image:: ../images/median_angle_correction_detailed.dot.png
        :width: 500

    """
    import os
    import nipype.pipeline.engine as pe
    import nipype.interfaces.utility as utility
    import PUMI.utils.utils_convert as utils_convert
    import nipype.interfaces.io as io
    import PUMI.utils.globals as globals
    import PUMI.utils.QC as qc

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)
    #TODO set target angle...
    inputspec = pe.Node(utility.IdentityInterface(
        fields=['realigned_file', 'target_angle', 'mask']),
                        name='inputspec')
    inputspec.inputs.target_angle = target_angle
    outputspec = pe.Node(
        utility.IdentityInterface(fields=['final_func', 'pc_angles']),
        name='outputspec')

    # Caution: inpout fmri must be masked (background=0)
    mac = pe.MapNode(utility.Function(
        input_names=['target_angle_deg', 'realigned_file', 'mask'],
        output_names=['corrected_file', 'angles_file'],
        function=median_angle_correct),
                     iterfield=['realigned_file', 'mask'],
                     name='median_angle_correct')

    myqc = qc.timecourse2png("timeseries", tag="050_medang")

    # collect and save median angle values
    pop_medang = pe.Node(
        interface=utils_convert.
        List2TxtFile,  #TODO: save subject level median angle
        name='pop_medang')

    # save mac file
    ds = pe.Node(interface=io.DataSink(), name='ds')
    ds.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

    # save data out with Datasink
    ds_medang = pe.Node(interface=io.DataSink(), name='ds_pop_medang')
    ds_medang.inputs.regexp_substitutions = [("(\/)[^\/]*$", "medang.txt")]
    ds_medang.inputs.base_directory = SinkDir

    #TODO set which files should be put into the datasink node...
    # Create workflow
    analysisflow = pe.Workflow(wf_name)
    analysisflow.connect(inputspec, 'realigned_file', mac, 'realigned_file')
    analysisflow.connect(inputspec, 'target_angle', mac, 'target_angle_deg')
    analysisflow.connect(inputspec, 'mask', mac, 'mask')
    analysisflow.connect(mac, 'corrected_file', outputspec, 'final_func')
    analysisflow.connect(mac, 'angles_file', outputspec, 'pc_angles')
    analysisflow.connect(mac, 'corrected_file', myqc, 'inputspec.func')
    # pop-level medang values
    analysisflow.connect(mac, 'angles_file', pop_medang, 'in_list')
    analysisflow.connect(pop_medang, 'txt_file', ds_medang, 'pop')
    analysisflow.connect(mac, 'corrected_file', ds, 'med_ang')

    return analysisflow
Ejemplo n.º 17
0
def build_netmat(SinkTag="connectivity", wf_name="build_network"):
    ########################################################################
    # Extract timeseries
    ########################################################################

    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    from nipype.interfaces.utility import Function
    import nipype.interfaces.io as io
    import PUMI.utils.globals as globals
    import PUMI.utils.QC as qc

    import os

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Identitiy mapping for input variables
    inputspec = pe.Node(
        utility.IdentityInterface(fields=[
            'timeseries',  #contains labels
            'modules',  # optional
            'measure',
            'atlas'  # optional, only for plotting purposes
        ]),
        name='inputspec')
    inputspec.inputs.atlas = False  # default value
    inputspec.inputs.measure = "partial correlation"

    # This is not a map node, since it takes all the subject-level regional timseries in a list and does population-level modelling
    # if measure == "tangent"
    estimate_network_mtx = pe.Node(interface=Function(
        input_names=['timeseries_list', 'modules', 'measure'],
        output_names=['mean_mtx', 'subject_matrix_list'],
        function=netmat),
                                   name='estimate_network_mtx')

    matrix_qc_mean = qc.matrixQC("group_mean_matrix", tag=wf_name + "_")
    matrix_qc = qc.matrixQC("matrices", tag=wf_name)

    # Save outputs which are important
    ds_meanmat = pe.Node(interface=io.DataSink(), name='ds_meanmat')
    ds_meanmat.inputs.base_directory = SinkDir
    ds_meanmat.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".tsv")]

    # Save outputs which are important
    ds_mat = pe.Node(interface=io.DataSink(), name='ds_mats')
    ds_mat.inputs.base_directory = SinkDir
    ds_mat.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".tsv")]

    analysisflow = pe.Workflow(wf_name)
    analysisflow.connect(inputspec, 'timeseries', estimate_network_mtx,
                         'timeseries_list')
    analysisflow.connect(inputspec, 'measure', estimate_network_mtx, 'measure')

    analysisflow.connect(estimate_network_mtx, 'mean_mtx', ds_meanmat,
                         'mean_connectivity_mat')
    analysisflow.connect(estimate_network_mtx, 'subject_matrix_list', ds_mat,
                         'connectivity_matrices')

    analysisflow.connect(estimate_network_mtx, 'mean_mtx', matrix_qc_mean,
                         'inputspec.matrix_file')
    analysisflow.connect(inputspec, 'modules', matrix_qc_mean,
                         'inputspec.modules')
    analysisflow.connect(inputspec, 'atlas', matrix_qc_mean, 'inputspec.atlas')

    analysisflow.connect(estimate_network_mtx, 'subject_matrix_list',
                         matrix_qc, 'inputspec.matrix_file')
    analysisflow.connect(inputspec, 'modules', matrix_qc, 'inputspec.modules')
    analysisflow.connect(inputspec, 'atlas', matrix_qc, 'inputspec.atlas')

    return analysisflow
Ejemplo n.º 18
0
def nuissremov_workflow(SinkTag="func_preproc", wf_name="nuisance_correction"):
    """
    The script uses the noise information to regress it out from the data.
   Workflow inputs:
        :param in_file: The reoriented an motion corrected functional data.
        :param desing_file: A matrix which contains all the nuissance regressor(motion+compcor noise+...).
        :param filter_all: To regress out all the columns of the desing matrix (default: True)
        :param SinkDir:
        :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found in a subdirectory directory specific for this workflow.

   Workflow outputs:


    :return: nuissremov_workflow


    Balint Kincses
    [email protected]
    2018

    """

    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.io as io
    import PUMI.utils.QC as qc
    import PUMI.utils.globals as globals

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Basic interface class generates identity mappings
    inputspec = pe.Node(
        utility.IdentityInterface(fields=['in_file', 'design_file']),
        name='inputspec')

    # Perform the nuissance regression
    nuisregression = pe.MapNode(interface=fsl.FilterRegressor(filter_all=True),
                                iterfield=['design_file', 'in_file'],
                                name='nuisregression')

    myqc = qc.timecourse2png("timeseries", tag="020_nuiscorr")

    # Basic interface class generates identity mappings
    outputspec = pe.Node(utility.IdentityInterface(fields=['out_file']),
                         name='outputspec')

    # save data out with Datasink
    ds = pe.Node(interface=io.DataSink(), name='ds')
    ds.inputs.base_directory = SinkDir

    #TODO_ready: qc timeseries before and after

    # Generate workflow
    analysisflow = nipype.Workflow(wf_name)
    analysisflow.connect(inputspec, 'in_file', nuisregression, 'in_file')
    analysisflow.connect(inputspec, 'design_file', nuisregression,
                         'design_file')
    analysisflow.connect(nuisregression, 'out_file', outputspec, 'out_file')
    analysisflow.connect(nuisregression, 'out_file', ds,
                         'func_nuiss_corrected')
    analysisflow.connect(nuisregression, 'out_file', myqc, 'inputspec.func')

    return analysisflow
Ejemplo n.º 19
0
def bbr_workflow(SinkTag="func_preproc", wf_name="func2anat"):
    """
        Modified version of CPAC.registration.registration:

        `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/registration/registration.html`


        BBR registration of functional image to anat.

        Workflow inputs:
            :param func: One volume of the 4D fMRI (The one which is the closest to the fieldmap recording in time should be chosen- e.g: if fieldmap was recorded after the fMRI the last volume of it should be chosen).
            :param skull: The oriented high res T1w image.
            :param anat_wm_segmentation: WM probability mask in .
            :param anat_csf_segmentation: CSF probability mask in
            :param bbr_schedule: Parameters which specifies BBR options.
            :param SinkDir:
            :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found.

        Workflow outputs:




            :return: bbreg_workflow - workflow
                func="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/s002/func_data.nii.gz",
                 skull="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres.nii.gz",
                 anat_wm_segmentation="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/anat_preproc/fast/fast__prob_2.nii.gz",



        Balint Kincses
        [email protected]
        2018


        """
    import os
    import nipype.pipeline as pe
    from nipype.interfaces.utility import Function
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.io as io
    import PUMI.func_preproc.Onevol as onevol
    import PUMI.utils.QC as qc
    import PUMI.utils.globals as globals

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Define inputs of the workflow
    inputspec = pe.Node(utility.IdentityInterface(fields=[
        'func', 'skull', 'anat_wm_segmentation', 'anat_gm_segmentation',
        'anat_csf_segmentation', 'anat_ventricle_segmentation'
    ]),
                        name='inputspec')

    myonevol = onevol.onevol_workflow()

    # trilinear interpolation is used by default in linear registration for func to anat
    linear_reg = pe.MapNode(interface=fsl.FLIRT(),
                            iterfield=['in_file', 'reference'],
                            name='linear_func_to_anat')
    linear_reg.inputs.cost = 'corratio'
    linear_reg.inputs.dof = 6
    linear_reg.inputs.out_matrix_file = "lin_mat"

    # WM probability map is thresholded and masked
    wm_bb_mask = pe.MapNode(interface=fsl.ImageMaths(),
                            iterfield=['in_file'],
                            name='wm_bb_mask')
    wm_bb_mask.inputs.op_string = '-thr 0.5 -bin'
    # CSf probability map is thresholded and masked
    csf_bb_mask = pe.MapNode(interface=fsl.ImageMaths(),
                             iterfield=['in_file'],
                             name='csf_bb_mask')
    csf_bb_mask.inputs.op_string = '-thr 0.5 -bin'

    # GM probability map is thresholded and masked
    gm_bb_mask = pe.MapNode(interface=fsl.ImageMaths(),
                            iterfield=['in_file'],
                            name='gm_bb_mask')
    gm_bb_mask.inputs.op_string = '-thr 0.1 -bin'  # liberal mask to capture all gm signal

    # ventricle probability map is thresholded and masked
    vent_bb_mask = pe.MapNode(interface=fsl.ImageMaths(),
                              iterfield=['in_file'],
                              name='vent_bb_mask')
    vent_bb_mask.inputs.op_string = '-thr 0.8 -bin -ero -dilM'  # stricter threshold and some morphology for compcor

    # add the CSF and WM masks
    #add_masks=pe.MapNode(interface=fsl.ImageMaths(),
    #                     iterfield=['in_file','in_file2'],
    #                     name='add_masks')
    #add_masks.inputs.op_string = ' -add'

    # A function is defined for define bbr argumentum which says flirt to perform bbr registration
    # for each element of the list, due to MapNode
    def bbreg_args(bbreg_target):
        return '-cost bbr -wmseg ' + bbreg_target

    bbreg_arg_convert = pe.MapNode(interface=Function(
        input_names=["bbreg_target"],
        output_names=["arg"],
        function=bbreg_args),
                                   iterfield=['bbreg_target'],
                                   name="bbr_arg_converter")

    # BBR registration within the FLIRT node
    bbreg_func_to_anat = pe.MapNode(
        interface=fsl.FLIRT(),
        iterfield=['in_file', 'reference', 'in_matrix_file', 'args'],
        name='bbreg_func_to_anat')
    bbreg_func_to_anat.inputs.dof = 6

    # calculate the inverse of the transformation matrix (of func to anat)
    convertmatrix = pe.MapNode(interface=fsl.ConvertXFM(),
                               iterfield=['in_file'],
                               name="convertmatrix")
    convertmatrix.inputs.invert_xfm = True

    # use the invers registration (anat to func) to transform anatomical csf mask
    reg_anatmask_to_func1 = pe.MapNode(
        interface=fsl.FLIRT(apply_xfm=True, interp='nearestneighbour'),
        iterfield=['in_file', 'reference', 'in_matrix_file'],
        name='anatmasks_to_func1')
    #reg_anatmask_to_func1.inputs.apply_xfm = True
    # use the invers registration (anat to func) to transform anatomical wm mask
    reg_anatmask_to_func2 = pe.MapNode(
        interface=fsl.FLIRT(apply_xfm=True, interp='nearestneighbour'),
        iterfield=['in_file', 'reference', 'in_matrix_file'],
        name='anatmasks_to_func2')
    #reg_anatmask_to_func2.inputs.apply_xfm = True

    # use the invers registration (anat to func) to transform anatomical gm mask
    reg_anatmask_to_func3 = pe.MapNode(
        interface=fsl.FLIRT(apply_xfm=True, interp='nearestneighbour'),
        iterfield=['in_file', 'reference', 'in_matrix_file'],
        name='anatmasks_to_func3')
    # reg_anatmask_to_func2.inputs.apply_xfm = True

    # use the invers registration (anat to func) to transform anatomical gm mask
    reg_anatmask_to_func4 = pe.MapNode(
        interface=fsl.FLIRT(apply_xfm=True, interp='nearestneighbour'),
        iterfield=['in_file', 'reference', 'in_matrix_file'],
        name='anatmasks_to_func4')
    # reg_anatmask_to_func2.inputs.apply_xfm = True

    # Create png images for quality check
    myqc = qc.vol2png("func2anat")

    # Save outputs which are important
    ds = pe.Node(interface=io.DataSink(), name='ds_nii')
    ds.inputs.base_directory = SinkDir
    ds.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

    # Define outputs of the workflow
    outputspec = pe.Node(utility.IdentityInterface(fields=[
        'func_sample2anat', 'example_func', 'func_to_anat_linear_xfm',
        'anat_to_func_linear_xfm', 'csf_mask_in_funcspace',
        'wm_mask_in_funcspace', 'gm_mask_in_funcspace',
        'ventricle_mask_in_funcspace'
    ]),
                         name='outputspec')

    analysisflow = pe.Workflow(name=wf_name)
    analysisflow.base_dir = '.'
    analysisflow.connect(inputspec, 'func', myonevol, 'inputspec.func')
    analysisflow.connect(myonevol, 'outputspec.func1vol', linear_reg,
                         'in_file')
    analysisflow.connect(inputspec, 'skull', linear_reg, 'reference')
    analysisflow.connect(linear_reg, 'out_matrix_file', bbreg_func_to_anat,
                         'in_matrix_file')
    analysisflow.connect(myonevol, 'outputspec.func1vol', bbreg_func_to_anat,
                         'in_file')
    analysisflow.connect(inputspec, 'anat_wm_segmentation', bbreg_arg_convert,
                         'bbreg_target')
    analysisflow.connect(bbreg_arg_convert, 'arg', bbreg_func_to_anat, 'args')
    analysisflow.connect(inputspec, 'skull', bbreg_func_to_anat, 'reference')
    analysisflow.connect(bbreg_func_to_anat, 'out_matrix_file', convertmatrix,
                         'in_file')
    analysisflow.connect(convertmatrix, 'out_file', reg_anatmask_to_func1,
                         'in_matrix_file')
    analysisflow.connect(myonevol, 'outputspec.func1vol',
                         reg_anatmask_to_func1, 'reference')
    analysisflow.connect(csf_bb_mask, 'out_file', reg_anatmask_to_func1,
                         'in_file')
    analysisflow.connect(convertmatrix, 'out_file', reg_anatmask_to_func2,
                         'in_matrix_file')
    analysisflow.connect(myonevol, 'outputspec.func1vol',
                         reg_anatmask_to_func2, 'reference')
    analysisflow.connect(wm_bb_mask, 'out_file', reg_anatmask_to_func2,
                         'in_file')
    analysisflow.connect(convertmatrix, 'out_file', reg_anatmask_to_func3,
                         'in_matrix_file')
    analysisflow.connect(myonevol, 'outputspec.func1vol',
                         reg_anatmask_to_func3, 'reference')
    analysisflow.connect(gm_bb_mask, 'out_file', reg_anatmask_to_func3,
                         'in_file')
    analysisflow.connect(convertmatrix, 'out_file', reg_anatmask_to_func4,
                         'in_matrix_file')
    analysisflow.connect(myonevol, 'outputspec.func1vol',
                         reg_anatmask_to_func4, 'reference')
    analysisflow.connect(vent_bb_mask, 'out_file', reg_anatmask_to_func4,
                         'in_file')
    analysisflow.connect(inputspec, 'anat_wm_segmentation', wm_bb_mask,
                         'in_file')
    analysisflow.connect(inputspec, 'anat_csf_segmentation', csf_bb_mask,
                         'in_file')
    analysisflow.connect(inputspec, 'anat_gm_segmentation', gm_bb_mask,
                         'in_file')
    analysisflow.connect(inputspec, 'anat_ventricle_segmentation',
                         vent_bb_mask, 'in_file')
    analysisflow.connect(bbreg_func_to_anat, 'out_file', outputspec,
                         'func_sample2anat')
    analysisflow.connect(bbreg_func_to_anat, 'out_matrix_file', outputspec,
                         'func_to_anat_linear_xfm')
    analysisflow.connect(reg_anatmask_to_func1, 'out_file', outputspec,
                         'csf_mask_in_funcspace')
    analysisflow.connect(reg_anatmask_to_func2, 'out_file', outputspec,
                         'wm_mask_in_funcspace')
    analysisflow.connect(reg_anatmask_to_func3, 'out_file', outputspec,
                         'gm_mask_in_funcspace')
    analysisflow.connect(reg_anatmask_to_func4, 'out_file', outputspec,
                         'ventricle_mask_in_funcspace')
    analysisflow.connect(myonevol, 'outputspec.func1vol', outputspec,
                         'example_func')
    analysisflow.connect(convertmatrix, 'out_file', outputspec,
                         'anat_to_func_linear_xfm')
    analysisflow.connect(bbreg_func_to_anat, 'out_file', ds, "func2anat")
    analysisflow.connect(bbreg_func_to_anat, 'out_file', myqc,
                         'inputspec.bg_image')
    analysisflow.connect(wm_bb_mask, 'out_file', myqc,
                         'inputspec.overlay_image')

    return analysisflow
Ejemplo n.º 20
0
def anat2mni_fsl_workflow(SinkTag="anat_preproc", wf_name="anat2mni_fsl"):
    """
    Modified version of CPAC.registration.registration:

    `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/registration/registration.html`


    Register skull and brain extracted image to MNI space and return the transformation martices.

    Workflow inputs:
        :param skull: The reoriented anatomical file.
        :param brain: The brain extracted anat.
        :param ref_skull: MNI152 skull file.
        :param ref_brain: MNI152 brain file.
        :param ref_mask: CSF mask of the MNI152 file.
        :param fnirt config: Parameters which specifies FNIRT options.
        :param SinkDir:
        :param SinkTag: The output directiry in which the returned images (see workflow outputs) could be found.

    Workflow outputs:




        :return: anat2mni_workflow - workflow


        anat="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres.nii.gz",
                      brain="/home/balint/Dokumentumok/phd/essen/PAINTER/probe/MS001/highres_brain.nii.gz",


    Balint Kincses
    [email protected]
    2018


    """

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    # Define inputs of workflow
    inputspec = pe.Node(utility.IdentityInterface(fields=[
        'brain', 'skull', 'reference_brain', 'reference_skull', 'ref_mask',
        'fnirt_config'
    ]),
                        name='inputspec')

    inputspec.inputs.reference_brain = globals._FSLDIR_ + globals._brainref
    inputspec.inputs.reference_skull = globals._FSLDIR_ + globals._headref
    inputspec.inputs.ref_mask = globals._FSLDIR_ + globals._brainref_mask
    # inputspec.inputs.fnirt_config = "T1_2_MNI152_2mm"

    # Linear registration node
    linear_reg = pe.MapNode(interface=fsl.FLIRT(),
                            iterfield=['in_file'],
                            name='linear_reg_0')
    linear_reg.inputs.cost = 'corratio'

    # Non-linear registration node
    nonlinear_reg = pe.MapNode(interface=fsl.FNIRT(),
                               iterfield=['in_file', 'affine_file'],
                               name='nonlinear_reg_1')
    nonlinear_reg.inputs.fieldcoeff_file = True
    nonlinear_reg.inputs.jacobian_file = True

    # Applying warp field
    brain_warp = pe.MapNode(interface=fsl.ApplyWarp(),
                            iterfield=['in_file', 'field_file'],
                            name='brain_warp')

    # Calculate the invers of the linear transformation
    inv_flirt_xfm = pe.MapNode(interface=fsl.utils.ConvertXFM(),
                               iterfield=['in_file'],
                               name='inv_linear_reg0_xfm')
    inv_flirt_xfm.inputs.invert_xfm = True

    # Calculate inverse of the nonlinear warping field
    inv_fnirt_xfm = pe.MapNode(interface=fsl.utils.InvWarp(),
                               iterfield=['warp', 'reference'],
                               name="inv_nonlinear_xfm")

    # Create png images for quality check
    myqc = qc.vol2png("anat2mni", "FSL2", overlayiterated=False)
    myqc.inputs.inputspec.overlay_image = globals._FSLDIR_ + globals._brainref
    myqc.inputs.slicer.image_width = 500
    myqc.inputs.slicer.threshold_edges = 0.1

    # Save outputs which are important
    ds = pe.Node(interface=io.DataSink(), name='ds')
    ds.inputs.base_directory = SinkDir
    ds.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

    # Define outputs of the workflow
    outputspec = pe.Node(utility.IdentityInterface(fields=[
        'output_brain', 'linear_xfm', 'invlinear_xfm', 'nonlinear_xfm',
        'invnonlinear_xfm', 'std_template'
    ]),
                         name='outputspec')

    # Create workflow nad connect nodes
    analysisflow = pe.Workflow(name=wf_name)
    analysisflow.connect(inputspec, 'brain', linear_reg, 'in_file')
    analysisflow.connect(inputspec, 'reference_brain', linear_reg, 'reference')
    analysisflow.connect(inputspec, 'skull', nonlinear_reg, 'in_file')
    analysisflow.connect(inputspec, 'reference_skull', nonlinear_reg,
                         'ref_file')
    analysisflow.connect(inputspec, 'ref_mask', nonlinear_reg, 'refmask_file')
    # FNIRT parameters are specified by FSL config file
    # ${FSLDIR}/etc/flirtsch/TI_2_MNI152_2mm.cnf (or user-specified)
    analysisflow.connect(inputspec, 'fnirt_config', nonlinear_reg,
                         'config_file')
    analysisflow.connect(linear_reg, 'out_matrix_file', nonlinear_reg,
                         'affine_file')
    analysisflow.connect(nonlinear_reg, 'fieldcoeff_file', outputspec,
                         'nonlinear_xfm')
    analysisflow.connect(nonlinear_reg, 'field_file', outputspec, 'field_file')
    analysisflow.connect(inputspec, 'brain', brain_warp, 'in_file')
    analysisflow.connect(nonlinear_reg, 'fieldcoeff_file', brain_warp,
                         'field_file')
    analysisflow.connect(inputspec, 'reference_brain', brain_warp, 'ref_file')
    analysisflow.connect(brain_warp, 'out_file', outputspec, 'output_brain')
    analysisflow.connect(linear_reg, 'out_matrix_file', inv_flirt_xfm,
                         'in_file')
    analysisflow.connect(inv_flirt_xfm, 'out_file', outputspec,
                         'invlinear_xfm')

    analysisflow.connect(nonlinear_reg, 'fieldcoeff_file', inv_fnirt_xfm,
                         'warp')
    analysisflow.connect(inputspec, 'brain', inv_fnirt_xfm, 'reference')
    analysisflow.connect(inv_fnirt_xfm, 'inverse_warp', outputspec,
                         'invnonlinear_xfm')

    analysisflow.connect(linear_reg, 'out_matrix_file', outputspec,
                         'linear_xfm')
    analysisflow.connect(inputspec, 'reference_brain', outputspec,
                         'std_template')
    analysisflow.connect(brain_warp, 'out_file', ds, 'anat2mni_std')
    analysisflow.connect(nonlinear_reg, 'fieldcoeff_file', ds,
                         'anat2mni_warpfield')
    analysisflow.connect(brain_warp, 'out_file', myqc, 'inputspec.bg_image')

    return analysisflow
Ejemplo n.º 21
0
def bet_workflow(Robust=True,
                 fmri=False,
                 SinkTag="anat_preproc",
                 wf_name="brain_extraction"):
    """
    Modified version of CPAC.anat_preproc.anat_preproc:

    `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/anat_preproc/anat_preproc.html`


    Creates a brain extracted image and its mask from a T1w anatomical image.

    Workflow inputs:
        :param anat: The reoriented anatomical file.
        :param SinkDir:
        :param SinkTag: The output directiry in which the returned images (see workflow outputs) could be found.

    Workflow outputs:




        :return: bet_workflow - workflow




    Balint Kincses
    [email protected]
    2018


    """

    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import nipype.interfaces.io as io
    import PUMI.utils.QC as qc
    import PUMI.utils.globals as globals
    import PUMI.func_preproc.Onevol as onevol

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)

    #Basic interface class generates identity mappings
    inputspec = pe.Node(
        utility.IdentityInterface(fields=[
            'in_file',
            'opt_R',
            'fract_int_thr',  # optional
            'vertical_gradient'
        ]),  # optional
        name='inputspec')
    inputspec.inputs.opt_R = Robust
    if fmri:
        inputspec.inputs.fract_int_thr = globals._fsl_bet_fract_int_thr_func_
    else:
        inputspec.inputs.fract_int_thr = globals._fsl_bet_fract_int_thr_anat_

    inputspec.inputs.vertical_gradient = globals._fsl_bet_vertical_gradient_

    #Wraps command **bet**
    bet = pe.MapNode(interface=fsl.BET(), iterfield=['in_file'], name='bet')
    bet.inputs.mask = True
    # bet.inputs.robust=Robust
    if fmri:
        bet.inputs.functional = True
        myonevol = onevol.onevol_workflow(wf_name="onevol")
        applymask = pe.MapNode(fsl.ApplyMask(),
                               iterfield=['in_file', 'mask_file'],
                               name="apply_mask")

    myqc = qc.vol2png(wf_name, overlay=True)

    #Basic interface class generates identity mappings
    outputspec = pe.Node(
        utility.IdentityInterface(fields=['brain', 'brain_mask']),
        name='outputspec')

    # Save outputs which are important
    ds = pe.Node(interface=io.DataSink(), name='ds')
    ds.inputs.base_directory = SinkDir
    ds.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]

    #Create a workflow to connect all those nodes
    analysisflow = nipype.Workflow(
        wf_name)  # The name here determine the folder of the workspace
    analysisflow.base_dir = '.'
    analysisflow.connect(inputspec, 'in_file', bet, 'in_file')
    analysisflow.connect(inputspec, 'opt_R', bet, 'robust')
    analysisflow.connect(inputspec, 'fract_int_thr', bet, 'frac')
    analysisflow.connect(inputspec, 'vertical_gradient', bet,
                         'vertical_gradient')
    analysisflow.connect(bet, 'mask_file', outputspec, 'brain_mask')
    if fmri:

        analysisflow.connect(bet, 'mask_file', myonevol, 'inputspec.func')
        analysisflow.connect(myonevol, 'outputspec.func1vol', applymask,
                             'mask_file')
        analysisflow.connect(inputspec, 'in_file', applymask, 'in_file')
        analysisflow.connect(applymask, 'out_file', outputspec, 'brain')
    else:
        analysisflow.connect(bet, 'out_file', outputspec, 'brain')
    analysisflow.connect(bet, 'out_file', ds, 'bet_brain')
    analysisflow.connect(bet, 'mask_file', ds, 'brain_mask')

    analysisflow.connect(inputspec, 'in_file', myqc, 'inputspec.bg_image')
    analysisflow.connect(bet, 'out_file', myqc, 'inputspec.overlay_image')

    return analysisflow
Ejemplo n.º 22
0
def mc_workflow_fsl(reference_vol="mid",
                    FD_mode="Power",
                    SinkTag="func_preproc",
                    wf_name="motion_correction_fsl"):
    """
    Modified version of CPAC.func_preproc.func_preproc and CPAC.generate_motion_statistics.generate_motion_statistics:

    `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/func_preproc/func_preproc.html`
    `source: https://fcp-indi.github.io/docs/developer/_modules/CPAC/generate_motion_statistics/generate_motion_statistics.html`

    Use FSL MCFLIRT to do the motion correction of the 4D functional data and use the 6df rigid body motion parameters to calculate friston24 parameters
    for later nuissance regression step.

    Workflow inputs:
        :param func: The reoriented functional file.
        :param reference_vol: Either "first", "mid", "last", "mean", or the index of the volume which the rigid body registration (motion correction) will use as reference.
        default: "mid"
        :param FD_mode Eiher "Power" or "Jenkinson"
        :param SinkDir:
        :param SinkTag: The output directory in which the returned images (see workflow outputs) could be found in a subdirectory directory specific for this workflow..

    Workflow outputs:




        :return: mc_workflow - workflow




    Balint Kincses
    [email protected]
    2018


    """
    # TODO_ready nipype has the ability to calculate FD: the function from CPAC calculates it correctly
    # import relevant packages
    import sys
    import os
    import nipype
    import nipype.pipeline as pe
    import nipype.interfaces.utility as utility
    import nipype.interfaces.fsl as fsl
    import nipype.algorithms.confounds as conf
    import PUMI.func_preproc.info.info_get as info_get
    import nipype.interfaces.io as io
    import PUMI.utils.utils_math as utils_math
    import PUMI.utils.utils_convert as utils_convert
    import PUMI.utils.globals as globals
    import PUMI.utils.QC as qc

    SinkDir = os.path.abspath(globals._SinkDir_ + "/" + SinkTag)
    if not os.path.exists(SinkDir):
        os.makedirs(SinkDir)
    QCDir = os.path.abspath(globals._SinkDir_ + "/" + globals._QCDir_)
    if not os.path.exists(QCDir):
        os.makedirs(QCDir)

    # Basic interface class generates identity mappings
    inputspec = pe.Node(utility.IdentityInterface(
        fields=['func', 'ref_vol', 'save_plots', 'stats_imgs']),
                        name='inputspec')
    inputspec.inputs.save_plots = True
    inputspec.inputs.stats_imgs = True
    inputspec.inputs.ref_vol = reference_vol

    # todo_ready: make parametrizable: the reference_vol variable is an argumentum of the mc_workflow

    # extract reference volume
    refvol = pe.MapNode(utility.Function(input_names=['refvol', 'func'],
                                         output_names=['refvol'],
                                         function=getRefVol),
                        iterfield=['func'],
                        name='getRefVol')

    # Wraps command **mcflirt**
    mcflirt = pe.MapNode(
        interface=fsl.MCFLIRT(
            interpolation="spline",
            stats_imgs=False),  # stages=4), #stages 4: more accurate but slow
        iterfield=['in_file',
                   'ref_file'],  # , 'ref_vol'], # make parametrizable
        name='mcflirt')

    if (reference_vol == "mean"):
        mcflirt = pe.MapNode(
            interface=fsl.MCFLIRT(interpolation="spline", stats_imgs=False),
            # stages=4), #stages 4: more accurate but slow
            iterfield=['in_file'],  # , 'ref_vol'], # make parametrizable
            name='mcflirt')
        mcflirt.inputs.mean_vol = True
    else:
        mcflirt = pe.MapNode(
            interface=fsl.MCFLIRT(interpolation="spline", stats_imgs=False),
            # stages=4), #stages 4: more accurate but slow
            iterfield=['in_file',
                       'ref_file'],  # , 'ref_vol'], # make parametrizable
            name='mcflirt')

    mcflirt.inputs.dof = 6
    mcflirt.inputs.save_mats = True
    mcflirt.inputs.save_plots = True
    mcflirt.inputs.save_rms = True
    mcflirt.inputs.stats_imgs = False

    myqc = qc.timecourse2png("timeseries", tag="010_motioncorr")

    # Calculate Friston24 parameters
    calc_friston = pe.MapNode(utility.Function(
        input_names=['in_file'],
        output_names=['out_file'],
        function=calc_friston_twenty_four),
                              iterfield=['in_file'],
                              name='calc_friston')

    # Calculate FD based on Power's method
    if FD_mode == "Power":
        calculate_FD = pe.MapNode(conf.FramewiseDisplacement(
            parameter_source='FSL', save_plot=True),
                                  iterfield=['in_file'],
                                  name='calculate_FD_Power')
    elif FD_mode == "Jenkinson":
        calculate_FD = pe.MapNode(utility.Function(input_names=['in_file'],
                                                   output_names=['out_file'],
                                                   function=calculate_FD_J),
                                  iterfield=['in_file'],
                                  name='calculate_FD_Jenkinson')

    # compute mean and max FD
    meanFD = pe.MapNode(interface=utils_math.Txt2meanTxt,
                        iterfield=['in_file'],
                        name='meanFD')
    meanFD.inputs.axis = 0  # global mean
    meanFD.inputs.header = True  # global mean

    maxFD = pe.MapNode(interface=utils_math.Txt2maxTxt,
                       iterfield=['in_file'],
                       name='maxFD')
    maxFD.inputs.axis = 0  # global mean
    maxFD.inputs.header = True

    pop_FD = pe.Node(interface=utils_convert.List2TxtFileOpen, name='pop_FD')
    pop_FDmax = pe.Node(interface=utils_convert.List2TxtFileOpen,
                        name='pop_FDmax')

    # save data out with Datasink
    ds_fd = pe.Node(interface=io.DataSink(), name='ds_pop_fd')
    ds_fd.inputs.regexp_substitutions = [("(\/)[^\/]*$", "FD.txt")]
    ds_fd.inputs.base_directory = SinkDir

    # save data out with Datasink
    ds_fd_max = pe.Node(interface=io.DataSink(), name='ds_pop_fd_max')
    ds_fd_max.inputs.regexp_substitutions = [("(\/)[^\/]*$", "FD_max.txt")]
    ds_fd_max.inputs.base_directory = SinkDir

    plot_motion_rot = pe.MapNode(
        interface=fsl.PlotMotionParams(in_source='fsl'),
        name='plot_motion_rot',
        iterfield=['in_file'])
    plot_motion_rot.inputs.plot_type = 'rotations'

    plot_motion_tra = pe.MapNode(
        interface=fsl.PlotMotionParams(in_source='fsl'),
        name='plot_motion_trans',
        iterfield=['in_file'])
    plot_motion_tra.inputs.plot_type = 'translations'

    # Basic interface class generates identity mappings
    outputspec = pe.Node(utility.IdentityInterface(fields=[
        'func_out_file', 'first24_file', 'mat_file', 'mc_par_file', 'FD_file'
    ]),
                         name='outputspec')

    # save data out with Datasink
    ds_nii = pe.Node(interface=io.DataSink(), name='ds_nii')
    ds_nii.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".nii.gz")]
    ds_nii.inputs.base_directory = SinkDir

    # save data out with Datasink
    ds_text = pe.Node(interface=io.DataSink(), name='ds_txt')
    ds_text.inputs.regexp_substitutions = [("(\/)[^\/]*$", ".txt")]
    ds_text.inputs.base_directory = SinkDir

    # Save outputs which are important
    ds_qc_fd = pe.Node(interface=io.DataSink(), name='ds_qc_fd')
    ds_qc_fd.inputs.base_directory = QCDir
    ds_qc_fd.inputs.regexp_substitutions = [("(\/)[^\/]*$", "_FD.pdf")]

    # Save outputs which are important
    ds_qc_rot = pe.Node(interface=io.DataSink(), name='ds_qc_rot')
    ds_qc_rot.inputs.base_directory = QCDir
    ds_qc_rot.inputs.regexp_substitutions = [("(\/)[^\/]*$", "_rot.png")]

    # Save outputs which are important
    ds_qc_tra = pe.Node(interface=io.DataSink(), name='ds_qc_tra')
    ds_qc_tra.inputs.base_directory = QCDir
    ds_qc_tra.inputs.regexp_substitutions = [("(\/)[^\/]*$", "_trans.png")]

    #TODO_ready set the proper images which has to be saved in a the datasink specified directory
    # Create a workflow to connect all those nodes
    analysisflow = nipype.Workflow(wf_name)
    analysisflow.connect(inputspec, 'func', mcflirt, 'in_file')
    analysisflow.connect(inputspec, 'func', refvol, 'func')
    analysisflow.connect(inputspec, 'ref_vol', refvol, 'refvol')
    if (reference_vol != "mean"):
        analysisflow.connect(refvol, 'refvol', mcflirt, 'ref_file')
    analysisflow.connect(mcflirt, 'par_file', calc_friston, 'in_file')
    analysisflow.connect(mcflirt, 'par_file', calculate_FD, 'in_file')

    analysisflow.connect(mcflirt, 'out_file', outputspec, 'func_out_file')
    analysisflow.connect(mcflirt, 'mat_file', outputspec, 'mat_file')
    analysisflow.connect(mcflirt, 'par_file', outputspec, 'mc_par_file')
    analysisflow.connect(mcflirt, 'out_file', ds_nii, 'mc_func')
    analysisflow.connect(mcflirt, 'par_file', ds_text, 'mc_par')
    #analysisflow.connect(mcflirt, 'std_img', ds, 'mc.@std_img')
    analysisflow.connect(mcflirt, 'rms_files', ds_text, 'mc_rms')
    #analysisflow.connect(mcflirt, 'variance_img', ds, 'mc.@variance_img')
    analysisflow.connect(calc_friston, 'out_file', outputspec, 'first24_file')
    analysisflow.connect(calc_friston, 'out_file', ds_text, 'mc_first24')
    analysisflow.connect(calculate_FD, 'out_file', outputspec, 'FD_file')
    analysisflow.connect(mcflirt, 'par_file', plot_motion_rot, 'in_file')
    analysisflow.connect(mcflirt, 'par_file', plot_motion_tra, 'in_file')
    analysisflow.connect(plot_motion_rot, 'out_file', ds_qc_rot,
                         'motion_correction')
    analysisflow.connect(plot_motion_tra, 'out_file', ds_qc_tra,
                         'motion_correction')
    analysisflow.connect(mcflirt, 'out_file', myqc, 'inputspec.func')
    # pop-level mean FD
    analysisflow.connect(calculate_FD, 'out_file', meanFD, 'in_file')
    analysisflow.connect(calculate_FD, 'out_file', ds_text, 'mc_fd')
    analysisflow.connect(calculate_FD, 'out_figure', ds_qc_fd, 'FD')
    analysisflow.connect(meanFD, 'mean_file', pop_FD, 'in_list')
    analysisflow.connect(pop_FD, 'txt_file', ds_fd, 'pop')

    analysisflow.connect(calculate_FD, 'out_file', maxFD, 'in_file')
    analysisflow.connect(maxFD, 'max_file', pop_FDmax, 'in_list')
    analysisflow.connect(pop_FDmax, 'txt_file', ds_fd_max, 'pop')

    return analysisflow