def anatomical_preprocessing(): ''' Inputs: MP2RAGE Skull stripped image using Spectre-2010 Workflow: 1. reorient to RPI 2. create a brain mask Returns: brain brain_mask ''' # define workflow flow = Workflow('anat_preprocess') inputnode = Node(util.IdentityInterface( fields=['anat', 'anat_gm', 'anat_wm', 'anat_csf', 'anat_first']), name='inputnode') outputnode = Node(util.IdentityInterface(fields=[ 'brain', 'brain_gm', 'brain_wm', 'brain_csf', 'brain_first', 'brain_mask', ]), name='outputnode') reorient = Node(interface=preprocess.Resample(), name='anat_reorient') reorient.inputs.orientation = 'RPI' reorient.inputs.outputtype = 'NIFTI' erode = Node(interface=fsl.ErodeImage(), name='anat_preproc') reorient_gm = reorient.clone('anat_preproc_gm') reorient_wm = reorient.clone('anat_preproc_wm') reorient_cm = reorient.clone('anat_preproc_csf') reorient_first = reorient.clone('anat_preproc_first') make_mask = Node(interface=fsl.UnaryMaths(), name='anat_preproc_mask') make_mask.inputs.operation = 'bin' # connect workflow nodes flow.connect(inputnode, 'anat', reorient, 'in_file') flow.connect(inputnode, 'anat_gm', reorient_gm, 'in_file') flow.connect(inputnode, 'anat_wm', reorient_wm, 'in_file') flow.connect(inputnode, 'anat_csf', reorient_cm, 'in_file') flow.connect(inputnode, 'anat_first', reorient_first, 'in_file') flow.connect(reorient, 'out_file', erode, 'in_file') flow.connect(erode, 'out_file', make_mask, 'in_file') flow.connect(make_mask, 'out_file', outputnode, 'brain_mask') flow.connect(erode, 'out_file', outputnode, 'brain') flow.connect(reorient_gm, 'out_file', outputnode, 'brain_gm') flow.connect(reorient_wm, 'out_file', outputnode, 'brain_wm') flow.connect(reorient_cm, 'out_file', outputnode, 'brain_csf') flow.connect(reorient_first, 'out_file', outputnode, 'brain_first') return flow
def __init__(self, name, base_dir=None): super(BrainExtractionWorkflow, self).__init__(name, base_dir) # Segmentation # ============ seg_node = npe.MapNode(name="Segmentation", iterfield="data", interface=spm.Segment()) seg_node.inputs.gm_output_type = [False, False, True] seg_node.inputs.wm_output_type = [False, False, True] seg_node.inputs.csf_output_type = [False, False, True] add1_node = npe.MapNode(name="AddGMWM", iterfield=["in_file", "operand_file"], interface=fsl.BinaryMaths()) add1_node.inputs.operation = 'add' add2_node = npe.MapNode(name="AddGMWMCSF", iterfield=["in_file", "operand_file"], interface=fsl.BinaryMaths()) add2_node.inputs.operation = 'add' dil_node = npe.MapNode(name="Dilate", iterfield="in_file", interface=fsl.DilateImage()) dil_node.inputs.operation = 'mean' ero_node = npe.MapNode(name="Erode", iterfield="in_file", interface=fsl.ErodeImage()) thre_node = npe.MapNode(name="Threshold", iterfield="in_file", interface=fsl.Threshold()) thre_node.inputs.thresh = 0.5 fill_node = npe.MapNode(name="Fill", iterfield="in_file", interface=fsl.UnaryMaths()) fill_node.inputs.operation = 'fillh' mask_node = npe.MapNode(name="ApplyMask", iterfield=["in_file", "mask_file"], interface=fsl.ApplyMask()) mask_node.inputs.output_type = str("NIFTI") self.connect([ (seg_node, add1_node, [('native_gm_image', 'in_file')]), (seg_node, add1_node, [('native_wm_image', 'operand_file')]), (seg_node, add2_node, [('native_csf_image', 'in_file')]), (add1_node, add2_node, [('out_file', 'operand_file')]), (add2_node, dil_node, [('out_file', 'in_file')]), (dil_node, ero_node, [('out_file', 'in_file')]), (ero_node, thre_node, [('out_file', 'in_file')]), (thre_node, fill_node, [('out_file', 'in_file')]), (fill_node, mask_node, [('out_file', 'mask_file')]), ])
def extractWhitematter(input_image, wmoutline_image, output_image): thresHolder = fsl.MultiImageMaths(input_file=input_image, out_file=output_image) thresHolder.inputs.op_string = '-uthr 41 -thr 41' thresHolder.run() thresHolder.inputs.input_file = output_image thresHolder.inputs.op_string = '-uthr 2 -thr 2' thresHolder.run() thresHolder.inputs.op_string = '-uthr 255 -thr 251' thresHolder.run() # Combine and binarize combinizer = fsl.BinaryMaths(operation='add', in_file=output_image, operand_file=wmoutline_image, out_file=output_image) binarizer = fsl.UnaryMaths(operation='bin', in_file=output_image, out_file=output_image) return output_image
def fieldmap_to_phasediff(name=WORKFLOW_NAME, settings=None): """Legacy workflow to create a phasediff map from a fieldmap, to be digested by FUGUE""" workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface( fields=['fieldmap', 'fmap_mask', 'unwarp_direction', 'dwell_time']), name='inputnode') outputnode = pe.Node( niu.IdentityInterface(fields=['fmap_rads', 'fmap_unmasked']), name='outputnode') # Convert topup fieldmap to rad/s [ 1 Hz = 6.283 rad/s] fmap_scale = pe.Node(fsl.BinaryMaths(operation='mul', operand_value=6.283), name='fmap_scale') # Compute a mask from the fieldmap (??) fmap_abs = pe.Node(fsl.UnaryMaths(operation='abs', args='-bin'), name='fmap_abs') fmap_mul = pe.Node(fsl.BinaryMaths(operation='mul'), name='fmap_mul_mask') # Compute an smoothed field without mask fugue_unmask = pe.Node(fsl.FUGUE(save_unmasked_fmap=True), name='fmap_unmask') workflow.connect([ (inputnode, fmap_scale, [('fieldmap', 'in_file')]), (inputnode, fmap_mul, [('fmap_mask', 'operand_file')]), (inputnode, fugue_unmask, [('unwarp_direction', 'unwarp_direction'), ('dwell_time', 'dwell_time')]), (fmap_scale, fmap_abs, [('out_file', 'in_file')]), (fmap_abs, fmap_mul, [('out_file', 'in_file')]), (fmap_scale, fugue_unmask, [('out_file', 'fmap_in_file')]), (fmap_mul, fugue_unmask, [('out_file', 'mask_file')]), (fmap_scale, outputnode, [('out_file', 'fmap_rads')]), (fugue_unmask, outputnode, [('fmap_out_file', 'fmap_unmasked')]) ]) return workflow
prepare = pe.Node(interface=fsl.epi.PrepareFieldmap(),name='prepare') prepare.inputs.output_type = "NIFTI_GZ" prepare.inputs.delta_TE = 2.46 # Co-Register EPI and Correct field inhomogeniety distortions #epireg = pe.Node(interface=fsl.epi.EpiReg(), name='epireg') #epireg.inputs.echospacing=0.00046 #epireg.inputs.pedir='-y' #epireg.inputs.output_type='NIFTI_GZ' # White Matter Segmentation (Make sure to generate edge map) segment=pe.Node(interface=fsl.FAST(),name='segment') #fast -o opname_fast anat_ss wmmapbin = pe.Node(interface=fsl.UnaryMaths(),name='wmmapbin') #fslmaths opname_fast_pve_2 -thr 0.5 -bin opname_fast_wmseg # in_file -> out_file wmmapbin.inputs.args='-thr 0.5 -bin' wmmapedge = pe.Node(interface=fsl.MultiImageMaths(),name='wmmapbin') #fslmaths opname_fast_wmseg -edge -bin -mas opname_fast_wmseg opname_fast_wmedge wmmapedge.inputs.op_string='-edge -bin -mas %s' # Flirt Pre-Alignment, using skullstripped T1 as reference #flirt -ref anat_ss -in epi -dof 6 -omat opname_init.mat
def create_extract_noT1_pipe(params_template, params={}, name="extract_noT1_pipe"): """ Description: Extract T1 brain using AtlasBrex Inputs: inputnode: restore_T1: preprocessed (debiased/denoised) T1 file name restore_T1: preprocessed (debiased/denoised)T2 file name arguments: params_template: dictionary of info about template params: dictionary of node sub-parameters (from a json file) name: pipeline name (default = "extract_pipe") Outputs: smooth_mask.out_file: Computed mask (after some smoothing) """ # creating pipeline extract_pipe = pe.Workflow(name=name) # creating inputnode inputnode = pe.Node( niu.IdentityInterface(fields=['restore_T1', "indiv_params"]), name='inputnode') # N4 intensity normalization with parameters from json norm_intensity = NodeParams(ants.N4BiasFieldCorrection(), params=parse_key(params, "norm_intensity"), name='norm_intensity') extract_pipe.connect(inputnode, 'restore_T1', norm_intensity, "input_image") # atlas_brex atlas_brex = NodeParams(AtlasBREX(), params=parse_key(params, "atlas_brex"), name='atlas_brex') extract_pipe.connect(norm_intensity, "output_image", atlas_brex, 't1_restored_file') atlas_brex.inputs.NMT_file = params_template["template_head"] atlas_brex.inputs.NMT_SS_file = params_template["template_brain"] extract_pipe.connect( inputnode, ("indiv_params", parse_key, "atlas_brex"), atlas_brex, 'indiv_params') # mask_brex mask_brex = pe.Node(fsl.UnaryMaths(), name='mask_brex') mask_brex.inputs.operation = 'bin' extract_pipe.connect(atlas_brex, 'brain_file', mask_brex, 'in_file') # smooth_mask smooth_mask = pe.Node(fsl.UnaryMaths(), name='smooth_mask') smooth_mask.inputs.operation = "bin" smooth_mask.inputs.args = "-s 1 -thr 0.5 -bin" extract_pipe.connect(mask_brex, 'out_file', smooth_mask, 'in_file') return extract_pipe
def register(warped_dir, atlas_image, atlas_image_brain, subject_T1ws_T2ws, subject_T2ws, n_jobs): input_spec = pe.Node(utility.IdentityInterface(fields=[ 'subject_image_list', 'subject_image', 'atlas_image', 'atlas_image_brain' ]), iterables=[('subject_image_list', subject_T1ws_T2ws), ('subject_image', subject_T2ws)], synchronize=True, name='input_spec') # set input_spec input_spec.inputs.subject_image_list = subject_T1ws_T2ws input_spec.inputs.subject_image = subject_T2ws input_spec.inputs.atlas_image = atlas_image input_spec.inputs.atlas_image_brain = atlas_image_brain ''' CC[x, x, 1, 8]: [fixed, moving, weight, radius]cd -t SyN[0.25]: Syn transform with a gradient step of 0.25 -r Gauss[3, 0]: sigma 0 -I 30x50x20 use - Histogram - Matching number - of - affine - iterations 10000x10000x10000x10000: 4 level image pyramid with 10000 iterations at each level MI - option 32x16000: 32 bins, 16000 samples ''' reg = pe.Node( ants.Registration( dimension=3, output_transform_prefix="output_", #interpolation='BSpline', transforms=['Affine', 'SyN'], transform_parameters=[(2.0, ), (0.25, )], #default values syn shrink_factors=[[8, 4, 2, 1], [4, 2, 1]], smoothing_sigmas=[[3, 2, 1, 0], [2, 1, 0]], #None for Syn? sigma_units=['vox'] * 2, sampling_percentage=[0.05, None], #just use default? sampling_strategy=['Random', 'None'], number_of_iterations=[[10000, 10000, 10000, 10000], [30, 50, 20]], metric=['MI', 'CC'], metric_weight=[1, 1], radius_or_number_of_bins=[(32), (8)], #winsorize_lower_quantile=0.05, #winsorize_upper_quantile=0.95, verbose=True, use_histogram_matching=[True, True]), name='calc_registration') applytransforms = pe.Node(ants.ApplyTransforms( dimension=3, interpolation='NearestNeighbor'), name='apply_warpfield') #Make warped atlas binary image #https://nipype.readthedocs.io/en/latest/interfaces/generated/interfaces.fsl/preprocess.html#bet binarize = pe.Node(fsl.UnaryMaths(operation='bin'), name='binarize') #apply binary warped atlas as mask to T2w #https://nipype.readthedocs.io/en/0.12.0/interfaces/generated/nipype.interfaces.fsl.maths.html#applymask applymask = pe.Node(fsl.ApplyMask(), name='apply_mask') wf = pe.Workflow(name='wf', base_dir=warped_dir) wf.connect([ (input_spec, reg, [('atlas_image', 'moving_image'), ('subject_image_list', 'fixed_image') ]), #create warp field to register atlas to subject (input_spec, applytransforms, [('atlas_image_brain', 'input_image'), ('subject_image', 'reference_image')]), (reg, applytransforms, [('forward_transforms', 'transforms')] ) #apply warpfield to register atlas brain to subject ]) wf.connect( applytransforms, 'output_image', binarize, 'in_file') #turn warped atlas brain into binary image to use as mask wf.connect(binarize, 'out_file', applymask, 'mask_file') wf.connect(input_spec, 'subject_image', applymask, 'in_file') wf.config['execution']['parameterize_dirs'] = False wf.write_graph() output = wf.run(plugin='MultiProc', plugin_args={'n_procs': n_jobs})
def create_randomise(name='randomise', working_dir=None, crash_dir=None): """ Parameters ---------- Returns ------- workflow : nipype.pipeline.engine.Workflow Randomise workflow. Notes ----- Workflow Inputs:: Workflow Outputs:: References ---------- """ if not working_dir: working_dir = os.path.join(os.getcwd(), 'Randomise_work_dir') if not crash_dir: crash_dir = os.path.join(os.getcwd(), 'Randomise_crash_dir') wf = pe.Workflow(name=name) wf.base_dir = working_dir wf.config['execution'] = { 'hash_method': 'timestamp', 'crashdump_dir': os.path.abspath(crash_dir) } inputspec = pe.Node(util.IdentityInterface(fields=[ 'subjects_list', 'pipeline_output_folder', 'permutations', 'mask_boolean', 'demean', 'c_thresh' ]), name='inputspec') outputspec = pe.Node(util.IdentityInterface(fields=[ 'tstat_files', 't_corrected_p_files', 'index_file', 'threshold_file', 'localmax_txt_file', 'localmax_vol_file', 'max_file', 'mean_file', 'pval_file', 'size_file' ]), name='outputspec') #merge = pe.Node(interface=fsl.Merge(), name='fsl_merge') #merge.inputs.dimension = 't' #merge.inputs.merged_file = "randomise_merged.nii.gz" #wf.connect(inputspec, 'subjects', merge, 'in_files') #mask = pe.Node(interface=fsl.maths.MathsCommand(), name='fsl_maths') #mask.inputs.args = '-abs -Tmin -bin' #mask.inputs.out_file = "randomise_mask.nii.gz" #wf.connect(inputspec, 'subjects', mask, 'in_file') randomise = pe.Node(interface=fsl.Randomise(), name='randomise') randomise.inputs.base_name = "randomise" randomise.inputs.demean = True randomise.inputs.tfce = True wf.connect([(inputspec, randomise, [ ('subjects', 'in_file'), ('design_matrix_file', 'design_mat'), ('constrast_file', 'tcon'), ('permutations', 'num_perm'), ])]) wf.connect(randomise, 'tstat_files', outputspec, 'tstat_files') wf.connect(randomise, 't_corrected_p_files', outputspec, 't_corrected_p_files') #------------- issue here arises while using tfce. By not using tfce, you don't get t_corrected_p files. R V in a conundrum? --------------------# select_tcorrp_files = pe.Node(Function(input_names=['input_list'], output_names=['out_file'], function=select), name='select_t_corrp') wf.connect(randomise, 't_corrected_p_files', select_tcorrp_files, 'input_list') wf.connect(select_tcorrp_files, 'out_file', outputspec, 'out_tcorr_corrected') select_tstat_files = pe.Node(Function(input_names=['input_list'], output_names=['out_file'], function=select), name='select_t_stat') wf.connect(randomise, 'tstat_files', select_tstat_files, 'input_list') wf.connect(select_tstat_files, 'out_file', outputspec, 'out_tstat_corrected') thresh = pe.Node(interface=fsl.Threshold(), name='fsl_threshold_contrast') thresh.inputs.thresh = 0.95 thresh.inputs.out_file = 'rando_pipe_thresh_tstat.nii.gz' wf.connect(select_tstat_files, 'out_file', thresh, 'in_file') wf.connect(thresh, 'out_file', outputspec, 'rando_pipe_thresh_tstat.nii.gz') thresh_bin = pe.Node(interface=fsl.UnaryMaths(), name='fsl_threshold_bin_contrast') thresh_bin.inputs.operation = 'bin' wf.connect(thresh, 'out_file', thresh_bin, 'in_file') wf.connect(thresh_bin, 'out_file', outputspec, 'thresh_bin_out') apply_mask = pe.Node(interface=fsl.ApplyMask(), name='fsl_applymask_contrast') wf.connect(select_tstat_files, 'out_file', apply_mask, 'in_file') wf.connect(thresh_bin, 'out_file', apply_mask, 'mask_file') cluster = pe.Node(interface=fsl.Cluster(), name='cluster_contrast') cluster.inputs.threshold = 0.0001 cluster.inputs.out_index_file = "index_file" cluster.inputs.out_localmax_txt_file = "lmax_contrast.txt" cluster.inputs.out_size_file = "cluster_size_contrast" cluster.inputs.out_threshold_file = True cluster.inputs.out_max_file = True cluster.inputs.out_mean_file = True cluster.inputs.out_pval_file = True cluster.inputs.out_size_file = True wf.connect(apply_mask, 'out_file', cluster, 'in_file') wf.connect(cluster, 'index_file', outputspec, 'index_file') wf.connect(cluster, 'threshold_file', outputspec, 'threshold_file') wf.connect(cluster, 'localmax_txt_file', outputspec, 'localmax_txt_file') wf.connect(cluster, 'localmax_vol_file', outputspec, 'localmax_vol_file') wf.connect(cluster, 'max_file', outputspec, 'max_file') wf.connect(cluster, 'mean_file', outputspec, 'meal_file') wf.connect(cluster, 'pval_file', outputspec, 'pval_file') wf.connect(cluster, 'size_file', outputspec, 'size_file') return wf
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 prep_randomise_workflow(c, merged_file, mask_file, f_test, mat_file, con_file, grp_file, output_dir, working_dir, log_dir, model_name, fts_file=None): import nipype.interfaces.utility as util import nipype.interfaces.fsl as fsl import nipype.interfaces.io as nio wf = pe.Workflow(name='randomise_workflow') wf.base_dir = c.work_dir randomise = pe.Node(interface=fsl.Randomise(), name='fsl-randomise_{0}'.format(model_name)) randomise.inputs.base_name = model_name randomise.inputs.in_file = merged_file randomise.inputs.mask = mask_file randomise.inputs.num_perm = c.randomise_permutation randomise.inputs.demean = c.randomise_demean randomise.inputs.c_thresh = c.randomise_thresh randomise.inputs.tfce = c.randomise_tfce randomise.inputs.design_mat = mat_file randomise.inputs.tcon = con_file if fts_file: randomise.inputs.fcon = fts_file select_tcorrp_files = pe.Node(util.Function(input_names=['input_list'], output_names=['out_file'], function=select), name='select_t_corrp') wf.connect(randomise, 't_corrected_p_files', select_tcorrp_files, 'input_list') select_tstat_files = pe.Node(util.Function(input_names=['input_list'], output_names=['out_file'], function=select), name='select_t_stat') wf.connect(randomise, 'tstat_files', select_tstat_files, 'input_list') thresh = pe.Node(interface=fsl.Threshold(), name='fsl_threshold_contrast') thresh.inputs.thresh = 0.95 thresh.inputs.out_file = 'randomise_pipe_thresh_tstat.nii.gz' wf.connect(select_tstat_files, 'out_file', thresh, 'in_file') thresh_bin = pe.Node(interface=fsl.UnaryMaths(), name='fsl_threshold_bin_contrast') thresh_bin.inputs.operation = 'bin' wf.connect(thresh, 'out_file', thresh_bin, 'in_file') apply_mask = pe.Node(interface=fsl.ApplyMask(), name='fsl_applymask_contrast') wf.connect(select_tstat_files, 'out_file', apply_mask, 'in_file') wf.connect(thresh_bin, 'out_file', apply_mask, 'mask_file') cluster = pe.Node(interface=fsl.Cluster(), name='cluster_contrast') cluster.inputs.threshold = 0.0001 cluster.inputs.out_index_file = "index_file" cluster.inputs.out_localmax_txt_file = "lmax_contrast.txt" cluster.inputs.out_size_file = "cluster_size_contrast" cluster.inputs.out_threshold_file = True cluster.inputs.out_max_file = True cluster.inputs.out_mean_file = True cluster.inputs.out_pval_file = True cluster.inputs.out_size_file = True wf.connect(apply_mask, 'out_file', cluster, 'in_file') ds = pe.Node(nio.DataSink(), name='fsl-randomise_sink') ds.inputs.base_directory = str(output_dir) ds.inputs.container = '' wf.connect(randomise, 'tstat_files', ds, 'tstat_files') wf.connect(randomise, 't_corrected_p_files', ds, 't_corrected_p_files') wf.connect(select_tcorrp_files, 'out_file', ds, 'out_tcorr_corrected') wf.connect(select_tstat_files, 'out_file', ds, 'out_tstat_corrected') wf.connect(thresh, 'out_file', ds, 'randomise_pipe_thresh_tstat.nii.gz') wf.connect(thresh_bin, 'out_file', ds, 'thresh_bin_out') wf.connect(cluster, 'index_file', ds, 'index_file') wf.connect(cluster, 'threshold_file', ds, 'threshold_file') wf.connect(cluster, 'localmax_txt_file', ds, 'localmax_txt_file') wf.connect(cluster, 'localmax_vol_file', ds, 'localmax_vol_file') wf.connect(cluster, 'max_file', ds, 'max_file') wf.connect(cluster, 'mean_file', ds, 'meal_file') wf.connect(cluster, 'pval_file', ds, 'pval_file') wf.connect(cluster, 'size_file', ds, 'size_file') wf.run()
(TumorwarpHighRes, LowThreshTumor, [('out_file', 'in_file')]), (NormalwarpHighRes, LowThreshNormal, [('out_file', 'in_file')]) ]) datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = parent_dir + '/FDM/Outputs' datasink.inputs.substitutions = [ ('_scan_id_', ''), ('_brain_flirt_volreg_masked_allineate_thresh', '_highres'), ('_brain_flirt_volreg_flirt_allineate_masked_allineate_thresh', '_highres'), ('_flirt_allineate_flirt_allineate_masked_allineate_thresh', '_highres') ] TumorBin = pe.Node(interface=fsl.UnaryMaths(), name='TumorBin') TumorBin.inputs.operation = 'bin' FDM = pe.Workflow(name='FDM') FDM.base_dir = parent_dir FDM.connect([ (Reg, Warp, [('MaskADC.out_file', 'get_Ref.LinADC')]), (Reg, Warp, [('MaskADC.out_file', 'ADCwarpHighRes.in_file')]), (Reg, Warp, [('MaskREF.out_file', 'REFwarpHighRes.in_file')]), (Reg, Warp, [('MaskTumor.out_file', 'TumorwarpHighRes.in_file')]), (Reg, Warp, [('MaskNormal.out_file', 'NormalwarpHighRes.in_file')]), (Warp, TumorBin, [('LowThreshTumor.out_file', 'in_file')]), (Warp, datasink, [('LowThreshREF.out_file', 'Ref.@ref')]), (Warp, datasink, [('LowThreshADC.out_file', 'ADC.@adc')]), (TumorBin, datasink, [('out_file', 'Tumor.@tumor')]), (Warp, datasink, [('LowThreshNormal.out_file', 'Normal.@normal')])
def create_correct_bias_pipe(params={}, name="correct_bias_pipe"): """ Description: Correct bias using T1 and T2 images Same as bash_regis.T1xT2BiasFieldCorrection Params: - smooth (see `MathsCommand <https://nipype.readthedocs.io/en/0.12.1/\ interfaces/generated/nipype.interfaces.fsl.maths.html#mathscommand>`_) - norm_smooth (see `MultiMathsCommand <https://nipype.readthedocs.io/\ en/0.12.1/interfaces/generated/nipype.interfaces.fsl.maths.html\ #multiimagemaths>`_) - smooth_bias (see `IsotropicSmooth <https://nipype.readthedocs.io/en/\ 0.12.1/interfaces/generated/nipype.interfaces.fsl.maths.html#\ isotropicsmooth>`_) Inputs: inputnode: preproc_T1: preprocessed T1 file name preproc_T2: preprocessed T2 file name arguments: params: dictionary of node sub-parameters (from a json file) name: pipeline name (default = "correct_bias_pipe") Outputs: outputnode.debiased_T1: T1 after bias correction outputnode.debiased_T2: T2 after bias correction """ # creating pipeline correct_bias_pipe = pe.Workflow(name=name) # creating inputnode inputnode = pe.Node( niu.IdentityInterface(fields=['preproc_T1', 'preproc_T2']), name='inputnode') # BinaryMaths mult_T1_T2 = pe.Node(fsl.BinaryMaths(), name='mult_T1_T2') mult_T1_T2.inputs.operation = "mul" mult_T1_T2.inputs.args = "-abs -sqrt" mult_T1_T2.inputs.output_datatype = "float" correct_bias_pipe.connect(inputnode, 'preproc_T1', mult_T1_T2, 'in_file') correct_bias_pipe.connect(inputnode, 'preproc_T2', mult_T1_T2, 'operand_file') # Mean Brain Val meanbrainval = pe.Node(fsl.ImageStats(), name='meanbrainval') meanbrainval.inputs.op_string = "-M" correct_bias_pipe.connect(mult_T1_T2, 'out_file', meanbrainval, 'in_file') # norm_mult norm_mult = pe.Node(fsl.BinaryMaths(), name='norm_mult') norm_mult.inputs.operation = "div" correct_bias_pipe.connect(mult_T1_T2, 'out_file', norm_mult, 'in_file') correct_bias_pipe.connect(meanbrainval, 'out_stat', norm_mult, 'operand_value') # smooth smooth = NodeParams(fsl.maths.MathsCommand(), params=parse_key(params, "smooth"), name='smooth') correct_bias_pipe.connect(norm_mult, 'out_file', smooth, 'in_file') # norm_smooth norm_smooth = NodeParams(fsl.MultiImageMaths(), params=parse_key(params, "norm_smooth"), name='norm_smooth') correct_bias_pipe.connect(norm_mult, 'out_file', norm_smooth, 'in_file') correct_bias_pipe.connect(smooth, 'out_file', norm_smooth, 'operand_files') # modulate modulate = pe.Node(fsl.BinaryMaths(), name='modulate') modulate.inputs.operation = "div" correct_bias_pipe.connect(norm_mult, 'out_file', modulate, 'in_file') correct_bias_pipe.connect(norm_smooth, 'out_file', modulate, 'operand_file') # std_modulate std_modulate = pe.Node(fsl.ImageStats(), name='std_modulate') std_modulate.inputs.op_string = "-S" correct_bias_pipe.connect(modulate, 'out_file', std_modulate, 'in_file') # mean_modulate mean_modulate = pe.Node(fsl.ImageStats(), name='mean_modulate') mean_modulate.inputs.op_string = "-M" correct_bias_pipe.connect(modulate, 'out_file', mean_modulate, 'in_file') # compute_lower_val def compute_lower_val(mean_val, std_val): return mean_val - (std_val * 0.5) # compute_lower lower = pe.Node(niu.Function(input_names=['mean_val', 'std_val'], output_names=['lower_val'], function=compute_lower_val), name='lower') correct_bias_pipe.connect(mean_modulate, 'out_stat', lower, 'mean_val') correct_bias_pipe.connect(std_modulate, 'out_stat', lower, 'std_val') # thresh_lower thresh_lower = pe.Node(fsl.Threshold(), name='thresh_lower') correct_bias_pipe.connect(lower, 'lower_val', thresh_lower, 'thresh') correct_bias_pipe.connect(modulate, 'out_file', thresh_lower, 'in_file') # mod_mask mod_mask = pe.Node(fsl.UnaryMaths(), name='mod_mask') mod_mask.inputs.operation = "bin" mod_mask.inputs.args = "-ero -mul 255" correct_bias_pipe.connect(thresh_lower, 'out_file', mod_mask, 'in_file') # bias bias = pe.Node(fsl.MultiImageMaths(), name='bias') bias.inputs.op_string = "-mas %s -dilall" bias.inputs.output_datatype = "float" correct_bias_pipe.connect(norm_mult, 'out_file', bias, 'in_file') correct_bias_pipe.connect(mod_mask, 'out_file', bias, 'operand_files') # smooth_bias smooth_bias = NodeParams(fsl.IsotropicSmooth(), params=parse_key(params, "smooth_bias"), name='smooth_bias') correct_bias_pipe.connect(bias, 'out_file', smooth_bias, 'in_file') # debiased_T1 debiased_T1 = pe.Node(fsl.BinaryMaths(), name='debiased_T1') debiased_T1.inputs.operation = "div" debiased_T1.inputs.output_datatype = "float" correct_bias_pipe.connect(inputnode, 'preproc_T1', debiased_T1, 'in_file') correct_bias_pipe.connect(smooth_bias, 'out_file', debiased_T1, 'operand_file') # debiased_T2 debiased_T2 = pe.Node(fsl.BinaryMaths(), name='debiased_T2') debiased_T2.inputs.operation = "div" debiased_T2.inputs.output_datatype = "float" correct_bias_pipe.connect(inputnode, 'preproc_T2', debiased_T2, 'in_file') correct_bias_pipe.connect(smooth_bias, 'out_file', debiased_T2, 'operand_file') # outputnode outputnode = pe.Node( niu.IdentityInterface(fields=["debiased_T1", "debiased_T2"]), name='outputnode') correct_bias_pipe.connect(debiased_T1, 'out_file', outputnode, 'debiased_T1') correct_bias_pipe.connect(debiased_T2, 'out_file', outputnode, 'debiased_T2') return correct_bias_pipe
def create_asl_processing_workflow(in_inversion_recovery_file, in_asl_file, output_dir, in_t1_file=None, name='asl_processing_workflow'): workflow = pe.Workflow(name=name) workflow.base_output_dir = name subject_id = split_filename(os.path.basename(in_asl_file))[1] ir_splitter = pe.Node(interface=fsl.Split( dimension='t', out_base_name='out_', in_file=in_inversion_recovery_file), name='ir_splitter') ir_selector = pe.Node(interface=niu.Select(index=[0, 2, 4]), name='ir_selector') workflow.connect(ir_splitter, 'out_files', ir_selector, 'inlist') ir_merger = pe.Node(interface=fsl.Merge(dimension='t'), name='ir_merger') workflow.connect(ir_selector, 'out', ir_merger, 'in_files') fitqt1 = pe.Node(interface=niftyfit.FitQt1(TIs=[4, 2, 1], SR=True), name='fitqt1') workflow.connect(ir_merger, 'merged_file', fitqt1, 'source_file') extract_ir_0 = pe.Node(interface=niftyseg.BinaryMathsInteger( operation='tp', operand_value=0, in_file=in_inversion_recovery_file), name='extract_ir_0') ir_thresolder = pe.Node(interface=fsl.Threshold(thresh=250), name='ir_thresolder') workflow.connect(extract_ir_0, 'out_file', ir_thresolder, 'in_file') create_mask = pe.Node(interface=fsl.UnaryMaths(operation='bin'), name='create_mask') workflow.connect(ir_thresolder, 'out_file', create_mask, 'in_file') model_fitting = pe.Node(niftyfit.FitAsl(source_file=in_asl_file, pcasl=True, PLD=1800, LDD=1800, eff=0.614, mul=0.1), name='model_fitting') workflow.connect(fitqt1, 'm0map', model_fitting, 'm0map') workflow.connect(create_mask, 'out_file', model_fitting, 'mask') t1_to_asl_registration = pe.Node(niftyreg.RegAladin(rig_only_flag=True), name='t1_to_asl_registration') m0_resampling = pe.Node(niftyreg.RegResample(inter_val='LIN'), name='m0_resampling') mc_resampling = pe.Node(niftyreg.RegResample(inter_val='LIN'), name='mc_resampling') t1_resampling = pe.Node(niftyreg.RegResample(inter_val='LIN'), name='t1_resampling') cbf_resampling = pe.Node(niftyreg.RegResample(inter_val='LIN'), name='cbf_resampling') if in_t1_file: t1_to_asl_registration.inputs.flo_file = in_asl_file t1_to_asl_registration.inputs.ref_file = in_t1_file m0_resampling.inputs.ref_file = in_t1_file mc_resampling.inputs.ref_file = in_t1_file t1_resampling.inputs.ref_file = in_t1_file cbf_resampling.inputs.ref_file = in_t1_file workflow.connect(fitqt1, 'm0map', m0_resampling, 'flo_file') workflow.connect(fitqt1, 'mcmap', mc_resampling, 'flo_file') workflow.connect(fitqt1, 't1map', t1_resampling, 'flo_file') workflow.connect(model_fitting, 'cbf_file', cbf_resampling, 'flo_file') workflow.connect(t1_to_asl_registration, 'aff_file', m0_resampling, 'trans_file') workflow.connect(t1_to_asl_registration, 'aff_file', mc_resampling, 'trans_file') workflow.connect(t1_to_asl_registration, 'aff_file', t1_resampling, 'trans_file') workflow.connect(t1_to_asl_registration, 'aff_file', cbf_resampling, 'trans_file') maskrenamer = pe.Node(interface=niu.Rename(format_string=subject_id + '_mask', keep_ext=True), name='maskrenamer') m0renamer = pe.Node(interface=niu.Rename(format_string=subject_id + '_m0map', keep_ext=True), name='m0renamer') mcrenamer = pe.Node(interface=niu.Rename(format_string=subject_id + '_mcmap', keep_ext=True), name='mcrenamer') t1renamer = pe.Node(interface=niu.Rename(format_string=subject_id + '_t1map', keep_ext=True), name='t1renamer') workflow.connect(create_mask, 'out_file', maskrenamer, 'in_file') if in_t1_file: workflow.connect(m0_resampling, 'out_file', m0renamer, 'in_file') workflow.connect(mc_resampling, 'out_file', mcrenamer, 'in_file') workflow.connect(t1_resampling, 'out_file', t1renamer, 'in_file') else: workflow.connect(fitqt1, 'm0map', m0renamer, 'in_file') workflow.connect(fitqt1, 'mcmap', mcrenamer, 'in_file') workflow.connect(fitqt1, 't1map', t1renamer, 'in_file') ds = pe.Node(nio.DataSink(parameterization=False, base_directory=output_dir), name='ds') workflow.connect(maskrenamer, 'out_file', ds, '@mask_file') workflow.connect(m0renamer, 'out_file', ds, '@m0_file') workflow.connect(mcrenamer, 'out_file', ds, '@mc_file') workflow.connect(t1renamer, 'out_file', ds, '@t1_file') if in_t1_file: workflow.connect(cbf_resampling, 'out_file', ds, '@cbf_file') else: workflow.connect(model_fitting, 'cbf_file', ds, '@cbf_file') workflow.connect(model_fitting, 'error_file', ds, '@err_file') return workflow
def create_segment_atropos_pipe(params={}, name="segment_atropos_pipe"): """ Description: Segmentation with ANTS atropos script Inputs: inputnode: brain_file: T1 image, after extraction and norm bin_norm_intensity gm_prior_file: grey matter tissue intensity file wm_prior_file: white matter tissue intensity file csf_prior_file: csf tissue intensity file arguments: params: dictionary of node sub-parameters (from a json file) name: pipeline name (default = "segment_atropos_pipe") Outputs: threshold_csf.out_file: csf tissue intensity mask in subject space threshold_gm.out_file: grey matter tissue intensity mask in subject space threshold_wm.out_file: white matter tissue intensity mask in subject space """ # creating pipeline segment_pipe = pe.Workflow(name=name) # creating inputnode inputnode = pe.Node( niu.IdentityInterface( fields=["brain_file", "gm_prior_file", "wm_prior_file", "csf_prior_file"]), name='inputnode') # bin_norm_intensity (a cheat from Kepkee if I understood well!) bin_norm_intensity = pe.Node(fsl.UnaryMaths(), name="bin_norm_intensity") bin_norm_intensity.inputs.operation = "bin" segment_pipe.connect(inputnode, "brain_file", bin_norm_intensity, "in_file") # merging priors as a list merge_3_elem = pe.Node(niu.Function( input_names=['elem1', 'elem2', 'elem3'], output_names=['merged_list'], function=merge_3_elem_to_list), name='merge_3_elem') # was like this before (1 -> csf, 2 -> gm, 3 -> wm, to check) segment_pipe.connect(inputnode, 'csf_prior_file', merge_3_elem, "elem1") segment_pipe.connect(inputnode, 'gm_prior_file', merge_3_elem, "elem2") segment_pipe.connect(inputnode, 'wm_prior_file', merge_3_elem, "elem3") # Atropos seg_at = NodeParams(AtroposN4(), params=parse_key(params, "Atropos"), name='seg_at') segment_pipe.connect(inputnode, "brain_file", seg_at, "brain_file") segment_pipe.connect(bin_norm_intensity, 'out_file', seg_at, "brainmask_file") segment_pipe.connect(merge_3_elem, 'merged_list', seg_at, "priors") # Threshold GM, WM and CSF thd_nodes = {} for i, tissue in enumerate(['csf', 'gm', 'wm']): tmp_node = NodeParams(fsl.Threshold(), params=parse_key(params, "threshold_" + tissue), name="threshold_" + tissue) segment_pipe.connect(seg_at, ('segmented_files', get_elem, i), tmp_node, 'in_file') thd_nodes[tissue] = tmp_node return segment_pipe
def create_extract_pipe(params_template, params={}, name="extract_pipe"): """ Description: Extract T1 brain using AtlasBrex Params: - norm_intensity (see `N4BiasFieldCorrection <https://nipype.readthedocs\ .io/en/0.12.1/interfaces/generated/nipype.interfaces.ants.segmentation.\ html#n4biasfieldcorrection>`_ for arguments) - atlas_brex (see :class:`AtlasBREX \ <macapype.nodes.extract_brain.AtlasBREX>` for arguments) - also \ available as :ref:`indiv_params <indiv_params>` Inputs: inputnode: restore_T1: preprocessed (debiased/denoised) T1 file name restore_T2: preprocessed (debiased/denoised)T2 file name arguments: params_template: dictionary of info about template params: dictionary of node sub-parameters (from a json file) name: pipeline name (default = "extract_pipe") Outputs: smooth_mask.out_file: Computed mask (after some smoothing) """ # creating pipeline extract_pipe = pe.Workflow(name=name) # creating inputnode inputnode = pe.Node(niu.IdentityInterface( fields=['restore_T1', 'restore_T2', "indiv_params"]), name='inputnode') # atlas_brex atlas_brex = NodeParams(AtlasBREX(), params=parse_key(params, "atlas_brex"), name='atlas_brex') extract_pipe.connect(inputnode, "restore_T1", atlas_brex, 't1_restored_file') atlas_brex.inputs.NMT_file = params_template["template_head"] atlas_brex.inputs.NMT_SS_file = params_template["template_brain"] extract_pipe.connect(inputnode, ("indiv_params", parse_key, "atlas_brex"), atlas_brex, 'indiv_params') # mask_brex mask_brex = pe.Node(fsl.UnaryMaths(), name='mask_brex') mask_brex.inputs.operation = 'bin' extract_pipe.connect(atlas_brex, 'brain_file', mask_brex, 'in_file') # smooth_mask smooth_mask = pe.Node(fsl.UnaryMaths(), name='smooth_mask') smooth_mask.inputs.operation = "bin" smooth_mask.inputs.args = "-s 1 -thr 0.5 -bin" extract_pipe.connect(mask_brex, 'out_file', smooth_mask, 'in_file') # mult_T1 mult_T1 = pe.Node(afni.Calc(), name='mult_T1') mult_T1.inputs.expr = "a*b" mult_T1.inputs.outputtype = 'NIFTI_GZ' extract_pipe.connect(inputnode, "restore_T1", mult_T1, 'in_file_a') extract_pipe.connect(smooth_mask, 'out_file', mult_T1, 'in_file_b') # mult_T2 mult_T2 = pe.Node(afni.Calc(), name='mult_T2') mult_T2.inputs.expr = "a*b" mult_T2.inputs.outputtype = 'NIFTI_GZ' extract_pipe.connect(inputnode, 'restore_T2', mult_T2, 'in_file_a') extract_pipe.connect(smooth_mask, 'out_file', mult_T2, 'in_file_b') return extract_pipe
def create_segment_atropos_seg_pipe(params={}, name="segment_atropos_pipe"): """ Description: Segmentation with ANTS atropos script using seg file Params: - Atropos (see :class:`AtroposN4 <macapype.nodes.segment.AtroposN4>`) - threshold_gm, threshold_wm, threshold_csf (see `Threshold \ <https://nipype.readthedocs.io/en/0.12.1/interfaces/generated/nipype.\ interfaces.fsl.maths.html#threshold>`_ for arguments) Inputs: inputnode: brain_file: T1 image, after extraction and norm bin_norm_intensity seg_file: indexed with all tissues as index file arguments: params: dictionary of node sub-parameters (from a json file) name: pipeline name (default = "segment_atropos_pipe") Outputs: threshold_csf.out_file: csf tissue intensity mask in subject space threshold_gm.out_file: grey matter tissue intensity mask in subject space threshold_wm.out_file: white matter tissue intensity mask in subject space """ # creating pipeline segment_pipe = pe.Workflow(name=name) # creating inputnode inputnode = pe.Node( niu.IdentityInterface(fields=["brain_file", "seg_file"]), name='inputnode') # bin_norm_intensity (a cheat from Kepkee if I understood well!) bin_norm_intensity = pe.Node(fsl.UnaryMaths(), name="bin_norm_intensity") bin_norm_intensity.inputs.operation = "bin" segment_pipe.connect(inputnode, "brain_file", bin_norm_intensity, "in_file") # merging priors as a list split_seg = pe.Node(niu.Function(input_names=['nii_file'], output_names=['list_split_files'], function=split_indexed_mask), name='split_seg') segment_pipe.connect(inputnode, 'seg_file', split_seg, "nii_file") # Atropos seg_at = NodeParams(AtroposN4(), params=parse_key(params, "Atropos"), name='seg_at') segment_pipe.connect(inputnode, "brain_file", seg_at, "brain_file") segment_pipe.connect(bin_norm_intensity, 'out_file', seg_at, "brainmask_file") segment_pipe.connect(split_seg, 'list_split_files', seg_at, "priors") # on segmentation indexed mask (with labels) # 1 -> CSF # 2 -> GM # 3 -> sub cortical? # 4 -> WM # 5 -> ? thd_nodes = {} for key, tissue in {0: 'csf', 1: 'gm', 3: 'wm'}.items(): tmp_node = NodeParams(fsl.Threshold(), params=parse_key(params, "threshold_" + tissue), name="threshold_" + tissue) segment_pipe.connect(seg_at, ('segmented_files', get_elem, key), tmp_node, 'in_file') thd_nodes[tissue] = tmp_node outputnode = pe.Node(niu.IdentityInterface(fields=[ "segmented_file", "threshold_gm", "threshold_wm", "threshold_csf" ]), name='outputnode') segment_pipe.connect(seg_at, 'segmented_file', outputnode, 'segmented_file') segment_pipe.connect(thd_nodes["gm"], 'out_file', outputnode, 'threshold_gm') segment_pipe.connect(thd_nodes["wm"], 'out_file', outputnode, 'threshold_wm') segment_pipe.connect(thd_nodes["csf"], 'out_file', outputnode, 'threshold_csf') return segment_pipe
def create_mask_from_seg_pipe(params={}, name="mask_from_seg_pipe"): """ Description: mask from segmentation tissues #TODO To be added if required (was in old_segment before) Function: - Compute union of those 3 tissues; - Apply morphological opening on the union mask - Fill holes Inputs: mask_gm, mask_wm: binary mask for grey matter and white matter Outputs: fill_holes.out_file: filled mask after erode fill_holes_dil.out_file filled mask after dilate """ # creating pipeline seg_pipe = pe.Workflow(name=name) # Creating inputnode inputnode = pe.Node(niu.IdentityInterface( fields=['mask_gm', 'mask_wm', 'mask_csf', 'indiv_params']), name='inputnode') # bin_gm bin_gm = pe.Node(interface=fsl.UnaryMaths(), name="bin_gm") bin_gm.inputs.operation = "fillh" seg_pipe.connect(inputnode, 'mask_gm', bin_gm, 'in_file') # bin_csf bin_csf = pe.Node(interface=fsl.UnaryMaths(), name="bin_csf") bin_csf.inputs.operation = "fillh" seg_pipe.connect(inputnode, 'mask_csf', bin_csf, 'in_file') # bin_wm bin_wm = pe.Node(interface=fsl.UnaryMaths(), name="bin_wm") bin_wm.inputs.operation = "fillh" seg_pipe.connect(inputnode, 'mask_wm', bin_wm, 'in_file') # Compute union of the 3 tissues # Done with 2 fslmaths as it seems to hard to do it wmgm_union = pe.Node(fsl.BinaryMaths(), name="wmgm_union") wmgm_union.inputs.operation = "add" seg_pipe.connect(bin_gm, 'out_file', wmgm_union, 'in_file') seg_pipe.connect(bin_wm, 'out_file', wmgm_union, 'operand_file') tissues_union = pe.Node(fsl.BinaryMaths(), name="tissues_union") tissues_union.inputs.operation = "add" seg_pipe.connect(wmgm_union, 'out_file', tissues_union, 'in_file') seg_pipe.connect(bin_csf, 'out_file', tissues_union, 'operand_file') # Opening (dilating) mask dilate_mask = NodeParams(fsl.DilateImage(), params=parse_key(params, "dilate_mask"), name="dilate_mask") dilate_mask.inputs.operation = "mean" # Arbitrary operation seg_pipe.connect(tissues_union, 'out_file', dilate_mask, 'in_file') # fill holes of dilate_mask fill_holes_dil = pe.Node(BinaryFillHoles(), name="fill_holes_dil") seg_pipe.connect(dilate_mask, 'out_file', fill_holes_dil, 'in_file') # Eroding mask erode_mask = NodeParams(fsl.ErodeImage(), params=parse_key(params, "erode_mask"), name="erode_mask") seg_pipe.connect(tissues_union, 'out_file', erode_mask, 'in_file') # fill holes of erode_mask fill_holes = pe.Node(BinaryFillHoles(), name="fill_holes") seg_pipe.connect(erode_mask, 'out_file', fill_holes, 'in_file') # merge to index merge_indexed_mask = NodeParams( interface=niu.Function(input_names=[ "mask_csf_file", "mask_wm_file", "mask_gm_file", "index_csf", "index_gm", "index_wm" ], output_names=['indexed_mask'], function=merge_masks), params=parse_key(params, "merge_indexed_mask"), name="merge_indexed_mask") seg_pipe.connect(bin_gm, 'out_file', merge_indexed_mask, "mask_gm_file") seg_pipe.connect(bin_wm, 'out_file', merge_indexed_mask, "mask_wm_file") seg_pipe.connect(bin_csf, 'out_file', merge_indexed_mask, "mask_csf_file") return seg_pipe
import nibabel as nb input = posteriors GM = posteriors[1] #posterior_01 print(GM) return GM get_gm = Node(name='Get_GM', interface=Function(input_names=['posteriors'], output_names=['GM'], function=Get_GM)) #----------------------------------------------------------------------------------------------------- # In[1]: #Make a mask of the warped image, to use it with atropos binarize_warped_image = Node(fsl.UnaryMaths(), name='Binarize_Warped_Image') binarize_warped_image.inputs.operation = 'bin' binarize_warped_image.output_datatype = 'char' #----------------------------------------------------------------------------------------------------- # In[1]: #Multiply by Jacobian determinant to ge the modulate image modulate_GM = Node(ants.MultiplyImages(), name='Modulate_GM') modulate_GM.inputs.dimension = 3 modulate_GM.inputs.output_product_image = 'Modulated_GM.nii.gz' #----------------------------------------------------------------------------------------------------- # In[1]: #Smooth the modulated images smoothing = Node(fsl.Smooth(), name='Smoothing') smoothing.iterables = ('fwhm', [1.5, 2, 2.3, 2.7, 3])
root_dir + nipype_dir + nlin_displacement_field_4d_only_split1, root_dir + nipype_dir + nlin_displacement_field_4d_only_split2, root_dir + nipype_dir + nlin_displacement_field_4d_only_split3 ] # Node 13 node_select3 = pe.Node(interface=util.Select(), name='node_select3') node_select3.inputs.index = [2] node_select3.inputs.inlist = [ root_dir + nipype_dir + nlin_displacement_field_4d_only_split1, root_dir + nipype_dir + nlin_displacement_field_4d_only_split2, root_dir + nipype_dir + nlin_displacement_field_4d_only_split3 ] # Node 14 node_fsl_sqr1 = pe.Node(interface=fsl.UnaryMaths(), name='node_fsl_sqr1') node_fsl_sqr1.inputs.operation = 'sqr' #node_fsl_sqr1.inputs.in_file = root_dir + nipype_dir + nlin_displacement_field_4d_only_split1 node_fsl_sqr1.inputs.out_file = root_dir + nipype_dir + nlin_displacement_field_4d_only_split1 # Node 15 node_fsl_sqr2 = pe.Node(interface=fsl.UnaryMaths(), name='node_fsl_sqr2') node_fsl_sqr2.inputs.operation = 'sqr' #node_fsl_sqr2.inputs.in_file = root_dir + nipype_dir + nlin_displacement_field_4d_only_split2 node_fsl_sqr2.inputs.out_file = root_dir + nipype_dir + nlin_displacement_field_4d_only_split2 # Node 16 node_fsl_sqr3 = pe.Node(interface=fsl.UnaryMaths(), name='node_fsl_sqr3') node_fsl_sqr3.inputs.operation = 'sqr' #node_fsl_sqr3.inputs.in_file = root_dir + nipype_dir + nlin_displacement_field_4d_only_split3 node_fsl_sqr3.inputs.out_file = root_dir + nipype_dir + nlin_displacement_field_4d_only_split3
def _create_split_hemi_pipe(params, params_template, name="split_hemi_pipe"): """Description: Split segmentated tissus according hemisheres after \ removal of cortical structure Processing steps: - TODO Params: - None so far Inputs: inputnode: warpinv_file: non-linear transformation (from NMT_subject_align) inv_transfo_file: inverse transformation aff_file: affine transformation file t1_ref_file: preprocessd T1 segmented_file: from atropos segmentation, with all the tissues segmented arguments: params: dictionary of node sub-parameters (from a json file) name: pipeline name (default = "split_hemi_pipe") Outputs: """ split_hemi_pipe = pe.Workflow(name=name) # creating inputnode inputnode = pe.Node(niu.IdentityInterface(fields=[ 'warpinv_file', 'inv_transfo_file', 'aff_file', 't1_ref_file', 'segmented_file' ]), name='inputnode') # get values if "cereb_template" in params_template.keys(): cereb_template_file = params_template["cereb_template"] # ### cereb # Binarize cerebellum bin_cereb = pe.Node(interface=fsl.UnaryMaths(), name='bin_cereb') bin_cereb.inputs.operation = "bin" bin_cereb.inputs.in_file = cereb_template_file # Warp cereb brainmask to subject space warp_cereb = pe.Node(interface=reg.NwarpApplyPriors(), name='warp_cereb') warp_cereb.inputs.in_file = cereb_template_file warp_cereb.inputs.out_file = cereb_template_file warp_cereb.inputs.interp = "NN" warp_cereb.inputs.args = "-overwrite" split_hemi_pipe.connect(bin_cereb, 'out_file', warp_cereb, 'in_file') split_hemi_pipe.connect(inputnode, 'aff_file', warp_cereb, 'master') split_hemi_pipe.connect(inputnode, 'warpinv_file', warp_cereb, "warp") # Align cereb template align_cereb = pe.Node(interface=afni.Allineate(), name='align_cereb') align_cereb.inputs.final_interpolation = "nearestneighbour" align_cereb.inputs.overwrite = True align_cereb.inputs.outputtype = "NIFTI_GZ" split_hemi_pipe.connect(warp_cereb, 'out_file', align_cereb, "in_file") # -source split_hemi_pipe.connect(inputnode, 't1_ref_file', align_cereb, "reference") # -base split_hemi_pipe.connect(inputnode, 'inv_transfo_file', align_cereb, "in_matrix") # -1Dmatrix_apply if "L_hemi_template" in params_template.keys() and \ "R_hemi_template" in params_template.keys(): L_hemi_template_file = params_template["L_hemi_template"] R_hemi_template_file = params_template["R_hemi_template"] # Warp L hemi template brainmask to subject space warp_L_hemi = pe.Node(interface=reg.NwarpApplyPriors(), name='warp_L_hemi') warp_L_hemi.inputs.in_file = L_hemi_template_file warp_L_hemi.inputs.out_file = L_hemi_template_file warp_L_hemi.inputs.interp = "NN" warp_L_hemi.inputs.args = "-overwrite" split_hemi_pipe.connect(inputnode, 'aff_file', warp_L_hemi, 'master') split_hemi_pipe.connect(inputnode, 'warpinv_file', warp_L_hemi, "warp") # Align L hemi template align_L_hemi = pe.Node(interface=afni.Allineate(), name='align_L_hemi') align_L_hemi.inputs.final_interpolation = "nearestneighbour" align_L_hemi.inputs.overwrite = True align_L_hemi.inputs.outputtype = "NIFTI_GZ" split_hemi_pipe.connect(warp_L_hemi, 'out_file', align_L_hemi, "in_file") # -source split_hemi_pipe.connect(inputnode, 't1_ref_file', align_L_hemi, "reference") # -base split_hemi_pipe.connect(inputnode, 'inv_transfo_file', align_L_hemi, "in_matrix") # -1Dmatrix_apply # Warp R hemi template brainmask to subject space warp_R_hemi = pe.Node(interface=reg.NwarpApplyPriors(), name='warp_R_hemi') warp_R_hemi.inputs.in_file = R_hemi_template_file warp_R_hemi.inputs.out_file = R_hemi_template_file warp_R_hemi.inputs.interp = "NN" warp_R_hemi.inputs.args = "-overwrite" split_hemi_pipe.connect(inputnode, 'aff_file', warp_R_hemi, 'master') split_hemi_pipe.connect(inputnode, 'warpinv_file', warp_R_hemi, "warp") # Align R hemi template align_R_hemi = pe.Node(interface=afni.Allineate(), name='align_R_hemi') align_R_hemi.inputs.final_interpolation = "nearestneighbour" align_R_hemi.inputs.overwrite = True align_R_hemi.inputs.outputtype = "NIFTI_GZ" split_hemi_pipe.connect(warp_R_hemi, 'out_file', align_R_hemi, "in_file") # -source split_hemi_pipe.connect(inputnode, 't1_ref_file', align_R_hemi, "reference") # -base split_hemi_pipe.connect(inputnode, 'inv_transfo_file', align_R_hemi, "in_matrix") # -1Dmatrix_apply elif "LR_hemi_template" in params_template.keys(): LR_hemi_template_file = params_template["LR_hemi_template"] # Warp LR hemi template brainmask to subject space warp_LR_hemi = pe.Node(interface=reg.NwarpApplyPriors(), name='warp_LR_hemi') warp_LR_hemi.inputs.in_file = LR_hemi_template_file warp_LR_hemi.inputs.out_file = LR_hemi_template_file warp_LR_hemi.inputs.interp = "NN" warp_LR_hemi.inputs.args = "-overwrite" split_hemi_pipe.connect(inputnode, 'aff_file', warp_LR_hemi, 'master') split_hemi_pipe.connect(inputnode, 'warpinv_file', warp_LR_hemi, "warp") # Align LR hemi template align_LR_hemi = pe.Node(interface=afni.Allineate(), name='align_LR_hemi') align_LR_hemi.inputs.final_interpolation = "nearestneighbour" align_LR_hemi.inputs.overwrite = True align_LR_hemi.inputs.outputtype = "NIFTI_GZ" split_hemi_pipe.connect(warp_LR_hemi, 'out_file', align_LR_hemi, "in_file") # -source split_hemi_pipe.connect(inputnode, 't1_ref_file', align_LR_hemi, "reference") # -base split_hemi_pipe.connect(inputnode, 'inv_transfo_file', align_LR_hemi, "in_matrix") # -1Dmatrix_apply split_LR = pe.Node(interface=niu.Function( input_names=["LR_mask_file"], output_names=["L_mask_file", "R_mask_file"], function=split_LR_mask), name="split_LR") split_hemi_pipe.connect(align_LR_hemi, "out_file", split_LR, 'LR_mask_file') else: print("Error, could not find LR_hemi_template or L_hemi_template and \ R_hemi_template, skipping") print(params_template.keys()) exit() # Using LH and RH masks to obtain hemisphere segmentation masks calc_L_hemi = pe.Node(interface=afni.Calc(), name='calc_L_hemi') calc_L_hemi.inputs.expr = 'a*b/b' calc_L_hemi.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(inputnode, 'segmented_file', calc_L_hemi, "in_file_a") if "LR_hemi_template" in params_template.keys(): split_hemi_pipe.connect(split_LR, 'L_mask_file', calc_L_hemi, "in_file_b") else: split_hemi_pipe.connect(align_L_hemi, 'out_file', calc_L_hemi, "in_file_b") # R_hemi calc_R_hemi = pe.Node(interface=afni.Calc(), name='calc_R_hemi') calc_R_hemi.inputs.expr = 'a*b/b' calc_R_hemi.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(inputnode, 'segmented_file', calc_R_hemi, "in_file_a") if "LR_hemi_template" in params_template.keys(): split_hemi_pipe.connect(split_LR, 'R_mask_file', calc_R_hemi, "in_file_b") else: split_hemi_pipe.connect(align_R_hemi, 'out_file', calc_R_hemi, "in_file_b") # remove cerebellum from left and right brain segmentations calc_nocb_L_hemi = pe.Node(interface=afni.Calc(), name='calc_nocb_L_hemi') calc_nocb_L_hemi.inputs.expr = '(a*(not (b)))' calc_nocb_L_hemi.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(calc_L_hemi, 'out_file', calc_nocb_L_hemi, "in_file_a") split_hemi_pipe.connect(align_cereb, 'out_file', calc_nocb_L_hemi, "in_file_b") calc_nocb_R_hemi = pe.Node(interface=afni.Calc(), name='calc_nocb_R_hemi') calc_nocb_R_hemi.inputs.expr = '(a*(not (b)))' calc_nocb_R_hemi.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(calc_R_hemi, 'out_file', calc_nocb_R_hemi, "in_file_a") split_hemi_pipe.connect(align_cereb, 'out_file', calc_nocb_R_hemi, "in_file_b") # create L/R GM and WM no-cerebellum masks from subject brain segmentation calc_GM_nocb_L_hemi = pe.Node(interface=afni.Calc(), name='calc_GM_nocb_L_hemi') calc_GM_nocb_L_hemi.inputs.expr = 'iszero(a-2)' calc_GM_nocb_L_hemi.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(calc_nocb_L_hemi, 'out_file', calc_GM_nocb_L_hemi, "in_file_a") calc_WM_nocb_L_hemi = pe.Node(interface=afni.Calc(), name='calc_WM_nocb_L_hemi') calc_WM_nocb_L_hemi.inputs.expr = 'iszero(a-3)' calc_WM_nocb_L_hemi.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(calc_nocb_L_hemi, 'out_file', calc_WM_nocb_L_hemi, "in_file_a") calc_GM_nocb_R_hemi = pe.Node(interface=afni.Calc(), name='calc_GM_nocb_R_hemi') calc_GM_nocb_R_hemi.inputs.expr = 'iszero(a-2)' calc_GM_nocb_R_hemi.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(calc_nocb_R_hemi, 'out_file', calc_GM_nocb_R_hemi, "in_file_a") calc_WM_nocb_R_hemi = pe.Node(interface=afni.Calc(), name='calc_WM_nocb_R_hemi') calc_WM_nocb_R_hemi.inputs.expr = 'iszero(a-3)' calc_WM_nocb_R_hemi.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(calc_nocb_R_hemi, 'out_file', calc_WM_nocb_R_hemi, "in_file_a") # Extract Cerebellum using template mask transformed to subject space extract_cereb = pe.Node(interface=afni.Calc(), name='extract_cereb') extract_cereb.inputs.expr = 'a*b/b' extract_cereb.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_cereb, "in_file_a") split_hemi_pipe.connect(align_cereb, 'out_file', extract_cereb, "in_file_b") # Extract L.GM using template mask transformed to subject space extract_L_GM = pe.Node(interface=afni.Calc(), name='extract_L_GM') extract_L_GM.inputs.expr = 'a*b/b' extract_L_GM.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_L_GM, "in_file_a") split_hemi_pipe.connect(calc_GM_nocb_L_hemi, 'out_file', extract_L_GM, "in_file_b") # Extract L.WM using template mask transformed to subject space extract_L_WM = pe.Node(interface=afni.Calc(), name='extract_L_WM') extract_L_WM.inputs.expr = 'a*b/b' extract_L_WM.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_L_WM, "in_file_a") split_hemi_pipe.connect(calc_WM_nocb_L_hemi, 'out_file', extract_L_WM, "in_file_b") # Extract L.GM using template mask transformed to subject space extract_R_GM = pe.Node(interface=afni.Calc(), name='extract_R_GM') extract_R_GM.inputs.expr = 'a*b/b' extract_R_GM.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_R_GM, "in_file_a") split_hemi_pipe.connect(calc_GM_nocb_R_hemi, 'out_file', extract_R_GM, "in_file_b") # Extract L.WM using template mask transformed to subject space extract_R_WM = pe.Node(interface=afni.Calc(), name='extract_R_WM') extract_R_WM.inputs.expr = 'a*b/b' extract_R_WM.inputs.outputtype = 'NIFTI_GZ' split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_R_WM, "in_file_a") split_hemi_pipe.connect(calc_WM_nocb_R_hemi, 'out_file', extract_R_WM, "in_file_b") return split_hemi_pipe
palm_corr = Node(name='palm_corr', interface=Function( input_names=['in_file', 'mask', 'design', 'contrast'], output_names=['tstat1', 'tstat2', 'P_value1', 'P_value2'], function=palm_corr)) palm_corr.iterables = [("design", designs), ("contrast", contrasts)] palm_corr.synchronize = True # synchronize here serves to make sure design and contrast are used in pairs # Not using all the possible permuatations #----------------------------------------------------------------------------------------------------- # use the tstat maps to calculate r-pearson correlation coeeficient # >>> fslmaths tstat.nii.gz -sqr tstat2.nii.gz # >>> fslmaths tstat.nii.gz -abs -div tstat.nii.gz sign.nii.gz # >>> fslmaths tstat2.nii.gz -add DF denominator.nii.gz # >>> fslmaths tstat2.nii.gz -div denominator.nii.gz -sqrt -mul sign.nii.gz correlation.nii.gz square1 = Node(fsl.UnaryMaths(), name='square1') square1.inputs.operation = 'sqr' square1.inputs.out_file = 'tstat1_squared.nii.gz' sign_t1 = Node(fsl.ImageMaths(), name='sign_t1') sign_t1.inputs.op_string = '-abs -div' sign_t1.inputs.out_file = 'sign_tstat1.nii.gz' add_df1 = Node(fsl.BinaryMaths(), name='add_df1') add_df1.inputs.operation = 'add' add_df1.inputs.operand_value = 27 #29 animals-2contrast = 27 dof add_df1.inputs.out_file = 'denominator_tstat1.nii.gz' div_by_denom1 = Node(fsl.BinaryMaths(), name='div_by_denom1') div_by_denom1.inputs.operation = 'div' div_by_denom1.inputs.out_file = 'divided_by_denominator.nii.gz'
def create_nii_to_mesh_fs_pipe(params, name="nii_to_mesh_fs_pipe"): """ Description: surface generation using freesurfer tools Params: - fill_wm (see `MRIFill <https://nipype.readthedocs.io/en/0.12.1/\ interfaces/generated/nipype.interfaces.freesurfer.utils.html#mrifill>`_) \ - also available as :ref:`indiv_params <indiv_params>` Inputs: inputnode: wm_mask_file: segmented white matter mask (binary) in template space reg_brain_file: preprocessd T1, registered to template indiv_params (opt): dict with individuals parameters for some nodes arguments: params: dictionary of node sub-parameters (from a json file) name: pipeline name (default = "nii_to_mesh_fs_pipe") Outputs: """ # creating pipeline nii_to_mesh_fs_pipe = pe.Workflow(name=name) # creating inputnode inputnode = pe.Node(niu.IdentityInterface( fields=['wm_mask_file', 'reg_brain_file', 'indiv_params']), name='inputnode') # bin_wm bin_wm = pe.Node(interface=fsl.UnaryMaths(), name="bin_wm") bin_wm.inputs.operation = "fillh" nii_to_mesh_fs_pipe.connect(inputnode, 'wm_mask_file', bin_wm, 'in_file') # resample everything refit_wm = pe.Node(interface=afni.Refit(), name="refit_wm") refit_wm.inputs.args = "-xdel 1.0 -ydel 1.0 -zdel 1.0 -keepcen" nii_to_mesh_fs_pipe.connect(bin_wm, 'out_file', refit_wm, 'in_file') # resample everything refit_reg = pe.Node(interface=afni.Refit(), name="refit_reg") refit_reg.inputs.args = "-xdel 1.0 -ydel 1.0 -zdel 1.0 -keepcen" nii_to_mesh_fs_pipe.connect(inputnode, 'reg_brain_file', refit_reg, 'in_file') # mri_convert wm to freesurfer mgz convert_wm = pe.Node(interface=fs.MRIConvert(), name="convert_wm") convert_wm.inputs.out_type = "mgz" convert_wm.inputs.conform = True nii_to_mesh_fs_pipe.connect(refit_wm, 'out_file', convert_wm, 'in_file') # mri_convert reg to freesurfer mgz convert_reg = pe.Node(interface=fs.MRIConvert(), name="convert_reg") convert_reg.inputs.out_type = "mgz" convert_reg.inputs.conform = True nii_to_mesh_fs_pipe.connect(refit_reg, 'out_file', convert_reg, 'in_file') # mri_fill fill_wm = NodeParams(interface=fs.MRIFill(), params=parse_key(params, "fill_wm"), name="fill_wm") fill_wm.inputs.out_file = "filled.mgz" nii_to_mesh_fs_pipe.connect(convert_wm, 'out_file', fill_wm, 'in_file') nii_to_mesh_fs_pipe.connect(inputnode, ("indiv_params", parse_key, "fill_wm"), fill_wm, 'indiv_params') # pretesselate wm pretess_wm = pe.Node(interface=fs.MRIPretess(), name="pretess_wm") pretess_wm.inputs.label = 255 nii_to_mesh_fs_pipe.connect(fill_wm, 'out_file', pretess_wm, 'in_filled') nii_to_mesh_fs_pipe.connect(convert_reg, 'out_file', pretess_wm, 'in_norm') # tesselate wm lh tess_wm_lh = pe.Node(interface=fs.MRITessellate(), name="tess_wm_lh") tess_wm_lh.inputs.label_value = 255 tess_wm_lh.inputs.out_file = "lh_tess" nii_to_mesh_fs_pipe.connect(pretess_wm, 'out_file', tess_wm_lh, 'in_file') # tesselate wm rh tess_wm_rh = pe.Node(interface=fs.MRITessellate(), name="tess_wm_rh") tess_wm_rh.inputs.label_value = 127 tess_wm_rh.inputs.out_file = "rh_tess" nii_to_mesh_fs_pipe.connect(pretess_wm, 'out_file', tess_wm_rh, 'in_file') # ExtractMainComponent lh extract_mc_lh = pe.Node(interface=fs.ExtractMainComponent(), name="extract_mc_lh") nii_to_mesh_fs_pipe.connect(tess_wm_lh, 'surface', extract_mc_lh, 'in_file') extract_mc_lh.inputs.out_file = "lh.lh_tess.maincmp" # ExtractMainComponent rh extract_mc_rh = pe.Node(interface=fs.ExtractMainComponent(), name="extract_mc_rh") nii_to_mesh_fs_pipe.connect(tess_wm_rh, 'surface', extract_mc_rh, 'in_file') extract_mc_rh.inputs.out_file = "rh.rh_tess.maincmp" # SmoothTessellation lh smooth_tess_lh = pe.Node(interface=fs.SmoothTessellation(), name="smooth_tess_lh") smooth_tess_lh.inputs.disable_estimates = True nii_to_mesh_fs_pipe.connect(extract_mc_lh, 'out_file', smooth_tess_lh, 'in_file') # SmoothTessellation rh smooth_tess_rh = pe.Node(interface=fs.SmoothTessellation(), name="smooth_tess_rh") smooth_tess_rh.inputs.disable_estimates = True nii_to_mesh_fs_pipe.connect(extract_mc_rh, 'out_file', smooth_tess_rh, 'in_file') return nii_to_mesh_fs_pipe
motionMask = pe.Node(fsl.maths.ApplyMask(output_type='NIFTI_GZ'), name='motionMask') # Pick the middle volume from the given run def middleVol(func): from nibabel import load funcfile = func _, _, _, timepoints = load(funcfile).shape return int((timepoints / 2) - 1) extractEPIref = pe.Node(fsl.ExtractROI(t_size=1, output_type='NIFTI_GZ'), name='extractEPIref') maskEPIref = pe.Node(fsl.UnaryMaths(operation='bin', output_type='NIFTI_GZ'), name='maskEPIref') # Despike raw data despike = pe.Node(afni.preprocess.Despike(outputtype='NIFTI_GZ'), name="despike") # Remove negative values (from despike procedure) posLimit = pe.Node(fsl.maths.Threshold(nan2zeros=True, thresh=0, output_type='NIFTI_GZ'), name='posLimit') ## Fieldmap workflow # Select magnitude image get_mag = pe.Node(fsl.ExtractROI(t_min=1, t_size=1, output_type='NIFTI_GZ'),
def ct_brain_extraction(data, working_directory=None, fractional_intensity_threshold=0.01, save_output=False, fsl_path=None): """ Automatic brain extraction of non contrast head CT images using bet2 by fsl. Ref.: Muschelli J, Ullman NL, Mould WA, Vespa P, Hanley DF, Crainiceanu CM. Validated automatic brain extraction of head CT images. NeuroImage. 2015 Jul 1;114:379–85. :param data: [str; np.ndarray] path to input data or input data in form of np.ndarray (x, y, z) :param working_directory: [str] path to directory to use to save temporary files and final output files :param fractional_intensity_threshold: fractional intensity threshold (0->1); default=0.01; smaller values give larger brain outline estimates :param save_output: [boolean] save or discard output :param fsl_path: [str], Optional path to fsl executable to help nipype find it :return: brain_mask, masked_image: np.ndarray """ if fsl_path is not None: os.environ["PATH"] += os.pathsep + fsl_path os.environ["FSLOUTPUTTYPE"] = 'NIFTI' temp_files = [] if working_directory is None: working_directory = tempfile.mkdtemp() if isinstance(data, np.ndarray): data_path = os.path.join(working_directory, 'temp_bet_input.nii') data_img = nib.Nifti1Image(data.astype('float64'), affine=None) nib.save(data_img, data_path) temp_files.append(data_path) elif os.path.exists(data): data_path = data else: raise NotImplementedError('Data has to be a path or an np.ndarray') output_file = os.path.join(working_directory, 'bet_output.nii') output_mask_file = os.path.join(working_directory, 'bet_output_mask.nii') if not save_output: temp_files.append(output_file) temp_files.append(output_mask_file) temp_intermediate_file = os.path.join(working_directory, 'temp_intermediate_file.nii') temp_files.append(temp_intermediate_file) # Thresholding Image to 0-100 # cli: fslmaths "${img}" -thr 0.000000 -uthr 100.000000 "${outfile}" thresholder1 = fsl.Threshold() thresholder1.inputs.in_file = data_path thresholder1.inputs.out_file = output_file thresholder1.inputs.thresh = 0 thresholder1.inputs.direction = 'below' thresholder1.inputs.output_type = 'NIFTI' thresholder1.run() thresholder2 = fsl.Threshold() thresholder2.inputs.in_file = output_file thresholder2.inputs.out_file = output_file thresholder2.inputs.thresh = 100 thresholder2.inputs.direction = 'above' thresholder2.inputs.output_type = 'NIFTI' thresholder2.run() # Creating 0 - 100 mask to remask after filling # cli: fslmaths "${outfile}" -bin "${tmpfile}"; # cli: fslmaths "${tmpfile}.nii.gz" -bin -fillh "${tmpfile}" binarizer1 = fsl.UnaryMaths() binarizer1.inputs.in_file = output_file binarizer1.inputs.out_file = temp_intermediate_file binarizer1.inputs.operation = 'bin' binarizer1.inputs.output_type = 'NIFTI' binarizer1.run() binarizer2 = fsl.UnaryMaths() binarizer2.inputs.in_file = temp_intermediate_file binarizer2.inputs.out_file = temp_intermediate_file binarizer2.inputs.operation = 'bin' binarizer2.inputs.output_type = 'NIFTI' binarizer2.run() fill_holes1 = fsl.UnaryMaths() fill_holes1.inputs.in_file = temp_intermediate_file fill_holes1.inputs.out_file = temp_intermediate_file fill_holes1.inputs.operation = 'fillh' fill_holes1.inputs.output_type = 'NIFTI' fill_holes1.run() # Presmoothing image # cli: fslmaths "${outfile}" - s 1 "${outfile}" smoothing = fsl.IsotropicSmooth() smoothing.inputs.in_file = output_file smoothing.inputs.out_file = output_file smoothing.inputs.sigma = 1 smoothing.inputs.output_type = 'NIFTI' smoothing.run() # Remasking Smoothed Image # cli: fslmaths "${outfile}" - mas "${tmpfile}" "${outfile}" masking1 = fsl.ApplyMask() masking1.inputs.in_file = output_file masking1.inputs.out_file = output_file masking1.inputs.mask_file = temp_intermediate_file masking1.inputs.output_type = 'NIFTI' masking1.run() # Running bet2 # cli: bet2 "${outfile}" "${outfile}" - f ${intensity} - v try: btr = fsl.BET() btr.inputs.in_file = output_file btr.inputs.out_file = output_file btr.inputs.frac = fractional_intensity_threshold btr.inputs.output_type = 'NIFTI' btr.run() except Exception as e: # sometimes nipype fails to find bet if fsl_path is not None: bet_path = os.path.join(fsl_path, 'bet2') else: bet_path = 'bet2' subprocess.run([ bet_path, output_file, output_file, '-f', str(fractional_intensity_threshold) ]) # Using fslfill to fill in any holes in mask # cli: fslmaths "${outfile}" - bin - fillh "${outfile}_Mask" binarizer3 = fsl.UnaryMaths() binarizer3.inputs.in_file = output_file binarizer3.inputs.out_file = output_mask_file binarizer3.inputs.operation = 'bin' binarizer3.inputs.output_type = 'NIFTI' binarizer3.run() fill_holes2 = fsl.UnaryMaths() fill_holes2.inputs.in_file = output_mask_file fill_holes2.inputs.out_file = output_mask_file fill_holes2.inputs.operation = 'fillh' fill_holes2.inputs.output_type = 'NIFTI' fill_holes2.run() # Using the filled mask to mask original image # cli: fslmaths "${img}" -mas "${outfile}_Mask" "${outfile}" masking2 = fsl.ApplyMask() masking2.inputs.in_file = data_path masking2.inputs.out_file = output_file masking2.inputs.mask_file = output_mask_file masking2.inputs.output_type = 'NIFTI' masking2.run() brain_mask = nib.load(output_mask_file).get_fdata() masked_image = nib.load(output_file).get_fdata() # delete temporary files for file in temp_files: os.remove(file) if not save_output: shutil.rmtree(working_directory) return brain_mask, masked_image
nilearn_smoothing = Node(name='nilearn_smoothing', interface=Function(input_names=['image'], output_names=['smoothed_output'], function=nilearn_smoothing)) #----------------------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------- #mask only FA values > 0.2 to gurantee it is WM thresh_FA = Node(fsl.Threshold(), name='thresh_FA') thresh_FA.inputs.thresh = 0.2 #----------------------------------------------------------------------------------------------------- #binarize this mask binarize_FA = Node(fsl.UnaryMaths(), name='binarize_FA') binarize_FA.inputs.operation = 'bin' binarize_FA.inputs.output_datatype = 'char' #----------------------------------------------------------------------------------------------------- #randomise on the smoothed all images randomise_VBA = Node(fsl.Randomise(), name='randomise_vba') randomise_VBA.inputs.design_mat = design randomise_VBA.inputs.tcon = contrast randomise_VBA.inputs.num_perm = 10000 randomise_VBA.inputs.tfce = True randomise_VBA.inputs.vox_p_values = True randomise_VBA.inputs.base_name = 'VBA_' #----------------------------------------------------------------------------------------------------- DTI_TBSS_Wax.connect([
# wraps command fslmaths with -mul flag # node_fslmath_multiply = pe.Node(interface=fsl.BinaryMaths(), name='node_fslmath_multiply') # uncomment for individual node testing # #node_fslmath_multiply.inputs.in_file = root_dir + despot1_nuc #node_fslmath_multiply.inputs.in_file = node_N4BiasFieldCorrection.inputs.output_image node_fslmath_multiply.inputs.operand_file = root_dir + despot1_mask node_fslmath_multiply.inputs.operation = "mul" node_fslmath_multiply.inputs.out_file = root_dir + despot1_nuc_masked #print node_fslmath_multiply.interface.cmdline # wraps command fslmaths with -bin flag # node_fslmath_binarize = pe.Node(interface=fsl.UnaryMaths(), name='node_fslmath_binarize') node_fslmath_binarize.inputs.operation = 'bin' node_fslmath_binarize.inputs.in_file = root_dir + highres_bet node_fslmath_binarize.inputs.out_file = root_dir + highres_mask #print node_fslmath_binarize.interface.cmdline # wraps command mri_convert # # mRs = mri_Resample #highres node_mRs = pe.Node(interface=fsurfer.Resample(), name='node_mRs') node_mRs.inputs.voxel_size = resampleVS node_mRs.inputs.in_file = root_dir + highres node_mRs.inputs.resampled_file = root_dir + resampled_highres #print node_mRs.interface.cmdline
def create_extract_pipe(params_template, params={}, name="extract_pipe"): """ Description: Extract T1 brain using AtlasBrex Inputs: inputnode: restore_T1: preprocessed (debiased/denoised) T1 file name restore_T1: preprocessed (debiased/denoised)T2 file name arguments: params_template: dictionary of info about template params: dictionary of node sub-parameters (from a json file) name: pipeline name (default = "extract_pipe") Outputs: smooth_mask.out_file: Computed mask (after some smoothing) """ # creating pipeline extract_pipe = pe.Workflow(name=name) # creating inputnode inputnode = pe.Node( niu.IdentityInterface(fields=['restore_T1', 'restore_T2', "indiv_params"]), name='inputnode') # atlas_brex atlas_brex = NodeParams(AtlasBREX(), params=parse_key(params, "atlas_brex"), name='atlas_brex') extract_pipe.connect(inputnode, "restore_T1", atlas_brex, 't1_restored_file') atlas_brex.inputs.NMT_file = params_template["template_head"] atlas_brex.inputs.NMT_SS_file = params_template["template_brain"] extract_pipe.connect( inputnode, ("indiv_params", parse_key, "atlas_brex"), atlas_brex, 'indiv_params') # mask_brex mask_brex = pe.Node(fsl.UnaryMaths(), name='mask_brex') mask_brex.inputs.operation = 'bin' extract_pipe.connect(atlas_brex, 'brain_file', mask_brex, 'in_file') # smooth_mask smooth_mask = pe.Node(fsl.UnaryMaths(), name='smooth_mask') smooth_mask.inputs.operation = "bin" smooth_mask.inputs.args = "-s 1 -thr 0.5 -bin" extract_pipe.connect(mask_brex, 'out_file', smooth_mask, 'in_file') # mult_T1 mult_T1 = pe.Node(afni.Calc(), name='mult_T1') mult_T1.inputs.expr = "a*b" mult_T1.inputs.outputtype = 'NIFTI_GZ' extract_pipe.connect(inputnode, "restore_T1", mult_T1, 'in_file_a') extract_pipe.connect(smooth_mask, 'out_file', mult_T1, 'in_file_b') # mult_T2 mult_T2 = pe.Node(afni.Calc(), name='mult_T2') mult_T2.inputs.expr = "a*b" mult_T2.inputs.outputtype = 'NIFTI_GZ' extract_pipe.connect(inputnode, 'restore_T2', mult_T2, 'in_file_a') extract_pipe.connect(smooth_mask, 'out_file', mult_T2, 'in_file_b') return extract_pipe
def create_segment_atropos_pipe(params={}, name="segment_atropos_pipe", space="native"): """ Description: Segmentation with ANTS atropos script Params: - Atropos (see :class:`AtroposN4 <macapype.nodes.segment.AtroposN4>`) - threshold_gm, threshold_wm, threshold_csf (see `Threshold \ <https://nipype.readthedocs.io/en/0.12.1/interfaces/generated/nipype.\ interfaces.fsl.maths.html#threshold>`_ for arguments) Inputs: inputnode: brain_file: T1 image, after extraction and norm bin_norm_intensity gm_prior_file: grey matter tissue intensity file wm_prior_file: white matter tissue intensity file csf_prior_file: csf tissue intensity file arguments: params: dictionary of node sub-parameters (from a json file) name: pipeline name (default = "segment_atropos_pipe") Outputs: threshold_csf.out_file: csf tissue intensity mask in subject space threshold_gm.out_file: grey matter tissue intensity mask in subject space threshold_wm.out_file: white matter tissue intensity mask in subject space """ # creating pipeline segment_pipe = pe.Workflow(name=name) # creating inputnode inputnode = pe.Node(niu.IdentityInterface(fields=[ "brain_file", "gm_prior_file", "wm_prior_file", "csf_prior_file" ]), name='inputnode') # bin_norm_intensity (a cheat from Kepkee if I understood well!) bin_norm_intensity = pe.Node(fsl.UnaryMaths(), name="bin_norm_intensity") bin_norm_intensity.inputs.operation = "bin" segment_pipe.connect(inputnode, "brain_file", bin_norm_intensity, "in_file") if "use_priors" in params.keys(): # copying header from img to csf_prior_file copy_header_to_csf = pe.Node(niu.Function( input_names=['ref_img', 'img_to_modify'], output_names=['modified_img'], function=copy_header), name='copy_header_to_csf') segment_pipe.connect(inputnode, "brain_file", copy_header_to_csf, "ref_img") segment_pipe.connect(inputnode, 'csf_prior_file', copy_header_to_csf, "img_to_modify") # copying header from img to gm_prior_file copy_header_to_gm = pe.Node(niu.Function( input_names=['ref_img', 'img_to_modify'], output_names=['modified_img'], function=copy_header), name='copy_header_to_gm') segment_pipe.connect(inputnode, "brain_file", copy_header_to_gm, "ref_img") segment_pipe.connect(inputnode, 'gm_prior_file', copy_header_to_gm, "img_to_modify") # copying header from img to wm_prior_file copy_header_to_wm = pe.Node(niu.Function( input_names=['ref_img', 'img_to_modify'], output_names=['modified_img'], function=copy_header), name='copy_header_to_wm') segment_pipe.connect(inputnode, "brain_file", copy_header_to_wm, "ref_img") segment_pipe.connect(inputnode, 'wm_prior_file', copy_header_to_wm, "img_to_modify") # merging priors as a list merge_3_elem = pe.Node(niu.Function( input_names=['elem1', 'elem2', 'elem3'], output_names=['merged_list'], function=merge_3_elem_to_list), name='merge_3_elem') # was like this before (1 -> csf, 2 -> gm, 3 -> wm, to check) segment_pipe.connect(copy_header_to_csf, 'modified_img', merge_3_elem, "elem1") segment_pipe.connect(copy_header_to_gm, 'modified_img', merge_3_elem, "elem2") segment_pipe.connect(copy_header_to_wm, 'modified_img', merge_3_elem, "elem3") # Atropos seg_at = NodeParams(AtroposN4(), params=parse_key(params, "Atropos"), name='seg_at') segment_pipe.connect(inputnode, "brain_file", seg_at, "brain_file") segment_pipe.connect(bin_norm_intensity, 'out_file', seg_at, "brainmask_file") if "use_priors" in params.keys(): segment_pipe.connect(merge_3_elem, 'merged_list', seg_at, "priors") seg_at.inputs.prior_weight = params["use_priors"] # Threshold GM, WM and CSF thd_nodes = {} for i, tissue in enumerate(['csf', 'gm', 'wm']): tmp_node = NodeParams(fsl.Threshold(), params=parse_key(params, "threshold_" + tissue), name="threshold_" + tissue) segment_pipe.connect(seg_at, ('segmented_files', get_elem, i), tmp_node, 'in_file') thd_nodes[tissue] = tmp_node outputnode = pe.Node(niu.IdentityInterface(fields=[ "segmented_file", "threshold_gm", "threshold_wm", "threshold_csf" ]), name='outputnode') segment_pipe.connect(seg_at, 'segmented_file', outputnode, 'segmented_file') segment_pipe.connect(thd_nodes["gm"], 'out_file', outputnode, 'threshold_gm') segment_pipe.connect(thd_nodes["wm"], 'out_file', outputnode, 'threshold_wm') segment_pipe.connect(thd_nodes["csf"], 'out_file', outputnode, 'threshold_csf') return segment_pipe
def create_EPI_DistCorr(use_BET, wf_name='epi_distcorr'): """ Fieldmap correction takes in an input magnitude image which is Skull Stripped (Tight). The magnitude images are obtained from each echo series. It also requires a phase image as an input, the phase image is a subtraction of the two phase images from each echo. Created on Thu Nov 9 10:44:47 2017 @author: nrajamani Order of commands and inputs: -- SkullStrip: 3d-SkullStrip (or FSL-BET) is used to strip the non-brain (tissue) regions from the fMRI Parameters: -f, default: 0.5 in_file: fmap_mag -- fslmath_mag: Magnitude image is eroded using the -ero option in fslmath, in order to remove the non-zero voxels Parameters: -ero in_file:fmap_mag -- bet_anat : Brain extraction of the anat file to provide as an input for the epi-registration interface Parameters: -f, default: 0.5 in_file: anat_file -- fast_anat : Fast segmentation to provide partial volume files of the anat file, which is further processed to provide the white mater segmentation input for the epi-registration interface. The most important output required from this is the second segment, (e.g.,'T1_brain_pve_2.nii.gz') Parameters: -img_type = 1 -bias_iters = 10 (-I) -bias_lowpass = 10 (-l) in_file: brain_extracted anat_file -- fslmath_anat: The output of the FAST interface is then analyzed to select all the voxels with more than 50% partial volume into the binary mask Parameters: -thr = 0.5 in_file : T1_brain_pve_2 -- fslmath_wmseg:The selected voxels are now used to create a binary mask which would can then be sent as the white matter segmentation (wm_seg) Parameters: -bin in_file: T1_brain_pve_2 -- Prepare :Preparing the fieldmap. Parameters: -deltaTE = default, 2.46 ms -Scanner = SIEMENS in_files: fmap_phase fmap_magnitude For more details, check:https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FUGUE/Guide -- FUGUE :One of the steps in EPI-DistCorrection toolbox, it unwarps the fieldmaps Parameters: dwell_to_asymm ratio = (0.77e-3 * 3)/(2.46e-3) dwell time = 0.0005 ms in_file = field map which is a 4D image (containing 2 unwarpped image) """ preproc = pe.Workflow(name=wf_name) inputNode = pe.Node( util.IdentityInterface(fields=['anat_file', 'fmap_pha', 'fmap_mag']), name='inputspec') inputNode_delTE = pe.Node(util.IdentityInterface(fields=['deltaTE']), name='deltaTE_input') inputNode_dwellT = pe.Node(util.IdentityInterface(fields=['dwellT']), name='dwellT_input') inputNode_dwell_asym_ratio = pe.Node( util.IdentityInterface(fields=['dwell_asym_ratio']), name='dwell_asym_ratio_input') inputNode_bet_frac = pe.Node(util.IdentityInterface(fields=['bet_frac']), name='bet_frac_input') inputNode_afni_threshold = pe.Node( util.IdentityInterface(fields=['afni_threshold']), name='afni_threshold_input') outputNode = pe.Node(util.IdentityInterface( fields=['fieldmap', 'fmap_despiked', 'fmapmagbrain', 'fieldmapmask']), name='outputspec') # Skull-strip, outputs a masked image file if use_BET == False: skullstrip_args = pe.Node(util.Function(input_names=['shrink_fac'], output_names=['expr'], function=createAFNIiterable), name='distcorr_skullstrip_arg') preproc.connect(inputNode_afni_threshold, 'afni_threshold', skullstrip_args, 'shrink_fac') bet = pe.Node(interface=afni.SkullStrip(), name='bet') bet.inputs.outputtype = 'NIFTI_GZ' preproc.connect(skullstrip_args, 'expr', bet, 'args') preproc.connect(inputNode, 'fmap_mag', bet, 'in_file') preproc.connect(bet, 'out_file', outputNode, 'magnitude_image') else: bet = pe.Node(interface=fsl.BET(), name='bet') bet.inputs.output_type = 'NIFTI_GZ' preproc.connect(inputNode_bet_frac, 'bet_frac', bet, 'frac') preproc.connect(inputNode, 'fmap_mag', bet, 'in_file') preproc.connect(bet, 'out_file', outputNode, 'magnitude_image') # Prepare Fieldmap # prepare the field map prepare = pe.Node(interface=fsl.epi.PrepareFieldmap(), name='prepare') prepare.inputs.output_type = "NIFTI_GZ" preproc.connect(inputNode_delTE, 'deltaTE', prepare, 'delta_TE') preproc.connect(inputNode, 'fmap_pha', prepare, 'in_phase') preproc.connect(bet, 'out_file', prepare, 'in_magnitude') preproc.connect(prepare, 'out_fieldmap', outputNode, 'fieldmap') # erode the masked magnitude image fslmath_mag = pe.Node(interface=fsl.ErodeImage(), name='fslmath_mag') preproc.connect(bet, 'out_file', fslmath_mag, 'in_file') preproc.connect(fslmath_mag, 'out_file', outputNode, 'fmapmagbrain') # calculate the absolute value of the eroded and masked magnitude # image fslmath_abs = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_abs') fslmath_abs.inputs.operation = 'abs' preproc.connect(fslmath_mag, 'out_file', fslmath_abs, 'in_file') preproc.connect(fslmath_abs, 'out_file', outputNode, 'fmapmag_abs') # binarize the absolute value of the eroded and masked magnitude # image fslmath_bin = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_bin') fslmath_bin.inputs.operation = 'bin' preproc.connect(fslmath_abs, 'out_file', fslmath_bin, 'in_file') preproc.connect(fslmath_bin, 'out_file', outputNode, 'fmapmag_bin') # take the absolute value of the fieldmap calculated in the prepare step fslmath_mask_1 = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_mask_1') fslmath_mask_1.inputs.operation = 'abs' preproc.connect(prepare, 'out_fieldmap', fslmath_mask_1, 'in_file') preproc.connect(fslmath_mask_1, 'out_file', outputNode, 'fieldmapmask_abs') # binarize the absolute value of the fieldmap calculated in the prepare step fslmath_mask_2 = pe.Node(interface=fsl.UnaryMaths(), name='fslmath_mask_2') fslmath_mask_2.inputs.operation = 'bin' preproc.connect(fslmath_mask_1, 'out_file', fslmath_mask_2, 'in_file') preproc.connect(fslmath_mask_2, 'out_file', outputNode, 'fieldmapmask_bin') # multiply together the binarized magnitude and fieldmap images fslmath_mask = pe.Node(interface=fsl.BinaryMaths(), name='fslmath_mask') fslmath_mask.inputs.operation = 'mul' preproc.connect(fslmath_mask_2, 'out_file', fslmath_mask, 'in_file') preproc.connect(fslmath_bin, 'out_file', fslmath_mask, 'operand_file') preproc.connect(fslmath_mask, 'out_file', outputNode, 'fieldmapmask') # Note for the user. Ensure the phase image is within 0-4096 (upper # threshold is 90% of 4096), fsl_prepare_fieldmap will only work in the # case of the SIEMENS format. #Maybe we could use deltaTE also as an # option in the GUI. # fugue fugue1 = pe.Node(interface=fsl.FUGUE(), name='fugue1') fugue1.inputs.save_fmap = True fugue1.outputs.fmap_out_file = 'fmap_rads' preproc.connect(fslmath_mask, 'out_file', fugue1, 'mask_file') preproc.connect(inputNode_dwellT, 'dwellT', fugue1, 'dwell_time') preproc.connect(inputNode_dwell_asym_ratio, 'dwell_asym_ratio', fugue1, 'dwell_to_asym_ratio') preproc.connect(prepare, 'out_fieldmap', fugue1, 'fmap_in_file') preproc.connect(fugue1, 'fmap_out_file', outputNode, 'fmap_despiked') return preproc
def create_restingstatefmri_preprocessing_pipeline(in_fmri, in_t1, in_segmentation, in_parcellation, output_dir, in_mag=None, in_phase=None, in_susceptibility_parameters=None, name='restingstatefmri'): """Perform pre-processing steps for the resting state fMRI using AFNI Parameters ---------- :: name : name of workflow (default: restingstatefmri) Inputs:: in_fmri : functional runs into a single 4D image in NIFTI format in_t1 : The structural T1 image in_segmentation : The segmentation image containing 6 volumes (background, CSF, GM, WM, deep GM, brainstem), in the space of the fMRI image in_parcellation : The parcellation image coming out of the GIF parcellation algorithm output_dir : The output directory for the workflow in_mag : *OPT*, magnitude image to use for susceptibility correction (default: None) in_phase : *OPT*, phase image to use for susceptibility correction (default: None) in_susceptibility_parameters : *OPT*, susceptibility parameters (in a vector: read-out-time, echo time difference, phase encoding direction], default : None) name : *OPT*, name of the workflow (default : restingstatefmri) Outputs:: Example ------- >>> preproc = create_restingstatefmri_preprocessing_pipeline(in_fmri, in_t1, in_segmentation, in_parcellation, output_dir) # doctest: +SKIP >>> preproc.base_dir = '/tmp' # doctest: +SKIP >>> preproc.run() # doctest: +SKIP """ workflow = pe.Workflow(name=name) workflow.base_output_dir = name # We need to create an input node for the workflow input_node = pe.Node( niu.IdentityInterface( fields=['in_fmri', 'in_t1', 'in_segmentation', 'in_parcellation']), name='input_node') input_node.inputs.in_fmri = in_fmri input_node.inputs.in_t1 = in_t1 input_node.inputs.in_segmentation = in_segmentation input_node.inputs.in_parcellation = in_parcellation resting_state_preproc = pe.Node(interface=RestingStatefMRIPreprocess(), name='resting_state_preproc') workflow.connect(input_node, 'in_fmri', resting_state_preproc, 'in_fmri') workflow.connect(input_node, 'in_t1', resting_state_preproc, 'in_t1') workflow.connect(input_node, 'in_segmentation', resting_state_preproc, 'in_tissue_segmentation') workflow.connect(input_node, 'in_parcellation', resting_state_preproc, 'in_parcellation') # fMRI QC plot plotter = pe.Node(interface=FmriQcPlot(), name='plotter') workflow.connect(input_node, 'in_fmri', plotter, 'in_raw_fmri') workflow.connect(resting_state_preproc, 'out_raw_fmri_gm', plotter, 'in_raw_fmri_gm') workflow.connect(resting_state_preproc, 'out_raw_fmri_wm', plotter, 'in_raw_fmri_wm') workflow.connect(resting_state_preproc, 'out_raw_fmri_csf', plotter, 'in_raw_fmri_csf') workflow.connect(resting_state_preproc, 'out_mrp_file', plotter, 'in_mrp_file') workflow.connect(resting_state_preproc, 'out_spike_file', plotter, 'in_spike_file') workflow.connect(resting_state_preproc, 'out_rms_file', plotter, 'in_rms_file') # Output node output_node = pe.Node(interface=niu.IdentityInterface(fields=['out_corrected_fmri', 'out_atlas_fmri', 'out_fmri_to_t1_transformation', 'out_raw_fmri_gm', 'out_raw_fmri_wm', 'out_raw_fmri_csf', 'out_fmri_qc', 'out_motioncorrected_file']), name="output_node") workflow.connect(resting_state_preproc, 'out_corrected_fmri', output_node, 'out_corrected_fmri') workflow.connect(resting_state_preproc, 'out_atlas_fmri', output_node, 'out_atlas_fmri') workflow.connect(resting_state_preproc, 'out_fmri_to_t1_transformation', output_node, 'out_fmri_to_t1_transformation') workflow.connect(resting_state_preproc, 'out_raw_fmri_gm', output_node, 'out_raw_fmri_gm') workflow.connect(resting_state_preproc, 'out_raw_fmri_wm', output_node, 'out_raw_fmri_wm') workflow.connect(resting_state_preproc, 'out_raw_fmri_csf', output_node, 'out_raw_fmri_csf') workflow.connect(resting_state_preproc, 'out_motioncorrected_file', output_node, 'out_motioncorrected_file') workflow.connect(plotter, 'out_file', output_node, 'out_fmri_qc') ds = pe.Node(nio.DataSink(), name='ds') ds.inputs.base_directory = os.path.abspath(output_dir) ds.inputs.parameterization = False workflow.connect(output_node, 'out_fmri_to_t1_transformation', ds, '@fmri_to_t1_transformation') workflow.connect(output_node, 'out_atlas_fmri', ds, '@atlas_in_fmri') workflow.connect(output_node, 'out_raw_fmri_gm', ds, '@gm_in_fmri') workflow.connect(output_node, 'out_raw_fmri_wm', ds, '@wm_in_fmri') workflow.connect(output_node, 'out_raw_fmri_csf', ds, '@csf_in_fmri') workflow.connect(output_node, 'out_fmri_qc', ds, '@fmri_qc') if in_mag is None or in_phase is None or in_susceptibility_parameters is None: workflow.connect(output_node, 'out_motioncorrected_file', ds, '@motioncorrected_file') workflow.connect(output_node, 'out_corrected_fmri', ds, '@corrected_fmri') else: split_fmri = pe.Node(interface=fsl.Split(dimension='t'), name='split_fmri') workflow.connect(output_node, 'out_motioncorrected_file', split_fmri, 'in_file') select_1st_fmri = pe.Node(interface=niu.Select(index=0), name='select_1st_fmri') workflow.connect(split_fmri, 'out_files', select_1st_fmri, 'inlist') binarise_parcellation = pe.Node(interface=fsl.UnaryMaths(operation='bin'), name='binarise_parcellation') workflow.connect(input_node, 'in_parcellation', binarise_parcellation, 'in_file') # Perform susceptibility correction, where we already have a mask in the b0 space susceptibility_correction = create_fieldmap_susceptibility_workflow('susceptibility_correction', reg_to_t1=True) susceptibility_correction.inputs.input_node.mag_image = os.path.abspath(in_mag) susceptibility_correction.inputs.input_node.phase_image = os.path.abspath(in_phase) susceptibility_correction.inputs.input_node.t1 = os.path.abspath(in_t1) susceptibility_correction.inputs.input_node.rot = in_susceptibility_parameters[0] susceptibility_correction.inputs.input_node.etd = in_susceptibility_parameters[1] susceptibility_correction.inputs.input_node.ped = in_susceptibility_parameters[2] workflow.connect(select_1st_fmri, 'out', susceptibility_correction, 'input_node.epi_image') workflow.connect(binarise_parcellation, 'out_file', susceptibility_correction, 'input_node.t1_mask') fmri_corrected_resample = pe.Node(interface=niftyreg.RegResample(inter_val='LIN'), name='fmri_corrected_resample') workflow.connect(output_node, 'out_corrected_fmri', fmri_corrected_resample, 'ref_file') workflow.connect(output_node, 'out_corrected_fmri', fmri_corrected_resample, 'flo_file') workflow.connect(susceptibility_correction.get_node('output_node'), 'out_field', fmri_corrected_resample, 'trans_file') workflow.connect(fmri_corrected_resample, 'out_file', ds, '@corrected_fmri') fmri_motion_corrected_resample = pe.Node(interface=niftyreg.RegResample(inter_val='LIN'), name='fmri_motion_corrected_resample') workflow.connect(output_node, 'out_motioncorrected_file', fmri_motion_corrected_resample, 'ref_file') workflow.connect(output_node, 'out_motioncorrected_file', fmri_motion_corrected_resample, 'flo_file') workflow.connect(susceptibility_correction.get_node('output_node'), 'out_field', fmri_motion_corrected_resample, 'trans_file') workflow.connect(fmri_motion_corrected_resample, 'out_file', ds, '@motioncorrected_file') return workflow