def init_fsl(self, in_file: str, ref: str, out_file: str, field_file: str): aw = fsl.ApplyWarp() aw.inputs.in_file = in_file aw.inputs.out_file = out_file aw.inputs.field_file = field_file aw.inputs.ref_file = ref return aw
def func2mni_wf(): mni_skull_2mm = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm.nii.gz' mni_brain_2mm = '/usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain.nii.gz' flow = Workflow('func2mni_nonlinear') inputnode = Node(util.IdentityInterface(fields=['func_image', 'reference_image', 'func2anat_affine', 'anat2mni_warp']),name = 'inputnode') outputnode = Node(util.IdentityInterface(fields=['func2mni_2mm', 'func2mni_4mm']),name = 'outputnode') applywarp = Node(fsl.ApplyWarp(), name = 'apply_warp',) applywarp.inputs.ref_file = mni_brain_2mm flirt4mm = Node(fsl.FLIRT(), name = 'resample_4mm') flirt4mm.inputs.reference = mni_brain_2mm flirt4mm.inputs.apply_isoxfm = 4.0 flow.connect(inputnode, 'func_image' , applywarp, 'in_file') flow.connect(inputnode, 'anat2mni_warp' , applywarp, 'field_file') flow.connect(inputnode, 'func2anat_affine' , applywarp, 'premat') flow.connect(applywarp, 'out_file' , flirt4mm, 'in_file') flow.connect(applywarp, 'out_file' , outputnode, 'func2mni_2mm') flow.connect(flirt4mm, 'out_file' , outputnode, 'func2mni_4mm') return flow
def apply_warp( in_file: Path, ref: Path, warp: Path, out_file: Path, interp: str = None ): """ Apply pre-calculated warp field coefficients to normalize an image. Parameters ---------- in_file : Path Path to image to be normalized ref : Path Path to reference image warp : Path Path to pre-calculated warp field out_file : Path Path to output warped image """ aw = fsl.ApplyWarp() aw.inputs.in_file = in_file aw.inputs.ref_file = ref aw.inputs.field_file = warp aw.inputs.out_file = out_file if interp: aw.inputs.interp = interp return aw
def create_templates_2func_workflow(threshold=0.5, name='templates_2func_workflow'): templates_2func_workflow = Workflow(name=name) # Input Node inputspec = Node(utility.IdentityInterface(fields=[ 'func_file', 'premat', 'warp', 'templates', ]), name='inputspec') # Get the overal EPI to MNI warp func_2mni_warp = Node(fsl.ConvertWarp(), name='func_2mni_warp') func_2mni_warp.inputs.reference = fsl.Info.standard_image( 'MNI152_T1_2mm.nii.gz') # Calculate the inverse warp mni_2func_warp = Node(fsl.InvWarp(), name='mni_2func_warp') # Transform MNI templates to EPI space templates_2func_apply = MapNode(fsl.ApplyWarp(), iterfield=['in_file'], name='templates_2func_apply') # Threshold templates templates_threshold = MapNode( fsl.ImageMaths(op_string='-thr {0} -bin'.format(threshold)), iterfield=['in_file'], name='templates_threshold') # Output Node outputspec = Node(utility.IdentityInterface( fields=['templates_2func_files', 'func_2mni_warp']), name='outputspec') # Connect the workflow nodes templates_2func_workflow.connect(inputspec, 'premat', func_2mni_warp, 'premat') templates_2func_workflow.connect(inputspec, 'warp', func_2mni_warp, 'warp1') templates_2func_workflow.connect(inputspec, 'func_file', mni_2func_warp, 'reference') templates_2func_workflow.connect(func_2mni_warp, 'out_file', mni_2func_warp, 'warp') templates_2func_workflow.connect(inputspec, 'templates', templates_2func_apply, 'in_file') templates_2func_workflow.connect(inputspec, 'func_file', templates_2func_apply, 'ref_file') templates_2func_workflow.connect(mni_2func_warp, 'inverse_warp', templates_2func_apply, 'field_file') templates_2func_workflow.connect(templates_2func_apply, 'out_file', templates_threshold, 'in_file') templates_2func_workflow.connect(func_2mni_warp, 'out_file', outputspec, 'func_2mni_warp') templates_2func_workflow.connect(templates_threshold, 'out_file', outputspec, 'templates_2func_files') return templates_2func_workflow
def create_normalize_workflow(name="normalize"): # Define the workflow inputs inputnode = pe.Node(util.IdentityInterface( fields=["timeseries", "flirt_affine", "warpfield"]), name="inputs") # Define the target space and warp to it mni152 = fsl.Info.standard_image("avg152T1_brain.nii.gz") applywarp = pe.MapNode(fsl.ApplyWarp(ref_file=mni152, interp="spline"), iterfield=["in_file", "premat"], name="applywarp") # Rename the timeseries rename = pe.MapNode(util.Rename(format_string="timeseries_warped", keep_ext=True), iterfield=["in_file"], name="rename") # Define the outputs outputnode = pe.Node(util.IdentityInterface(fields=["timeseries"]), name="outputs") normalize = pe.Workflow(name=name) normalize.connect([ (inputnode, applywarp, [("timeseries", "in_file"), ("warpfield", "field_file"), ("flirt_affine", "premat")]), (applywarp, rename, [("out_file", "in_file")]), (rename, outputnode, [("out_file", "timeseries")]), ]) return normalize
def test_nonlinear_register(): from ..registration import create_nonlinear_register from CPAC.pipeline import nipype_pipeline_engine as pe import nipype.interfaces.fsl as fsl ## necessary inputs ## -input_brain ## -input_skull ## -reference_brain ## -reference_skull ## -fnirt_config ## -fnirt_warp_res ## input_brain anat_bet_file = '/home/data/Projects/nuisance_reliability_paper/working_dir_CPAC_order/resting_preproc/anatpreproc/_session_id_NYU_TRT_session1_subject_id_sub05676/anat_skullstrip/mprage_anonymized_RPI_3dT.nii.gz' ## input_skull ## reference_brain mni_file = '/usr/share/fsl/4.1/data/standard/MNI152_T1_3mm_brain.nii.gz' ## reference_skull ## fnirt_config fnirt_config = 'T1_2_MNI152_3mm' ## fnirt_warp_res fnirt_warp_res = None #?? what is this for?: func_file = '/home/data/Projects/nuisance_reliability_paper/working_dir_CPAC_order/resting_preproc/nuisance_preproc/_session_id_NYU_TRT_session1_subject_id_sub05676/_csf_threshold_0.4/_gm_threshold_0.2/_wm_threshold_0.66/_run_scrubbing_False/_nc_5/_selector_6.7/regress_nuisance/mapflow/_regress_nuisance0/residual.nii.gz' mni_workflow = pe.Workflow(name='mni_workflow') linear_reg = pe.Node(interface=fsl.FLIRT(), name='linear_reg_0') linear_reg.inputs.cost = 'corratio' linear_reg.inputs.dof = 6 linear_reg.inputs.interp = 'nearestneighbour' linear_reg.inputs.in_file = func_file linear_reg.inputs.reference = anat_bet_file #T1 to MNI Node c = create_nonlinear_register() c.inputs.inputspec.input = anat_bet_file c.inputs.inputspec.reference = '/usr/share/fsl/4.1/data/standard/MNI152_T1_3mm_brain.nii.gz' c.inputs.inputspec.fnirt_config = 'T1_2_MNI152_3mm' #EPI to MNI warp Node mni_warp = pe.Node(interface=fsl.ApplyWarp(), name='mni_warp') mni_warp.inputs.ref_file = '/usr/share/fsl/4.1/data/standard/MNI152_T1_3mm_brain.nii.gz' mni_warp.inputs.in_file = func_file mni_workflow.connect(c, 'outputspec.nonlinear_xfm', mni_warp, 'field_file') mni_workflow.connect(linear_reg, 'out_matrix_file', mni_warp, 'premat') mni_workflow.base_dir = './' mni_workflow.run()
def apply_all_corrections(name='UnwarpArtifacts'): """ Combines two lists of linear transforms with the deformation field map obtained typically after the SDC process. Additionally, computes the corresponding bspline coefficients and the map of determinants of the jacobian. """ inputnode = pe.Node(niu.IdentityInterface(fields=['in_sdc', 'in_hmc', 'in_ecc', 'in_dwi']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_warp', 'out_coeff', 'out_jacobian']), name='outputnode') warps = pe.MapNode(fsl.ConvertWarp(relwarp=True), iterfield=['premat', 'postmat'], name='ConvertWarp') selref = pe.Node(niu.Select(index=[0]), name='Reference') split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs') unwarp = pe.MapNode(fsl.ApplyWarp(), iterfield=['in_file', 'field_file'], name='UnwarpDWIs') coeffs = pe.MapNode(fsl.WarpUtils(out_format='spline'), iterfield=['in_file'], name='CoeffComp') jacobian = pe.MapNode(fsl.WarpUtils(write_jacobian=True), iterfield=['in_file'], name='JacobianComp') jacmult = pe.MapNode(fsl.MultiImageMaths(op_string='-mul %s'), iterfield=['in_file', 'operand_files'], name='ModulateDWIs') thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'], name='RemoveNegative') merge = pe.Node(fsl.Merge(dimension='t'), name='MergeDWIs') wf = pe.Workflow(name=name) wf.connect([ (inputnode, warps, [('in_sdc', 'warp1'), ('in_hmc', 'premat'), ('in_ecc', 'postmat'), ('in_dwi', 'reference')]), (inputnode, split, [('in_dwi', 'in_file')]), (split, selref, [('out_files', 'inlist')]), (warps, unwarp, [('out_file', 'field_file')]), (split, unwarp, [('out_files', 'in_file')]), (selref, unwarp, [('out', 'ref_file')]), (selref, coeffs, [('out', 'reference')]), (warps, coeffs, [('out_file', 'in_file')]), (selref, jacobian, [('out', 'reference')]), (coeffs, jacobian, [('out_file', 'in_file')]), (unwarp, jacmult, [('out_file', 'in_file')]), (jacobian, jacmult, [('out_jacobian', 'operand_files')]), (jacmult, thres, [('out_file', 'in_file')]), (thres, merge, [('out_file', 'in_files')]), (warps, outputnode, [('out_file', 'out_warp')]), (coeffs, outputnode, [('out_file', 'out_coeff')]), (jacobian, outputnode, [('out_jacobian', 'out_jacobian')]), (merge, outputnode, [('merged_file', 'out_file')]) ]) return wf
def _run_interface(self, runtime): for in_file in self.inputs.in_files: ax = fsl.ApplyWarp(in_file=in_file, interp=self.inputs.interp, field_file=self.inputs.field_file, ref_file=self.inputs.ref_file) ax.run() return runtime
def preprocess_and_tmp_save_fmri(data_path, task, subj, model, tmp_path, group_mask=None): ''' Generator for preprocessed fMRI runs from one subject of Forrest Gump aligns to group template run-wise linear de-trending and z-scoring IN: data_path - string, path pointing to the Forrest Gump directory task - string, which part of the Forrest Gump dataset to load subj - int, subject to pre-process tmp_path - string, path to save the dataset temporarily to OUT: preprocessed fMRI samples per run''' from nipype.interfaces import fsl dhandle = mvpa.OpenFMRIDataset(data_path) flavor = 'dico_bold7Tp1_to_subjbold7Tp1' if group_mask is None: group_mask = os.path.join(data_path, 'sub{0:03d}'.format(subj), 'templates', 'bold7Tp1', 'in_grpbold7Tp1', 'brain_mask.nii.gz') mask_fname = os.path.join(data_path, 'sub{0:03d}'.format(subj), 'templates', 'bold7Tp1', 'brain_mask.nii.gz') for run_id in dhandle.get_task_bold_run_ids(task)[subj]: run_ds = dhandle.get_bold_run_dataset(subj, task, run_id, chunks=run_id - 1, mask=mask_fname, flavor=flavor) filename = 'brain_subj_{}_run_{}.nii.gz'.format(subj, run_id) tmp_file = os.path.join(tmp_path, filename) save(unmask(run_ds.samples.astype('float32'), mask_fname), tmp_file) warp = fsl.ApplyWarp() warp.inputs.in_file = tmp_file warp.inputs.out_file = os.path.join(tmp_path, 'group_' + filename) warp.inputs.ref_file = os.path.join(data_path, 'templates', 'grpbold7Tp1', 'brain.nii.gz') warp.inputs.field_file = os.path.join(data_path, 'sub{0:03d}'.format(subj), 'templates', 'bold7Tp1', 'in_grpbold7Tp1', 'subj2tmpl_warp.nii.gz') warp.inputs.interp = 'nn' warp.run() os.remove(tmp_file) run_ds = mvpa.fmri_dataset(os.path.join(tmp_path, 'group_' + filename), mask=group_mask, chunks=run_id - 1) mvpa.poly_detrend(run_ds, polyord=1) mvpa.zscore(run_ds) os.remove(os.path.join(tmp_path, 'group_' + filename)) yield run_ds.samples.astype('float32')
def create_realign_flow(name='realign'): """Realign a time series to the middle volume using spline interpolation Uses MCFLIRT to realign the time series and ApplyWarp to apply the rigid body transformations using spline interpolation (unknown order). Example ------- >>> wf = create_realign_flow() >>> wf.inputs.inputspec.func = 'f3.nii' >>> wf.run() # doctest: +SKIP """ realignflow = pe.Workflow(name=name) inputnode = pe.Node(interface=util.IdentityInterface(fields=[ 'func', ]), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface( fields=['realigned_file', 'rms_files', 'par_file']), name='outputspec') start_dropper = pe.Node(util.Function( input_names=['in_vol_fn', 'n_frames'], output_names=['out_fn'], function=remove_first_n_frames), name='start_dropper') start_dropper.inputs.n_frames = 5 realigner = pe.Node(fsl.MCFLIRT(save_mats=True, stats_imgs=True, save_rms=True, save_plots=True), name='realigner') splitter = pe.Node(fsl.Split(dimension='t'), name='splitter') warper = pe.MapNode(fsl.ApplyWarp(interp='spline'), iterfield=['in_file', 'premat'], name='warper') joiner = pe.Node(fsl.Merge(dimension='t'), name='joiner') realignflow.connect(inputnode, 'func', start_dropper, 'in_vol_fn') realignflow.connect(start_dropper, 'out_fn', realigner, 'in_file') realignflow.connect(start_dropper, ('out_fn', select_volume, 'middle'), realigner, 'ref_vol') realignflow.connect(realigner, 'out_file', splitter, 'in_file') realignflow.connect(realigner, 'mat_file', warper, 'premat') realignflow.connect(realigner, 'variance_img', warper, 'ref_file') realignflow.connect(splitter, 'out_files', warper, 'in_file') realignflow.connect(warper, 'out_file', joiner, 'in_files') realignflow.connect(joiner, 'merged_file', outputnode, 'realigned_file') realignflow.connect(realigner, 'rms_files', outputnode, 'rms_files') realignflow.connect(realigner, 'par_file', outputnode, 'par_file') return realignflow
def apply_warp(in_file: Path, ref: Path, warp: Path, out_file: Path): """ Apply non-linear warp file in an image to resample it to another one Arguments: in_file {Path} -- [Image to apply non-linear warp on] ref {Path} -- [Image to resample to] warp {Path} -- [non-linear warp file] out_file {Path} -- [Output image] """ aw = fsl.ApplyWarp() aw.inputs.in_file = in_file aw.inputs.ref_file = ref aw.inputs.field_file = warp aw.inputs.out_file = out_file return aw
def CBF_modulation_( self, CBF_dir ): """CBF applyed GM Modulation.""" try: # # # Loop on the tasks while True: # get the item item = self.queue_CBF_.get() # find the corresponding GM GM_warp_coeff = "%s_non_li_template_coeff.nii.gz"%(item[4:-7]) GM_warp_jac = "%s_non_li_template_jac.nii.gz"%(item[4:-7]) # apply the GM warp aw = fsl.ApplyWarp() aw.inputs.in_file = os.path.join(CBF_dir, item ) aw.inputs.ref_file = self.template_ aw.inputs.out_file = os.path.join( self.template_dir_, "%s_non_li_template_warped.nii.gz"%item[:-7] ) aw.inputs.field_file = os.path.join( self.template_dir_, GM_warp_coeff ) res = aw.run() # Modulate with the GM jacobian maths = fsl.ImageMaths() maths.inputs.in_file = os.path.join(self.template_dir_, "%s_non_li_template_warped.nii.gz"%item[:-7]) maths.inputs.op_string = '-mul %s'%( os.path.join(self.template_dir_, GM_warp_jac) ) maths.inputs.out_file = os.path.join( self.template_dir_, "%s_modulated.nii.gz"%item[:-7] ) maths.inputs.out_data_type = "float" maths.run(); # lock and add the file singlelock.acquire() self.CBF_warped_template_.append( aw.inputs.out_file ) self.CBF_modulated_template_.append( maths.inputs.out_file ) singlelock.release() # job is done self.queue_CBF_.task_done() # # except Exception as inst: print inst _log.error(inst) quit(-1) except IOError as e: print "I/O error({0}): {1}".format(e.errno, e.strerror) quit(-1) except: print "Unexpected error:", sys.exc_info()[0] quit(-1)
def create_normalization_wf(transformations=["mni2func"]): wf = pe.Workflow(name="normalization") inputspec = pe.Node(util.IdentityInterface(fields=[ 'T1', 'skullstripped_T1', 'preprocessed_epi', 'func2anat_transform' ]), name="inputspec") anat2mni = create_nonlinear_register("anat2mni") linear_reg = anat2mni.get_node("linear_reg_0") linear_reg.inputs.searchr_x = [-180, 180] linear_reg.inputs.searchr_y = [-180, 180] linear_reg.inputs.searchr_z = [-180, 180] skull_mgz2nii = pe.Node(fs.MRIConvert(out_type="nii"), name="skull_mgs2nii") brain_mgz2nii = skull_mgz2nii.clone(name="brain_mgs2nii") wf.connect(inputspec, "skullstripped_T1", brain_mgz2nii, "in_file") wf.connect(inputspec, "T1", skull_mgz2nii, "in_file") anat2mni.inputs.inputspec.reference_skull = fsl.Info.standard_image( "MNI152_T1_2mm.nii.gz") anat2mni.inputs.inputspec.reference_brain = fsl.Info.standard_image( "MNI152_T1_2mm_brain.nii.gz") anat2mni.inputs.inputspec.fnirt_config = "T1_2_MNI152_2mm" wf.connect(skull_mgz2nii, "out_file", anat2mni, "inputspec.input_skull") wf.connect(brain_mgz2nii, "out_file", anat2mni, "inputspec.input_brain") if 'mni2func' in transformations: invert_warp = pe.Node(fsl.InvWarp(), name="invert_warp") wf.connect(anat2mni, "outputspec.nonlinear_xfm", invert_warp, "warp_file") wf.connect(skull_mgz2nii, "out_file", invert_warp, "ref_file") if 'func2mni' in transformations: mni_warp = pe.Node(interface=fsl.ApplyWarp(), name='mni_warp') mni_warp.inputs.ref_file = fsl.Info.standard_image( "MNI152_T1_2mm.nii.gz") wf.connect(inputspec, 'preprocessed_epi', mni_warp, 'in_file') wf.connect(anat2mni, 'outputspec.nonlinear_xfm', mni_warp, 'field_file') wf.connect(inputspec, 'func2anat_transform', mni_warp, 'premat') return wf
def apply_warp(in_file, ref_file, field_file, output_dir, recalculate=False, **kwargs): """Wrapper for the Nipype FSL applywarp wrapper. Please remember to set the kwarg interp='nn' if you are warping a file with discrete ROI's. Args: in_file: image to be warped ref_file: the reference image field_file: file containing warp field (this is the --warp parameter from FSL applywarp) output_dir: the output directory recalculate (boolean): if we recalculate if the output already exists. Set this to False to easily get the output easily. **kwargs: extra arguments for the Nipype FSL applywarp Returns: dict: location of the output files: - warped_image: the path to the output image. """ output_file = os.path.join(output_dir, 'warped_' + os.path.basename(in_file)) output = {'warped_image': output_file} if not recalculate and os.path.isfile(output_file): return output aw = fsl.ApplyWarp(**kwargs) aw.inputs.in_file = in_file aw.inputs.ref_file = ref_file aw.inputs.field_file = field_file aw.inputs.out_file = output_file applywarp = pe.Node(aw, name='applywarp') applywarp.base_dir = os.path.join(output_dir, '_nipype_work_dir') applywarp.run() return output
def apply_warp_( self, Dir_list ): """.""" try: # # # # Loop on the tasks while True: # get the item item = os.path.join( Dir_list, self.queue_warp_.get() ) # # Find the matching T1 image PIDN = [int(s) for s in item.split("_") if s.isdigit()] # warping_coeff = [ s for s in os.listdir(self.template_dir_) if str(PIDN[0]) in s and "template_coeff" in s] # Warp the brain aw = fsl.ApplyWarp() aw.inputs.in_file = item aw.inputs.ref_file = self.template_ aw.inputs.out_file = "%s_MNI.nii.gz"%item[:-7] aw.inputs.field_file = os.path.join( self.template_dir_, warping_coeff[0] ) res = aw.run() # job is done self.queue_warp_.task_done() # # except Exception as inst: print inst _log.error(inst) quit(-1) except IOError as e: print "I/O error({0}): {1}".format(e.errno, e.strerror) quit(-1) except: print "Unexpected error:", sys.exc_info()[0] quit(-1)
def create_workflow(config: AttrDict, resource_pool: ResourcePool, context: Context): for _, rp in resource_pool[['brain', 'label-reorient_T1w']]: # TODO: disable skullstrip linear_reg = NipypeJob(interface=fsl.FLIRT(cost='corratio'), reference='linear_reg_0') inv_flirt_xfm = NipypeJob( interface=fsl.utils.ConvertXFM(invert_xfm=True), reference='inv_linear_reg0_xfm') linear_reg.in_file = rp[R('brain')] linear_reg.reference = config.template_brain linear_reg.interp = config.interpolation inv_flirt_xfm.in_file = linear_reg.out_matrix_file if config.linear_only: rp[R('brain', space='MNI')] = linear_reg.out_file # other xfm return else: nonlinear_reg = NipypeJob(interface=fsl.FNIRT(fieldcoeff_file=True, jacobian_file=True), reference='nonlinear_reg_1') brain_warp = NipypeJob(interface=fsl.ApplyWarp(), reference='brain_warp') nonlinear_reg.in_file = rp[R('T1w', label='reorient')] nonlinear_reg.ref_file = config.template_skull nonlinear_reg.refmask_file = config.ref_mask nonlinear_reg.config_file = config.fnirt_config nonlinear_reg.affine_file = linear_reg.out_matrix_file brain_warp.interp = config.interpolation brain_warp.in_file = rp[R('brain')] brain_warp.field_file = nonlinear_reg.fieldcoeff_file brain_warp.ref_file = config.template_brain rp[R('brain', space='MNI')] = brain_warp.out_file
def create_indnet_workflow(hp_cutoff=100, smoothing=5, smm_threshold=0.5, binarise_threshold=0.5, melodic_seed=None, aggr_aroma=False, name="indnet"): indnet = Workflow(name=name) # Input node inputspec = Node(utility.IdentityInterface( fields=['anat_file', 'func_file', 'templates', 'networks']), name='inputspec') # T1 skullstrip anat_bet = Node(fsl.BET(), name="anat_bet") # EPI preprocessing func_realignsmooth = create_featreg_preproc(highpass=False, whichvol='first', name='func_realignsmooth') func_realignsmooth.inputs.inputspec.fwhm = smoothing # Transform EPI to MNI space func_2mni = create_reg_workflow(name='func_2mni') func_2mni.inputs.inputspec.target_image = fsl.Info.standard_image( 'MNI152_T1_2mm.nii.gz') func_2mni.inputs.inputspec.target_image_brain = fsl.Info.standard_image( 'MNI152_T1_2mm_brain.nii.gz') func_2mni.inputs.inputspec.config_file = 'T1_2_MNI152_2mm' # Segmentation of T1 anat_segmentation = Node(fsl.FAST(output_biascorrected=True), name='anat_segmentation') # Transfrom segments to EPI space segments_2func = create_segments_2func_workflow( threshold=binarise_threshold, name='segments_2func') # Transform templates to EPI space templates_2func = create_templates_2func_workflow( threshold=binarise_threshold, name='templates_2func') # Mask network templates with GM gm_mask_templates = MapNode(fsl.ImageMaths(op_string='-mul'), iterfield=['in_file2'], name='gm_mask_templates') # Mask for ICA-AROMA and statistics func_brainmask = Node(fsl.BET(frac=0.3, mask=True, no_output=True, robust=True), name='func_brainmask') # Melodic ICA if melodic_seed != None: func_melodic = Node(fsl.MELODIC(args='--seed={}'.format(melodic_seed), out_stats=True), name='func_melodic') # ICA-AROMA func_aroma = Node(fsl.ICA_AROMA(), name='func_aroma') if aggr_aroma: func_aroma.inputs.denoise_type = 'aggr' else: func_aroma.inputs.denoise_type = 'nonaggr' # Highpass filter ICA results func_highpass = create_highpass_filter(cutoff=hp_cutoff, name='func_highpass') # Calculate mean CSF sgnal csf_meansignal = Node(fsl.ImageMeants(), name='csf_meansignal') # Calculate mean WM signal wm_meansignal = Node(fsl.ImageMeants(), name='wm_meansignal') # Calculate mean non-brain signal nonbrain_meansignal = create_nonbrain_meansignal( name='nonbrain_meansignal') # Calculate first Eigenvariates firsteigenvariates = MapNode(fsl.ImageMeants(show_all=True, eig=True), iterfield=['mask'], name='firsteigenvariates') # Combine first eigenvariates and wm/csf/non-brain signals regressors = Node(utility.Merge(4), name='regressors') # z-transform regressors ztransform = MapNode(Ztransform(), iterfield=['in_file'], name='ztransform') # Create design matrix designmatrix = Node(DesignMatrix(), name='designmatrix') # Create contrasts contrasts = Node(Contrasts(), name='contrasts') # GLM glm = Node(fsl.GLM(), name='glm') glm.inputs.out_z_name = 'z_stats.nii.gz' glm.inputs.demean = True # Split z-maps zmaps = Node(fsl.Split(), name='zmaps') zmaps.inputs.dimension = 't' # Spatial Mixture Modelling smm = MapNode(fsl.SMM(), iterfield=['spatial_data_file'], name='smm') # Transform probability maps to native (anat) space actmaps_2anat = MapNode(fsl.ApplyXFM(), iterfield=['in_file'], name='actmaps_2anat') # Transform probability maps to MNI space actmaps_2mni = MapNode(fsl.ApplyWarp(), iterfield=['in_file'], name='actmaps_2mni') actmaps_2mni.inputs.ref_file = fsl.Info.standard_image( 'MNI152_T1_2mm.nii.gz') # Create network masks in native (func) space network_masks_func = create_network_masks_workflow( name='network_masks_func', smm_threshold=smm_threshold) # Create network masks in native (anat) space network_masks_anat = create_network_masks_workflow( name='network_masks_anat', smm_threshold=smm_threshold) # Create network masks in MNI space network_masks_mni = create_network_masks_workflow( name='network_masks_mni', smm_threshold=smm_threshold) # Output node outputspec = Node(utility.IdentityInterface(fields=[ 'network_masks_func_main', 'network_masks_func_exclusive', 'network_masks_anat_main', 'network_masks_anat_exclusive', 'network_masks_mni_main', 'network_masks_mni_exclusive', 'preprocessed_func_file', 'preprocessed_anat_file', 'motion_parameters', 'func2anat_transform', 'anat2mni_transform' ]), name='outputspec') # Helper functions def get_first_item(x): try: return x[0] except: return x def get_second_item(x): return x[1] def get_third_item(x): return x[2] def get_components(x): return [y['components'] for y in x] # Connect the nodes # anat_bet indnet.connect(inputspec, 'anat_file', anat_bet, 'in_file') # func_realignsmooth indnet.connect(inputspec, 'func_file', func_realignsmooth, 'inputspec.func') # func_2mni indnet.connect(func_realignsmooth, ('outputspec.smoothed_files', get_first_item), func_2mni, 'inputspec.source_files') indnet.connect(inputspec, 'anat_file', func_2mni, 'inputspec.anatomical_image') indnet.connect(func_realignsmooth, 'outputspec.reference', func_2mni, 'inputspec.mean_image') # anat_segmentation indnet.connect(anat_bet, 'out_file', anat_segmentation, 'in_files') # segments_2func indnet.connect(anat_segmentation, 'partial_volume_files', segments_2func, 'inputspec.segments') indnet.connect(func_2mni, 'outputspec.func2anat_transform', segments_2func, 'inputspec.premat') indnet.connect(func_realignsmooth, 'outputspec.mean', segments_2func, 'inputspec.func_file') # templates_2func indnet.connect(func_realignsmooth, 'outputspec.mean', templates_2func, 'inputspec.func_file') indnet.connect(func_2mni, 'outputspec.func2anat_transform', templates_2func, 'inputspec.premat') indnet.connect(func_2mni, 'outputspec.anat2target_transform', templates_2func, 'inputspec.warp') indnet.connect(inputspec, 'templates', templates_2func, 'inputspec.templates') # gm_mask_templates indnet.connect(segments_2func, ('outputspec.segments_2func_files', get_second_item), gm_mask_templates, 'in_file') indnet.connect(templates_2func, 'outputspec.templates_2func_files', gm_mask_templates, 'in_file2') # func_brainmask indnet.connect(func_realignsmooth, 'outputspec.mean', func_brainmask, 'in_file') # func_melodic if melodic_seed != None: indnet.connect(func_realignsmooth, ('outputspec.smoothed_files', get_first_item), func_melodic, 'in_files') indnet.connect(func_brainmask, 'mask_file', func_melodic, 'mask') # func_aroma indnet.connect(func_realignsmooth, ('outputspec.smoothed_files', get_first_item), func_aroma, 'in_file') indnet.connect(func_2mni, 'outputspec.func2anat_transform', func_aroma, 'mat_file') indnet.connect(func_2mni, 'outputspec.anat2target_transform', func_aroma, 'fnirt_warp_file') indnet.connect(func_realignsmooth, ('outputspec.motion_parameters', get_first_item), func_aroma, 'motion_parameters') indnet.connect(func_brainmask, 'mask_file', func_aroma, 'mask') if melodic_seed != None: indnet.connect(func_melodic, 'out_dir', func_aroma, 'melodic_dir') # func_highpass if aggr_aroma: indnet.connect(func_aroma, 'aggr_denoised_file', func_highpass, 'inputspec.in_file') else: indnet.connect(func_aroma, 'nonaggr_denoised_file', func_highpass, 'inputspec.in_file') # csf_meansignal indnet.connect(segments_2func, ('outputspec.segments_2func_files', get_first_item), csf_meansignal, 'mask') indnet.connect(func_highpass, 'outputspec.filtered_file', csf_meansignal, 'in_file') # wm_meansignal indnet.connect(segments_2func, ('outputspec.segments_2func_files', get_third_item), wm_meansignal, 'mask') indnet.connect(func_highpass, 'outputspec.filtered_file', wm_meansignal, 'in_file') # nonbrain_meansignal indnet.connect(inputspec, 'func_file', nonbrain_meansignal, 'inputspec.func_file') # firsteigenvariates indnet.connect(gm_mask_templates, 'out_file', firsteigenvariates, 'mask') indnet.connect(func_highpass, 'outputspec.filtered_file', firsteigenvariates, 'in_file') # regressors indnet.connect(firsteigenvariates, 'out_file', regressors, 'in1') indnet.connect(wm_meansignal, 'out_file', regressors, 'in2') indnet.connect(csf_meansignal, 'out_file', regressors, 'in3') indnet.connect(nonbrain_meansignal, 'outputspec.nonbrain_regressor', regressors, 'in4') # ztransform indnet.connect(regressors, 'out', ztransform, 'in_file') # designmatrix indnet.connect(ztransform, 'out_file', designmatrix, 'in_files') # contrasts indnet.connect(inputspec, ('networks', get_components), contrasts, 'in_list') indnet.connect(designmatrix, 'out_file', contrasts, 'design') # glm indnet.connect(designmatrix, 'out_file', glm, 'design') indnet.connect(contrasts, 'out_file', glm, 'contrasts') indnet.connect(func_brainmask, 'mask_file', glm, 'mask') indnet.connect(func_highpass, 'outputspec.filtered_file', glm, 'in_file') # zmaps indnet.connect(glm, 'out_z', zmaps, 'in_file') # smm indnet.connect(zmaps, 'out_files', smm, 'spatial_data_file') indnet.connect(func_brainmask, 'mask_file', smm, 'mask') # actmaps_2anat indnet.connect(smm, 'activation_p_map', actmaps_2anat, 'in_file') indnet.connect(func_2mni, 'outputspec.func2anat_transform', actmaps_2anat, 'in_matrix_file') indnet.connect(anat_bet, 'out_file', actmaps_2anat, 'reference') # actmaps_2mni indnet.connect(smm, 'activation_p_map', actmaps_2mni, 'in_file') indnet.connect(templates_2func, 'outputspec.func_2mni_warp', actmaps_2mni, 'field_file') # network_masks_func indnet.connect(smm, 'activation_p_map', network_masks_func, 'inputspec.actmaps') indnet.connect(inputspec, 'networks', network_masks_func, 'inputspec.networks') # network_masks_anat indnet.connect(actmaps_2anat, 'out_file', network_masks_anat, 'inputspec.actmaps') indnet.connect(inputspec, 'networks', network_masks_anat, 'inputspec.networks') # network_masks_mni indnet.connect(actmaps_2mni, 'out_file', network_masks_mni, 'inputspec.actmaps') indnet.connect(inputspec, 'networks', network_masks_mni, 'inputspec.networks') # output node indnet.connect(network_masks_func, 'outputspec.main_masks', outputspec, 'network_masks_func_main') indnet.connect(network_masks_func, 'outputspec.exclusive_masks', outputspec, 'network_masks_func_exclusive') indnet.connect(network_masks_anat, 'outputspec.main_masks', outputspec, 'network_masks_anat_main') indnet.connect(network_masks_anat, 'outputspec.exclusive_masks', outputspec, 'network_masks_anat_exclusive') indnet.connect(network_masks_mni, 'outputspec.main_masks', outputspec, 'network_masks_mni_main') indnet.connect(network_masks_mni, 'outputspec.exclusive_masks', outputspec, 'network_masks_mni_exclusive') indnet.connect(func_highpass, 'outputspec.filtered_file', outputspec, 'preprocessed_func_file') indnet.connect(anat_segmentation, 'restored_image', outputspec, 'preprocessed_anat_file') indnet.connect(func_realignsmooth, ('outputspec.motion_parameters', get_first_item), outputspec, 'motion_parameters') indnet.connect(func_2mni, 'outputspec.func2anat_transform', outputspec, 'func2anat_transform') indnet.connect(func_2mni, 'outputspec.anat2target_transform', outputspec, 'anat2mni_transform') return indnet
def create_nonlinear_register(name='nonlinear_register'): """ Performs non-linear registration of an input file to a reference file. Parameters ---------- name : string, optional Name of the workflow. Returns ------- nonlinear_register : nipype.pipeline.engine.Workflow Notes ----- Workflow Inputs:: inputspec.input_brain : string (nifti file) File of brain to be normalized (registered) inputspec.input_skull : string (nifti file) File of input brain with skull inputspec.reference_brain : string (nifti file) Target brain file to normalize to inputspec.reference_skull : string (nifti file) Target brain with skull to normalize to inputspec.fnirt_config : string (fsl fnirt config file) Configuration file containing parameters that can be specified in fnirt Workflow Outputs:: outputspec.output_brain : string (nifti file) Normalizion of input brain file outputspec.linear_xfm : string (.mat file) Affine matrix of linear transformation of brain file outputspec.invlinear_xfm : string Inverse of affine matrix of linear transformation of brain file outputspec.nonlinear_xfm : string Nonlinear field coefficients file of nonlinear transformation Registration Procedure: 1. Perform a linear registration to get affine transformation matrix. 2. Perform a nonlinear registration on an input file to the reference file utilizing affine transformation from the previous step as a starting point. 3. Invert the affine transformation to provide the user a transformation (affine only) from the space of the reference file to the input file. Workflow Graph: .. image:: ../images/nonlinear_register.dot.png :width: 500 Detailed Workflow Graph: .. image:: ../images/nonlinear_register_detailed.dot.png :width: 500 """ nonlinear_register = pe.Workflow(name=name) inputspec = pe.Node(util.IdentityInterface(fields=[ 'input_brain', 'input_skull', 'reference_brain', 'reference_skull', 'fnirt_config' ]), name='inputspec') outputspec = pe.Node(util.IdentityInterface(fields=[ 'output_brain', 'linear_xfm', 'invlinear_xfm', 'nonlinear_xfm' ]), name='outputspec') linear_reg = pe.Node(interface=fsl.FLIRT(), name='linear_reg_0') linear_reg.inputs.cost = 'corratio' nonlinear_reg = pe.Node(interface=fsl.FNIRT(), name='nonlinear_reg_1') nonlinear_reg.inputs.fieldcoeff_file = True nonlinear_reg.inputs.jacobian_file = True brain_warp = pe.Node(interface=fsl.ApplyWarp(), name='brain_warp') inv_flirt_xfm = pe.Node(interface=fsl.utils.ConvertXFM(), name='inv_linear_reg0_xfm') inv_flirt_xfm.inputs.invert_xfm = True nonlinear_register.connect(inputspec, 'input_brain', linear_reg, 'in_file') nonlinear_register.connect(inputspec, 'reference_brain', linear_reg, 'reference') nonlinear_register.connect(inputspec, 'input_skull', nonlinear_reg, 'in_file') nonlinear_register.connect(inputspec, 'reference_skull', nonlinear_reg, 'ref_file') # FNIRT parameters are specified by FSL config file # ${FSLDIR}/etc/flirtsch/TI_2_MNI152_2mm.cnf (or user-specified) nonlinear_register.connect(inputspec, 'fnirt_config', nonlinear_reg, 'config_file') nonlinear_register.connect(linear_reg, 'out_matrix_file', nonlinear_reg, 'affine_file') nonlinear_register.connect(nonlinear_reg, 'fieldcoeff_file', outputspec, 'nonlinear_xfm') nonlinear_register.connect(inputspec, 'input_brain', brain_warp, 'in_file') nonlinear_register.connect(nonlinear_reg, 'fieldcoeff_file', brain_warp, 'field_file') nonlinear_register.connect(inputspec, 'reference_brain', brain_warp, 'ref_file') nonlinear_register.connect(brain_warp, 'out_file', outputspec, 'output_brain') nonlinear_register.connect(linear_reg, 'out_matrix_file', inv_flirt_xfm, 'in_file') nonlinear_register.connect(inv_flirt_xfm, 'out_file', outputspec, 'invlinear_xfm') nonlinear_register.connect(linear_reg, 'out_matrix_file', outputspec, 'linear_xfm') return nonlinear_register
def create_register_func_to_mni(name='register_func_to_mni'): """ Registers a functional scan in native space to MNI standard space. This is meant to be used after create_nonlinear_register() has been run and relies on some of it's outputs. Parameters ---------- name : string, optional Name of the workflow. Returns ------- register_func_to_mni : nipype.pipeline.engine.Workflow Notes ----- Workflow Inputs:: inputspec.func : string (nifti file) Input functional scan to be registered to MNI space inputspec.mni : string (nifti file) Reference MNI file inputspec.anat : string (nifti file) Corresponding anatomical scan of subject inputspec.interp : string Type of interpolation to use ('trilinear' or 'nearestneighbour' or 'sinc') inputspec.anat_to_mni_nonlinear_xfm : string (warp file) Corresponding anatomical native space to MNI warp file inputspec.anat_to_mni_linear_xfm : string (mat file) Corresponding anatomical native space to MNI mat file Workflow Outputs:: outputspec.func_to_anat_linear_xfm : string (mat file) Affine transformation from functional to anatomical native space outputspec.func_to_mni_linear_xfm : string (mat file) Affine transformation from functional to MNI space outputspec.mni_to_func_linear_xfm : string (mat file) Affine transformation from MNI to functional space outputspec.mni_func : string (nifti file) Functional scan registered to MNI standard space Workflow Graph: .. image:: ../images/register_func_to_mni.dot.png :width: 500 Detailed Workflow Graph: .. image:: ../images/register_func_to_mni_detailed.dot.png :width: 500 """ register_func_to_mni = pe.Workflow(name=name) inputspec = pe.Node(util.IdentityInterface(fields=[ 'func', 'mni', 'anat', 'interp', 'anat_to_mni_nonlinear_xfm', 'anat_to_mni_linear_xfm' ]), name='inputspec') outputspec = pe.Node(util.IdentityInterface(fields=[ 'func_to_anat_linear_xfm', 'func_to_mni_linear_xfm', 'mni_to_func_linear_xfm', 'mni_func' ]), name='outputspec') linear_reg = pe.Node(interface=fsl.FLIRT(), name='linear_func_to_anat') linear_reg.inputs.cost = 'corratio' linear_reg.inputs.dof = 6 mni_warp = pe.Node(interface=fsl.ApplyWarp(), name='mni_warp') mni_affine = pe.Node(interface=fsl.ConvertXFM(), name='mni_affine') mni_affine.inputs.concat_xfm = True register_func_to_mni.connect(linear_reg, 'out_matrix_file', mni_affine, 'in_file2') register_func_to_mni.connect(inputspec, 'anat_to_mni_linear_xfm', mni_affine, 'in_file') register_func_to_mni.connect(mni_affine, 'out_file', outputspec, 'func_to_mni_linear_xfm') inv_mni_affine = pe.Node(interface=fsl.ConvertXFM(), name='inv_mni_affine') inv_mni_affine.inputs.invert_xfm = True register_func_to_mni.connect(mni_affine, 'out_file', inv_mni_affine, 'in_file') register_func_to_mni.connect(inv_mni_affine, 'out_file', outputspec, 'mni_to_func_linear_xfm') register_func_to_mni.connect(inputspec, 'func', linear_reg, 'in_file') register_func_to_mni.connect(inputspec, 'anat', linear_reg, 'reference') register_func_to_mni.connect(inputspec, 'interp', linear_reg, 'interp') register_func_to_mni.connect(inputspec, 'func', mni_warp, 'in_file') register_func_to_mni.connect(inputspec, 'mni', mni_warp, 'ref_file') register_func_to_mni.connect(inputspec, 'anat_to_mni_nonlinear_xfm', mni_warp, 'field_file') register_func_to_mni.connect(linear_reg, 'out_matrix_file', mni_warp, 'premat') register_func_to_mni.connect(linear_reg, 'out_matrix_file', outputspec, 'func_to_anat_linear_xfm') register_func_to_mni.connect(mni_warp, 'out_file', outputspec, 'mni_func') return register_func_to_mni
def create_vmhc(use_ants, name='vmhc_workflow', ants_threads=1): """ Compute the map of brain functional homotopy, the high degree of synchrony in spontaneous activity between geometrically corresponding interhemispheric (i.e., homotopic) regions. Parameters ---------- None Returns ------- vmhc_workflow : workflow Voxel Mirrored Homotopic Connectivity Analysis Workflow Notes ----- `Source <https://github.com/FCP-INDI/C-PAC/blob/master/CPAC/vmhc/vmhc.py>`_ Workflow Inputs:: inputspec.brain : string (existing nifti file) Anatomical image(without skull) inputspec.symmetric_brain : string (existing nifti file) MNI152_T1_2mm_symmetric_brain.nii.gz inputspec.rest_res_filt : string (existing nifti file) Band passed Image with nuisance signal regressed out(and optionally scrubbed). Recommended bandpass filter (0.001,0.1) ) inputspec.reorient : string (existing nifti file) RPI oriented anatomical data inputspec.example_func2highres_mat : string (existing affine transformation .mat file) Specifies an affine transform that should be applied to the example_func before non linear warping inputspec.standard_for_func: string (existing nifti file) MNI152_T1_standard_resolution_brain.nii.gz inputspec.symmetric_skull : string (existing nifti file) MNI152_T1_2mm_symmetric.nii.gz inputspec.twomm_brain_mask_dil : string (existing nifti file) MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz inputspec.config_file_twomm_symmetric : string (existing .cnf file) T1_2_MNI152_2mm_symmetric.cnf inputspec.rest_mask : string (existing nifti file) A mask functional volume(derived by dilation from motion corrected functional volume) fwhm_input.fwhm : list (float) For spatial smoothing the Z-transformed correlations in MNI space. Generally the value of this parameter is 1.5 or 2 times the voxel size of the input Image. inputspec.mean_functional : string (existing nifti file) The mean functional image for use in the func-to-anat registration matrix conversion to ITK (ANTS) format, if the user selects to use ANTS. Workflow Outputs:: outputspec.highres2symmstandard : string (nifti file) Linear registration of T1 image to symmetric standard image outputspec.highres2symmstandard_mat : string (affine transformation .mat file) An affine transformation .mat file from linear registration and used in non linear registration outputspec.highres2symmstandard_warp : string (nifti file) warp file from Non Linear registration of T1 to symmetrical standard brain outputspec.fnirt_highres2symmstandard : string (nifti file) Non Linear registration of T1 to symmetrical standard brain outputspec.highres2symmstandard_jac : string (nifti file) jacobian determinant image from Non Linear registration of T1 to symmetrical standard brain outputspec.rest_res_2symmstandard : string (nifti file) nonlinear registration (func to standard) image outputspec.VMHC_FWHM_img : string (nifti file) pearson correlation between res2standard and flipped res2standard outputspec.VMHC_Z_FWHM_img : string (nifti file) Fisher Z transform map outputspec.VMHC_Z_stat_FWHM_img : string (nifti file) Z statistic map Order of commands: - Perform linear registration of Anatomical brain in T1 space to symmetric standard space. For details see `flirt <http://www.fmrib.ox.ac.uk/fsl/flirt/index.html>`_:: flirt -ref MNI152_T1_2mm_symmetric_brain.nii.gz -in mprage_brain.nii.gz -out highres2symmstandard.nii.gz -omat highres2symmstandard.mat -cost corratio -searchcost corratio -dof 12 -interp trilinear - Perform nonlinear registration (higres to standard) to symmetric standard brain. For details see `fnirt <http://fsl.fmrib.ox.ac.uk/fsl/fnirt/>`_:: fnirt --in=head.nii.gz --aff=highres2symmstandard.mat --cout=highres2symmstandard_warp.nii.gz --iout=fnirt_highres2symmstandard.nii.gz --jout=highres2symmstandard_jac.nii.gz --config=T1_2_MNI152_2mm_symmetric.cnf --ref=MNI152_T1_2mm_symmetric.nii.gz --refmask=MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz --warpres=10,10,10 - Perform spatial smoothing on the input functional image(inputspec.rest_res_filt). For details see `PrinciplesSmoothing <http://imaging.mrc-cbu.cam.ac.uk/imaging/PrinciplesSmoothing>`_ `fslmaths <http://www.fmrib.ox.ac.uk/fslcourse/lectures/practicals/intro/index.htm>`_:: fslmaths rest_res_filt.nii.gz -kernel gauss FWHM/ sqrt(8-ln(2)) -fmean -mas rest_mask.nii.gz rest_res_filt_FWHM.nii.gz - Apply nonlinear registration (func to standard). For details see `applywarp <http://www.fmrib.ox.ac.uk/fsl/fnirt/warp_utils.html#applywarp>`_:: applywarp --ref=MNI152_T1_2mm_symmetric.nii.gz --in=rest_res_filt_FWHM.nii.gz --out=rest_res_2symmstandard.nii.gz --warp=highres2symmstandard_warp.nii.gz --premat=example_func2highres.mat - Copy and L/R swap the output of applywarp command (rest_res_2symmstandard.nii.gz). For details see `fslswapdim <http://fsl.fmrib.ox.ac.uk/fsl/fsl4.0/avwutils/index.html>`_:: fslswapdim rest_res_2symmstandard.nii.gz -x y z tmp_LRflipped.nii.gz - Calculate pearson correlation between rest_res_2symmstandard.nii.gz and flipped rest_res_2symmstandard.nii.gz(tmp_LRflipped.nii.gz). For details see `3dTcorrelate <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dTcorrelate.html>`_:: 3dTcorrelate -pearson -polort -1 -prefix VMHC_FWHM.nii.gz rest_res_2symmstandard.nii.gz tmp_LRflipped.nii.gz - Fisher Z Transform the correlation. For details see `3dcalc <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dcalc.html>`_:: 3dcalc -a VMHC_FWHM.nii.gz -expr 'log((a+1)/(1-a))/2' -prefix VMHC_FWHM_Z.nii.gz - Calculate the number of volumes(nvols) in flipped rest_res_2symmstandard.nii.gz(tmp_LRflipped.nii.gz) :: -Use Nibabel to do this - Compute the Z statistic map :: 3dcalc -a VMHC_FWHM_Z.nii.gz -expr 'a*sqrt('${nvols}'-3)' -prefix VMHC_FWHM_Z_stat.nii.gz Workflow: .. image:: ../images/vmhc_graph.dot.png :width: 500 Workflow Detailed: .. image:: ../images/vmhc_detailed_graph.dot.png :width: 500 References ---------- .. [1] Zuo, X.-N., Kelly, C., Di Martino, A., Mennes, M., Margulies, D. S., Bangaru, S., Grzadzinski, R., et al. (2010). Growing together and growing apart: regional and sex differences in the lifespan developmental trajectories of functional homotopy. The Journal of neuroscience : the official journal of the Society for Neuroscience, 30(45), 15034-43. doi:10.1523/JNEUROSCI.2612-10.2010 Examples -------- >>> vmhc_w = create_vmhc() >>> vmhc_w.inputs.inputspec.symmetric_brain = 'MNI152_T1_2mm_symmetric_brain.nii.gz' >>> vmhc_w.inputs.inputspec.symmetric_skull = 'MNI152_T1_2mm_symmetric.nii.gz' >>> vmhc_w.inputs.inputspec.twomm_brain_mask_dil = 'MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz' >>> vmhc_w.inputs.inputspec.config_file_twomm = 'T1_2_MNI152_2mm_symmetric.cnf' >>> vmhc_w.inputs.inputspec.standard_for_func= 'MNI152_T1_2mm.nii.gz' >>> vmhc_w.inputs.fwhm_input.fwhm = [4.5, 6] >>> vmhc_w.get_node('fwhm_input').iterables = ('fwhm', [4.5, 6]) >>> vmhc_w.inputs.inputspec.rest_res = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/func/original/rest_res_filt.nii.gz') >>> vmhc_w.inputs.inputspec.reorient = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/anat/mprage_RPI.nii.gz') >>> vmhc_w.inputs.inputspec.brain = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/anat/mprage_brain.nii.gz') >>> vmhc_w.inputs.inputspec.example_func2highres_mat = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/func/original/reg/example_func2highres.mat') >>> vmhc_w.inputs.inputspec.rest_mask = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/func/original/rest_mask.nii.gz') >>> vmhc_w.run() # doctest: +SKIP """ vmhc = pe.Workflow(name=name) inputNode = pe.Node(util.IdentityInterface(fields=[ 'rest_res', 'example_func2highres_mat', 'rest_mask', 'standard_for_func', 'mean_functional', 'brain', 'fnirt_nonlinear_warp', 'ants_symm_initial_xfm', 'ants_symm_rigid_xfm', 'ants_symm_affine_xfm', 'ants_symm_warp_field' ]), name='inputspec') outputNode = pe.Node(util.IdentityInterface(fields=[ 'rest_res_2symmstandard', 'VMHC_FWHM_img', 'VMHC_Z_FWHM_img', 'VMHC_Z_stat_FWHM_img' ]), name='outputspec') inputnode_fwhm = pe.Node(util.IdentityInterface(fields=['fwhm']), name='fwhm_input') if use_ants == False: # Apply nonlinear registration (func to standard) nonlinear_func_to_standard = pe.Node(interface=fsl.ApplyWarp(), name='nonlinear_func_to_standard') elif use_ants == True: # ANTS warp image etc. fsl_to_itk_vmhc = create_wf_c3d_fsl_to_itk(0, name='fsl_to_itk_vmhc') collect_transforms_vmhc = create_wf_collect_transforms( 0, name='collect_transforms_vmhc') apply_ants_xfm_vmhc = create_wf_apply_ants_warp( 0, name='apply_ants_xfm_vmhc', ants_threads=ants_threads) # this has to be 3 instead of default 0 because it is a 4D file apply_ants_xfm_vmhc.inputs.inputspec.input_image_type = 3 # copy and L/R swap file copy_and_L_R_swap = pe.Node(interface=fsl.SwapDimensions(), name='copy_and_L_R_swap') copy_and_L_R_swap.inputs.new_dims = ('-x', 'y', 'z') # calculate vmhc pearson_correlation = pe.Node(interface=preprocess.TCorrelate(), name='pearson_correlation') pearson_correlation.inputs.pearson = True pearson_correlation.inputs.polort = -1 pearson_correlation.inputs.outputtype = 'NIFTI_GZ' try: z_trans = pe.Node(interface=preprocess.Calc(), name='z_trans') z_stat = pe.Node(interface=preprocess.Calc(), name='z_stat') except AttributeError: from nipype.interfaces.afni import utils as afni_utils z_trans = pe.Node(interface=afni_utils.Calc(), name='z_trans') z_stat = pe.Node(interface=afni_utils.Calc(), name='z_stat') z_trans.inputs.expr = 'log((1+a)/(1-a))/2' z_trans.inputs.outputtype = 'NIFTI_GZ' z_stat.inputs.outputtype = 'NIFTI_GZ' NVOLS = pe.Node(util.Function(input_names=['in_files'], output_names=['nvols'], function=get_img_nvols), name='NVOLS') generateEXP = pe.Node(util.Function(input_names=['nvols'], output_names=['expr'], function=get_operand_expression), name='generateEXP') smooth = pe.Node(interface=fsl.MultiImageMaths(), name='smooth') if use_ants == False: vmhc.connect(inputNode, 'rest_res', smooth, 'in_file') vmhc.connect(inputnode_fwhm, ('fwhm', set_gauss), smooth, 'op_string') vmhc.connect(inputNode, 'rest_mask', smooth, 'operand_files') vmhc.connect(smooth, 'out_file', nonlinear_func_to_standard, 'in_file') vmhc.connect(inputNode, 'standard_for_func', nonlinear_func_to_standard, 'ref_file') vmhc.connect(inputNode, 'fnirt_nonlinear_warp', nonlinear_func_to_standard, 'field_file') ## func->anat matrix (bbreg) vmhc.connect(inputNode, 'example_func2highres_mat', nonlinear_func_to_standard, 'premat') vmhc.connect(nonlinear_func_to_standard, 'out_file', copy_and_L_R_swap, 'in_file') vmhc.connect(nonlinear_func_to_standard, 'out_file', pearson_correlation, 'xset') elif use_ants == True: # connections for ANTS stuff # functional apply warp stuff vmhc.connect(inputNode, 'rest_res', smooth, 'in_file') vmhc.connect(inputnode_fwhm, ('fwhm', set_gauss), smooth, 'op_string') vmhc.connect(inputNode, 'rest_mask', smooth, 'operand_files') vmhc.connect(smooth, 'out_file', apply_ants_xfm_vmhc, 'inputspec.input_image') vmhc.connect(inputNode, 'ants_symm_initial_xfm', collect_transforms_vmhc, 'inputspec.linear_initial') vmhc.connect(inputNode, 'ants_symm_rigid_xfm', collect_transforms_vmhc, 'inputspec.linear_rigid') vmhc.connect(inputNode, 'ants_symm_affine_xfm', collect_transforms_vmhc, 'inputspec.linear_affine') vmhc.connect(inputNode, 'ants_symm_warp_field', collect_transforms_vmhc, 'inputspec.warp_file') # func->anat matrix (bbreg) vmhc.connect(inputNode, 'example_func2highres_mat', fsl_to_itk_vmhc, 'inputspec.affine_file') vmhc.connect(inputNode, 'brain', fsl_to_itk_vmhc, 'inputspec.reference_file') vmhc.connect(inputNode, 'mean_functional', fsl_to_itk_vmhc, 'inputspec.source_file') vmhc.connect(fsl_to_itk_vmhc, 'outputspec.itk_transform', collect_transforms_vmhc, 'inputspec.fsl_to_itk_affine') vmhc.connect(inputNode, 'standard_for_func', apply_ants_xfm_vmhc, 'inputspec.reference_image') vmhc.connect(collect_transforms_vmhc, 'outputspec.transformation_series', apply_ants_xfm_vmhc, 'inputspec.transforms') vmhc.connect(apply_ants_xfm_vmhc, 'outputspec.output_image', copy_and_L_R_swap, 'in_file') vmhc.connect(apply_ants_xfm_vmhc, 'outputspec.output_image', pearson_correlation, 'xset') vmhc.connect(copy_and_L_R_swap, 'out_file', pearson_correlation, 'yset') vmhc.connect(pearson_correlation, 'out_file', z_trans, 'in_file_a') vmhc.connect(copy_and_L_R_swap, 'out_file', NVOLS, 'in_files') vmhc.connect(NVOLS, 'nvols', generateEXP, 'nvols') vmhc.connect(z_trans, 'out_file', z_stat, 'in_file_a') vmhc.connect(generateEXP, 'expr', z_stat, 'expr') if use_ants == False: vmhc.connect(nonlinear_func_to_standard, 'out_file', outputNode, 'rest_res_2symmstandard') elif use_ants == True: # ANTS warp outputs to outputnode vmhc.connect(apply_ants_xfm_vmhc, 'outputspec.output_image', outputNode, 'rest_res_2symmstandard') vmhc.connect(pearson_correlation, 'out_file', outputNode, 'VMHC_FWHM_img') vmhc.connect(z_trans, 'out_file', outputNode, 'VMHC_Z_FWHM_img') vmhc.connect(z_stat, 'out_file', outputNode, 'VMHC_Z_stat_FWHM_img') return vmhc
def define_preproc_workflow(info, subjects, sessions, qc=True): # --- Workflow parameterization and data input scan_info = info.scan_info experiment = info.experiment_name iterables = generate_iterables(scan_info, experiment, subjects, sessions) subject_iterables, session_iterables, run_iterables = iterables subject_iterables = subjects subject_source = Node(IdentityInterface(["subject"]), name="subject_source", iterables=("subject", subject_iterables)) session_source = Node(IdentityInterface(["subject", "session"]), name="session_source", itersource=("subject_source", "subject"), iterables=("session", session_iterables)) run_source = Node(IdentityInterface(["subject", "session", "run"]), name="run_source", itersource=("session_source", "session"), iterables=("run", run_iterables)) session_input = Node(SessionInput(data_dir=info.data_dir, proc_dir=info.proc_dir, fm_template=info.fm_template, phase_encoding=info.phase_encoding), "session_input") run_input = Node(RunInput(experiment=experiment, data_dir=info.data_dir, proc_dir=info.proc_dir, sb_template=info.sb_template, ts_template=info.ts_template, crop_frames=info.crop_frames), name="run_input") # --- Warpfield estimation using topup # Distortion warpfield estimation # TODO figure out how to parameterize for testing # topup_config = op.realpath(op.join(__file__, "../../../topup_fast.cnf")) topup_config = "b02b0.cnf" estimate_distortions = Node(fsl.TOPUP(config=topup_config), "estimate_distortions") # Post-process the TOPUP outputs finalize_unwarping = Node(FinalizeUnwarping(), "finalize_unwarping") # --- Registration of SE-EPI (without distortions) to Freesurfer anatomy fm2anat = Node(fs.BBRegister(init="fsl", contrast_type="t2", registered_file=True, out_fsl_file="sess2anat.mat", out_reg_file="sess2anat.dat"), "fm2anat") fm2anat_qc = Node(AnatRegReport(data_dir=info.data_dir), "fm2anat_qc") # --- Registration of SBRef to SE-EPI (with distortions) sb2fm = Node(fsl.FLIRT(dof=6, interp="spline"), "sb2fm") sb2fm_qc = Node(CoregGIF(out_file="coreg.gif"), "sb2fm_qc") # --- Motion correction of time series to SBRef (with distortions) ts2sb = Node(fsl.MCFLIRT(save_mats=True, save_plots=True), "ts2sb") ts2sb_qc = Node(RealignmentReport(), "ts2sb_qc") # --- Combined motion correction, unwarping, and template registration # Combine pre-and post-warp linear transforms combine_premats = MapNode(fsl.ConvertXFM(concat_xfm=True), "in_file", "combine_premats") combine_postmats = Node(fsl.ConvertXFM(concat_xfm=True), "combine_postmats") # Transform Jacobian images into the template space transform_jacobian = Node(fsl.ApplyWarp(relwarp=True), "transform_jacobian") # Apply rigid transforms and nonlinear warpfield to time series frames restore_timeseries = MapNode(fsl.ApplyWarp(interp="spline", relwarp=True), ["in_file", "premat"], "restore_timeseries") # Apply rigid transforms and nonlinear warpfield to template frames restore_template = MapNode(fsl.ApplyWarp(interp="spline", relwarp=True), ["in_file", "premat", "field_file"], "restore_template") # Perform final preprocessing operations on timeseries finalize_timeseries = Node(FinalizeTimeseries(experiment=experiment), "finalize_timeseries") # Perform final preprocessing operations on template finalize_template = JoinNode(FinalizeTemplate(experiment=experiment), name="finalize_template", joinsource="run_source", joinfield=["mean_files", "tsnr_files", "mask_files", "noise_files"]) # --- Workflow ouptut save_info = Node(SaveInfo(info_dict=info.trait_get()), "save_info") template_output = Node(DataSink(base_directory=info.proc_dir, parameterization=False), "template_output") timeseries_output = Node(DataSink(base_directory=info.proc_dir, parameterization=False), "timeseries_output") # === Assemble pipeline cache_base = op.join(info.cache_dir, info.experiment_name) workflow = Workflow(name="preproc", base_dir=cache_base) # Connect processing nodes processing_edges = [ (subject_source, session_source, [("subject", "subject")]), (subject_source, run_source, [("subject", "subject")]), (session_source, run_source, [("session", "session")]), (session_source, session_input, [("session", "session")]), (run_source, run_input, [("run", "run")]), # Phase-encode distortion estimation (session_input, estimate_distortions, [("fm_file", "in_file"), ("phase_encoding", "encoding_direction"), ("readout_times", "readout_times")]), (session_input, finalize_unwarping, [("fm_file", "raw_file"), ("phase_encoding", "phase_encoding")]), (estimate_distortions, finalize_unwarping, [("out_corrected", "corrected_file"), ("out_warps", "warp_files"), ("out_jacs", "jacobian_files")]), # Registration of corrected SE-EPI to anatomy (session_input, fm2anat, [("subject", "subject_id")]), (finalize_unwarping, fm2anat, [("corrected_file", "source_file")]), # Registration of each frame to SBRef image (run_input, ts2sb, [("ts_file", "in_file"), ("sb_file", "ref_file")]), (ts2sb, finalize_timeseries, [("par_file", "mc_file")]), # Registration of SBRef volume to SE-EPI fieldmap (run_input, sb2fm, [("sb_file", "in_file")]), (finalize_unwarping, sb2fm, [("raw_file", "reference"), ("mask_file", "ref_weight")]), # Single-interpolation spatial realignment and unwarping (ts2sb, combine_premats, [("mat_file", "in_file")]), (sb2fm, combine_premats, [("out_matrix_file", "in_file2")]), (fm2anat, combine_postmats, [("out_fsl_file", "in_file")]), (session_input, combine_postmats, [("reg_file", "in_file2")]), (run_input, transform_jacobian, [("anat_file", "ref_file")]), (finalize_unwarping, transform_jacobian, [("jacobian_file", "in_file")]), (combine_postmats, transform_jacobian, [("out_file", "premat")]), (run_input, restore_timeseries, [("ts_frames", "in_file")]), (run_input, restore_timeseries, [("anat_file", "ref_file")]), (combine_premats, restore_timeseries, [("out_file", "premat")]), (finalize_unwarping, restore_timeseries, [("warp_file", "field_file")]), (combine_postmats, restore_timeseries, [("out_file", "postmat")]), (run_input, finalize_timeseries, [("run_tuple", "run_tuple"), ("anat_file", "anat_file"), ("seg_file", "seg_file"), ("mask_file", "mask_file")]), (transform_jacobian, finalize_timeseries, [("out_file", "jacobian_file")]), (restore_timeseries, finalize_timeseries, [("out_file", "in_files")]), (session_input, restore_template, [("fm_frames", "in_file"), ("anat_file", "ref_file")]), (estimate_distortions, restore_template, [("out_mats", "premat"), ("out_warps", "field_file")]), (combine_postmats, restore_template, [("out_file", "postmat")]), (session_input, finalize_template, [("session_tuple", "session_tuple"), ("seg_file", "seg_file"), ("anat_file", "anat_file")]), (transform_jacobian, finalize_template, [("out_file", "jacobian_file")]), (restore_template, finalize_template, [("out_file", "in_files")]), (finalize_timeseries, finalize_template, [("mean_file", "mean_files"), ("tsnr_file", "tsnr_files"), ("mask_file", "mask_files"), ("noise_file", "noise_files")]), # --- Persistent data storage # Ouputs associated with each scanner run (finalize_timeseries, timeseries_output, [("output_path", "container"), ("out_file", "@func"), ("mean_file", "@mean"), ("mask_file", "@mask"), ("tsnr_file", "@tsnr"), ("noise_file", "@noise"), ("mc_file", "@mc")]), # Ouputs associated with the session template (finalize_template, template_output, [("output_path", "container"), ("out_file", "@func"), ("mean_file", "@mean"), ("tsnr_file", "@tsnr"), ("mask_file", "@mask"), ("noise_file", "@noise")]), ] workflow.connect(processing_edges) # Optionally connect QC nodes qc_edges = [ # Registration of each frame to SBRef image (run_input, ts2sb_qc, [("sb_file", "target_file")]), (ts2sb, ts2sb_qc, [("par_file", "realign_params")]), # Registration of corrected SE-EPI to anatomy (session_input, fm2anat_qc, [("subject", "subject_id")]), (fm2anat, fm2anat_qc, [("registered_file", "in_file"), ("min_cost_file", "cost_file")]), # Registration of SBRef volume to SE-EPI fieldmap (sb2fm, sb2fm_qc, [("out_file", "in_file")]), (finalize_unwarping, sb2fm_qc, [("raw_file", "ref_file")]), # Ouputs associated with each scanner run (run_source, save_info, [("run", "parameterization")]), (save_info, timeseries_output, [("info_file", "qc.@info_json")]), (run_input, timeseries_output, [("ts_plot", "qc.@raw_gif")]), (sb2fm_qc, timeseries_output, [("out_file", "qc.@sb2fm_gif")]), (ts2sb_qc, timeseries_output, [("params_plot", "qc.@params_plot"), ("target_plot", "qc.@target_plot")]), (finalize_timeseries, timeseries_output, [("out_gif", "qc.@ts_gif"), ("out_png", "qc.@ts_png"), ("mask_plot", "qc.@mask_plot"), ("mean_plot", "qc.@ts_mean_plot"), ("tsnr_plot", "qc.@ts_tsnr_plot"), ("noise_plot", "qc.@noise_plot")]), # Outputs associated with the session template (finalize_unwarping, template_output, [("warp_plot", "qc.@warp_png"), ("unwarp_gif", "qc.@unwarp_gif")]), (fm2anat_qc, template_output, [("out_file", "qc.@reg_png")]), (finalize_template, template_output, [("out_plot", "qc.@func_png"), ("mean_plot", "qc.@mean"), ("tsnr_plot", "qc.@tsnr"), ("mask_plot", "qc.@mask"), ("noise_plot", "qc.@noise")]), ] if qc: workflow.connect(qc_edges) return workflow
masterdi = '/data/pt_neuam005/FSTIM_1_Think_preprocessed/fmriprep/sub-10/ses-01/func/' masterte = 'sub-10_ses-01_task-future_bold_space-MNI152NLin2009cAsym_preproc.nii.gz' masterfi = os.path.join(masterdi, masterte) os.chdir(myindata) # afni resample resample = afni.Resample() resample.inputs.in_file = 'mni_icbm152_t1_tal_nlin_asym_09c.nii' resample.inputs.voxel_size = (2.0, 2.0, 2.0) resample.inputs.master = masterfi resample.inputs.outputtype = 'NIFTI' resample.inputs.out_file = 'mni_icbm152_t1_tal_nlin_asym_09c_2mm.nii.gz' print(resample.cmdline) resample.run() # transforming template mask to 2mm (fsl nonlinear transform) aw = fsl.ApplyWarp() aw.inputs.in_file = 'mni_icbm152_t1_tal_nlin_asym_09c_mask.nii' aw.inputs.ref_file = 'mni_icbm152_t1_tal_nlin_asym_09c_2mm.nii.gz' aw.inputs.out_file = 'mni_icbm152_t1_tal_nlin_asym_09c_2mm_trf.nii.gz' print(aw.cmdline) aw.run() binar = fsl.maths.MathsCommand() binar.inputs.args = '-thr 0.90 -bin' binar.inputs.in_file = 'mni_icbm152_t1_tal_nlin_asym_09c_2mm_trf.nii.gz' binar.inputs.out_file = 'mni_icbm152_t1_tal_nlin_asym_09c_2mm_mask.nii.gz' print(binar.cmdline) binar.run()
def create_tbss_non_FA(name='tbss_non_FA'): """ A pipeline that implement tbss_non_FA in FSL Example ------- >>> from nipype.workflows.dmri.fsl import tbss >>> tbss_MD = tbss.create_tbss_non_FA() >>> tbss_MD.inputs.inputnode.file_list = [] >>> tbss_MD.inputs.inputnode.field_list = [] >>> tbss_MD.inputs.inputnode.skeleton_thresh = 0.2 >>> tbss_MD.inputs.inputnode.groupmask = './xxx' >>> tbss_MD.inputs.inputnode.meanfa_file = './xxx' >>> tbss_MD.inputs.inputnode.distance_map = [] Inputs:: inputnode.file_list inputnode.field_list inputnode.skeleton_thresh inputnode.groupmask inputnode.meanfa_file inputnode.distance_map Outputs:: outputnode.projected_nonFA_file """ # Define the inputnode inputnode = pe.Node(interface=util.IdentityInterface(fields=[ 'file_list', 'field_list', 'skeleton_thresh', 'groupmask', 'meanfa_file', 'distance_map' ]), name='inputnode') # Apply the warpfield to the non FA image applywarp = pe.MapNode(interface=fsl.ApplyWarp(), iterfield=['in_file', 'field_file'], name="applywarp") if fsl.no_fsl(): warn('NO FSL found') else: applywarp.inputs.ref_file = fsl.Info.standard_image( "FMRIB58_FA_1mm.nii.gz") # Merge the non FA files into a 4D file merge = pe.Node(fsl.Merge(dimension="t"), name="merge") #merged_file="all_FA.nii.gz" maskgroup = pe.Node(fsl.ImageMaths(op_string="-mas", suffix="_masked"), name="maskgroup") projectfa = pe.Node( fsl.TractSkeleton( project_data=True, #projected_data = 'test.nii.gz', use_cingulum_mask=True), name="projectfa") tbss_non_FA = pe.Workflow(name=name) tbss_non_FA.connect([ (inputnode, applywarp, [ ('file_list', 'in_file'), ('field_list', 'field_file'), ]), (applywarp, merge, [("out_file", "in_files")]), (merge, maskgroup, [("merged_file", "in_file")]), (inputnode, maskgroup, [('groupmask', 'in_file2')]), (maskgroup, projectfa, [('out_file', 'data_file')]), (inputnode, projectfa, [ ('skeleton_thresh', 'threshold'), ("meanfa_file", "in_file"), ("distance_map", "distance_map"), ]), ]) # Define the outputnode outputnode = pe.Node( interface=util.IdentityInterface(fields=['projected_nonFA_file']), name='outputnode') tbss_non_FA.connect([ (projectfa, outputnode, [ ('projected_data', 'projected_nonFA_file'), ]), ]) return tbss_non_FA
def create_qc_snr(wf_name='qc_snr'): wf = pe.Workflow(name=wf_name) input_node = pe.Node(util.IdentityInterface(fields=[ 'functional_preprocessed', 'functional_brain_mask', 'functional_to_anat_linear_xfm', 'anatomical_brain', 'mean_functional_in_anat' ]), name='inputspec') output_node = pe.Node(util.IdentityInterface(fields=[ 'snr_axial_image', 'snr_sagittal_image', 'snr_histogram_image', 'snr_mean' ]), name='outputspec') std_dev = pe.Node(afni.TStat(args='-stdev'), name='std_dev') std_dev.inputs.outputtype = 'NIFTI_GZ' wf.connect(input_node, 'functional_preprocessed', std_dev, 'in_file') wf.connect(input_node, 'functional_brain_mask', std_dev, 'mask') std_dev_anat = pe.Node(fsl.ApplyWarp(interp='trilinear'), name='std_dev_anat') wf.connect(input_node, 'functional_to_anat_linear_xfm', std_dev_anat, 'premat') wf.connect(std_dev, 'out_file', std_dev_anat, 'in_file') wf.connect(input_node, 'anatomical_brain', std_dev_anat, 'ref_file') snr = pe.Node(afni.Calc(expr='b/a'), name='snr') snr.inputs.outputtype = 'NIFTI_GZ' wf.connect(input_node, 'mean_functional_in_anat', snr, 'in_file_b') wf.connect(std_dev_anat, 'out_file', snr, 'in_file_a') snr_val = pe.Node(Function(input_names=['measure_file'], output_names=['snr_storefl'], function=cal_snr_val, as_module=True), name='snr_val') wf.connect(snr, 'out_file', snr_val, 'measure_file') hist_snr = pe.Node(Function(input_names=['measure_file', 'measure'], output_names=['hist_path'], function=gen_histogram, as_module=True), name='hist_snr') hist_snr.inputs.measure = 'snr' wf.connect(snr, 'out_file', hist_snr, 'measure_file') snr_drop_percent = pe.Node(Function( input_names=['measure_file', 'percent'], output_names=['modified_measure_file'], function=drop_percent, as_module=True), name='dp_snr') snr_drop_percent.inputs.percent = 99 wf.connect(snr, 'out_file', snr_drop_percent, 'measure_file') montage_snr = create_montage('montage_snr', 'red_to_blue', 'snr') wf.connect(snr_drop_percent, 'modified_measure_file', montage_snr, 'inputspec.overlay') wf.connect(input_node, 'anatomical_brain', montage_snr, 'inputspec.underlay') wf.connect(montage_snr, 'outputspec.axial_png', output_node, 'snr_axial_image') wf.connect(montage_snr, 'outputspec.sagittal_png', output_node, 'snr_sagittal_image') wf.connect(hist_snr, 'hist_path', output_node, 'snr_histogram_image') wf.connect(snr_val, 'snr_storefl', output_node, 'snr_mean') return wf
def create_reg_workflow(name='registration'): """Create a FEAT preprocessing workflow together with freesurfer Parameters ---------- :: name : name of workflow (default: 'registration') Inputs:: inputspec.source_files : files (filename or list of filenames to register) inputspec.mean_image : reference image to use inputspec.anatomical_image : anatomical image to coregister to inputspec.target_image : registration target Outputs:: outputspec.func2anat_transform : FLIRT transform outputspec.anat2target_transform : FLIRT+FNIRT transform outputspec.transformed_files : transformed files in target space outputspec.transformed_mean : mean image in target space Example ------- """ register = pe.Workflow(name=name) inputnode = pe.Node(interface=util.IdentityInterface(fields=['source_files', 'mean_image', 'anatomical_image', 'target_image']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['func2anat_transform', 'anat2target_transform', 'transformed_files', 'transformed_mean', ]), name='outputspec') """ Estimate the tissue classes from the anatomical image. But use spm's segment as FSL appears to be breaking. """ stripper = pe.Node(fsl.BET(), name='stripper') register.connect(inputnode, 'anatomical_image', stripper, 'in_file') fast = pe.Node(fsl.FAST(), name='fast') register.connect(stripper, 'out_file', fast, 'in_files') """ Binarize the segmentation """ binarize = pe.Node(fsl.ImageMaths(op_string='-nan -thr 0.5 -bin'), name='binarize') pickindex = lambda x, i: x[i] register.connect(fast, ('partial_volume_files', pickindex, 2), binarize, 'in_file') """ Calculate rigid transform from mean image to anatomical image """ mean2anat = pe.Node(fsl.FLIRT(), name='mean2anat') mean2anat.inputs.dof = 6 register.connect(inputnode, 'mean_image', mean2anat, 'in_file') register.connect(stripper, 'out_file', mean2anat, 'reference') """ Now use bbr cost function to improve the transform """ mean2anatbbr = pe.Node(fsl.FLIRT(), name='mean2anatbbr') mean2anatbbr.inputs.dof = 6 mean2anatbbr.inputs.cost = 'bbr' mean2anatbbr.inputs.schedule = os.path.join(os.getenv('FSLDIR'), 'etc/flirtsch/bbr.sch') register.connect(inputnode, 'mean_image', mean2anatbbr, 'in_file') register.connect(binarize, 'out_file', mean2anatbbr, 'wm_seg') register.connect(inputnode, 'anatomical_image', mean2anatbbr, 'reference') register.connect(mean2anat, 'out_matrix_file', mean2anatbbr, 'in_matrix_file') """ Calculate affine transform from anatomical to target """ anat2target_affine = pe.Node(fsl.FLIRT(), name='anat2target_linear') register.connect(inputnode, 'anatomical_image', anat2target_affine, 'in_file') register.connect(inputnode, 'target_image', anat2target_affine, 'reference') """ Calculate nonlinear transform from anatomical to target """ anat2target_nonlinear = pe.Node(fsl.FNIRT(), name='anat2target_nonlinear') anat2target_nonlinear.inputs.fieldcoeff_file=True register.connect(anat2target_affine, 'out_matrix_file', anat2target_nonlinear, 'affine_file') anat2target_nonlinear.inputs.warp_resolution = (8, 8, 8) register.connect(inputnode, 'anatomical_image', anat2target_nonlinear, 'in_file') register.connect(inputnode, 'target_image', anat2target_nonlinear, 'ref_file') """ Transform the mean image. First to anatomical and then to target """ warp2anat = pe.Node(fsl.ApplyWarp(interp='spline'), name='warp2anat') register.connect(inputnode, 'mean_image', warp2anat, 'in_file') register.connect(inputnode, 'anatomical_image', warp2anat, 'ref_file') register.connect(mean2anatbbr, 'out_matrix_file', warp2anat, 'premat') warpmean = warp2anat.clone(name='warpmean') register.connect(warp2anat, 'out_file', warpmean, 'in_file') register.connect(inputnode, 'target_image', warpmean, 'ref_file') register.connect(anat2target_nonlinear, 'fieldcoeff_file', warpmean, 'field_file') """ Transform the remaining images. First to anatomical and then to target """ warpall2anat = pe.MapNode(fsl.ApplyWarp(interp='spline'), iterfield=['in_file'], name='warpall2anat') register.connect(inputnode, 'source_files', warpall2anat, 'in_file') register.connect(inputnode, 'anatomical_image', warpall2anat, 'ref_file') register.connect(mean2anatbbr, 'out_matrix_file', warpall2anat, 'premat') warpall = warpall2anat.clone(name='warpall') register.connect(warpall2anat, 'out_file', warpall, 'in_file') register.connect(inputnode, 'target_image', warpall, 'ref_file') register.connect(anat2target_nonlinear, 'fieldcoeff_file', warpall, 'field_file') """ Assign all the output files """ register.connect(warpmean, 'out_file', outputnode, 'transformed_mean') register.connect(warpall, 'out_file', outputnode, 'transformed_files') register.connect(mean2anatbbr, 'out_matrix_file', outputnode, 'func2anat_transform') register.connect(anat2target_nonlinear, 'fieldcoeff_file', outputnode, 'anat2target_transform') return register
def create_fsl_workflow(data_dir=None, subjects=None, name="fslwarp"): """Set up the anatomical normalzation workflow using FNIRT. Your anatomical data must have been processed in Freesurfer. Unlike most lyman workflows, the DataGrabber and DataSink nodes are hardwired within the returned workflow, as this tightly integrates with the Freesurfer subjects directory structure. Parameters ---------- data_dir : path top level of data hierarchy/FS subjects directory subjects : list of strings list of subject IDs name : alphanumeric string, optional workflow name """ if data_dir is None: data_dir = os.environ["SUBJECTS_DIR"] if subjects is None: subjects = [] # Get target images target_brain = fsl.Info.standard_image("avg152T1_brain.nii.gz") target_head = fsl.Info.standard_image("avg152T1.nii.gz") hires_head = fsl.Info.standard_image("MNI152_T1_1mm.nii.gz") target_mask = fsl.Info.standard_image( "MNI152_T1_2mm_brain_mask_dil.nii.gz") fnirt_cfg = os.path.join(os.environ["FSLDIR"], "etc/flirtsch/T1_2_MNI152_2mm.cnf") # Subject source node subjectsource = Node(IdentityInterface(fields=["subject_id"]), iterables=("subject_id", subjects), name="subjectsource") # Grab recon-all outputs head_image = "T1" templates = dict(aseg="{subject_id}/mri/aparc+aseg.mgz", head="{subject_id}/mri/" + head_image + ".mgz") datasource = Node(SelectFiles(templates, base_directory=data_dir), "datasource") # Convert images to nifti storage and float representation cvtaseg = Node(fs.MRIConvert(out_type="niigz"), "convertaseg") cvthead = Node(fs.MRIConvert(out_type="niigz", out_datatype="float"), "converthead") # Turn the aparc+aseg into a brainmask makemask = Node(fs.Binarize(dilate=1, min=0.5), "makemask") # Extract the brain from the orig.mgz using the mask skullstrip = Node(fsl.ApplyMask(), "skullstrip") # FLIRT brain to MNI152_brain flirt = Node(fsl.FLIRT(reference=target_brain), "flirt") sw = [-180, 180] for dim in ["x", "y", "z"]: setattr(flirt.inputs, "searchr_%s" % dim, sw) # FNIRT head to MNI152 fnirt = Node( fsl.FNIRT(ref_file=target_head, refmask_file=target_mask, config_file=fnirt_cfg, fieldcoeff_file=True), "fnirt") # Warp and rename the images warpbrain = Node( fsl.ApplyWarp(ref_file=target_head, interp="spline", out_file="brain_warp.nii.gz"), "warpbrain") warpbrainhr = Node( fsl.ApplyWarp(ref_file=hires_head, interp="spline", out_file="brain_warp_hires.nii.gz"), "warpbrainhr") # Generate a png summarizing the registration warpreport = Node(WarpReport(), "warpreport") # Save relevant files to the data directory fnirt_subs = [(head_image + "_out_masked_flirt.mat", "affine.mat"), (head_image + "_out_fieldwarp", "warpfield"), (head_image + "_out_masked", "brain"), (head_image + "_out", "T1")] datasink = Node( DataSink(base_directory=data_dir, parameterization=False, substitutions=fnirt_subs), "datasink") # Define and connect the workflow # ------------------------------- normalize = Workflow(name=name) normalize.connect([ (subjectsource, datasource, [("subject_id", "subject_id")]), (datasource, cvtaseg, [("aseg", "in_file")]), (datasource, cvthead, [("head", "in_file")]), (cvtaseg, makemask, [("out_file", "in_file")]), (cvthead, skullstrip, [("out_file", "in_file")]), (makemask, skullstrip, [("binary_file", "mask_file")]), (skullstrip, flirt, [("out_file", "in_file")]), (flirt, fnirt, [("out_matrix_file", "affine_file")]), (cvthead, fnirt, [("out_file", "in_file")]), (skullstrip, warpbrain, [("out_file", "in_file")]), (fnirt, warpbrain, [("fieldcoeff_file", "field_file")]), (skullstrip, warpbrainhr, [("out_file", "in_file")]), (fnirt, warpbrainhr, [("fieldcoeff_file", "field_file")]), (warpbrain, warpreport, [("out_file", "in_file")]), (subjectsource, datasink, [("subject_id", "container")]), (skullstrip, datasink, [("out_file", "normalization.@brain")]), (cvthead, datasink, [("out_file", "normalization.@t1")]), (flirt, datasink, [("out_file", "normalization.@brain_flirted")]), (flirt, datasink, [("out_matrix_file", "normalization.@affine")]), (warpbrain, datasink, [("out_file", "normalization.@brain_warped")]), (warpbrainhr, datasink, [("out_file", "normalization.@brain_hires")]), (fnirt, datasink, [("fieldcoeff_file", "normalization.@warpfield")]), (warpreport, datasink, [("out_file", "normalization.@report")]), ]) return normalize
def create_transform_pipeline(name='transfrom_timeseries'): # set fsl output type fsl.FSLCommand.set_default_output_type('NIFTI_GZ') # initiate workflow transform_ts = Workflow(name='transform_timeseries') # inputnode inputnode=Node(util.IdentityInterface(fields=['orig_ts', 'anat_head', 'mat_moco', 'fullwarp', 'resolution', 'brain_mask' ]), name='inputnode') # outputnode outputnode=Node(util.IdentityInterface(fields=['trans_ts', 'trans_ts_mean', 'trans_ts_masked', 'resamp_brain', 'brain_mask_resamp', 'out_dvars' ]), name='outputnode') #resample anatomy resample = Node(fsl.FLIRT(datatype='float', out_file='T1_resampled.nii.gz'), name = 'resample_anat') transform_ts.connect([(inputnode, resample, [('anat_head', 'in_file'), ('anat_head', 'reference'), ('resolution', 'apply_isoxfm') ]), (resample, outputnode, [('out_file', 'resamp_brain')]) ]) # split timeseries in single volumes split=Node(fsl.Split(dimension='t', out_base_name='timeseries'), name='split') transform_ts.connect([(inputnode, split, [('orig_ts','in_file')])]) # applymoco premat and fullwarpfield applywarp = MapNode(fsl.ApplyWarp(interp='spline', relwarp=True, out_file='rest2anat.nii.gz', datatype='float'), iterfield=['in_file', 'premat'], name='applywarp') transform_ts.connect([(split, applywarp, [('out_files', 'in_file')]), (inputnode, applywarp, [('mat_moco', 'premat'), ('fullwarp','field_file')]), (resample, applywarp, [('out_file', 'ref_file')]) ]) # re-concatenate volumes merge=Node(fsl.Merge(dimension='t', merged_file='rest2anat.nii.gz'), name='merge') transform_ts.connect([(applywarp,merge,[('out_file','in_files')]), (merge, outputnode, [('merged_file', 'trans_ts')])]) # calculate new mean tmean = Node(fsl.maths.MeanImage(dimension='T', out_file='rest_mean2anat_lowres.nii.gz'), name='tmean') transform_ts.connect([(merge, tmean, [('merged_file', 'in_file')]), (tmean, outputnode, [('out_file', 'trans_ts_mean')]) ]) # resample brain mask resample_brain = Node(afni.Resample(resample_mode='NN', outputtype='NIFTI_GZ', out_file='T1_brain_mask_lowres.nii.gz'), name = 'resample_brain') transform_ts.connect([(inputnode, resample_brain, [('brain_mask', 'in_file')]), (tmean, resample_brain, [('out_file', 'master')]), (resample_brain, outputnode, [('out_file', 'brain_mask_resamp')]) ]) #mask the transformed file mask = Node(fsl.ApplyMask(), name="mask") transform_ts.connect([(resample_brain,mask, [('out_file', 'mask_file')]), (merge, mask, [('merged_file', 'in_file')]), (mask, outputnode, [('out_file', 'trans_ts_masked')]) ]) #calculate DVARS dvars = Node(confounds.ComputeDVARS(save_all=True, save_plot=True), name="dvars") transform_ts.connect([(resample_brain, dvars, [('out_file', 'in_mask')]), (merge, dvars, [('merged_file', 'in_file')]), (dvars, outputnode, [('out_all', 'out_dvars')]) ]) return transform_ts
def prep_for_fmriprep(bidsdir, rawdir, substr): #make subject dir, anat and func subid = substr.replace('-', '_').replace('_', '') anatdir = bidsdir + '/sub-' + subid + '/anat/' funcdir = bidsdir + '/sub-' + subid + '/func/' os.makedirs(anatdir, exist_ok=True) os.makedirs(funcdir, exist_ok=True) # get t1brain and MNI template t1brain = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.ica/reg/highres.nii.gz' % substr template = str( get_template('MNI152NLin2009cAsym', resolution=2, desc='brain', suffix='T1w', extension=['.nii', '.nii.gz'])) ## registered T1w to template for fmriprep standard ### this reg files may not be used tranformfile = tempfile.mkdtemp() reg = Registration() reg.inputs.fixed_image = template reg.inputs.moving_image = t1brain reg.inputs.output_transform_prefix = tranformfile + '/t12mni_' reg.inputs.transforms = ['Affine', 'SyN'] reg.inputs.transform_parameters = [(2.0, ), (0.25, 3.0, 0.0)] reg.inputs.number_of_iterations = [[1500, 200], [100, 50, 30]] reg.inputs.dimension = 3 reg.inputs.num_threads = 3 reg.inputs.write_composite_transform = True reg.inputs.collapse_output_transforms = False reg.inputs.initialize_transforms_per_stage = True reg.inputs.metric = ['Mattes'] * 2 reg.inputs.metric_weight = [ 1 ] * 2 # Default (value ignored currently by ANTs) reg.inputs.radius_or_number_of_bins = [32] * 2 reg.inputs.sampling_strategy = ['Random', None] reg.inputs.sampling_percentage = [0.05, None] reg.inputs.convergence_threshold = [1.e-8, 1.e-9] reg.inputs.convergence_window_size = [20] * 2 reg.inputs.smoothing_sigmas = [[1, 0], [2, 1, 0]] reg.inputs.sigma_units = ['vox'] * 2 reg.inputs.shrink_factors = [[2, 1], [3, 2, 1]] reg.inputs.use_estimate_learning_rate_once = [True, True] reg.inputs.use_histogram_matching = [True, True] # This is the default #reg.inputs.output_warped_image = 'output_warped_image.nii.gz' reg.cmdline reg.run() ## copy transform file to fmriprep directory mni2twtransform = anatdir + '/sub-' + subid + '_from-MNI152NLin2009cAsym_to-T1w_mode-image_xfm.h5' t1w2mnitransform = anatdir + '/sub-' + subid + '_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5' copyfile(tranformfile + '/t12mni_Composite.h5', t1w2mnitransform) copyfile(tranformfile + '/t12mni_InverseComposite.h5', mni2twtransform) ### warp the non-processed/filtered/smooth bold to fmriprep ### now functional boldmask = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.ica/mask.nii.gz' % substr boldref = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI_SBREF.nii.gz' % substr boldprep = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.nii.gz' % substr reffile = tempfile.mkdtemp() + '/reffile.nii.gz' boldstd = reffile = tempfile.mkdtemp() + '/boldstd.nii.gz' maskstd = reffile = tempfile.mkdtemp() + '/maskstd.nii.gz' aw = fsl.ApplyWarp() aw.inputs.in_file = boldref aw.inputs.ref_file = template aw.inputs.field_file = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.ica/reg/example_func2standard_warp.nii.gz' % substr aw.inputs.out_file = reffile aw.inputs.output_type = 'NIFTI_GZ' res = aw.run() aw1 = fsl.ApplyWarp() aw1.inputs.interp = 'spline' aw1.inputs.ref_file = template aw1.inputs.field_file = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.ica/reg/example_func2standard_warp.nii.gz' % substr aw1.inputs.in_file = boldprep aw1.inputs.out_file = boldstd aw1.inputs.output_type = 'NIFTI_GZ' res1 = aw1.run() aw2 = fsl.ApplyWarp() aw2.inputs.in_file = boldmask aw2.inputs.ref_file = template aw2.inputs.field_file = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.ica/reg/example_func2standard_warp.nii.gz' % substr aw2.inputs.out_file = maskstd aw2.inputs.output_type = 'NIFTI_GZ' res2 = aw2.run() tr = nb.load(boldprep).header.get_zooms()[-1] jsontis = { "RepetitionTime": np.float64(tr), "TaskName": 'rest', "SkullStripped": False, } jsmaks = {"mask": True} #newname preprocbold = funcdir + '/sub-' + subid + '_task-rest_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz' preprocboldjson = funcdir + '/sub-' + subid + '_task-rest_space-MNI152NLin2009cAsym_desc-preproc_bold.json' preprocboldref = funcdir + '/sub-' + subid + '_task-rest_space-MNI152NLin2009cAsym_boldref.nii.gz' preprocmask = funcdir + '/sub-' + subid + '_task-rest_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz' preprocmaskjson = funcdir + '/sub-' + subid + '_task-rest_space-MNI152NLin2009cAsym_desc-brain_mask.json' copyfile(maskstd, preprocmask) copyfile(reffile, preprocboldref) copyfile(boldstd, preprocbold) writejson(jsontis, preprocboldjson) writejson(jsmaks, preprocmaskjson) # get wm and csf mask to extract mean signals for regressors ### first warp the anatomical to bold space wmask = rawdir + '/UKB_Pipeline/%s/T1/T1_fast/T1_brain_pve_2.nii.gz' % substr csfmask = rawdir + '/UKB_Pipeline/%s/T1/T1_fast/T1_brain_pve_0.nii.gz' % substr t2funcwmask = tempfile.mkdtemp() + '/wmask.nii.gz' t2funcwcsf = tempfile.mkdtemp() + '/csf.nii.gz' aw = fsl.preprocess.ApplyXFM() aw.inputs.in_file = wmask aw.inputs.reference = boldref aw.inputs.in_matrix_file = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.ica/reg/highres2example_func.mat' % substr aw.inputs.out_file = t2funcwmask aw.inputs.apply_xfm = True aw.inputs.interp = 'nearestneighbour' aw.inputs.output_type = 'NIFTI_GZ' res = aw.run() aw2 = fsl.preprocess.ApplyXFM() aw2.inputs.in_file = csfmask aw2.inputs.reference = boldref aw2.inputs.in_matrix_file = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.ica/reg/highres2example_func.mat' % substr aw2.inputs.out_file = t2funcwcsf aw2.inputs.apply_xfm = True aw2.inputs.interp = 'nearestneighbour' aw2.inputs.output_type = 'NIFTI_GZ' res2 = aw2.run() # binarized and extract signals wmbin = nb.load(t2funcwmask).get_fdata() wmbin[wmbin < 0.99999] = 0 csfbin = nb.load(t2funcwcsf).get_fdata() csfbin[csfbin < 0.99999] = 0 maskbin = nb.load(boldmask).get_fdata() bolddata = nb.load(boldprep).get_fdata() wm_mean = bolddata[wmbin > 0, :].mean(axis=0) csf_mean = bolddata[csfbin > 0, :].mean(axis=0) global_mean = bolddata[maskbin > 0, :].mean(axis=0) #### combine all the regressors mcfile = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.ica/mc/prefiltered_func_data_mcf.par' % substr rsmdfile = rawdir + '/UKB_Pipeline/%s/fMRI_nosmooth/rfMRI.ica/mc/prefiltered_func_data_mcf_abs.rms' % substr motionfile = np.loadtxt(mcfile) rsmd = np.loadtxt(rsmdfile) motionparam = pd.DataFrame( motionfile, columns=['rot_x', 'rot_y', 'rot_z', 'trans_x', 'trans_y', 'trans_z']) otherparam = pd.DataFrame({ 'global_signal': global_mean, 'white_matter': wm_mean, 'csf': csf_mean, 'rmsd': rsmd }) regressors = pd.concat([motionparam, otherparam], axis=1) jsonreg = {'regressor': 'not'} regcsv = funcdir + '/sub-' + subid + '_task-rest_desc-confounds_timeseries.tsv' regjson = funcdir + '/sub-' + subid + '_task-rest_desc-confounds_timeseries.json' regressors.to_csv(regcsv, index=None, sep='\t') writejson(jsonreg, regjson)
def reg2std(name='standardization'): """ Linear and non-linear standardization for structural rat MRI images Input: upscaled data """ reg = pe.Workflow(name=name) """ Set up a node to define all inputs required for the preprocessing workflow """ inputnode = pe.Node(interface=util.IdentityInterface(fields=['in_file_head', 'in_file_brain'], mandatory_inputs=True), name='inputspec') """ Set up a node to define outputs for the preprocessing workflow """ outputnode = pe.Node(interface=util.IdentityInterface(fields=['out_nonlin_head', 'out_nonlin_brain', 'out_warpfield', 'out_lin_brain'], mandatory_inputs=True), name='outputspec') """ Node for linear (12-param) reg flirt -in $in -ref $std -dof 12 -omat $omat -bins 256 -cost $type -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -interp trilinear """ flirt=pe.MapNode(interface=fsl.FLIRT(reference='/opt/shared/etc/std/new/standard-wistar_2mm_brain.nii.gz', dof=12, bins=256, cost='corratio', interp='trilinear'), name='linear_standardization', iterfield=['in_file']) #out_matrix_file?, searchr? """ Non-linear reg fnirt --in=$in --ref=$std --aff=$init --iout=$out --miter=2,3 --infwhm=4,1 --reffwhm=2,0 --subsamp=8,1 --estint=1,1 --applyrefmask=1,1 --applyinmask=0,0 --lambda=200,500 --warpres=10,10,10 --intmod=global_non_linear --refmask=$refmask --fout=$warpingfield --interp=spline """ #TODO: parametrize standard template fnirt=pe.MapNode(interface=fsl.FNIRT( \ ref_file='/opt/shared/etc/std/new/standard-wistar_2mm_brain.nii.gz', \ refmask_file='/opt/shared/etc/std/new/standard-wistar_2mm_brain_mask.nii.gz', \ max_nonlin_iter=[2,3], \ in_fwhm=[2,0], \ ref_fwhm=[2,0], \ subsampling_scheme=[8,1],\ apply_intensity_mapping=[1,1],\ apply_refmask=[1,1],\ apply_inmask=[0,0],\ regularization_lambda=[200,500],\ warp_resolution=(10,10,10),\ intensity_mapping_model='global_non_linear_with_bias',\ field_file=True), name='nonlinear_standardization', iterfield=['in_file', 'affine_file' ]) """ Non-linear reg fnirt --in=$in --ref=$std --aff=$init --iout=$out --miter=2,3 --infwhm=4,1 --reffwhm=2,0 --subsamp=8,1 --estint=1,1 --applyrefmask=1,1 --applyinmask=0,0 --lambda=200,500 --warpres=10,10,10 --intmod=global_non_linear --refmask=$refmask --fout=$warpingfield --interp=spline """ applyWarp=pe.MapNode(interface=fsl.ApplyWarp(), name="warp_brain", iterfield=['in_file', 'ref_file', 'field_file']) # TODO applywarp: brain reg.connect(inputnode, "in_file_brain", flirt, "in_file") reg.connect(flirt, "out_file", outputnode, "out_lin_brain") reg.connect(inputnode, "in_file_head", fnirt, "in_file") reg.connect(flirt, "out_matrix_file", fnirt, "affine_file") reg.connect(inputnode, "in_file_brain", applyWarp, "in_file") reg.connect(fnirt, "warped_file", applyWarp, "ref_file") reg.connect(fnirt, "field_file", applyWarp, "field_file") reg.connect(fnirt, "warped_file", outputnode, "out_nonlin_head") reg.connect(applyWarp, "out_file", outputnode, "out_nonlin_brain") reg.connect(fnirt, "field_file", outputnode, "out_warpfield") return reg
def output_to_standard(workflow, output_name, strat, num_strat, pipeline_config_obj, map_node=False, input_image_type=0): nodes = strat.get_nodes_names() if 'apply_ants_warp_functional_to_standard' in nodes: # ANTS WARP APPLICATION # convert the func-to-anat linear warp from FSL FLIRT to # ITK (ANTS) format fsl_to_itk_convert = create_wf_c3d_fsl_to_itk( input_image_type, map_node, name='{0}_fsl_to_itk_{1}'.format(output_name, num_strat)) # collect the list of warps into a single stack to feed into the # ANTS warp apply tool collect_transforms = create_wf_collect_transforms( map_node, name='{0}_collect_transforms_{1}'.format(output_name, num_strat)) # ANTS apply warp apply_ants_warp = create_wf_apply_ants_warp( map_node, name='{0}_to_standard_{1}'.format(output_name, num_strat), ants_threads=int(pipeline_config_obj.num_ants_threads)) apply_ants_warp.inputs.inputspec.dimension = 3 apply_ants_warp.inputs.inputspec.interpolation = 'Linear' apply_ants_warp.inputs.inputspec.reference_image = \ pipeline_config_obj.template_brain_only_for_func apply_ants_warp.inputs.inputspec.input_image_type = \ input_image_type # affine from FLIRT func->anat linear registration node, out_file = strat['functional_to_anat_linear_xfm'] workflow.connect(node, out_file, fsl_to_itk_convert, 'inputspec.affine_file') # reference used in FLIRT func->anat linear registration node, out_file = strat['anatomical_brain'] workflow.connect(node, out_file, fsl_to_itk_convert, 'inputspec.reference_file') # output file to be converted node, out_file = \ strat[output_name] workflow.connect(node, out_file, fsl_to_itk_convert, 'inputspec.source_file') # nonlinear warp from anatomical->template ANTS registration node, out_file = strat['anatomical_to_mni_nonlinear_xfm'] workflow.connect(node, out_file, collect_transforms, 'inputspec.warp_file') # linear initial from anatomical->template ANTS registration node, out_file = strat['ants_initial_xfm'] workflow.connect(node, out_file, collect_transforms, 'inputspec.linear_initial') # linear affine from anatomical->template ANTS registration node, out_file = strat['ants_affine_xfm'] workflow.connect(node, out_file, collect_transforms, 'inputspec.linear_affine') # rigid affine from anatomical->template ANTS registration node, out_file = strat['ants_rigid_xfm'] workflow.connect(node, out_file, collect_transforms, 'inputspec.linear_rigid') # converted FLIRT func->anat affine, now in ITK (ANTS) format workflow.connect(fsl_to_itk_convert, 'outputspec.itk_transform', collect_transforms, 'inputspec.fsl_to_itk_affine') # output file to be converted node, out_file = strat[output_name] workflow.connect(node, out_file, apply_ants_warp, 'inputspec.input_image') # collection of warps to be applied to the output file workflow.connect(collect_transforms, 'outputspec.transformation_series', apply_ants_warp, 'inputspec.transforms') strat.update_resource_pool({ '{0}_to_standard'.format(output_name): (apply_ants_warp, 'outputspec.output_image') }) strat.append_name(apply_ants_warp.name) num_strat += 1 elif 'anat_mni_fnirt_register' in nodes: # FSL WARP APPLICATION if map_node: apply_fsl_warp = pe.MapNode(interface=fsl.ApplyWarp(), name='{0}_to_standard_{1}'.format( output_name, num_strat), iterfield=['in_file']) else: apply_fsl_warp = pe.Node(interface=fsl.ApplyWarp(), name='{0}_to_standard_{1}'.format( output_name, num_strat)) apply_fsl_warp.inputs.ref_file = \ pipeline_config_obj.template_skull_for_func # output file to be warped node, out_file = strat[output_name] workflow.connect(node, out_file, apply_fsl_warp, 'in_file') # linear affine from func->anat linear FLIRT registration node, out_file = strat['functional_to_anat_linear_xfm'] workflow.connect(node, out_file, apply_fsl_warp, 'premat') # nonlinear warp from anatomical->template FNIRT registration node, out_file = strat['anatomical_to_mni_nonlinear_xfm'] workflow.connect(node, out_file, apply_fsl_warp, 'field_file') strat.update_resource_pool({ '{0}_to_standard'.format(output_name): (apply_fsl_warp, 'out_file') }) strat.append_name(apply_fsl_warp.name) elif 'anat_mni_flirt_register' in nodes: # FSL WARP APPLICATION if map_node: apply_anat_warp = pe.MapNode(interface=fsl.ApplyWarp(), name='{0}_to_anat_{1}'.format( output_name, num_strat), iterfield=['in_file']) apply_fsl_warp = pe.MapNode(interface=fsl.ApplyWarp(), name='{0}_to_standard_{1}'.format( output_name, num_strat), iterfield=['in_file']) else: apply_anat_warp = pe.Node(interface=fsl.ApplyWarp(), name='{0}_to_anat_{1}'.format( output_name, num_strat)) apply_fsl_warp = pe.Node(interface=fsl.ApplyWarp(), name='{0}_to_standard_{1}'.format( output_name, num_strat)) node, out_file = strat['anatomical_brain'] workflow.connect(node, out_file, apply_anat_warp, 'ref_file') apply_fsl_warp.inputs.ref_file = \ pipeline_config_obj.template_skull_for_func # output file to be warped node, out_file = strat[output_name] workflow.connect(node, out_file, apply_anat_warp, 'in_file') # linear affine from func->anat linear FLIRT registration node, out_file = strat['functional_to_anat_linear_xfm'] workflow.connect(node, out_file, apply_anat_warp, 'premat') # output file to be warped workflow.connect(apply_anat_warp, 'out_file', apply_fsl_warp, 'in_file') # nonlinear warp from anatomical->template FNIRT registration node, out_file = strat['anatomical_to_mni_linear_xfm'] workflow.connect(node, out_file, apply_fsl_warp, 'premat') strat.update_resource_pool({ '{0}_to_standard'.format(output_name): (apply_fsl_warp, 'out_file') }) strat.append_name(apply_fsl_warp.name) return strat