Ejemplo n.º 1
0
def create_tbss_4_prestats(name='tbss_4_prestats'):
    """Post-registration processing:Creating skeleton mask using a threshold
     projecting all FA data onto skeleton.
    A pipeline that does the same as tbss_4_prestats script from FSL

    Example
    -------

    >>> from nipype.workflows.dmri.fsl import tbss
    >>> tbss4 = tbss.create_tbss_4_prestats(name='tbss4')
    >>> tbss4.inputs.inputnode.skeleton_thresh = 0.2

    Inputs::

        inputnode.skeleton_thresh
        inputnode.groupmask
        inputnode.skeleton_file
        inputnode.meanfa_file
        inputnode.mergefa_file

    Outputs::

        outputnode.all_FA_skeletonised
        outputnode.mean_FA_skeleton_mask
        outputnode.distance_map
        outputnode.skeleton_file

    """
    # Create inputnode
    inputnode = pe.Node(interface=util.IdentityInterface(fields=[
        'groupmask', 'skeleton_file', 'meanfa_file', 'mergefa_file',
        'skeleton_thresh'
    ]),
                        name='inputnode')

    # Mask the skeleton at the threshold
    skeletonmask = pe.Node(fsl.ImageMaths(suffix="_mask"), name="skeletonmask")

    # Invert the brainmask then add in the tract skeleton
    invertmask = pe.Node(fsl.ImageMaths(suffix="_inv",
                                        op_string="-mul -1 -add 1 -add"),
                         name="invertmask")

    # Generate a distance map with the tract skeleton
    distancemap = pe.Node(fsl.DistanceMap(), name="distancemap")

    # Project the FA values onto the skeleton
    projectfa = pe.Node(fsl.TractSkeleton(project_data=True,
                                          skeleton_file=True,
                                          use_cingulum_mask=True),
                        name="projectfa")

    # Create tbss4 workflow
    tbss4 = pe.Workflow(name=name)
    tbss4.connect([
        (inputnode, invertmask, [("groupmask", "in_file")]),
        (inputnode, skeletonmask, [("skeleton_file", "in_file"),
                                   (('skeleton_thresh', tbss4_op_string),
                                    'op_string')]),
        (inputnode, projectfa, [('skeleton_thresh', 'threshold'),
                                ("meanfa_file", "in_file"),
                                ("mergefa_file", "data_file")]),
        (skeletonmask, invertmask, [("out_file", "in_file2")]),
        (invertmask, distancemap, [("out_file", "in_file")]),
        (distancemap, projectfa, [("distance_map", "distance_map")]),
    ])

    # Create the outputnode
    outputnode = pe.Node(interface=util.IdentityInterface(fields=[
        'projectedfa_file', 'skeleton_mask', 'distance_map', 'skeleton_file'
    ]),
                         name='outputnode')

    tbss4.connect([
        (projectfa, outputnode, [('projected_data', 'projectedfa_file'),
                                 ('skeleton_file', 'skeleton_file')]),
        (distancemap, outputnode, [('distance_map', 'distance_map')]),
        (skeletonmask, outputnode, [('out_file', 'skeleton_mask')])
    ])

    return tbss4
Ejemplo n.º 2
0
def create_cross_sectional_tbss_pipeline(in_files,
                                         output_dir,
                                         name='cross_sectional_tbss',
                                         skeleton_threshold=0.2,
                                         design_mat=None,
                                         design_con=None):
    workflow = pe.Workflow(name=name)
    workflow.base_dir = output_dir
    workflow.base_output_dir = name

    # Create the dtitk groupwise registration workflow
    groupwise_dtitk = create_dtitk_groupwise_workflow(in_files=in_files,
                                                      name="dtitk_groupwise",
                                                      rig_iteration=3,
                                                      aff_iteration=3,
                                                      nrr_iteration=6)

    # Create the average FA map
    mean_fa = pe.Node(interface=dtitk.TVtool(), name="mean_fa")
    workflow.connect(groupwise_dtitk, 'output_node.out_template', mean_fa,
                     'in_file')
    mean_fa.inputs.operation = 'fa'

    # Register the FMRIB58_FA_1mm.nii.gz atlas to the mean FA map
    reg_atlas = pe.Node(interface=niftyreg.RegAladin(), name='reg_atlas')
    workflow.connect(mean_fa, 'out_file', reg_atlas, 'ref_file')
    reg_atlas.inputs.flo_file = os.path.join(os.environ['FSLDIR'], 'data',
                                             'standard',
                                             'FMRIB58_FA_1mm.nii.gz')

    # Apply the transformation to the lower cingulum image
    war_atlas = pe.Node(interface=niftyreg.RegResample(), name='war_atlas')
    workflow.connect(mean_fa, 'out_file', war_atlas, 'ref_file')
    war_atlas.inputs.flo_file = os.path.join(os.environ['FSLDIR'], 'data',
                                             'standard',
                                             'LowerCingulum_1mm.nii.gz')
    workflow.connect(reg_atlas, 'aff_file', war_atlas, 'trans_file')
    war_atlas.inputs.inter_val = 'LIN'

    # Threshold the propagated lower cingulum
    thr_atlas = pe.Node(interface=niftyseg.BinaryMaths(), name='thr_atlas')
    workflow.connect(war_atlas, 'out_file', thr_atlas, 'in_file')
    thr_atlas.inputs.operation = 'thr'
    thr_atlas.inputs.operand_value = 0.5

    # Binarise the propagated lower cingulum
    bin_atlas = pe.Node(interface=niftyseg.UnaryMaths(), name='bin_atlas')
    workflow.connect(thr_atlas, 'out_file', bin_atlas, 'in_file')
    bin_atlas.inputs.operation = 'bin'

    # Create all the individual FA maps
    individual_fa = pe.MapNode(interface=dtitk.TVtool(),
                               name="individual_fa",
                               iterfield=['in_file'])
    workflow.connect(groupwise_dtitk, 'output_node.out_res', individual_fa,
                     'in_file')
    individual_fa.inputs.operation = 'fa'

    # Create all the individual MD maps
    individual_md = pe.MapNode(interface=dtitk.TVtool(),
                               name="individual_md",
                               iterfield=['in_file'])
    workflow.connect(groupwise_dtitk, 'output_node.out_res', individual_md,
                     'in_file')
    individual_md.inputs.operation = 'tr'

    # Create all the individual RD maps
    individual_rd = pe.MapNode(interface=dtitk.TVtool(),
                               name="individual_rd",
                               iterfield=['in_file'])
    workflow.connect(groupwise_dtitk, 'output_node.out_res', individual_rd,
                     'in_file')
    individual_rd.inputs.operation = 'rd'

    # Create all the individual RD maps
    individual_ad = pe.MapNode(interface=dtitk.TVtool(),
                               name="individual_ad",
                               iterfield=['in_file'])
    workflow.connect(groupwise_dtitk, 'output_node.out_res', individual_ad,
                     'in_file')
    individual_ad.inputs.operation = 'ad'

    # Combine all the warped FA images into a 4D image
    merged_4d_fa = pe.Node(interface=fsl.Merge(), name='merged_4d_fa')
    merged_4d_fa.inputs.dimension = 't'
    workflow.connect(individual_fa, 'out_file', merged_4d_fa, 'in_files')

    # Combine all the warped MD images into a 4D image
    merged_4d_md = pe.Node(interface=fsl.Merge(), name='merged_4d_md')
    merged_4d_md.inputs.dimension = 't'
    workflow.connect(individual_md, 'out_file', merged_4d_md, 'in_files')

    # Combine all the warped RD images into a 4D image
    merged_4d_rd = pe.Node(interface=fsl.Merge(), name='merged_4d_rd')
    merged_4d_rd.inputs.dimension = 't'
    workflow.connect(individual_rd, 'out_file', merged_4d_rd, 'in_files')

    # Combine all the warped AD images into a 4D image
    merged_4d_ad = pe.Node(interface=fsl.Merge(), name='merged_4d_ad')
    merged_4d_ad.inputs.dimension = 't'
    workflow.connect(individual_ad, 'out_file', merged_4d_ad, 'in_files')

    # Threshold the 4D FA image to 0
    merged_4d_fa_thresholded = pe.Node(interface=niftyseg.BinaryMaths(),
                                       name='merged_4d_fa_thresholded')
    merged_4d_fa_thresholded.inputs.operation = 'thr'
    merged_4d_fa_thresholded.inputs.operand_value = 0
    workflow.connect(merged_4d_fa, 'merged_file', merged_4d_fa_thresholded,
                     'in_file')

    # Extract the min value from the 4D FA image
    minimal_value_across_all_fa = pe.Node(interface=niftyseg.UnaryMaths(),
                                          name='minimal_value_across_all_fa')
    minimal_value_across_all_fa.inputs.operation = 'tmin'
    workflow.connect(merged_4d_fa_thresholded, 'out_file',
                     minimal_value_across_all_fa, 'in_file')

    # Create the mask image
    fa_mask = pe.Node(interface=niftyseg.UnaryMaths(), name='fa_mask')
    fa_mask.inputs.operation = 'bin'
    fa_mask.inputs.output_datatype = 'char'
    workflow.connect(minimal_value_across_all_fa, 'out_file', fa_mask,
                     'in_file')

    # Mask the mean FA image
    masked_mean_fa = pe.Node(interface=fsl.ApplyMask(), name='masked_mean_fa')
    workflow.connect(mean_fa, 'out_file', masked_mean_fa, 'in_file')
    workflow.connect(fa_mask, 'out_file', masked_mean_fa, 'mask_file')

    # Create the skeleton image
    skeleton = pe.Node(interface=fsl.TractSkeleton(), name='skeleton')
    skeleton.inputs.skeleton_file = True
    workflow.connect(masked_mean_fa, 'out_file', skeleton, 'in_file')

    # Threshold the skeleton image
    thresholded_skeleton = pe.Node(interface=niftyseg.BinaryMaths(),
                                   name='thresholded_skeleton')
    thresholded_skeleton.inputs.operation = 'thr'
    thresholded_skeleton.inputs.operand_value = skeleton_threshold
    workflow.connect(skeleton, 'skeleton_file', thresholded_skeleton,
                     'in_file')

    # Binarise the skeleton image
    binarised_skeleton = pe.Node(interface=niftyseg.UnaryMaths(),
                                 name='binarised_skeleton')
    binarised_skeleton.inputs.operation = 'bin'
    workflow.connect(thresholded_skeleton, 'out_file', binarised_skeleton,
                     'in_file')

    # Create skeleton distance map
    invert_mask1 = pe.Node(interface=niftyseg.BinaryMaths(),
                           name='invert_mask1')
    invert_mask1.inputs.operation = 'mul'
    invert_mask1.inputs.operand_value = -1
    workflow.connect(fa_mask, 'out_file', invert_mask1, 'in_file')
    invert_mask2 = pe.Node(interface=niftyseg.BinaryMaths(),
                           name='invert_mask2')
    invert_mask2.inputs.operation = 'add'
    invert_mask2.inputs.operand_value = 1
    workflow.connect(invert_mask1, 'out_file', invert_mask2, 'in_file')
    invert_mask3 = pe.Node(interface=niftyseg.BinaryMaths(),
                           name='invert_mask3')
    invert_mask3.inputs.operation = 'add'
    workflow.connect(invert_mask2, 'out_file', invert_mask3, 'in_file')
    workflow.connect(binarised_skeleton, 'out_file', invert_mask3,
                     'operand_file')
    distance_map = pe.Node(interface=fsl.DistanceMap(), name='distance_map')
    workflow.connect(invert_mask3, 'out_file', distance_map, 'in_file')

    # Project the FA values onto the skeleton
    all_fa_projected = pe.Node(interface=fsl.TractSkeleton(),
                               name='all_fa_projected')
    all_fa_projected.inputs.threshold = skeleton_threshold
    all_fa_projected.inputs.project_data = True
    workflow.connect(masked_mean_fa, 'out_file', all_fa_projected, 'in_file')
    workflow.connect(distance_map, 'distance_map', all_fa_projected,
                     'distance_map')
    workflow.connect(merged_4d_fa, 'merged_file', all_fa_projected,
                     'data_file')
    workflow.connect(bin_atlas, 'out_file', all_fa_projected,
                     'search_mask_file')

    # Project the MD values onto the skeleton
    all_md_projected = pe.Node(interface=fsl.TractSkeleton(),
                               name='all_md_projected')
    all_md_projected.inputs.threshold = skeleton_threshold
    all_md_projected.inputs.project_data = True
    workflow.connect(masked_mean_fa, 'out_file', all_md_projected, 'in_file')
    workflow.connect(distance_map, 'distance_map', all_md_projected,
                     'distance_map')
    workflow.connect(merged_4d_fa, 'merged_file', all_md_projected,
                     'data_file')
    workflow.connect(merged_4d_md, 'merged_file', all_md_projected,
                     'alt_data_file')
    workflow.connect(bin_atlas, 'out_file', all_md_projected,
                     'search_mask_file')

    # Project the RD values onto the skeleton
    all_rd_projected = pe.Node(interface=fsl.TractSkeleton(),
                               name='all_rd_projected')
    all_rd_projected.inputs.threshold = skeleton_threshold
    all_rd_projected.inputs.project_data = True
    workflow.connect(masked_mean_fa, 'out_file', all_rd_projected, 'in_file')
    workflow.connect(distance_map, 'distance_map', all_rd_projected,
                     'distance_map')
    workflow.connect(merged_4d_fa, 'merged_file', all_rd_projected,
                     'data_file')
    workflow.connect(merged_4d_rd, 'merged_file', all_rd_projected,
                     'alt_data_file')
    workflow.connect(bin_atlas, 'out_file', all_rd_projected,
                     'search_mask_file')

    # Project the RD values onto the skeleton
    all_ad_projected = pe.Node(interface=fsl.TractSkeleton(),
                               name='all_ad_projected')
    all_ad_projected.inputs.threshold = skeleton_threshold
    all_ad_projected.inputs.project_data = True
    workflow.connect(masked_mean_fa, 'out_file', all_ad_projected, 'in_file')
    workflow.connect(distance_map, 'distance_map', all_ad_projected,
                     'distance_map')
    workflow.connect(merged_4d_fa, 'merged_file', all_ad_projected,
                     'data_file')
    workflow.connect(merged_4d_ad, 'merged_file', all_ad_projected,
                     'alt_data_file')
    workflow.connect(bin_atlas, 'out_file', all_ad_projected,
                     'search_mask_file')

    # Create an output node
    output_node = pe.Node(interface=niu.IdentityInterface(fields=[
        'mean_fa', 'all_fa_skeletonised', 'all_md_skeletonised',
        'all_rd_skeletonised', 'all_ad_skeletonised', 'skeleton',
        'skeleton_bin', 't_contrast_raw_stat', 't_contrast_uncorrected_pvalue',
        't_contrast_corrected_pvalue'
    ]),
                          name='output_node')

    # Connect the workflow to the output node
    workflow.connect(masked_mean_fa, 'out_file', output_node, 'mean_fa')
    workflow.connect(all_fa_projected, 'projected_data', output_node,
                     'all_fa_skeletonised')
    workflow.connect(all_md_projected, 'projected_data', output_node,
                     'all_md_skeletonised')
    workflow.connect(all_rd_projected, 'projected_data', output_node,
                     'all_rd_skeletonised')
    workflow.connect(all_ad_projected, 'projected_data', output_node,
                     'all_ad_skeletonised')
    workflow.connect(skeleton, 'skeleton_file', output_node, 'skeleton')
    workflow.connect(binarised_skeleton, 'out_file', output_node,
                     'skeleton_bin')

    # Run randomise if required and connect its output to the output node
    if design_mat is not None and design_con is not None:
        randomise = pe.Node(interface=fsl.Randomise(), name='randomise')
        randomise.inputs.base_name = 'stats_tbss'
        randomise.inputs.tfce2D = True
        randomise.inputs.num_perm = 5000
        workflow.connect(all_fa_projected, 'projected_data', randomise,
                         'in_file')
        randomise.inputs.design_mat = design_mat
        randomise.inputs.design_con = design_con
        workflow.connect(binarised_skeleton, 'out_file', randomise, 'mask')

        workflow.connect(randomise, 'tstat_files', output_node,
                         't_contrast_raw_stat')
        workflow.connect(randomise, 't_p_files', output_node,
                         't_contrast_uncorrected_pvalue')
        workflow.connect(randomise, 't_corrected_p_files', output_node,
                         't_contrast_corrected_pvalue')

    # Create nodes to rename the outputs
    mean_fa_renamer = pe.Node(interface=niu.Rename(
        format_string='tbss_mean_fa', keep_ext=True),
                              name='mean_fa_renamer')
    workflow.connect(output_node, 'mean_fa', mean_fa_renamer, 'in_file')

    mean_sk_renamer = pe.Node(interface=niu.Rename(
        format_string='tbss_mean_fa_skeleton', keep_ext=True),
                              name='mean_sk_renamer')
    workflow.connect(output_node, 'skeleton', mean_sk_renamer, 'in_file')

    bin_ske_renamer = pe.Node(interface=niu.Rename(
        format_string='tbss_mean_fa_skeleton_mask', keep_ext=True),
                              name='bin_ske_renamer')
    workflow.connect(output_node, 'skeleton_bin', bin_ske_renamer, 'in_file')

    fa_skel_renamer = pe.Node(interface=niu.Rename(
        format_string='tbss_all_fa_skeletonised', keep_ext=True),
                              name='fa_skel_renamer')
    workflow.connect(output_node, 'all_fa_skeletonised', fa_skel_renamer,
                     'in_file')
    md_skel_renamer = pe.Node(interface=niu.Rename(
        format_string='tbss_all_md_skeletonised', keep_ext=True),
                              name='md_skel_renamer')
    workflow.connect(output_node, 'all_md_skeletonised', md_skel_renamer,
                     'in_file')
    rd_skel_renamer = pe.Node(interface=niu.Rename(
        format_string='tbss_all_rd_skeletonised', keep_ext=True),
                              name='rd_skel_renamer')
    workflow.connect(output_node, 'all_rd_skeletonised', rd_skel_renamer,
                     'in_file')
    ad_skel_renamer = pe.Node(interface=niu.Rename(
        format_string='tbss_all_ad_skeletonised', keep_ext=True),
                              name='ad_skel_renamer')
    workflow.connect(output_node, 'all_ad_skeletonised', ad_skel_renamer,
                     'in_file')

    # Create a data sink
    ds = pe.Node(nio.DataSink(parameterization=False), name='data_sink')
    ds.inputs.base_directory = os.path.abspath(output_dir)

    # Connect the data sink
    workflow.connect(mean_fa_renamer, 'out_file', ds, '@mean_fa')
    workflow.connect(mean_sk_renamer, 'out_file', ds, '@skel_fa')
    workflow.connect(bin_ske_renamer, 'out_file', ds, '@bkel_fa')
    workflow.connect(fa_skel_renamer, 'out_file', ds, '@all_fa')
    workflow.connect(md_skel_renamer, 'out_file', ds, '@all_md')
    workflow.connect(rd_skel_renamer, 'out_file', ds, '@all_rd')
    workflow.connect(ad_skel_renamer, 'out_file', ds, '@all_ad')

    if design_mat is not None and design_con is not None:
        workflow.connect(output_node, 't_contrast_raw_stat', ds,
                         '@t_contrast_raw_stat')
        workflow.connect(output_node, 't_contrast_uncorrected_pvalue', ds,
                         '@t_contrast_uncorrected_pvalue')
        workflow.connect(output_node, 't_contrast_corrected_pvalue', ds,
                         '@t_contrast_corrected_pvalue')

    return workflow
Ejemplo n.º 3
0
 def tbss4d(self, tbss_dir, oDir, template, **kwargs):
     """
     python function to generate 4d nii files for randomise from TBSS.
     
     Required arguments:
         tbss_dir --- where the 'FA' and 'stats' folder exists.  This by default on knicr servers is here:
         /Volumes/rbraid/mr_data_idc/aug2013_final/dti/tbss
     
         oDir --- this is where you want the 4d files to go. This should be specific to the analysis you are doing
         e.g., /home/tonya/my_data/tbss/dysregulation_analysis/
     
 
     Default is to assume scalars FA, MD, RD, AD are all processed.
     Also assumes the subject files are named as such:
     
         idc_#_SCALAR_to_FMRIB58_FA_2mm_nonlinear.nii.gz
         
     
     Optional Arguments:
         
         tbss_pfix --- default is "idc_"
         This is what goes before the subject id
         String type
         
         tbss_sfix --- default is "_to_FMRIB58_FA_2mm_nonlin.nii.gz"
         This is what goes after the subject id and scalar name (eg FA, MD)
         String type
         
         Scalars --- List of Scalars 
         default is: [FA, MD, RD, AD] 
         List type
         
         opfix --- prefix for the 4d output file. suffix will be the scalar type.
         default is tbss_all_
         string type.
         
         
     """
     tbss_pfix = 'idc_'
     tbss_sfix = '_to_FMRIB58_FA_2mm_nonlin.nii.gz'
     scalars = ['FA', 'MD', 'RD', 'AD']
     opfix = 'tbss_all_'
     threshold = 0.2
     for i in kwargs.keys():
         if i == 'tbss_pfix':
             tbss_pfix = kwargs[i]
         elif i == 'tbss_sfix':
             tbss_sfix = kwargs[i]
         elif i == 'opfix':
             opfix = kwargs[i]
         elif i == 'scalars':
             scalars = kwargs[i]
             if not type(scalars) is list:
                 print 'ERROR....scalar option must be a LIST!'
                 print 'Resetting scalars to be FA only...'
                 scalars = ['FA']
         elif i == 'threshold':
             threshold = kwarg[i]
     for scalar in scalars:
         print 'writing out 4d file for component: ', scalar
         fourDlist = []
         for s in range(0, self.subj_list.shape[0]):
             subj = str(int(self.subj_list[s][0]))
             tbss_file = os.path.join(
                 tbss_dir, 'FA',
                 tbss_pfix + subj + '_' + scalar + tbss_sfix)
             if not os.path.exists(tbss_file):
                 print 'CANNOT FIND tbss data for :', subj, scalar
                 print 'Looked here: ', tbss_file
                 print 'Cannot continue...must exit...'
                 sys.exit(0)
             fourDlist.append(tbss_file)
         #merge the file
         logFile = os.path.join(oDir, 'tbss_nonFA.log')
         merged4d = os.path.join(oDir, opfix + scalar + '.nii.gz')
         if not os.path.exists(merged4d):
             fslmerge = fsl.Merge(dimension='t',
                                  terminal_output='stream',
                                  in_files=fourDlist,
                                  merged_file=merged4d,
                                  output_type='NIFTI_GZ')
             fslmerge.run()
             write_log(fslmerge.cmdline, logFile)
             subjinfo = merged4d.replace('.nii.gz', '_mergeInfo.csv')
             write_txt(fourDlist, subjinfo)
         if scalar.endswith('_FA'):
             #next we make the mean FA image
             op_str = '-max 0 -Tmin -bin'
             fslmaths = fsl.ImageMaths(in_file=merged4d,
                                       op_string=op_str,
                                       out_file=os.path.join(
                                           oDir, 'mean_FA_mask.nii.gz'),
                                       output_type='NIFTI_GZ',
                                       out_data_type='char')
             fslmaths.run()
             write_log(fslmaths.cmdline, logFile)
             op_str = '-mas ' + os.path.join(oDir, 'mean_FA_mask.nii.gz')
             fslmaths = fsl.ImageMaths(in_file=merged4d,
                                       op_string=op_str,
                                       out_file=merged4d.replace(
                                           '.nii.gz', '_masked.nii.gz'),
                                       output_type='NIFTI_GZ')
             fslmaths.run()
             write_log(fslmaths.cmdline, logFile)
             op_str = '-Tmean'
             fslmaths = fsl.ImageMaths(
                 in_file=merged4d.replace('.nii.gz', '_masked.nii.gz'),
                 op_string=op_str,
                 out_file=os.path.join(oDir, 'mean_FA.nii.gz'),
                 output_type='NIFTI_GZ')
             fslmaths.run()
             write_log(fslmaths.cmdline, logFile)
             #now make the initial skeleton
             tbss_skeleton = fsl.TractSkeleton(
                 in_file=os.path.join(oDir, 'mean_FA.nii.gz'),
                 skeleton_file=os.path.join(oDir,
                                            'mean_FA_skeleton.nii.gz'))
             tbss_skeleton.run()
             write_log(tbss_skeleton.cmdline, logFile)
             print 'Creating Skeleton Mask using threshold', str(threshold)
             op_str = '-thr ' + str(threshold) + ' -bin'
             fslmaths = fsl.ImageMaths(
                 in_file=os.path.join(oDir, 'mean_FA_skeleton.nii.gz'),
                 op_string=op_str,
                 out_file=os.path.join(oDir,
                                       'mean_FA_skeleton_mask.nii.gz'),
                 output_type='NIFTI_GZ')
             fslmaths.run()
             write_log(fslmaths.cmdline, logFile)
             print 'Creating skeleton distancemap (for use in projection search)'
             op_str = '-mul 1 -add 1 -add ' + os.path.join(
                 oDir, 'mean_FA_skeleton_mask.nii.gz')
             fslmaths = fsl.ImageMaths(
                 in_file=os.path.join(oDir, 'mean_FA_mask.nii.gz'),
                 op_string=op_str,
                 out_file=os.path.join(oDir,
                                       'mean_FA_skeleton_mask_dst.nii.gz'),
                 output_type='NIFTI_GZ')
             fslmaths.run()
             write_log(fslmaths.cmdline, logFile)
             distancemap = fsl.DistanceMap(
                 in_file=os.path.join(oDir,
                                      'mean_FA_skeleton_mask_dst.nii.gz'),
                 distance_map=os.path.join(
                     oDir, 'mean_FA_skeleton_mask_dst.nii.gz'))
             distancemap.run()
             write_log(distancemap.cmdline, logFile)
             #to make things easier below, make a generic-named copy of the 4d fa map. needed for skeletonization.
             shutil.copyfile(merged4d.replace('.nii.gz', '_masked.nii.gz'),
                             os.path.join(oDir, 'all_FA.nii.gz'))
         else:
             if not os.path.exists(os.path.join(oDir,
                                                'mean_FA_mask.nii.gz')):
                 print oDir, 'mean_FA_mask.nii.gz does not exist'
                 print 'Make sure FA is the first scalar in your list. Must exit'
                 sys.exit(0)
             #mask other scalars
             op_str = '-mas ' + os.path.join(oDir, 'mean_FA_mask.nii.gz')
             fslmaths = fsl.ImageMaths(in_file=merged4d,
                                       op_string=op_str,
                                       out_file=merged4d.replace(
                                           '.nii.gz', '_masked.nii.gz'),
                                       output_type='NIFTI_GZ')
             fslmaths.run()
             write_log(fslmaths.cmdline, logFile)
         #skeletenize
         nb_template = nb.load(template)
         x = abs(nb_template.get_affine()[0][0])
         y = abs(nb_template.get_affine()[1][1])
         z = abs(nb_template.get_affine()[2][2])
         cing_file1mm = os.path.join(os.environ['FSLDIR'], 'data',
                                     'standard', 'LowerCingulum_1mm.nii.gz')
         if x == 1 and y == 1 and z == 1:
             cing_file = cing_file1mm
         elif x == 2 and y == 2 and z == 2:
             cing_file = os.path.join(os.environ['FSLDIR'], 'data',
                                      'standard',
                                      'LowerCingulum_2mm.nii.gz')
             if not os.path.exists(cing_file):
                 cing_file = os.path.join(oDir, 'LowerCingulum_2mm.nii.gz')
                 flirt = fsl.FLIRT(in_file=cing_file1mm,
                                   reference=os.path.join(
                                       os.environ['FSLDIR'], 'data',
                                       'standard', 'MNI152_T1_2mm.nii.gz'),
                                   out_file=cing_file,
                                   args='-applyisoxfm 2')
                 flirt.run()
                 write_log(flirt.cmdline, logFile)
         else:
             cing_file = False
         if not cing_file:
             print 'Cannot find cingulum file.'
             return
         print 'Projecting all FA data onto Skeleton'
         #run the tbss skeletonize thing
         if not os.path.exists(os.path.join(oDir, 'mean_FA_mask.nii.gz')):
             print oDir, 'mean_FA_mask.nii.gz does not exist'
             print 'Make sure FA is the first scalar in your list. Must exit'
             sys.exit(0)
         final4d = merged4d.replace('.nii.gz', '_skeletonized.nii.gz')
         tbss_skeleton = fsl.TractSkeleton(
             threshold=threshold,
             distance_map=os.path.join(oDir,
                                       'mean_FA_skeleton_mask_dst.nii.gz'),
             alt_data_file=merged4d.replace('.nii.gz', '_masked.nii.gz'),
             data_file=os.path.join(oDir, 'all_FA.nii.gz'),
             projected_data=final4d,
             in_file=os.path.join(oDir, 'mean_FA.nii.gz'),
             project_data=True)
         tbss_skeleton.inputs.use_cingulum_mask = Undefined
         tbss_skeleton.inputs.search_mask_file = cing_file
         tbss_skeleton.run()
         write_log(tbss_skeleton.cmdline, logFile)
Ejemplo n.º 4
0
def prepare_template_wf(name="prepare_template"):
    wf = Workflow(name=name)

    inputnode = pe.Node(niu.IdentityInterface(
        fields=['tpl_t1w', 'tpl_t1w_brainmask', 'CSF_pve']),
                        name='inputnode')

    tpl_t1w_brain = pe.Node(fsl.ApplyMask(), name='tpl_t1w_brain')
    wf.connect(inputnode, "tpl_t1w", tpl_t1w_brain, "in_file")
    wf.connect(inputnode, "tpl_t1w_brainmask", tpl_t1w_brain, "mask_file")

    norm_wf = get_norm_wf()
    wf.connect(inputnode, 'tpl_t1w', norm_wf, "inputnode.t1w")
    wf.connect(tpl_t1w_brain, 'out_file', norm_wf, "inputnode.t1w_brain")

    MNI_2_t1w_warp = pe.Node(fsl.InvWarp(), name='MNI_2_t1w_warp')
    wf.connect(inputnode, 'tpl_t1w', MNI_2_t1w_warp, 'reference')
    wf.connect(norm_wf, 'outputnode.t1w_2_MNI_warp', MNI_2_t1w_warp, 'warp')

    bianca_mask = pe.Node(MakeBiancaMask(), name='bianca_mask')
    bianca_mask.inputs.keep_intermediate_files = 0

    wf.connect(inputnode, 'tpl_t1w', bianca_mask, 'structural_image')
    wf.connect(inputnode, 'CSF_pve', bianca_mask, 'CSF_pve')
    wf.connect(MNI_2_t1w_warp, 'inverse_warp', bianca_mask,
               'warp_file_MNI2structural')
    wf.connect(tpl_t1w_brain, 'out_file', bianca_mask,
               'structural_image_brainextracted')
    wf.connect(inputnode, 'tpl_t1w_brainmask', bianca_mask, 'brainmask')

    # distancemap
    # dilate for distancemap to avoid rim effects when resampling distancemap
    brainmask_dil = pe.Node(fsl.DilateImage(operation="max"),
                            name="brainmask_dil")
    wf.connect(inputnode, 'tpl_t1w_brainmask', brainmask_dil, "in_file")

    distancemap = pe.Node(fsl.DistanceMap(), name="distancemap")
    wf.connect(bianca_mask, 'vent_file', distancemap, "in_file")
    wf.connect(brainmask_dil, 'out_file', distancemap, "mask_file")

    perivent_mask_init = pe.Node(fsl.maths.MathsCommand(),
                                 name="perivent_mask_init")
    perivent_mask_init.inputs.args = "-uthr 10 -bin"
    wf.connect(distancemap, "distance_map", perivent_mask_init, "in_file")

    perivent_mask = pe.Node(fsl.ApplyMask(), name="perivent_mask")
    wf.connect(perivent_mask_init, "out_file", perivent_mask, "in_file")
    wf.connect(inputnode, "tpl_t1w_brainmask", perivent_mask, "mask_file")

    deepWM_mask_init = pe.Node(fsl.maths.MathsCommand(),
                               name="deepWM_mask_init")
    deepWM_mask_init.inputs.args = "-thr 10 -bin"
    wf.connect(distancemap, "distance_map", deepWM_mask_init, "in_file")

    deepWM_mask = pe.Node(fsl.ApplyMask(), name="deepWM_mask")
    wf.connect(deepWM_mask_init, "out_file", deepWM_mask, "in_file")
    wf.connect(inputnode, "tpl_t1w_brainmask", deepWM_mask, "mask_file")

    outputnode = pe.Node(niu.IdentityInterface(fields=[
        "t1w_2_MNI_mat", "t1w_MNIspace", "t1w_2_MNI_warp",
        "bianca_wm_mask_file", "vent_file", "distance_map", "perivent_mask",
        "deepWM_mask"
    ]),
                         name='outputnode')

    wf.connect(norm_wf, 'outputnode.t1w_2_MNI_mat', outputnode,
               "t1w_2_MNI_mat")
    wf.connect(norm_wf, 'outputnode.t1w_MNIspace', outputnode, "t1w_MNIspace")
    wf.connect(norm_wf, 'outputnode.t1w_2_MNI_warp', outputnode,
               "t1w_2_MNI_warp")
    wf.connect(bianca_mask, 'mask_file', outputnode, "bianca_wm_mask_file")
    wf.connect(bianca_mask, 'vent_file', outputnode, "vent_file")
    wf.connect(distancemap, "distance_map", outputnode, "distance_map")
    wf.connect(perivent_mask, "out_file", outputnode, "perivent_mask")
    wf.connect(deepWM_mask, "out_file", outputnode, "deepWM_mask")
    return wf