import nipype.interfaces.io as io #Wraps command **bet** my_fsl_BET = pe.Node(interface=fsl.BET(), name='my_fsl_BET', iterfield=['']) #Generic datagrabber module that wraps around glob in an my_io_S3DataGrabber = pe.Node(io.S3DataGrabber(outfields=["out_file, func"]), name='my_io_S3DataGrabber') #Generic datasink module to store structured outputs my_io_DataSink = pe.Node(interface=io.DataSink(), name='my_io_DataSink', iterfield=['']) #Wraps command **epi_reg** my_fsl_EpiReg = pe.Node(interface=fsl.EpiReg(), name='my_fsl_EpiReg', iterfield=['']) #Create a workflow to connect all those nodes analysisflow = nipype.Workflow('MyWorkflow') analysisflow.connect(my_io_S3DataGrabber, "out_file", my_fsl_BET, "in_file") analysisflow.connect(my_fsl_BET, "out_file", my_fsl_EpiReg, "t1_brain") analysisflow.connect(my_io_S3DataGrabber, "out_file", my_fsl_EpiReg, "t1_head") analysisflow.connect(my_io_S3DataGrabber, "func", my_fsl_EpiReg, "epi") analysisflow.connect(my_fsl_EpiReg, "out_file", my_io_DataSink, "registered_epi") analysisflow.connect(my_fsl_EpiReg, "epi2str_mat", my_io_DataSink, "epi_to_struc") analysisflow.connect(my_fsl_EpiReg, "epi2str_inv", my_io_DataSink, "struc_to_epi")
my_io_S3DataGrabber.inputs.bucket = 'openneuro' my_io_S3DataGrabber.inputs.sort_filelist = True my_io_S3DataGrabber.inputs.template = 'sub-01/anat/sub-01_T1w.nii.gz' my_io_S3DataGrabber.inputs.anon = True my_io_S3DataGrabber.inputs.bucket_path = 'ds000101/ds000101_R2.0.0/uncompressed/' my_io_S3DataGrabber.inputs.local_directory = '/tmp' #Wraps command **bet** my_fsl_BET = pe.Node(interface = fsl.BET(), name='my_fsl_BET', iterfield = ['']) #Generic datasink module to store structured outputs my_io_DataSink = pe.Node(interface = io.DataSink(), name='my_io_DataSink', iterfield = ['']) my_io_DataSink.inputs.base_directory = '/tmp' #Wraps command **epi_reg** my_fsl_EpiReg = pe.Node(interface = fsl.EpiReg(), name='my_fsl_EpiReg', iterfield = ['']) #Generic datagrabber module that wraps around glob in an my_io_S3DataGrabber = pe.Node(io.S3DataGrabber(), name = 'my_io_S3DataGrabber') #Create a workflow to connect all those nodes analysisflow = nipype.Workflow('MyWorkflow') analysisflow.connect(my_io_S3DataGrabber, "anat", my_fsl_BET, "in_file") analysisflow.connect(my_io_S3DataGrabber, "anat", my_fsl_EpiReg, "epi") analysisflow.connect(my_fsl_EpiReg, "out_file", my_io_DataSink, "registered") #Run the workflow plugin = 'MultiProc' #adjust your desired plugin here plugin_args = {'n_procs': 1} #adjust to your number of cores analysisflow.write_graph(graph2use='flat', format='png', simple_form=False) analysisflow.run(plugin=plugin, plugin_args=plugin_args)
def get_fmri2standard_wf( tvols, subject_id, ACQ_PARAMS="/home/didac/LabScripts/fMRI_preprocess/acparams_hcp.txt"): """Estimates transformation from Gradiend Field Distortion-warped BOLD to T1 In general: BOLD is field-inhomogeneity corrected and corregistered into standard space (T1). To do so, the following steps are carried out: 1) Corregister SBref to SEgfmAP (fsl.FLIRT) 2) Realign BOLD to corrected SBref (fsl.MCFLIRT) 3) Field inhomogeneity correction estimation of SBref from SEfm_AP and SEfm_PA (fsl.TOPUP) 4) Apply field inhomogeneity correction to SBref (fsl.ApplyTOPUP) 5) Apply field inhomogeneity correction to BOLD (fsl.ApplyTOPUP) 6) Transform free-surfer brain mask (brain.mgz) to T1 space (freesurfer.ApplyVolTransform ;mri_vol2vol), then binarized (fsl.UnaryMaths) and the mask is extracted from T1 (fsl.BinaryMaths) 7) Corregister BOLD (field-inhomogeneity corrected) to Standard T1 (fsl.Epi2Reg) Parameters ---------- tvols: [t_initial, t_final] volumes included in the preprocess ACQ_params: Path to txt file containing MRI acquisition parameters; needs to be specified for topup correction Returns ------- Workflow with the transformation """ from nipype import Workflow, Node, interfaces from nipype.interfaces import fsl, utility, freesurfer print("defining workflow...") wf = Workflow(name=subject_id, base_dir='') #Setting INPUT node... print("defines input node...") node_input = Node(utility.IdentityInterface(fields=[ 'func_sbref_img', 'func_segfm_ap_img', 'func_segfm_pa_img', 'func_bold_ap_img', 'T1_img', 'T1_brain_freesurfer_mask' ]), name='input_node') print( "Averages the three repeated Spin-Echo images with same Phase Encoding (AP or PA) for Susceptibility Correction (unwarping)..." ) node_average_SEgfm = Node(fsl.maths.MeanImage(), name='Mean_SEgfm_AP') print("Corregister SB-ref to average SEgfm-AP") node_coregister_SBref2SEgfm = Node( fsl.FLIRT(dof=6 #translation and rotation only ), name='Corregister_SBref2SEgfm') print("Eliminates first volumes.") node_eliminate_first_scans = Node( fsl.ExtractROI( t_min=tvols[0], # first included volume t_size=tvols[1] - tvols[0], # number of volumes from the first to the last one ), name="eliminate_first_scans") print("Realigns fMRI BOLD volumes to SBref in SEgfm-AP space") node_realign_bold = Node( fsl.MCFLIRT( save_plots=True, # save transformation matrices ), name="realign_fmri2SBref") print("Concatenates AP and PA SEgfm volumes...") # AP AP AP PA PA PA node_merge_ap_pa_inputs = Node( utility.base.Merge(2 # number of inputs; it concatenates lists ), name='Merge_ap_pa_inputs') node_merge_SEgfm = Node( fsl.Merge(dimension='t' # ¿? ), name='Merge_SEgfm_AP_PA') print( "Estimates TopUp inhomogeneity correction from SEfm_AP and SEfm_PA...") node_topup_SEgfm = Node(fsl.TOPUP(encoding_file=ACQ_PARAMS, ), name='Topup_SEgfm_estimation') print("Applies warp from TOPUP to correct SBref...") node_apply_topup_to_SBref = Node( fsl.ApplyTOPUP( encoding_file=ACQ_PARAMS, method='jac', # jacobian modulation interp='spline', # interpolation method ), name="apply_topup_to_SBref") print("Applies warp from TOPUP to correct realigned BOLD...") node_apply_topup = Node( fsl.ApplyTOPUP( encoding_file=ACQ_PARAMS, method='jac', # jacobian modulation interp='spline', # interpolation method ), name="apply_topup") ## BRAIN MASK #Registration to T1. Epireg without fieldmaps combined (see https://www.fmrib.ox.ac.uk/primers/intro_primer/ExBox20/IntroBox20.html) # print ("Eliminates scalp from brain using T1 high res image"); # node_mask_T1=Node(fsl.BET( # frac=0.7 # umbral # ), # name="mask_T1"); print('Transform brain mask T1 from freesurfer space to T1 space') node_vol2vol_brain = Node( freesurfer.ApplyVolTransform( reg_header=True, # (--regheader) transformed_file='brainmask_warped.nii.gz' #source_file --mov (INPUT; freesurfer brain.mgz) #transformed_file --o (OUTPUT; ...brain.nii.gz) #target_file --targ (REFERENCE; ...T1w.nii.gz) ), name="vol2vol") print('Transform brain mask T1 to binary mask') node_bin_mask_brain = Node( fsl.UnaryMaths( # fslmaths T1_brain -bin T1_binarized mask operation='bin', # (-bin) #in_file (T1_brain) #out_file (T1_binarized_mask) ), name="binarize_mask") print('Extract brain mask from T1 using binary mask') node_extract_mask = Node( fsl. BinaryMaths( # fslmaths T1 -mul T1_binarized_mask T1_extracted_mask operation='mul' # (-mul) #in_file (T1) #out_file (T1_extracted_mask) #operand_file (T1_binarized_mask) ), name="extract_mask") ## print("Estimate and appply transformation from SBref to T1") node_epireg = Node( fsl.EpiReg( #t1_head=SUBJECT_FSTRUCT_DIC['anat_T1'], out_base='SEgfm2T1'), name="epi2reg") ''' EPI2REG ALREADY APPLIED print ("Apply epi2reg to SBRef.."); node_apply_epi2reg_SBref= Node(fsl.ApplyXFM( ), name="node_apply_epi2reg_SBref"); ''' print("Estimates inverse transform from epi2reg...") # quality control node_invert_epi2reg = Node(fsl.ConvertXFM(invert_xfm=True), name="invert_epi2reg") print("...") node_mask_fMRI = Node(fsl.BET(mask=True, ), name='mask_fMRI') #node_fmriMask.overwrite=True print("Setting OUTPUT node...") node_output = Node(interfaces.utility.IdentityInterface(fields=[ 'SBref2SEgfm_mat', 'realign_movpar_txt', 'realign_fmri_img', 'topup_movpar_txt', 'topup_field_coef_img', 'epi2str_mat', 'epi2str_img', 'fmri_mask_img', 'rfmri_unwarped_imgs', 'sb_ref_unwarped_img', ]), name='output_node') print("All nodes created; Starts creating connections") #Connects nodes wf.connect([ #inputs (node_input, node_average_SEgfm, [("func_segfm_ap_img", "in_file")]), (node_input, node_coregister_SBref2SEgfm, [("func_sbref_img", "in_file")]), (node_input, node_eliminate_first_scans, [("func_bold_ap_img", "in_file")]), (node_input, node_merge_ap_pa_inputs, [("func_segfm_ap_img", "in1"), ("func_segfm_pa_img", "in2")]), (node_merge_ap_pa_inputs, node_merge_SEgfm, [("out", "in_files")]), (node_input, node_epireg, [("T1_img", "t1_head")]), (node_input, node_vol2vol_brain, [("T1_brain_freesurfer_mask", "source_file")]), (node_input, node_vol2vol_brain, [("T1_img", "target_file")]), (node_input, node_extract_mask, [("T1_img", "in_file")]), #connections (node_eliminate_first_scans, node_realign_bold, [("roi_file", "in_file")]), (node_average_SEgfm, node_coregister_SBref2SEgfm, [("out_file", "reference")]), (node_coregister_SBref2SEgfm, node_realign_bold, [("out_file", "ref_file")]), #T1 brain mask transformations (change space / vol2vol, binarize and extract) (node_vol2vol_brain, node_bin_mask_brain, [("transformed_file", "in_file")]), (node_bin_mask_brain, node_extract_mask, [("out_file", "operand_file") ]), #(node_realign_bold, node_tsnr, [("out_file", "in_file")]), (node_merge_SEgfm, node_topup_SEgfm, [("merged_file", "in_file")]), (node_realign_bold, node_apply_topup, [("out_file", "in_files")]), (node_topup_SEgfm, node_apply_topup, [("out_fieldcoef", "in_topup_fieldcoef"), ("out_movpar", "in_topup_movpar")]), (node_topup_SEgfm, node_apply_topup_to_SBref, [("out_fieldcoef", "in_topup_fieldcoef"), ("out_movpar", "in_topup_movpar")]), (node_coregister_SBref2SEgfm, node_apply_topup_to_SBref, [("out_file", "in_files")]), #corregister to T1 (node_extract_mask, node_epireg, [("out_file", "t1_brain")]), (node_apply_topup_to_SBref, node_epireg, [("out_corrected", "epi")]), (node_epireg, node_invert_epi2reg, [("epi2str_mat", "in_file")]), (node_coregister_SBref2SEgfm, node_mask_fMRI, [("out_file", "in_file") ]), #yeld relevant data to output node (node_coregister_SBref2SEgfm, node_output, [("out_matrix_file", "SBref2SEgfm_mat")]), (node_realign_bold, node_output, [("par_file", "realign_movpar_txt"), ("out_file", "realign_fmri_img")]), (node_mask_fMRI, node_output, [("mask_file", "fmri_mask_img")]), (node_epireg, node_output, [("epi2str_mat", "epi2str_mat")]), (node_epireg, node_output, [("out_file", "epi2str_img")]), (node_topup_SEgfm, node_output, [("out_fieldcoef", "topup_field_coef_img"), ("out_corrected", "sb_ref_unwarped_img")]), (node_apply_topup, node_output, [("out_corrected", "rfmri_unwarped_imgs")]) ]) print("All connections created") return (wf)
def NORMPIPE(): #--- 1) Import modules from nipype.interfaces.ants import Registration, ApplyTransforms import nipype.pipeline.engine as pe import matplotlib import os from glob import glob from nilearn import plotting from nilearn import image from nipype.interfaces.utility import Function import nipype.interfaces.fsl.preprocess as fsl import nipype.interfaces.fsl as fslbase import nipype.interfaces.fsl.utils as fslu from nipype.interfaces.fsl import Info import nipype.interfaces.utility as util INITDIR = os.getcwd() #--- 2) Define input node template = Info.standard_image('MNI152_T1_2mm_brain.nii.gz') inputnode = pe.Node(interface=util.IdentityInterface(fields=['standard']), name='inputspec') inputnode.inputs.standard = template #--- 3) Get inputs and define node for registering EPI to structural. alsonorm = bool(input('Also normalise?\n')) epireg = pe.Node(interface=fslbase.EpiReg(), name='EPIREG') t1_brain = raw_input( 'Please drag in the brain-extracted structural volume\n') t1_head = raw_input( 'Please drag in the non-brain extracted structural volume\n') epi = raw_input('Please drag in the mean functional volume.\n') epireg.inputs.t1_brain = t1_brain.strip('\'"') epireg.inputs.t1_head = t1_head.strip('\'"') epireg.inputs.epi = epi.strip('\'"') NIFTIDIR = os.path.split(epireg.inputs.t1_brain)[0] #--- 4) Register the T1 to the MNI registerT12S = pe.Node(interface=fsl.FLIRT(), name='REGISTEREDT12MNI') registerT12S.inputs.dof = int(12) registerT12S.inputs.reference = template registerT12S.inputs.in_file = epireg.inputs.t1_brain #--- 5) Concatenate the two transformation matrices from 3 and 4. concatxfm = pe.Node(interface=fslbase.ConvertXFM(), name='CONCATMATRICES') concatxfm.inputs.concat_xfm = bool(1) #--- 6) Register the EPI to the standard, using the combined transformation matrix registerF2S = pe.Node(interface=fsl.ApplyXFM(), name='REGISTEREDF2MNI') registerF2S.inputs.reference = template registerF2S.inputs.in_file = epireg.inputs.epi #--- 7) Use ANTS to normalise the structural to the MNI antsregfast = pe.Node(Registration( args='--float', collapse_output_transforms=True, fixed_image=template, initial_moving_transform_com=True, output_inverse_warped_image=True, output_warped_image=True, sigma_units=['vox'] * 3, transforms=['Rigid', 'Affine', 'SyN'], terminal_output='file', winsorize_lower_quantile=0.005, winsorize_upper_quantile=0.995, convergence_threshold=[1e-08, 1e-08, -0.01], convergence_window_size=[20, 20, 5], metric=['Mattes', 'Mattes', ['Mattes', 'CC']], metric_weight=[1.0, 1.0, [0.5, 0.5]], number_of_iterations=[[10000, 11110, 11110], [10000, 11110, 11110], [100, 30, 20]], radius_or_number_of_bins=[32, 32, [32, 4]], sampling_percentage=[0.3, 0.3, [None, None]], sampling_strategy=['Regular', 'Regular', [None, None]], shrink_factors=[[3, 2, 1], [3, 2, 1], [4, 2, 1]], smoothing_sigmas=[[4.0, 2.0, 1.0], [4.0, 2.0, 1.0], [1.0, 0.5, 0.0]], transform_parameters=[(0.1, ), (0.1, ), (0.2, 3.0, 0.0)], use_estimate_learning_rate_once=[True] * 3, use_histogram_matching=[False, False, True], write_composite_transform=True), name='NORMSTRUCT') #--- 8) Apply the same warping to the EPI apply2mean = pe.Node(ApplyTransforms(args='--float', input_image_type=3, interpolation='Linear', invert_transform_flags=[False], num_threads=1, reference_image=template, terminal_output='file'), name='NORMFUNC') #--- 9) Also need an outputnode, since otherwise some outputs may be binned. outputnode = pe.Node(interface=util.IdentityInterface(fields=[ 'warped', 'structmat', 'funcmat', 'epimat', 'funcreg', 'structreg' ]), name='outputnode') #--- 10) Custom plotting functions. def bplot(in_file, MNI): from nilearn import image from nilearn import plotting import matplotlib niftifiledim = len(image.load_img(in_file).shape) display = plotting.plot_anat(template) display.add_edges(in_file) matplotlib.pyplot.show() return niftifiledim def bplotN(in_file, MNI): from nilearn import image from nilearn import plotting import matplotlib niftifiledim = len(image.load_img(in_file).shape) display = plotting.plot_anat(MNI) display.add_edges(in_file) matplotlib.pyplot.show() return niftifiledim showregL = pe.Node(Function(input_names=['in_file', 'MNI'], output_names=['niftifiledim'], function=bplot), name='SHOWREG') showregNL = pe.Node(Function(input_names=['in_file', 'MNI'], output_names=['niftifiledim'], function=bplotN), name='SHOWREG') #--- 11) Setup workflow workflow = pe.Workflow(name='NORMPIPE') workflow.base_dir = NIFTIDIR #--- 12) Connect nodes, depending on whether we want to do normalisation too. if alsonorm == bool(0): workflow.connect(epireg, 'epi2str_mat', outputnode, 'epimat') workflow.connect(epireg, 'epi2str_mat', concatxfm, 'in_file') workflow.connect(registerT12S, 'out_matrix_file', concatxfm, 'in_file2') workflow.connect(concatxfm, 'out_file', registerF2S, 'in_matrix_file') workflow.connect(registerT12S, 'out_matrix_file', outputnode, 'structmat') workflow.connect(registerF2S, 'out_matrix_file', outputnode, 'funcmat') workflow.connect(registerF2S, 'out_file', outputnode, 'funcreg') workflow.connect(registerT12S, 'out_file', outputnode, 'structreg') workflow.connect(registerT12S, 'out_file', showregL, 'in_file') workflow.connect(inputnode, 'standard', showregL, 'MNI') workflow.write_graph(graph2use='exec') workflow.run() elif alsonorm == bool(1): workflow.connect(epireg, 'epi2str_mat', outputnode, 'epimat') workflow.connect(epireg, 'epi2str_mat', concatxfm, 'in_file') workflow.connect(registerT12S, 'out_matrix_file', concatxfm, 'in_file2') workflow.connect(concatxfm, 'out_file', registerF2S, 'in_matrix_file') workflow.connect(registerT12S, 'out_matrix_file', outputnode, 'structmat') workflow.connect(registerF2S, 'out_matrix_file', outputnode, 'funcmat') workflow.connect(registerF2S, 'out_file', outputnode, 'funcreg') workflow.connect(registerT12S, 'out_file', outputnode, 'structreg') workflow.connect(registerF2S, 'out_file', apply2mean, 'input_image') workflow.connect(registerT12S, 'out_file', antsregfast, 'moving_image') workflow.connect(antsregfast, 'warped_image', outputnode, 'warped') workflow.connect([(antsregfast, apply2mean, [('composite_transform', 'transforms')])]) workflow.connect(antsregfast, 'warped_image', showregNL, 'in_file') workflow.connect(inputnode, 'standard', showregNL, 'MNI') workflow.write_graph(graph2use='exec') workflow.run() print "Node completed. Returning to intital directory\n" os.chdir(INITDIR)