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
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
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"))
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')