Beispiel #1
0
def QA_workflow(QAc, c=foo, name='QA'):
    """ Workflow that generates a Quality Assurance Report
    
    Parameters
    ----------
    name : name of workflow
    
    Inputs
    ------
    inputspec.subject_id : Subject id
    inputspec.config_params : configuration parameters to print in PDF (in the form of a 2D List)
    inputspec.in_file : original functional run
    inputspec.art_file : art outlier file
    inputspec.reg_file : bbregister file
    inputspec.tsnr_detrended : detrended image
    inputspec.tsnr : signal-to-noise ratio image
    inputspec.tsnr_mean : mean image
    inputspec.tsnr_stddev : standard deviation image
    inputspec.ADnorm : norm components file from art
    inputspec.TR : repetition time of acquisition
    inputspec.sd : freesurfer subjects directory
    
    """
    import nipype.pipeline.engine as pe
    import nipype.interfaces.utility as util

    from nipype.interfaces.freesurfer import ApplyVolTransform
    from nipype.interfaces import freesurfer as fs
    from nipype.interfaces.io import FreeSurferSource

    from ...scripts.QA_utils import (plot_ADnorm, tsdiffana, tsnr_roi,
                                     combine_table, reduce_table, art_output,
                                     plot_motion, plot_ribbon, plot_anat,
                                     overlay_new, overlay_dB,
                                     spectrum_ts_table)

    from ......utils.reportsink.io import ReportSink
    # Define Workflow

    workflow = pe.Workflow(name=name)

    inputspec = pe.Node(interface=util.IdentityInterface(fields=[
        'subject_id', 'config_params', 'in_file', 'art_file', 'motion_plots',
        'reg_file', 'tsnr', 'tsnr_detrended', 'tsnr_stddev', 'ADnorm', 'TR',
        'sd'
    ]),
                        name='inputspec')

    infosource = pe.Node(util.IdentityInterface(fields=['subject_id']),
                         name='subject_names')
    if QAc.test_mode:
        infosource.iterables = ('subject_id', [QAc.subjects[0]])
    else:
        infosource.iterables = ('subject_id', QAc.subjects)

    datagrabber = preproc_datagrabber(c)

    datagrabber.inputs.node_type = c.motion_correct_node

    orig_datagrabber = get_dataflow(c)

    workflow.connect(infosource, 'subject_id', datagrabber, 'subject_id')

    workflow.connect(infosource, 'subject_id', orig_datagrabber, 'subject_id')

    workflow.connect(orig_datagrabber, 'func', inputspec, 'in_file')
    workflow.connect(infosource, 'subject_id', inputspec, 'subject_id')

    workflow.connect(datagrabber, ('outlier_files', sort), inputspec,
                     'art_file')
    workflow.connect(datagrabber, ('reg_file', sort), inputspec, 'reg_file')
    workflow.connect(datagrabber, ('tsnr', sort), inputspec, 'tsnr')
    workflow.connect(datagrabber, ('tsnr_stddev', sort), inputspec,
                     'tsnr_stddev')
    workflow.connect(datagrabber, ('tsnr_detrended', sort), inputspec,
                     'tsnr_detrended')
    workflow.connect(datagrabber, ('art_norm', sort), inputspec, 'ADnorm')

    if not c.use_metadata:
        inputspec.inputs.TR = c.TR
    else:
        from .....base import load_json
        metadata_file = os.path.join(c.sink_dir, QAc.subjects[0],
                                     'preproc/metadata/metadata.json')
        meta_tr = load_json(metadata_file)["tr"]
        inputspec.inputs.TR = meta_tr

    inputspec.inputs.sd = c.surf_dir

    # Define Nodes

    plot_m = pe.MapNode(util.Function(input_names=['motion_parameters'],
                                      output_names=['fname_t', 'fname_r'],
                                      function=plot_motion),
                        name="motion_plots",
                        iterfield=['motion_parameters'])

    workflow.connect(datagrabber, ('motion_parameters', sort), plot_m,
                     'motion_parameters')
    #workflow.connect(plot_m, 'fname',inputspec,'motion_plots')

    tsdiff = pe.MapNode(util.Function(input_names=['img'],
                                      output_names=['out_file'],
                                      function=tsdiffana),
                        name='tsdiffana',
                        iterfield=["img"])

    art_info = pe.MapNode(
        util.Function(input_names=['art_file', 'intensity_file', 'stats_file'],
                      output_names=['table', 'out', 'intensity_plot'],
                      function=art_output),
        name='art_output',
        iterfield=["art_file", "intensity_file", "stats_file"])

    fssource = pe.Node(interface=FreeSurferSource(), name='fssource')

    plotribbon = pe.Node(util.Function(input_names=['Brain'],
                                       output_names=['images'],
                                       function=plot_ribbon),
                         name="plot_ribbon")

    workflow.connect(fssource, 'ribbon', plotribbon, 'Brain')

    plotanat = pe.Node(util.Function(input_names=['brain'],
                                     output_names=['images'],
                                     function=plot_anat),
                       name="plot_anat")
    plotmask = plotanat.clone('plot_mask')
    workflow.connect(datagrabber, 'mask', plotmask, 'brain')
    roidevplot = tsnr_roi(plot=False,
                          name='tsnr_stddev_roi',
                          roi=['all'],
                          onsets=False)

    if not c.use_metadata:
        roidevplot.inputs.inputspec.TR = c.TR
    else:
        from .....base import load_json
        metadata_file = os.path.join(c.sink_dir, QAc.subjects[0],
                                     'preproc/metadata/metadata.json')
        meta_tr = load_json(metadata_file)["tr"]
        roidevplot.inputs.inputspec.TR = meta_tr

    roisnrplot = tsnr_roi(plot=False,
                          name='SNR_roi',
                          roi=['all'],
                          onsets=False)

    if not c.use_metadata:
        roisnrplot.inputs.inputspec.TR = c.TR
    else:
        from .....base import load_json
        metadata_file = os.path.join(c.sink_dir, QAc.subjects[0],
                                     'preproc/metadata/metadata.json')
        meta_tr = load_json(metadata_file)["tr"]
        roisnrplot.inputs.inputspec.TR = meta_tr

    workflow.connect(fssource, ('aparc_aseg', pickfirst), roisnrplot,
                     'inputspec.aparc_aseg')
    workflow.connect(fssource, ('aparc_aseg', pickfirst), roidevplot,
                     'inputspec.aparc_aseg')

    workflow.connect(infosource, 'subject_id', roidevplot, 'inputspec.subject')
    workflow.connect(infosource, 'subject_id', roisnrplot, 'inputspec.subject')

    tablecombine = pe.MapNode(util.Function(
        input_names=['roidev', 'roisnr', 'imagetable'],
        output_names=['imagetable'],
        function=combine_table),
                              name='combinetable',
                              iterfield=['roidev', 'roisnr', 'imagetable'])

    tablereduce = pe.MapNode(util.Function(
        input_names=['imagetable', 'custom_LUT_file'],
        output_names=['reduced_imagetable'],
        function=reduce_table),
                             name='reducetable',
                             iterfield=['imagetable'])

    adnormplot = pe.MapNode(util.Function(
        input_names=['ADnorm', 'TR', 'norm_thresh', 'out'],
        output_names=['plot'],
        function=plot_ADnorm),
                            name='ADnormplot',
                            iterfield=['ADnorm', 'out'])
    adnormplot.inputs.norm_thresh = c.norm_thresh
    workflow.connect(art_info, 'out', adnormplot, 'out')

    convert = pe.Node(interface=fs.MRIConvert(), name='converter')

    voltransform = pe.MapNode(interface=ApplyVolTransform(),
                              name='register',
                              iterfield=['source_file'])

    overlaynew = pe.MapNode(util.Function(
        input_names=['stat_image', 'background_image', 'threshold', "dB"],
        output_names=['fnames'],
        function=overlay_dB),
                            name='overlay_new',
                            iterfield=['stat_image'])
    overlaynew.inputs.dB = False
    overlaynew.inputs.threshold = 20

    overlaymask = pe.MapNode(util.Function(
        input_names=['stat_image', 'background_image', 'threshold'],
        output_names=['fnames'],
        function=overlay_new),
                             name='overlay_mask',
                             iterfield=['stat_image'])
    overlaymask.inputs.threshold = 0.5
    workflow.connect(convert, 'out_file', overlaymask, 'background_image')
    overlaymask2 = overlaymask.clone('acompcor_image')
    workflow.connect(convert, 'out_file', overlaymask2, 'background_image')
    workflow.connect(datagrabber, 'tcompcor', overlaymask, 'stat_image')
    workflow.connect(datagrabber, 'acompcor', overlaymask2, 'stat_image')

    workflow.connect(datagrabber, ('mean_image', sort), plotanat, 'brain')

    ts_and_spectra = spectrum_ts_table()

    timeseries_segstats = tsnr_roi(plot=False,
                                   name='timeseries_roi',
                                   roi=['all'],
                                   onsets=False)
    workflow.connect(inputspec, 'tsnr_detrended', timeseries_segstats,
                     'inputspec.tsnr_file')
    workflow.connect(inputspec, 'reg_file', timeseries_segstats,
                     'inputspec.reg_file')
    workflow.connect(infosource, 'subject_id', timeseries_segstats,
                     'inputspec.subject')
    workflow.connect(fssource, ('aparc_aseg', pickfirst), timeseries_segstats,
                     'inputspec.aparc_aseg')

    if not c.use_metadata:
        timeseries_segstats.inputs.inputspec.TR = c.TR
        ts_and_spectra.inputs.inputspec.tr = c.TR
    else:
        from .....base import load_json
        metadata_file = os.path.join(c.sink_dir, QAc.subjects[0],
                                     'preproc/metadata/metadata.json')
        meta_tr = load_json(metadata_file)["tr"]
        timeseries_segstats.inputs.inputspec.TR = meta_tr
        ts_and_spectra.inputs.inputspec.tr = meta_tr

    workflow.connect(timeseries_segstats, 'outputspec.roi_file',
                     ts_and_spectra, 'inputspec.stats_file')

    write_rep = pe.Node(interface=ReportSink(orderfields=[
        'Introduction', 'in_file', 'config_params', 'Art_Detect',
        'Global_Intensity', 'Mean_Functional', 'Ribbon', 'Mask',
        'motion_plot_translations', 'motion_plot_rotations', 'tsdiffana',
        'ADnorm', 'A_CompCor', 'T_CompCor', 'TSNR_Images', 'tsnr_roi_table'
    ]),
                        name='report_sink')
    write_rep.inputs.Introduction = "Quality Assurance Report for fMRI preprocessing."
    write_rep.inputs.base_directory = os.path.join(QAc.sink_dir)
    write_rep.inputs.report_name = "Preprocessing_Report"
    write_rep.inputs.json_sink = QAc.json_sink
    workflow.connect(infosource, 'subject_id', write_rep, 'container')
    workflow.connect(plotanat, 'images', write_rep, "Mean_Functional")
    write_rep.inputs.table_as_para = False
    # Define Inputs

    convert.inputs.out_type = 'niigz'
    convert.inputs.in_type = 'mgz'

    # Define Connections

    workflow.connect(inputspec, 'TR', adnormplot, 'TR')
    workflow.connect(inputspec, 'subject_id', fssource, 'subject_id')
    workflow.connect(inputspec, 'sd', fssource, 'subjects_dir')
    workflow.connect(inputspec, 'in_file', write_rep, 'in_file')
    workflow.connect(datagrabber, 'art_intensity', art_info, 'intensity_file')
    workflow.connect(datagrabber, ('art_stats', sort), art_info, 'stats_file')
    workflow.connect(inputspec, 'art_file', art_info, 'art_file')
    workflow.connect(art_info, ('table', to1table), write_rep, 'Art_Detect')
    workflow.connect(ts_and_spectra, 'outputspec.imagetable', tablecombine,
                     'imagetable')
    workflow.connect(art_info, 'intensity_plot', write_rep, 'Global_Intensity')
    workflow.connect(plot_m, 'fname_t', write_rep, 'motion_plot_translations')
    workflow.connect(plot_m, 'fname_r', write_rep, 'motion_plot_rotations')
    workflow.connect(inputspec, 'in_file', tsdiff, 'img')
    workflow.connect(tsdiff, "out_file", write_rep, "tsdiffana")
    workflow.connect(inputspec, ('config_params', totable), write_rep,
                     'config_params')
    workflow.connect(inputspec, 'reg_file', roidevplot, 'inputspec.reg_file')
    workflow.connect(inputspec, 'tsnr_stddev', roidevplot,
                     'inputspec.tsnr_file')
    workflow.connect(roidevplot, 'outputspec.roi_table', tablecombine,
                     'roidev')
    workflow.connect(inputspec, 'reg_file', roisnrplot, 'inputspec.reg_file')
    workflow.connect(inputspec, 'tsnr', roisnrplot, 'inputspec.tsnr_file')
    workflow.connect(roisnrplot, 'outputspec.roi_table', tablecombine,
                     'roisnr')

    if QAc.use_custom_ROI_list_file:
        workflow.connect(tablecombine, 'imagetable', tablereduce, 'imagetable')
        tablereduce.inputs.custom_LUT_file = QAc.custom_ROI_list_file
        workflow.connect(tablereduce, ('reduced_imagetable', to1table),
                         write_rep, 'tsnr_roi_table')
    else:
        workflow.connect(tablecombine, ('imagetable', to1table), write_rep,
                         'tsnr_roi_table')

    workflow.connect(inputspec, 'ADnorm', adnormplot, 'ADnorm')
    workflow.connect(adnormplot, 'plot', write_rep, 'ADnorm')
    workflow.connect(fssource, 'orig', convert, 'in_file')
    workflow.connect(convert, 'out_file', voltransform, 'target_file')
    workflow.connect(inputspec, 'reg_file', voltransform, 'reg_file')
    workflow.connect(inputspec, 'tsnr', voltransform, 'source_file')
    workflow.connect(plotribbon, 'images', write_rep, 'Ribbon')
    workflow.connect(voltransform, 'transformed_file', overlaynew,
                     'stat_image')
    workflow.connect(convert, 'out_file', overlaynew, 'background_image')

    workflow.connect(overlaynew, 'fnames', write_rep, 'TSNR_Images')
    workflow.connect(overlaymask, 'fnames', write_rep, 'T_CompCor')
    workflow.connect(overlaymask2, 'fnames', write_rep, 'A_CompCor')
    workflow.connect(plotmask, 'images', write_rep, 'Mask')

    workflow.write_graph()
    return workflow
def skullstrip_refined(file_mask1, file_mask2):
    """
    The purpose of the following function is to enhance the skullstrip mask in native space. It
    uses a second mask which was manually corrected during the freesurfer segmentation. This
    corrected brainmask is converted to native space and multiplied with the initial brainmask.
    Inputs:
        *file_mask1: brainmask in original space.
        *file_mask2: manually corrected brainmask in freesurfer space (brain.finalsurfs.mgz).
    Outputs:
        *file_out: filename of enhanced brainmask.
        
    created by Daniel Haenelt
    Date created: 31-01-2020            
    Last modified: 31-01-2020
    """
    import os
    import nibabel as nb
    from nipype.interfaces.freesurfer import ApplyVolTransform
    from lib.io.get_filename import get_filename

    # get output path and basename
    path_output, name_output, _ = get_filename(file_mask1)

    # filename of temporary and enhanced brainmask
    file_temp = os.path.join(path_output, "temp.nii")
    file_out = os.path.join(path_output, name_output + "_enhanced.nii")

    # bring skullstrip_mask from conformed space into original space
    transmask = ApplyVolTransform()
    transmask.inputs.source_file = file_mask2
    transmask.inputs.target_file = file_mask1
    transmask.inputs.reg_header = True
    transmask.inputs.interp = "nearest"
    transmask.inputs.transformed_file = file_temp
    transmask.inputs.args = "--no-save-reg"
    transmask.run()

    # load first brainmask in original space
    mask1 = nb.load(file_mask1)
    mask1_array = mask1.get_fdata()

    # load second brainmask transformed into original space
    mask2 = nb.load(file_temp)
    mask2_array = mask2.get_fdata()

    # make second brainmask binary
    mask2_array[mask2_array == 1] = 0
    mask2_array[mask2_array > 0] = 1

    # multiply both masks
    mask_enhanced_array = mask1_array * mask2_array

    # write enhancec brainmask
    mask_enhanced = nb.Nifti1Image(mask_enhanced_array, mask1.affine,
                                   mask1.header)
    nb.save(mask_enhanced, file_out)

    # remove temporary file
    os.remove(file_temp)

    return file_out
Beispiel #3
0
    def whole_brain_tractography(subject_list, base_directory, out_directory):

        # ==================================================================
        # Loading required packages
        import nipype.pipeline.engine as pe
        import nipype.interfaces.utility as util
        from nipype.interfaces.freesurfer import ApplyVolTransform
        from nipype.interfaces.freesurfer import BBRegister
        import nipype.interfaces.fsl as fsl
        import nipype.interfaces.dipy as dipy
        import nipype.interfaces.diffusion_toolkit as dtk
        import nipype.algorithms.misc as misc
        from nipype.interfaces.utility import Merge
        from BrainTypes_additional_interfaces import Tractography
        from BrainTypes_additional_interfaces import DipyDenoise
        from BrainTypes_additional_pipelines import DWIPreproc
        from BrainTypes_additional_interfaces import CalcMatrix
        from BrainTypes_additional_pipelines import T1Preproc
        from BrainTypes_additional_pipelines import SubjectSpaceParcellation
        from BrainTypes_additional_interfaces import Extractb0 as extract_b0

        from nipype import SelectFiles
        import os

        # ==================================================================
        # Defining the nodes for the workflow

        # Getting the subject ID
        infosource = pe.Node(
            interface=util.IdentityInterface(fields=['subject_id']),
            name='infosource')
        infosource.iterables = ('subject_id', subject_list)

        # Getting the relevant diffusion-weighted data
        templates = dict(T1='{subject_id}/anat/{subject_id}_T1w.nii.gz',
                         dwi='{subject_id}/dwi/{subject_id}_dwi.nii.gz',
                         bvec='{subject_id}/dwi/{subject_id}_dwi.bvec',
                         bval='{subject_id}/dwi/{subject_id}_dwi.bval')

        selectfiles = pe.Node(SelectFiles(templates), name='selectfiles')
        selectfiles.inputs.base_directory = os.path.abspath(base_directory)

        # ==============================================================
        # T1 processing
        t1_preproc = pe.Node(interface=T1Preproc(), name='t1_preproc')
        t1_preproc.inputs.out_directory = out_directory + '/whole_brain_tractography/'
        t1_preproc.inputs.template_directory = template_directory

        # DWI processing
        dwi_preproc = pe.Node(interface=DWIPreproc(), name='dwi_preproc')
        dwi_preproc.inputs.out_directory = out_directory + '/whole_brain_tractography/'
        dwi_preproc.inputs.acqparams = acquisition_parameters
        dwi_preproc.inputs.index_file = index_file
        dwi_preproc.inputs.out_directory = out_directory + '/whole_brain_tractography/'

        # Eroding the brain mask
        erode_mask = pe.Node(interface=fsl.maths.ErodeImage(),
                             name='erode_mask')

        # Reconstruction and tractography
        tractography = pe.Node(interface=Tractography(), name='tractography')
        tractography.iterables = ('model', ['CSA', 'CSD'])

        # smoothing the tracts
        smooth = pe.Node(interface=dtk.SplineFilter(step_length=0.5),
                         name='smooth')

        # Moving to subject space
        subject_parcellation = pe.Node(interface=SubjectSpaceParcellation(),
                                       name='subject_parcellation')
        subject_parcellation.inputs.source_subject = 'fsaverage'
        subject_parcellation.inputs.source_annot_file = 'aparc'
        subject_parcellation.inputs.out_directory = out_directory + '/connectome/'
        subject_parcellation.inputs.parcellation_directory = parcellation_directory

        # Co-registering T1 and dwi
        bbreg = pe.Node(interface=BBRegister(), name='bbreg')
        bbreg.inputs.init = 'fsl'
        bbreg.inputs.contrast_type = 't2'

        applyreg = pe.Node(interface=ApplyVolTransform(), name='applyreg')
        applyreg.inputs.interp = 'nearest'
        applyreg.inputs.inverse = True

        # ==================================================================
        # Setting up the workflow
        whole_brain_tractography = pe.Workflow(name='whole_brain_tractography')

        # Reading in files
        whole_brain_tractography.connect(infosource, 'subject_id', selectfiles,
                                         'subject_id')

        # DWI preprocessing
        whole_brain_tractography.connect(infosource, 'subject_id', dwi_preproc,
                                         'subject_id')
        whole_brain_tractography.connect(selectfiles, 'dwi', dwi_preproc,
                                         'dwi')
        whole_brain_tractography.connect(selectfiles, 'bval', dwi_preproc,
                                         'bvals')
        whole_brain_tractography.connect(selectfiles, 'bvec', dwi_preproc,
                                         'bvecs')

        # CSD model and streamline tracking
        whole_brain_tractography.connect(dwi_preproc, 'mask', erode_mask,
                                         'in_file')

        whole_brain_tractography.connect(selectfiles, 'bvec', tractography,
                                         'bvec')
        whole_brain_tractography.connect(selectfiles, 'bval', tractography,
                                         'bval')
        whole_brain_tractography.connect(dwi_preproc, 'dwi', tractography,
                                         'in_file')
        whole_brain_tractography.connect(dwi_preproc, 'FA', tractography, 'FA')
        whole_brain_tractography.connect(erode_mask, 'out_file', tractography,
                                         'brain_mask')

        # Smoothing the trackfile
        whole_brain_tractography.connect(tractography, 'out_track', smooth,
                                         'track_file')

        # Preprocessing the T1-weighted file
        whole_brain_tractography.connect(infosource, 'subject_id', t1_preproc,
                                         'subject_id')
        whole_brain_tractography.connect(selectfiles, 'T1', t1_preproc, 'T1')
        whole_brain_tractography.connect(t1_preproc, 'wm',
                                         subject_parcellation, 'wm')
        whole_brain_tractography.connect(t1_preproc, 'subjects_dir',
                                         subject_parcellation, 'subjects_dir')
        whole_brain_tractography.connect(t1_preproc, 'subject_id',
                                         subject_parcellation, 'subject_id')

        # Getting the parcellation into diffusion space
        whole_brain_tractography.connect(t1_preproc, 'subject_id', bbreg,
                                         'subject_id')
        whole_brain_tractography.connect(t1_preproc, 'subjects_dir', bbreg,
                                         'subjects_dir')
        whole_brain_tractography.connect(dwi_preproc, 'b0', bbreg,
                                         'source_file')

        whole_brain_tractography.connect(dwi_preproc, 'b0', applyreg,
                                         'source_file')
        whole_brain_tractography.connect(bbreg, 'out_reg_file', applyreg,
                                         'reg_file')
        whole_brain_tractography.connect(subject_parcellation,
                                         'renum_expanded', applyreg,
                                         'target_file')

        # ==================================================================
        # Running the workflow
        whole_brain_tractography.base_dir = os.path.abspath(out_directory)
        whole_brain_tractography.write_graph()
        whole_brain_tractography.run()
    def connectome(subject_list, base_directory, out_directory):

        # ==================================================================
        # Loading required packages
        import nipype.pipeline.engine as pe
        import nipype.interfaces.utility as util
        from nipype.interfaces.freesurfer import ApplyVolTransform
        from nipype.interfaces.freesurfer import BBRegister
        import nipype.interfaces.fsl as fsl
        import nipype.interfaces.diffusion_toolkit as dtk
        from nipype.interfaces.utility import Merge
        import numpy as np
        from additional_interfaces import AtlasValues
        from additional_interfaces import AparcStats
        from additional_interfaces import CalcMatrix
        from additional_interfaces import FreeSurferValues
        from additional_interfaces import Tractography
        from additional_pipelines import DWIPreproc
        from additional_pipelines import SubjectSpaceParcellation
        from additional_pipelines import T1Preproc

        from nipype import SelectFiles
        import os

        # ==================================================================
        # Defining the nodes for the workflow

        # Getting the subject ID
        infosource = pe.Node(
            interface=util.IdentityInterface(fields=['subject_id']),
            name='infosource')
        infosource.iterables = ('subject_id', subject_list)

        # Getting the relevant diffusion-weighted data
        templates = dict(T1='{subject_id}/anat/{subject_id}_T1w.nii.gz',
                         dwi='{subject_id}/dwi/{subject_id}_dwi.nii.gz',
                         bvec='{subject_id}/dwi/{subject_id}_dwi.bvec',
                         bval='{subject_id}/dwi/{subject_id}_dwi.bval')

        selectfiles = pe.Node(SelectFiles(templates), name='selectfiles')
        selectfiles.inputs.base_directory = os.path.abspath(base_directory)

        # ==============================================================
        # T1 processing
        t1_preproc = pe.Node(interface=T1Preproc(), name='t1_preproc')
        t1_preproc.inputs.out_directory = out_directory + '/connectome/'
        t1_preproc.inputs.template_directory = template_directory

        # DWI processing
        dwi_preproc = pe.Node(interface=DWIPreproc(), name='dwi_preproc')
        dwi_preproc.inputs.out_directory = out_directory + '/connectome/'
        dwi_preproc.inputs.acqparams = acquisition_parameters
        dwi_preproc.inputs.index_file = index_file
        dwi_preproc.inputs.out_directory = out_directory + '/connectome/'

        # Eroding the brain mask
        erode_mask = pe.Node(interface=fsl.maths.ErodeImage(),
                             name='erode_mask')

        # Reconstruction and tractography
        tractography = pe.Node(interface=Tractography(), name='tractography')
        tractography.iterables = ('model', ['CSA', 'CSD'])

        # smoothing the tracts
        smooth = pe.Node(interface=dtk.SplineFilter(step_length=0.5),
                         name='smooth')

        # Moving to subject space
        subject_parcellation = pe.Node(interface=SubjectSpaceParcellation(),
                                       name='subject_parcellation')
        subject_parcellation.inputs.source_subject = 'fsaverage'
        subject_parcellation.inputs.source_annot_file = 'aparc'
        subject_parcellation.inputs.out_directory = out_directory + '/connectome/'
        subject_parcellation.inputs.parcellation_directory = parcellation_directory

        # Co-registering T1 and dwi
        bbreg = pe.Node(interface=BBRegister(), name='bbreg')
        bbreg.inputs.init = 'fsl'
        bbreg.inputs.contrast_type = 't2'

        applyreg = pe.Node(interface=ApplyVolTransform(), name='applyreg')
        applyreg.inputs.interp = 'nearest'
        applyreg.inputs.inverse = True

        # Merge outputs to pass on to CalcMatrix
        merge = pe.Node(interface=Merge(3), name='merge')

        # calcuating the connectome matrix
        calc_matrix = pe.MapNode(interface=CalcMatrix(),
                                 name='calc_matrix',
                                 iterfield=['scalar_file'])
        calc_matrix.iterables = ('threshold', np.arange(0, 100, 10))

        # Getting values of diffusion measures
        FA_values = pe.Node(interface=AtlasValues(), name='FA_values')
        RD_values = pe.Node(interface=AtlasValues(), name='RD_values')
        AD_values = pe.Node(interface=AtlasValues(), name='AD_values')
        MD_values = pe.Node(interface=AtlasValues(), name='MD_values')

        # Getting additional surface measures
        aparcstats = pe.Node(interface=AparcStats(), name='aparcstats')
        aparcstats.inputs.parcellation_name = 'aparc'

        freesurfer_values = pe.Node(interface=FreeSurferValues(),
                                    name='freesurfer_values')
        freesurfer_values.inputs.parcellation_name = 'aparc'

        # ==================================================================
        # Setting up the workflow
        connectome = pe.Workflow(name='connectome')

        # Reading in files
        connectome.connect(infosource, 'subject_id', selectfiles, 'subject_id')

        # DWI preprocessing
        connectome.connect(infosource, 'subject_id', dwi_preproc, 'subject_id')
        connectome.connect(selectfiles, 'dwi', dwi_preproc, 'dwi')
        connectome.connect(selectfiles, 'bval', dwi_preproc, 'bvals')
        connectome.connect(selectfiles, 'bvec', dwi_preproc, 'bvecs')

        # CSD model and streamline tracking
        connectome.connect(dwi_preproc, 'mask', erode_mask, 'in_file')

        connectome.connect(selectfiles, 'bvec', tractography, 'bvec')
        connectome.connect(selectfiles, 'bval', tractography, 'bval')
        connectome.connect(dwi_preproc, 'dwi', tractography, 'in_file')
        connectome.connect(dwi_preproc, 'FA', tractography, 'FA')
        connectome.connect(erode_mask, 'out_file', tractography, 'brain_mask')

        # Smoothing the trackfile
        connectome.connect(tractography, 'out_track', smooth, 'track_file')

        # Preprocessing the T1-weighted file
        connectome.connect(infosource, 'subject_id', t1_preproc, 'subject_id')
        connectome.connect(selectfiles, 'T1', t1_preproc, 'T1')
        connectome.connect(t1_preproc, 'wm', subject_parcellation, 'wm')
        connectome.connect(t1_preproc, 'subjects_dir', subject_parcellation,
                           'subjects_dir')
        connectome.connect(t1_preproc, 'subject_id', subject_parcellation,
                           'subject_id')

        # Getting the parcellation into diffusion space
        connectome.connect(t1_preproc, 'subject_id', bbreg, 'subject_id')
        connectome.connect(t1_preproc, 'subjects_dir', bbreg, 'subjects_dir')
        connectome.connect(dwi_preproc, 'b0', bbreg, 'source_file')

        connectome.connect(dwi_preproc, 'b0', applyreg, 'source_file')
        connectome.connect(bbreg, 'out_reg_file', applyreg, 'reg_file')
        connectome.connect(subject_parcellation, 'renum_expanded', applyreg,
                           'target_file')

        # Calculating the FA connectome
        connectome.connect(tractography, 'out_file', calc_matrix, 'track_file')
        connectome.connect(dwi_preproc, 'FA', merge, 'in1')
        connectome.connect(dwi_preproc, 'RD', merge, 'in2')
        connectome.connect(tractography, 'GFA', merge, 'in3')
        connectome.connect(merge, 'out', calc_matrix, 'scalar_file')
        connectome.connect(applyreg, 'transformed_file', calc_matrix,
                           'ROI_file')

        # Getting values for additional measures
        connectome.connect(dwi_preproc, 'FA', FA_values, 'morpho_filename')
        connectome.connect(dwi_preproc, 'RD', RD_values, 'morpho_filename')
        connectome.connect(dwi_preproc, 'AD', AD_values, 'morpho_filename')
        connectome.connect(dwi_preproc, 'MD', MD_values, 'morpho_filename')
        connectome.connect(applyreg, 'transformed_file', FA_values,
                           'atlas_filename')
        connectome.connect(applyreg, 'transformed_file', RD_values,
                           'atlas_filename')
        connectome.connect(applyreg, 'transformed_file', AD_values,
                           'atlas_filename')
        connectome.connect(applyreg, 'transformed_file', MD_values,
                           'atlas_filename')

        # Getting FreeSurfer morphological values
        connectome.connect(t1_preproc, 'subject_id', aparcstats, 'subject_id')
        connectome.connect(t1_preproc, 'subjects_dir', aparcstats,
                           'subjects_dir')
        connectome.connect(aparcstats, 'lh_stats', freesurfer_values,
                           'lh_filename')
        connectome.connect(aparcstats, 'rh_stats', freesurfer_values,
                           'rh_filename')

        # ==================================================================
        # Running the workflow
        connectome.base_dir = os.path.abspath(out_directory)
        connectome.write_graph()
        connectome.run()
#I will not be using this if I'm doing MVPA analysis, but may use it for GLM analysis
smooth = Node(Smooth(fwhm=fwhm_size), name="smooth")

# FreeSurferSource - Data grabber specific for FreeSurfer data
fssource = Node(FreeSurferSource(subjects_dir=fs_dir),
                run_without_submitting=True,
                name='fssource')

# BBRegister - coregister a volume to the Freesurfer anatomical
bbregister = Node(BBRegister(init='header',
                             contrast_type='t2',
                             out_fsl_file=True),
                  name='bbregister')

# Volume Transformation - transform the brainmask into functional space
applyVolTrans = Node(ApplyVolTransform(inverse=True), name='applyVolTrans')

# Binarize -  binarize and dilate an image to create a brainmask
binarize = Node(Binarize(min=0.5, dilate=1, out_type='nii'), name='binarize')

### Connect the workflow
# Create a preprocessing workflow
preproc = Workflow(name='preproc')

# Connect all components of the preprocessing workflow
preproc.connect([
    (despike, sliceTiming, [('out_file', 'in_files')]),
    (sliceTiming, realign, [('timecorrected_files', 'in_files')]),
    (realign, tsnr, [('realigned_files', 'in_file')]),
    (tsnr, art, [('detrended_file', 'realigned_files')]),
    (realign, art, [('mean_image', 'mask_file'),
def tsnr_roi(roi=[1021],name='roi_flow',plot=False, onsets=False):
    """ Return a workflow that outputs either a graph of the average \
        
    timseries of each roi specified OR a table of average value across \
    all timeseries for each voxel in each ROI.
    
    Parameters
    ----------
    roi : List of Integers or ['all']
          Specify a list of ROI number corresponding to the Freesurfer LUT.
          Default = 1021 (lh-pericalcarine)
    name : String
           Name of workflow. 
           Default = 'roi_flow'
    plot : Boolean
           True if workflow should output timeseries plots/ROI
           False if workflow should output a table of avg.value/ROI
           Default = False
           
    Inputs
    ------
    inputspec.reg_file :
    inputspec.tsnr_file :
    inputspec.TR :
    inputspec.subject :
    inputspec.sd :
    
    Outputs
    -------
    outputspec.out_file :
    
    
    """
    import nipype.pipeline.engine as pe
    import nipype.interfaces.utility as util
    from nipype.interfaces.freesurfer import ApplyVolTransform
    from nipype.workflows.smri.freesurfer.utils import create_get_stats_flow

    preproc = pe.Workflow(name=name)
    
    inputspec = pe.Node(interface=util.IdentityInterface(fields=['reg_file',
                                                                 'tsnr_file',
                                                                 'TR',
                                                                 'aparc_aseg',
                                                                 'subject',
                                                                 'onsets',
                                                                 'input_units','sd']),name='inputspec')
    
    voltransform = pe.MapNode(interface=ApplyVolTransform(inverse=True, interp='nearest'),name='applyreg', iterfield=['source_file'])
    
    preproc.connect(inputspec,'tsnr_file',voltransform,'source_file')
    
    preproc.connect(inputspec,'reg_file',voltransform,'reg_file')
    
    preproc.connect(inputspec,'aparc_aseg',voltransform,'target_file')
    
    statsflow = create_get_stats_flow()
    preproc.connect(voltransform,'transformed_file',statsflow,'inputspec.label_file')
    preproc.connect(inputspec,'tsnr_file',statsflow,'inputspec.source_file')
    
    statsflow.inputs.segstats.avgwf_txt_file = True

    def strip_ids(subject_id, summary_file, roi_file):
        import numpy as np
        import os
        roi_idx = np.genfromtxt(summary_file)[:,1].astype(int)
        roi_vals = np.genfromtxt(roi_file)
        rois2skip = [0, 2, 4, 5, 7, 14, 15, 24, 30, 31, 41, 43, 44, 46,
                     62, 63, 77, 80, 85, 1000, 2000]
        ids2remove = []
        for roi in rois2skip:
            idx, = np.nonzero(roi_idx==roi)
            ids2remove.extend(idx)
        ids2keep = np.setdiff1d(range(roi_idx.shape[0]), ids2remove)
        filename = os.path.join(os.getcwd(), subject_id+'.csv')
        newvals = np.vstack((roi_idx[ids2keep], roi_vals[:, np.array(ids2keep)])).T
        np.savetxt(filename, newvals, '%.4f', delimiter=',')
        return filename

    roistripper = pe.MapNode(util.Function(input_names=['subject_id', 'summary_file', 'roi_file'],
                                       output_names=['roi_file'],
                                       function=strip_ids),
                          name='roistripper', iterfield=['summary_file','roi_file'])
    
    preproc.connect(inputspec,'subject',roistripper,'subject_id')
    
    preproc.connect(statsflow, 'segstats.avgwf_txt_file', roistripper, 'roi_file')
    preproc.connect(statsflow, 'segstats.summary_file', roistripper, 'summary_file')


    if onsets:
        roiplotter = pe.MapNode(util.Function(input_names=['statsfile', 'roi','TR','plot','onsets','units'],
            output_names=['Fname','AvgRoi'],
            function=plot_timeseries),
            name='roiplotter', iterfield=['statsfile','onsets'])
        preproc.connect(inputspec,'onsets',roiplotter,'onsets')
        preproc.connect(inputspec, 'input_units',roiplotter,'units')
    else:
        roiplotter = pe.MapNode(util.Function(input_names=['statsfile', 'roi','TR','plot','onsets','units'],
            output_names=['Fname','AvgRoi'],
            function=plot_timeseries),
            name='roiplotter', iterfield=['statsfile'])
        roiplotter.inputs.onsets = None
        roiplotter.inputs.units = None

    roiplotter.inputs.roi = roi
    preproc.connect(inputspec,'TR',roiplotter,'TR')
    roiplotter.inputs.plot = plot
    preproc.connect(roistripper,'roi_file',roiplotter,'statsfile')

    outputspec = pe.Node(interface=util.IdentityInterface(fields=['out_file','roi_table','roi_file']),name='outputspec')
    preproc.connect(roiplotter,'Fname',outputspec,'out_file')
    preproc.connect(roiplotter,'AvgRoi',outputspec,'roi_table')
    preproc.connect(roistripper,'roi_file', outputspec,'roi_file')

    return preproc
def make_w_freesurfer2func():
    n_in = Node(IdentityInterface(fields=[
        'T1w',
        'mean',
        'subject',  # without sub-
        ]), name='input')

    n_out = Node(IdentityInterface(fields=[
        'brain',
        'func2struct',
        'struct2func',
        'freesurfer2func',
        'func2freesurfer',
        ]), name='output')

    freesurfer = Node(FreeSurferSource(), name='freesurfer')
    freesurfer.inputs.subjects_dir = '/Fridge/R01_BAIR/freesurfer'

    n_fs2s = Node(Tkregister2(), name='freesurfer2struct')
    n_fs2s.inputs.reg_header = True
    n_fs2s.inputs.fsl_out = 'mat_freesurfer2struct.mat'
    n_fs2s.inputs.noedit = True

    n_s2fs = Node(ConvertXFM(), name='struct2freesurfer')
    n_s2fs.inputs.invert_xfm = True
    n_s2fs.inputs.out_file = 'mat_struct2freesurfer.mat'

    n_vol = Node(ApplyVolTransform(), name='vol2vol')
    n_vol.inputs.reg_header = True
    n_vol.inputs.transformed_file = 'brain.nii.gz'

    n_f2s = Node(FLIRT(), name='func2struct')
    n_f2s.inputs.cost = 'corratio'
    n_f2s.inputs.dof = 6
    n_f2s.inputs.no_search = True
    n_f2s.inputs.output_type = 'NIFTI_GZ'
    n_f2s.inputs.out_matrix_file = 'mat_func2struct.mat'

    n_s2f = Node(ConvertXFM(), name='struct2func')
    n_s2f.inputs.invert_xfm = True
    n_s2f.inputs.out_file = 'mat_struct2func.mat'

    n_f2fs = Node(ConvertXFM(), name='func2freesurfer')
    n_f2fs.inputs.concat_xfm = True
    n_f2fs.inputs.out_file = 'mat_func2freesurfer.mat'

    n_fs2f = Node(ConvertXFM(), name='freesurfer2func')
    n_fs2f.inputs.invert_xfm = True
    n_fs2f.inputs.out_file = 'mat_freesurfer2func.mat'

    w = Workflow('coreg_3T_fs')
    w.connect(n_in, 'subject', freesurfer, 'subject_id')
    w.connect(freesurfer, 'orig', n_fs2s, 'moving_image')
    w.connect(freesurfer, 'rawavg', n_fs2s, 'target_image')
    w.connect(freesurfer, 'brain', n_vol, 'source_file')
    w.connect(freesurfer, 'rawavg', n_vol, 'target_file')
    w.connect(n_in, 'mean', n_f2s, 'in_file')
    w.connect(n_vol, 'transformed_file', n_f2s, 'reference')
    w.connect(n_f2s, 'out_matrix_file', n_s2f, 'in_file')
    w.connect(n_fs2s, 'fsl_file', n_s2fs, 'in_file')
    w.connect(n_f2s, 'out_matrix_file', n_f2fs, 'in_file')
    w.connect(n_s2fs, 'out_file', n_f2fs, 'in_file2')
    w.connect(n_f2fs, 'out_file', n_fs2f, 'in_file')
    w.connect(n_f2s, 'out_matrix_file', n_out, 'func2struct')
    w.connect(n_s2f, 'out_file', n_out, 'struct2func')
    w.connect(n_fs2f, 'out_file', n_out, 'freesurfer2func')
    w.connect(n_f2fs, 'out_file', n_out, 'func2freesurfer')
    w.connect(freesurfer, 'brain', n_out, 'brain')

    return w
Beispiel #8
0
    print("Autorecon1")
    os.system("recon-all" + \
              " -i " + os.path.join(path_bias,"mn"+file) + \
              " -hires" + \
              " -autorecon1" + \
              " -noskullstrip" + \
              " -sd " + path + \
              " -s " + sub + \
              " -parallel")

    # skullstrip anatomy
    print("Skullstrip INV2")
    skullstrip_spm12(fileINV2, pathSPM12, path)

    # bring skullstrip_mask in conformed space (mri_vol2vol, NN)
    transmask = ApplyVolTransform()
    transmask.inputs.source_file = os.path.join(path_skull,
                                                "skullstrip_mask.nii")
    transmask.inputs.target_file = os.path.join(path, sub, "mri", "orig.mgz")
    transmask.inputs.reg_header = True
    transmask.inputs.interp = "nearest"
    transmask.inputs.transformed_file = os.path.join(path, sub, "mri",
                                                     "skullstrip_mask.nii")
    transmask.inputs.args = "--no-save-reg"
    transmask.run()

    # apply skullstrip mask to T1 and save as brainmask
    multiply_images(os.path.join(path, sub, "mri", "T1.mgz"),
                    os.path.join(path, sub, "mri", "skullstrip_mask.nii"),
                    os.path.join(path, sub, "mri", "brainmask.mgz"))
Beispiel #9
0
    gunzip(os.path.join(path_t1, "mask.nii.gz"))
elif os.path.splitext(file_mask)[1] == ".nii":
    sh.copyfile(file_mask, os.path.join(path_t1, "mask.nii"))
else:
    print("File extension of mask could not be identified!")

# binarise and overwrite mask
mask = nb.load(os.path.join(path_t1, "mask.nii"))
mask_array = mask.get_fdata()
mask_array[mask_array <= mask_threshold] = 0
mask_array[mask_array != 0] = 1
output = nb.Nifti1Image(mask_array, mask.affine, mask.header)
nb.save(output, os.path.join(path_t1, "mask.nii"))

# transform to mp2rage space via scanner coordinates
applyreg = ApplyVolTransform()
applyreg.inputs.source_file = os.path.join(path_t1, "mask.nii")
applyreg.inputs.target_file = os.path.join(path_t1, "T1.nii")
applyreg.inputs.transformed_file = os.path.join(path_t1, "mask.nii")
applyreg.inputs.reg_header = True
applyreg.inputs.interp = "nearest"
applyreg.run()
"""
convert orig to nifti
"""
mc = MRIConvert()
mc.inputs.in_file = os.path.join(path_orig, "orig.mgz")
mc.inputs.out_file = os.path.join(path_orig, "orig.nii")
mc.inputs.in_type = "mgz"
mc.inputs.out_type = "nii"
mc.run()
# Connect the base preprocessing nodes to a pipeline
preproc_ALPACA_base.connect([(gunzip, realign, [('out_file', 'in_file')]),
                 (realign, plotrot, [('par_file', 'in_file')]),
                 (realign, plottrans, [('par_file', 'in_file')]),
                 (realign, plotdisp,  [('rms_files', 'in_file')]),
                 (realign, bbregister, [('mean_img', 'source_file')]),
                 (realign, art, [('par_file', 'realignment_parameters'),
                                ('mean_img', 'mask_file')]),
                 (realign, art, [('out_file', 'realigned_files')]),
                 (realign, smooth, [('out_file', 'in_file')]),
                 ])

### MVPA preprocessing pipeline

# Transform node - apply volume transformation
applyVolReg = Node(ApplyVolTransform(fs_target = True, no_resample=True),
                   name='applyVolReg')

# Despike node - despike data
despike = Node(Despike(outputtype='NIFTI'),
               name='despike')

# TSNR node - remove polynomials 2nd order
tsnr = Node(TSNR(regress_poly=2),
            name='tsnr')

# Demean node - demean data
demean = Node(BinaryMaths(operation='sub'),
              name='demean')

# Standard deviation node - calculate standard deviation
                              use_differences=[True, False]),
                name="art")

# Gunzip - unzip functional
gunzip = MapNode(Gunzip(), name="gunzip", iterfield=['in_file'])

# Smooth - to smooth the images with a given kernel
smooth = Node(Smooth(fwhm=fwhm_size),
              name="smooth")

# FreeSurferSource - Data grabber specific for FreeSurfer data
fssource = Node(FreeSurferSource(subjects_dir=fs_dir),
                run_without_submitting=True,
                name='fssource')

# BBRegister - coregister a volume to the Freesurfer anatomical
bbregister = Node(BBRegister(init='header',
                             contrast_type='t2',
                             out_fsl_file=True),
                  name='bbregister')

# Volume Transformation - transform the brainmask into functional space
applyVolTrans = Node(ApplyVolTransform(inverse=True),
                     name='applyVolTrans')

# Binarize -  binarize and dilate an image to create a brainmask
binarize = Node(Binarize(min=0.5,
                         dilate=1,
                         out_type='nii'),
                name='binarize')