def test_normalize_list_outputs(): filelist, outdir, cwd = create_files_in_directory() norm = spm.Normalize(source=filelist[0]) yield assert_true, norm._list_outputs()['normalized_source'][0].startswith( 'w') norm = spm.Normalize(source=filelist[0], apply_to_files=filelist[1]) yield assert_true, norm._list_outputs()['normalized_files'][0].startswith( 'w') clean_directory(outdir, cwd)
def __init__(self, experiment_dir, output_dir, working_dir, func_source, struct_source, datasink): self.experiment_dir = experiment_dir self.output_dir = output_dir self.working_dir = working_dir # specify input and output nodes self.func_source = func_source self.struct_source = struct_source self.datasink = datasink # specify workflow instance self.workflow = pe.Workflow(name='workflow') # specify nodes self.realign = pe.Node(interface=spm.Realign(), name='realign') self.coregister = pe.Node(interface=spm.Coregister(), name="coregister") self.coregister.inputs.jobtype = 'estimate' self.segment = pe.Node(interface=spm.Segment(), name="segment") self.normalize_func = pe.Node(interface=spm.Normalize(), name="normalize_func") self.normalize_func.inputs.jobtype = "write" self.normalize_struc = pe.Node(interface=spm.Normalize(), name="normalize_struc") self.normalize_struc.inputs.jobtype = "write" self.smooth = pe.Node(interface=spm.Smooth(), name="smooth") # connect the nodes to complete the workflow self.workflow.connect([ (self.func_source, self.realign, [('outfiles', 'in_files')]), (self.struct_source, self.coregister, [('outfiles', 'source')]), (self.realign, self.coregister, [('mean_image', 'target')]), (self.coregister, self.segment, [('coregistered_source', 'data')]), (self.segment, self.normalize_func, [('transformation_mat', 'parameter_file')]), (self.realign, self.normalize_func, [('realigned_files', 'apply_to_files')]), (self.normalize_func, self.smooth, [('normalized_files', 'in_files')]), #(self.realign, self.datasink, [('realigned_files', 'realign')]), #(self.realign, self.datasink, [('mean_image', 'mean')]), (self.normalize_func, self.datasink, [('normalized_files', 'norm')] ), (self.smooth, self.datasink, [('smoothed_files', 'smooth')]) ])
def __init__(self, parameter_file='path', source=['path'], template='path', **options): import nipype.interfaces.spm as spm norm = spm.Normalize() norm.inputs.parameter_file = parameter_file norm.inputs.source = source norm.inputs.template = template for ef in options: setattr(norm.inputs, ef, options[ef]) self.res = norm.run()
def test_normalize(): yield assert_equal, spm.Normalize._jobtype, 'spatial' yield assert_equal, spm.Normalize._jobname, 'normalise' yield assert_equal, spm.Normalize().inputs.jobtype, 'estwrite' input_map = dict(template=dict(field='eoptions.template', mandatory=True, xor=['parameter_file'], copyfile=False), source=dict(field='subj.source', xor=['parameter_file'], mandatory=True, copyfile=True), apply_to_files=dict(field='subj.resample', copyfile=True), parameter_file=dict(field='subj.matname', mandatory=True, xor=['source', 'template'], copyfile=False), source_weight=dict(field='subj.wtsrc', copyfile=False), template_weight=dict(field='eoptions.weight', copyfile=False), source_image_smoothing=dict(field='eoptions.smosrc'), template_image_smoothing=dict(field='eoptions.smoref'), affine_regularization_type=dict(field='eoptions.regype'), DCT_period_cutoff=dict(field='eoptions.cutoff'), nonlinear_iterations=dict(field='eoptions.nits'), nonlinear_regularization=dict(field='eoptions.reg'), write_preserve=dict(field='roptions.preserve'), write_bounding_box=dict(field='roptions.bb'), write_voxel_sizes=dict(field='roptions.vox'), write_interp=dict(field='roptions.interp'), write_wrap=dict(field='roptions.wrap')) norm = spm.Normalize() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(norm.inputs.traits()[key], metakey), value
def simple_warp(template, warped, other=None): """ uses basic spm Normalize to warp warped to template applies parameters to other if specified""" startdir = os.getcwd() pth, _ = os.path.split(warped) os.chdir(pth) warp = spm.Normalize(matlab_cmd='matlab-spm8') warp.inputs.template = template warp.inputs.source = warped warp.inputs.ignore_exception = True if other is not None: warp.inputs.apply_to_files = other warp_out = warp.run() os.chdir(startdir) return warp_out
def normalize_T1_toMNI152(T1_dir, slice_time_dir): # Function normalizes an AC-PC aligned T1 into MNI 152 space # Get the name of the ac-pc aligned T1 os.chdir(T1_dir) for files in os.listdir(T1_dir): if files.startswith('r'): T1name = files # Get list of EPIs to apply MNI normalization transform result from T1 EPI_list = [] os.chdir(slice_time_dir) for files in os.listdir(slice_time_dir): if files.startswith('ar'): EPI_list.append(files) # Initialize SPM normalization EPI_list.sort() mni_template = matlab_dir + '/toolbox/spm8/canonical/avg152T1.nii' os.system('cp %s %s' % (mni_template, slice_time_dir)) # copy spm mni template to cwd norm = spm.Normalize() norm.inputs.source = T1_dir + '/' + T1name norm.inputs.template = mni_template norm.inputs.affine_regularization_type = 'mni' EPI_list.append(norm.inputs.source) # apply normalization to T1 and all EPIs norm.inputs.apply_to_files = EPI_list print "<:::Normalizing T1 and EPIs to MNI 152:::>" norm.run() # Make a new dir for MNI warped EPIs MNI_dir = os.mkdir('MNI_Normalized') os.system('cp w* %s' % (MNI_dir)) return MNI_dir
""" skullstrip = pe.Node(fsl.BET(), name="skullstrip") skullstrip.inputs.mask = True """Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid body registration of the functional data to the structural data. """ coregister = pe.Node(spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' """Warp functional and structural data to SPM's T1 template using :class:`nipype.interfaces.spm.Normalize`. The tutorial data set includes the template image, T1.nii. """ normalize = pe.Node(spm.Normalize(), name="normalize") """Smooth the functional data using :class:`nipype.interfaces.spm.Smooth`. """ smooth = pe.Node(spm.Smooth(), name="smooth") fwhmlist = [4] smooth.iterables = ('fwhm', fwhmlist) preproc.connect([ (inputnode, normalize, [(('in_data', _template_path), 'template')]), (realign, coregister, [('mean_image', 'source'), ('realigned_files', 'apply_to_files')]), (coregister, normalize, [('coregistered_files', 'apply_to_files')]), (normalize, smooth, [('normalized_files', 'in_files')]), (normalize, skullstrip, [('normalized_source', 'in_file')]),
""" skullstrip = pe.Node(interface=fsl.BET(), name="skullstrip") skullstrip.inputs.mask = True """Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid body registration of the functional data to the structural data. """ coregister = pe.Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' """Warp functional and structural data to SPM's T1 template using :class:`nipype.interfaces.spm.Normalize`. The tutorial data set includes the template image, T1.nii. """ normalize = pe.Node(interface=spm.Normalize(), name="normalize") normalize.inputs.template = os.path.abspath('data/T1.nii') """Smooth the functional data using :class:`nipype.interfaces.spm.Smooth`. """ smooth = pe.Node(interface=spm.Smooth(), name="smooth") fwhmlist = [4] smooth.iterables = ('fwhm', fwhmlist) preproc.connect([ (realign, coregister, [('mean_image', 'source'), ('realigned_files', 'apply_to_files')]), (coregister, normalize, [('coregistered_files', 'apply_to_files')]), (normalize, smooth, [('normalized_files', 'in_files')]), (normalize, skullstrip, [('normalized_source', 'in_file')]),
segment = pe.Node(interface=spm.Segment(), name='segment') """ Use :class:`nipype.interfaces.freesurfer.ApplyVolTransform` to convert contrast images into freesurfer space. """ normwreg = pe.MapNode(interface=fs.ApplyVolTransform(), iterfield=['source_file'], name='applyreg2con') """ Use :class:`nipype.interfaces.spm.Normalize` to normalize the contrast images to MNI space """ normalize = pe.Node(interface=spm.Normalize(jobtype='write'), name='norm2mni') """ Connect up the volume normalization components """ volnorm.connect([ (convert, segment, [('out_file', 'data')]), (convert2, normwreg, [('out_file', 'source_file')]), (segment, normalize, [('transformation_mat', 'parameter_file')]), (normwreg, normalize, [('transformed_file', 'apply_to_files')]), ]) """ Preproc + Analysis + VolumeNormalization workflow ------------------------------------------------- Connect up the lower level workflows into an integrated analysis. In addition,
def test_normalize_list_outputs(create_files_in_directory): filelist, outdir, cwd = create_files_in_directory norm = spm.Normalize(source=filelist[0]) assert norm._list_outputs()['normalized_source'][0].startswith('w') norm = spm.Normalize(source=filelist[0], apply_to_files=filelist[1]) assert norm._list_outputs()['normalized_files'][0].startswith('w')
def test_normalize(): assert spm.Normalize._jobtype == 'spatial' assert spm.Normalize._jobname == 'normalise' assert spm.Normalize().inputs.jobtype == 'estwrite'
def create_spm_preproc_func_pipeline(data_dir=None, subject_id=None, task_list=None): ############################### ## Set up Nodes ############################### ds = Node(nio.DataGrabber(infields=['subject_id', 'task_id'], outfields=['func', 'struc']), name='datasource') ds.inputs.base_directory = os.path.abspath(data_dir + '/' + subject_id) ds.inputs.template = '*' ds.inputs.sort_filelist = True ds.inputs.template_args = {'func': [['task_id']], 'struc': []} ds.inputs.field_template = { 'func': 'Functional/Raw/%s/func.nii', 'struc': 'Structural/SPGR/spgr.nii' } ds.inputs.subject_id = subject_id ds.inputs.task_id = task_list ds.iterables = ('task_id', task_list) # ds.run().outputs #show datafiles # #Setup Data Sinker for writing output files # datasink = Node(nio.DataSink(), name='sinker') # datasink.inputs.base_directory = '/path/to/output' # workflow.connect(realigner, 'realignment_parameters', datasink, 'motion.@par') # datasink.inputs.substitutions = [('_variable', 'variable'),('file_subject_', '')] #Get Timing Acquisition for slice timing tr = 2 ta = Node(interface=util.Function(input_names=['tr', 'n_slices'], output_names=['ta'], function=get_ta), name="ta") ta.inputs.tr = tr #Slice Timing: sequential ascending slice_timing = Node(interface=spm.SliceTiming(), name="slice_timing") slice_timing.inputs.time_repetition = tr slice_timing.inputs.ref_slice = 1 #Realignment - 6 parameters - realign to first image of very first series. realign = Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True #Plot Realignment plot_realign = Node(interface=PlotRealignmentParameters(), name="plot_realign") #Artifact Detection art = Node(interface=ra.ArtifactDetect(), name="art") art.inputs.use_differences = [True, False] art.inputs.use_norm = True art.inputs.norm_threshold = 1 art.inputs.zintensity_threshold = 3 art.inputs.mask_type = 'file' art.inputs.parameter_source = 'SPM' #Coregister - 12 parameters, cost function = 'nmi', fwhm 7, interpolate, don't mask #anatomical to functional mean across all available data. coregister = Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' # Segment structural, gray/white/csf,mni, segment = Node(interface=spm.Segment(), name="segment") segment.inputs.save_bias_corrected = True #Normalize - structural to MNI - then apply this to the coregistered functionals normalize = Node(interface=spm.Normalize(), name="normalize") normalize.inputs.template = os.path.abspath(t1_template_file) #Plot normalization Check plot_normalization_check = Node(interface=Plot_Coregistration_Montage(), name="plot_normalization_check") plot_normalization_check.inputs.canonical_img = canonical_file #Create Mask compute_mask = Node(interface=ComputeMask(), name="compute_mask") #remove lower 5% of histogram of mean image compute_mask.inputs.m = .05 #Smooth #implicit masking (.im) = 0, dtype = 0 smooth = Node(interface=spm.Smooth(), name="smooth") fwhmlist = [0, 5, 8] smooth.iterables = ('fwhm', fwhmlist) #Create Covariate matrix make_covariates = Node(interface=Create_Covariates(), name="make_covariates") ############################### ## Create Pipeline ############################### Preprocessed = Workflow(name="Preprocessed") Preprocessed.base_dir = os.path.abspath(data_dir + '/' + subject_id + '/Functional') Preprocessed.connect([ (ds, ta, [(('func', get_n_slices), "n_slices")]), (ta, slice_timing, [("ta", "time_acquisition")]), (ds, slice_timing, [ ('func', 'in_files'), (('func', get_n_slices), "num_slices"), (('func', get_slice_order), "slice_order"), ]), (slice_timing, realign, [('timecorrected_files', 'in_files')]), (realign, compute_mask, [('mean_image', 'mean_volume')]), (realign, coregister, [('mean_image', 'target')]), (ds, coregister, [('struc', 'source')]), (coregister, segment, [('coregistered_source', 'data')]), (segment, normalize, [ ('transformation_mat', 'parameter_file'), ('bias_corrected_image', 'source'), ]), (realign, normalize, [('realigned_files', 'apply_to_files'), (('realigned_files', get_vox_dims), 'write_voxel_sizes')]), (normalize, smooth, [('normalized_files', 'in_files')]), (compute_mask, art, [('brain_mask', 'mask_file')]), (realign, art, [('realignment_parameters', 'realignment_parameters')]), (realign, art, [('realigned_files', 'realigned_files')]), (realign, plot_realign, [('realignment_parameters', 'realignment_parameters')]), (normalize, plot_normalization_check, [('normalized_files', 'wra_img') ]), (realign, make_covariates, [('realignment_parameters', 'realignment_parameters')]), (art, make_covariates, [('outlier_files', 'spike_id')]), ]) return Preprocessed
def __init__(self, subject, func_source, struct_source, datasink, TR, num_slices, dim=2): self.subject = subject # specify input and output nodes self.func_source = func_source self.struct_source = struct_source self.datasink = datasink self.TR = TR self.num_slices = num_slices # specify nodes # structual process self.bet_struct = pe.Node(interface=fsl.BET(), name='non_brain_removal_BET_struct') self.bet_struct.inputs.output_type = "NIFTI" self.bet_struct.inputs.frac = 0.3 self.coregister_struct = pe.Node(interface=spm.Coregister(), name="coregister_struct_to_mni") self.coregister_struct.inputs.target = '/mnt/Program/python/dev/images/MNI152_T1_2mm_brain.nii' if dim == 1: self.coregister_struct.inputs.target = '/mnt/Program/python/dev/images/MNI152_T1_1mm_brain.nii' self.coregister_struct.inputs.write_interp = 7 self.coregister_struct.inputs.separation = [1.0, 1.0] self.coregister_struct.inputs.jobtype = 'estwrite' self.segment_struct = pe.Node(interface=spm.Segment(), name="segment_struct") # self.segment_struct.inputs.affine_regularization = 'mni' self.segment_struct.inputs.csf_output_type = [True, True, True] self.segment_struct.inputs.gm_output_type = [True, True, True] self.segment_struct.inputs.wm_output_type = [True, True, True] self.normalize_struct = pe.Node(interface=spm.Normalize(), name='normalize_struct') self.normalize_struct.inputs.jobtype = 'write' self.normalize_struct.inputs.write_bounding_box = [[-90, -126, -72], [90, 90, 108] ] # 91, 109, 91 if dim == 1: self.normalize_struct.inputs.write_bounding_box = [[ -91, -126, -72 ], [90, 91, 109]] # 182, 218, 182 self.normalize_struct.inputs.write_voxel_sizes = [1, 1, 1] self.normalize_gm = pe.Node(interface=spm.Normalize(), name='normalize_gm') self.normalize_gm.inputs.jobtype = 'write' self.normalize_gm.inputs.write_bounding_box = [[-90, -126, -72], [90, 90, 108]] # 91, 109, 91 if dim == 1: self.normalize_gm.inputs.write_bounding_box = [[-91, -126, -72], [90, 91, 109] ] # 182, 218, 182 self.normalize_gm.inputs.write_voxel_sizes = [1, 1, 1] self.normalize_wm = pe.Node(interface=spm.Normalize(), name='normalize_wm') self.normalize_wm.inputs.jobtype = 'write' self.normalize_wm.inputs.write_bounding_box = [[-90, -126, -72], [90, 90, 108]] # 91, 109, 91 if dim == 1: self.normalize_wm.inputs.write_bounding_box = [[-91, -126, -72], [90, 91, 109] ] # 182, 218, 182 self.normalize_wm.inputs.write_voxel_sizes = [1, 1, 1] self.normalize_csf = pe.Node(interface=spm.Normalize(), name='normalize_csf') self.normalize_csf.inputs.jobtype = 'write' self.normalize_csf.inputs.write_bounding_box = [[-90, -126, -72], [90, 90, 108]] # 91, 109, 91 if dim == 1: self.normalize_csf.inputs.write_bounding_box = [[-91, -126, -72], [90, 91, 109] ] # 182, 218, 182 self.normalize_csf.inputs.write_voxel_sizes = [1, 1, 1] ################################################################################################### # functional process self.fslsplit = pe.Node(interface=fsl.Split(), name='fslsplit') self.fslsplit.inputs.dimension = 't' self.fslsplit.inputs.output_type = "NIFTI" self.fslmerge = pe.Node(interface=fsl.Merge(), name='fslmerge') self.fslmerge.inputs.dimension = 't' self.fslmerge.inputs.output_type = "NIFTI" # helper function(s) def bet_each(in_files, subject_name): ''' @param in_files: list of image files @return out_files: list of image files after applied fsl.BET on it ''' from nipype.interfaces import fsl import nipype.pipeline.engine as pe out_files = list() step_no = 0 for file_ in in_files: bet = pe.Node(interface=fsl.BET(), name='BET_for_step_{}_{}'.format( step_no, subject_name)) bet.inputs.in_file = file_ bet.inputs.out_file = file_[:len(file_) - 4] + '_bet.nii' bet.inputs.output_type = "NIFTI" bet.inputs.frac = 0.5 bet.run() out_files.append(bet.inputs.out_file) step_no += 1 return out_files # bet_func return a list of NIFITI files self.bet_func = pe.Node(interface=Function( input_names=['in_files', 'subject_name'], output_names=['out_files'], function=bet_each), name='non_brain_removal_BET_func') self.bet_func.inputs.subject_name = self.subject self.realign = pe.Node(interface=spm.Realign(), name='realign_motion_correction') self.realign.inputs.register_to_mean = True self.coregister_func = pe.Node(interface=spm.Coregister(), name="coregister_func_to_mni") self.coregister_func.inputs.target = '/mnt/Program/python/dev/images/MNI152_T1_2mm_brain.nii' self.coregister_func.inputs.write_interp = 7 self.coregister_func.inputs.separation = [1.0, 1.0] self.coregister_func.inputs.jobtype = 'estwrite' self.segment = pe.Node(interface=spm.Segment(), name="segment") self.normalize_func = pe.Node(interface=spm.Normalize(), name="normalize_func") self.normalize_func.inputs.jobtype = 'write' self.normalize_func.inputs.write_bounding_box = [[-90, -126, -72], [90, 90, 108]] # 91, 109, 91 self.smooth = pe.Node(interface=spm.Smooth(), name="smooth") self.smooth.inputs.fwhm = [8, 8, 8] # backup node(s) self.slice_timing = pe.Node(interface=spm.SliceTiming(), name='time_slice_correction') self.slice_timing.inputs.time_repetition = self.TR self.slice_timing.inputs.num_slices = self.num_slices self.slice_timing.inputs.time_acquisition = self.TR - (self.TR / self.num_slices) self.slice_timing.inputs.slice_order = list( range(self.num_slices, 0, -1)) self.slice_timing.inputs.ref_slice = 1 self.direct_normalize = pe.Node(interface=spm.Normalize12(), name='direct_normalize') self.direct_normalize.inputs.image_to_align = 'images/MNI152_T1_2mm_brain.nii' self.direct_normalize.inputs.affine_regularization_type = 'size' # specify workflow instance self.workflow = pe.Workflow(name='preprocess_workflow') # connect nodes self.workflow.connect([ (self.struct_source, self.bet_struct, [('outfiles', 'in_file')]), (self.bet_struct, self.coregister_struct, [('out_file', 'source') ]), (self.coregister_struct, self.segment_struct, [('coregistered_source', 'data')]), (self.segment_struct, self.normalize_struct, [('transformation_mat', 'parameter_file')]), (self.coregister_struct, self.normalize_struct, [('coregistered_source', 'apply_to_files')]), (self.segment_struct, self.normalize_gm, [('transformation_mat', 'parameter_file')]), (self.segment_struct, self.normalize_gm, [('native_gm_image', 'apply_to_files')]), (self.segment_struct, self.normalize_wm, [('transformation_mat', 'parameter_file')]), (self.segment_struct, self.normalize_wm, [('native_wm_image', 'apply_to_files')]), (self.segment_struct, self.normalize_csf, [('transformation_mat', 'parameter_file')]), (self.segment_struct, self.normalize_csf, [('native_csf_image', 'apply_to_files')]), (self.func_source, self.fslsplit, [('outfiles', 'in_file')]), (self.fslsplit, self.bet_func, [('out_files', 'in_files')]), (self.bet_func, self.fslmerge, [('out_files', 'in_files')]), (self.fslmerge, self.realign, [('merged_file', 'in_files')]), (self.realign, self.datasink, [('realignment_parameters', 'realignment_parameters')]), (self.realign, self.coregister_func, [('mean_image', 'source')]), (self.realign, self.coregister_func, [('realigned_files', 'apply_to_files')]), (self.coregister_func, self.segment, [('coregistered_source', 'data')]), (self.segment, self.normalize_func, [('transformation_mat', 'parameter_file')]), (self.coregister_func, self.normalize_func, [('coregistered_files', 'apply_to_files')]), (self.normalize_func, self.smooth, [('normalized_files', 'in_files')]), # end (self.normalize_func, self.datasink, [('normalized_files', 'before_smooth')]), (self.smooth, self.datasink, [('smoothed_files', 'final_out')]), (self.normalize_struct, self.datasink, [('normalized_files', 'standardized_struct_file')]), # (self.segment_struct, self.datasink, [('native_csf_image', 'csf'), ('native_gm_image', 'grey_matter'), ('native_wm_image', 'white_matter')]) (self.normalize_gm, self.datasink, [('normalized_files', 'grey_matter')]), (self.normalize_wm, self.datasink, [('normalized_files', 'white_matter')]), (self.normalize_csf, self.datasink, [('normalized_files', 'csf')]), ]) # backup workflow(s) self.workflow_only_fmri = pe.Workflow(name='preprocess_workflow') # connect nodes self.workflow_only_fmri.connect([ (self.func_source, self.fslsplit, [('outfiles', 'in_file')]), (self.fslsplit, self.bet_func, [('out_files', 'in_files')]), (self.bet_func, self.fslmerge, [('out_files', 'in_files')]), (self.fslmerge, self.realign, [('merged_file', 'in_files')]), (self.realign, self.direct_normalize, [('realigned_files', 'apply_to_files')]), (self.direct_normalize, self.smooth, [('normalized_files', 'in_files')]), # end (self.direct_normalize, self.datasink, [('normalized_files', 'before_smooth')]), (self.smooth, self.datasink, [('smoothed_files', 'final_out')]) ])
def test_normalize(): assert spm.Normalize._jobtype == "spatial" assert spm.Normalize._jobname == "normalise" assert spm.Normalize().inputs.jobtype == "estwrite"
def spm_mrpet_grouptemplate_preprocessing(wf_name="spm_mrpet_grouptemplate_preproc"): """ Run the PET pre-processing workflow against the gunzip_pet.in_file files. It depends on the anat_preproc_workflow, so if this has not been run, this function will run it too. This is identical to the workflow defined in `spm_mrpet_preprocessing`, with the only difference that we now normalize all subjects agains a custom template using the spm Old Normalize interface. It does: - SPM12 Coregister T1 and tissues to PET - PVC the PET image in PET space - SPM12 Warp PET to the given template Parameters ---------- wf_name: str Name of the workflow. Nipype Inputs ------------- pet_input.in_file: traits.File The raw NIFTI_GZ PET image file. pet_input.atlas_anat: traits.File The atlas file in anatomical space. pet_input.anat: traits.File Path to the high-contrast anatomical image. Reference file of the warp_field, i.e., the anatomical image in its native space. pet_input.tissues: list of traits.File List of tissues files from the New Segment process. At least the first 3 tissues must be present. pet_input.pet_template: traits.File The template file for inter-subject registration reference. Nipype outputs -------------- pet_output.pvc_out: existing file The results of the PVC process. pet_output.brain_mask: existing file A brain mask calculated with the tissues file. pet_output.coreg_ref: existing file The coregistered reference image to PET space. pet_output.coreg_others: list of existing files List of coregistered files from coreg_pet.apply_to_files. pet_output.pet_warped: existing file PET image normalized to the group template. pet_output.pvc_warped: existing file The outputs of the PETPVC workflow normalized to the group template. The result of every internal pre-processing step is normalized to the group template here. pet_output.warp_field: existing files Spatial normalization parameters .mat files. pet_output.gm_norm: existing file The output of the grey matter intensity normalization process. This is the last step in the PET signal correction, before registration. pet_output.atlas_pet: existing file Atlas image warped to PET space. If the `atlas_file` option is an existing file and `normalize_atlas` is True. Returns ------- wf: nipype Workflow """ # specify input and output fields in_fields = ["in_file", "anat", "tissues", "pet_template"] out_fields = ["brain_mask", "coreg_others", "coreg_ref", "pvc_warped", "pet_warped", "warp_field", "pvc_out", "pvc_mask", "gm_norm",] do_atlas, _ = check_atlas_file() if do_atlas: in_fields += ["atlas_anat"] out_fields += ["atlas_pet" ] # input pet_input = setup_node(IdentityInterface(fields=in_fields, mandatory_inputs=True), name="pet_input") # workflow to perform partial volume correction petpvc = petpvc_workflow(wf_name="petpvc") unzip_mrg = setup_node(Merge(4), name='merge_for_unzip') gunzipper = pe.MapNode(Gunzip(), name="gunzip", iterfield=['in_file']) # warp each subject to the group template gunzip_template = setup_node(Gunzip(), name="gunzip_template",) gunzip_pet = setup_node(Gunzip(), name="gunzip_pet",) warp_mrg = setup_node(Merge(2), name='merge_for_warp') warp2template = setup_node(spm.Normalize(jobtype="estwrite", out_prefix="wgrptemplate_"), name="warp2template",) get_bbox = setup_node(Function(function=get_bounding_box, input_names=["in_file"], output_names=["bbox"]), name="get_bbox") # output pet_output = setup_node(IdentityInterface(fields=out_fields), name="pet_output") # Create the workflow object wf = pe.Workflow(name=wf_name) wf.connect([ # inputs (pet_input, petpvc, [("in_file", "pvc_input.in_file"), ("anat", "pvc_input.reference_file"), ("tissues", "pvc_input.tissues")]), # get template bounding box to apply to results (pet_input, get_bbox, [("pet_template", "in_file")]), # gunzip some inputs (pet_input, gunzip_pet, [("in_file", "in_file")]), (pet_input, gunzip_template, [("pet_template", "in_file")]), # gunzip some files for SPM Normalize (petpvc, unzip_mrg, [("pvc_output.pvc_out", "in1"), ("pvc_output.brain_mask", "in2"), ("pvc_output.gm_norm", "in3")]), (pet_input, unzip_mrg, [("in_file", "in4")]), (unzip_mrg, gunzipper, [("out", "in_file")]), (gunzipper, warp_mrg, [("out_file", "in1")]), (warp_mrg, warp2template, [(("out", flatten_list), "apply_to_files")]), # prepare the target parameters of the warp to template (gunzip_pet, warp2template, [("out_file", "source")]), (gunzip_template, warp2template, [("out_file", "template")]), (get_bbox, warp2template, [("bbox", "write_bounding_box")]), # output (warp2template, pet_output, [("normalization_parameters", "warp_field"), ("normalized_files" , "pvc_warped"), ("normalized_source", "pet_warped"), ]), # output (petpvc, pet_output, [("pvc_output.pvc_out", "pvc_out"), ("pvc_output.brain_mask", "brain_mask"), ("pvc_output.coreg_ref", "coreg_ref"), ("pvc_output.coreg_others", "coreg_others"), ("pvc_output.gm_norm", "gm_norm")]), ]) if do_atlas: coreg_atlas = setup_node(spm_coregister(cost_function="mi"), name="coreg_atlas") # set the registration interpolation to nearest neighbour. coreg_atlas.inputs.write_interp = 0 wf.connect([ (pet_input, coreg_atlas, [("anat", "source")]), (petpvc, coreg_atlas, [("pvc_output.coreg_ref", "target")]), (pet_input, coreg_atlas, [("atlas_anat", "apply_to_files")]), (coreg_atlas, pet_output, [("coregistered_files", "atlas_pet")]), # warp the atlas to the template space as well (coreg_atlas, warp_mrg, [("coregistered_files", "in2")]), ]) return wf
def create_spm_preproc(c, name='preproc'): """Create an spm preprocessing workflow with freesurfer registration and artifact detection. The workflow realigns and smooths and registers the functional images with the subject's freesurfer space. Example ------- >>> preproc = create_spm_preproc() >>> preproc.base_dir = '.' >>> preproc.inputs.inputspec.fwhm = 6 >>> preproc.inputs.inputspec.subject_id = 's1' >>> preproc.inputs.inputspec.subjects_dir = '.' >>> preproc.inputs.inputspec.functionals = ['f3.nii', 'f5.nii'] >>> preproc.inputs.inputspec.norm_threshold = 1 >>> preproc.inputs.inputspec.zintensity_threshold = 3 Inputs:: inputspec.functionals : functional runs use 4d nifti inputspec.subject_id : freesurfer subject id inputspec.subjects_dir : freesurfer subjects dir inputspec.fwhm : smoothing fwhm inputspec.norm_threshold : norm threshold for outliers inputspec.zintensity_threshold : intensity threshold in z-score Outputs:: outputspec.realignment_parameters : realignment parameter files outputspec.smoothed_files : smoothed functional files outputspec.outlier_files : list of outliers outputspec.outlier_stats : statistics of outliers outputspec.outlier_plots : images of outliers outputspec.mask_file : binary mask file in reference image space outputspec.reg_file : registration file that maps reference image to freesurfer space outputspec.reg_cost : cost of registration (useful for detecting misalignment) """ from nipype.workflows.smri.freesurfer.utils import create_getmask_flow import nipype.algorithms.rapidart as ra import nipype.interfaces.spm as spm import nipype.interfaces.utility as niu import nipype.pipeline.engine as pe import nipype.interfaces.io as nio """ Initialize the workflow """ workflow = pe.Workflow(name=name) """ Define the inputs to this workflow """ inputnode = pe.Node(niu.IdentityInterface(fields=[ 'functionals', 'subject_id', 'subjects_dir', 'fwhm', 'norm_threshold', 'zintensity_threshold', 'tr', 'do_slicetime', 'sliceorder', 'node', 'csf_prob', 'wm_prob', 'gm_prob' ]), name='inputspec') """ Setup the processing nodes and create the mask generation and coregistration workflow """ poplist = lambda x: x.pop() #realign = pe.Node(spm.Realign(), name='realign') sym_func = pe.Node(niu.Function(input_names=['in_file'], output_names=['out_link'], function=do_symlink), name='func_symlink') realign = pe.Node(niu.Function( input_names=['node', 'in_file', 'tr', 'do_slicetime', 'sliceorder'], output_names=['out_file', 'par_file'], function=mod_realign), name="mod_realign") mean = art_mean_workflow() workflow.connect(realign, 'out_file', mean, 'inputspec.realigned_files') workflow.connect(realign, 'par_file', mean, 'inputspec.realignment_parameters') mean.inputs.inputspec.parameter_source = 'FSL' # Modular realign puts it in FSL format for consistency #workflow.connect(inputnode, 'functionals', realign, 'in_file') workflow.connect(inputnode, 'functionals', sym_func, 'in_file') workflow.connect(sym_func, 'out_link', realign, 'in_file') workflow.connect(inputnode, 'tr', realign, 'tr') workflow.connect(inputnode, 'do_slicetime', realign, 'do_slicetime') workflow.connect(inputnode, 'sliceorder', realign, 'sliceorder') workflow.connect(inputnode, 'node', realign, 'node') maskflow = create_getmask_flow() workflow.connect([(inputnode, maskflow, [('subject_id', 'inputspec.subject_id'), ('subjects_dir', 'inputspec.subjects_dir')])]) maskflow.inputs.inputspec.contrast_type = 't2' workflow.connect(mean, 'outputspec.mean_image', maskflow, 'inputspec.source_file') smooth = pe.Node(spm.Smooth(), name='smooth') normalize = pe.Node(spm.Normalize(jobtype='write'), name='normalize') normalize_struct = normalize.clone('normalize_struct') segment = pe.Node(spm.Segment(csf_output_type=[True, True, False], gm_output_type=[True, True, False], wm_output_type=[True, True, False]), name='segment') mergefunc = lambda in1, in2, in3: [in1, in2, in3] # merge = pe.Node(niu.Merge(),name='merge') merge = pe.Node(niu.Function(input_names=['in1', 'in2', 'in3'], output_names=['out'], function=mergefunc), name='merge') workflow.connect(inputnode, 'csf_prob', merge, 'in3') workflow.connect(inputnode, 'wm_prob', merge, 'in2') workflow.connect(inputnode, 'gm_prob', merge, 'in1') #workflow.connect(merge,'out', segment,'tissue_prob_maps') sym_prob = sym_func.clone('sym_prob') workflow.connect(merge, 'out', sym_prob, 'in_file') workflow.connect(sym_prob, 'out_link', segment, 'tissue_prob_maps') workflow.connect(maskflow, ('outputspec.mask_file', pickfirst), segment, 'mask_image') workflow.connect(inputnode, 'fwhm', smooth, 'fwhm') #sym_brain = sym_func.clone('sym_brain') #workflow.connect(realign, 'mean_image', normalize, 'source') #workflow.connect(maskflow,'fssource.brain',segment,'data') fssource = maskflow.get_node('fssource') import nipype.interfaces.freesurfer as fs convert_brain = pe.Node(interface=fs.ApplyVolTransform(inverse=True), name='convert') workflow.connect(fssource, 'brain', convert_brain, 'target_file') workflow.connect(maskflow, ('outputspec.reg_file', pickfirst), convert_brain, 'reg_file') workflow.connect(mean, 'outputspec.mean_image', convert_brain, 'source_file') convert2nii = pe.Node(fs.MRIConvert(in_type='mgz', out_type='nii'), name='convert2nii') workflow.connect(convert_brain, 'transformed_file', convert2nii, 'in_file') workflow.connect(convert2nii, 'out_file', segment, 'data') workflow.connect(segment, 'transformation_mat', normalize, 'parameter_file') workflow.connect(segment, 'transformation_mat', normalize_struct, 'parameter_file') workflow.connect(convert2nii, 'out_file', normalize_struct, 'apply_to_files') workflow.connect(realign, 'out_file', normalize, 'apply_to_files') #normalize.inputs.template='/software/spm8/templates/EPI.nii' workflow.connect(normalize, 'normalized_files', smooth, 'in_files') #workflow.connect(realign, 'realigned_files', smooth, 'in_files') artdetect = pe.Node(ra.ArtifactDetect(mask_type='file', parameter_source='FSL', use_differences=[True, False], use_norm=True, save_plot=True), name='artdetect') workflow.connect([(inputnode, artdetect, [('norm_threshold', 'norm_threshold'), ('zintensity_threshold', 'zintensity_threshold')])]) workflow.connect([(realign, artdetect, [('out_file', 'realigned_files'), ('par_file', 'realignment_parameters')])]) workflow.connect(maskflow, ('outputspec.mask_file', poplist), artdetect, 'mask_file') """ Define the outputs of the workflow and connect the nodes to the outputnode """ outputnode = pe.Node(niu.IdentityInterface(fields=[ "realignment_parameters", "smoothed_files", "mask_file", "mean_image", "reg_file", "reg_cost", 'outlier_files', 'outlier_stats', 'outlier_plots', 'norm_components', 'mod_csf', 'unmod_csf', 'mod_wm', 'unmod_wm', 'mod_gm', 'unmod_gm', 'mean', 'normalized_struct', 'struct_in_functional_space', 'normalization_parameters', 'reverse_normalize_parameters' ]), name="outputspec") workflow.connect([ (maskflow, outputnode, [("outputspec.reg_file", "reg_file")]), (maskflow, outputnode, [("outputspec.reg_cost", "reg_cost")]), (maskflow, outputnode, [(("outputspec.mask_file", poplist), "mask_file")]), (realign, outputnode, [('par_file', 'realignment_parameters')]), (smooth, outputnode, [('smoothed_files', 'smoothed_files')]), (artdetect, outputnode, [('outlier_files', 'outlier_files'), ('statistic_files', 'outlier_stats'), ('plot_files', 'outlier_plots'), ('norm_files', 'norm_components')]) ]) workflow.connect(segment, 'modulated_csf_image', outputnode, 'mod_csf') workflow.connect(segment, 'modulated_wm_image', outputnode, 'mod_wm') workflow.connect(segment, 'modulated_gm_image', outputnode, 'mod_gm') workflow.connect(segment, 'normalized_csf_image', outputnode, 'unmod_csf') workflow.connect(segment, 'normalized_wm_image', outputnode, 'unmod_wm') workflow.connect(segment, 'normalized_gm_image', outputnode, 'unmod_gm') workflow.connect(mean, 'outputspec.mean_image', outputnode, 'mean') workflow.connect(normalize_struct, 'normalized_files', outputnode, 'normalized_struct') workflow.connect(segment, 'transformation_mat', outputnode, 'normalization_parameters') workflow.connect(segment, 'inverse_transformation_mat', outputnode, 'reverse_normalize_parameters') workflow.connect(convert2nii, 'out_file', outputnode, 'struct_in_functional_space') workflow.inputs.inputspec.fwhm = c.fwhm workflow.inputs.inputspec.subjects_dir = c.surf_dir workflow.inputs.inputspec.norm_threshold = c.norm_thresh workflow.inputs.inputspec.zintensity_threshold = c.z_thresh workflow.inputs.inputspec.node = c.motion_correct_node workflow.inputs.inputspec.tr = c.TR workflow.inputs.inputspec.do_slicetime = c.do_slicetiming workflow.inputs.inputspec.sliceorder = c.SliceOrder workflow.inputs.inputspec.csf_prob = c.csf_prob workflow.inputs.inputspec.gm_prob = c.grey_prob workflow.inputs.inputspec.wm_prob = c.white_prob workflow.base_dir = c.working_dir workflow.config = {'execution': {'crashdump_dir': c.crash_dir}} datagrabber = get_dataflow(c) workflow.connect(datagrabber, 'func', inputnode, 'functionals') infosource = pe.Node(niu.IdentityInterface(fields=['subject_id']), name='subject_names') if not c.test_mode: infosource.iterables = ('subject_id', c.subjects) else: infosource.iterables = ('subject_id', c.subjects[:1]) workflow.connect(infosource, 'subject_id', inputnode, 'subject_id') workflow.connect(infosource, 'subject_id', datagrabber, 'subject_id') sub = lambda x: [('_subject_id_%s' % x, '')] sinker = pe.Node(nio.DataSink(), name='sinker') workflow.connect(infosource, 'subject_id', sinker, 'container') workflow.connect(infosource, ('subject_id', sub), sinker, 'substitutions') sinker.inputs.base_directory = c.sink_dir outputspec = workflow.get_node('outputspec') workflow.connect(outputspec, 'realignment_parameters', sinker, 'spm_preproc.realignment_parameters') workflow.connect(outputspec, 'smoothed_files', sinker, 'spm_preproc.smoothed_outputs') workflow.connect(outputspec, 'outlier_files', sinker, 'spm_preproc.art.@outlier_files') workflow.connect(outputspec, 'outlier_stats', sinker, 'spm_preproc.art.@outlier_stats') workflow.connect(outputspec, 'outlier_plots', sinker, 'spm_preproc.art.@outlier_plots') workflow.connect(outputspec, 'norm_components', sinker, 'spm_preproc.art.@norm') workflow.connect(outputspec, 'reg_file', sinker, 'spm_preproc.bbreg.@reg_file') workflow.connect(outputspec, 'reg_cost', sinker, 'spm_preproc.bbreg.@reg_cost') workflow.connect(outputspec, 'mask_file', sinker, 'spm_preproc.mask.@mask_file') workflow.connect(outputspec, 'mod_csf', sinker, 'spm_preproc.segment.mod.@csf') workflow.connect(outputspec, 'mod_wm', sinker, 'spm_preproc.segment.mod.@wm') workflow.connect(outputspec, 'mod_gm', sinker, 'spm_preproc.segment.mod.@gm') workflow.connect(outputspec, 'unmod_csf', sinker, 'spm_preproc.segment.unmod.@csf') workflow.connect(outputspec, 'unmod_wm', sinker, 'spm_preproc.segment.unmod.@wm') workflow.connect(outputspec, 'unmod_gm', sinker, 'spm_preproc.segment.unmod.@gm') workflow.connect(outputspec, 'mean', sinker, 'spm_preproc.mean') workflow.connect(outputspec, 'normalized_struct', sinker, 'spm_preproc.normalized_struct') workflow.connect(outputspec, 'normalization_parameters', sinker, 'spm_preproc.normalization_parameters.@forward') workflow.connect(outputspec, 'reverse_normalize_parameters', sinker, 'spm_preproc.normalization_parameters.@reverse') workflow.connect(outputspec, 'struct_in_functional_space', sinker, 'spm_preproc.struct_in_func_space') return workflow
coregister.iterables = ('target', 'func') coregister.inputs.source = 't2.nii' coregister2 = pe.Node(interface=spm.Coregister(), name="coregister2") coregister2.inputs.jobtype = 'estimate' # coreg output of T2 and T2* to T1 coregister2.iterables = ('target', ['func','t2.nii']) coregister2.inputs.source = 't1.nii' ## old segment # Q: why old? ## old normalize # prefix = w (norm'd to MNI) normalize = pe.Node(interface=spm.Normalize(), name="normalize") # Q: is this old norm? normalize.inputs.template = os.path.abspath('data/T1.nii') # Q: dir of MNI? ## smooth # 8 fwhm smooth = pe.Node(interface=spm.Smooth(), name="smooth") smooth.iterables = ('fwhm', [8]) ## set up pipeline preproc_pipeline = pe.Workflow(name="preproc") preproc_pipeline.base_dir = os.path.abspath('spm_tutorial/workingdir') #Q: dir? preproc_pipeline.connect([(infosource, datasource, [('subject_id', 'subject_id')]),
def spm_register_to_template_wf(wf_name="spm_registration_to_template"): """Return a workflow that registers each reg_input.in_file to the file in reg_input.template. For now this does not do atlas registration. It does: - SPM12 Warp input image to the given template Parameters ---------- wf_name: str Name of the workflow. Nipype Inputs ------------- reg_input.in_file: traits.File The raw NIFTI_GZ subject image file. reg_input.template: list of traits.File The template file for inter-subject registration reference. Nipype outputs -------------- reg_output.warped: existing file Image normalized to the given template. reg_output.warp_field: existing files Spatial normalization parameters .mat file. Returns ------- wf: nipype Workflow """ # specify input and output fields in_fields = [ "in_file", "template", ] out_fields = [ "warped", "warp_field", ] # input reg_input = setup_node(IdentityInterface(fields=in_fields, mandatory_inputs=True), name="reg_input") # warp each subject to the group template gunzip_template = setup_node( Gunzip(), name="gunzip_template", ) gunzip_input = setup_node( Gunzip(), name="gunzip_input", ) warp2template = setup_node(spm.Normalize(jobtype="estwrite", out_prefix="wgrptemplate_"), name="warp2template") get_bbox = setup_node(Function(function=get_bounding_box, input_names=["in_file"], output_names=["bbox"]), name="get_bbox") # output reg_output = setup_node(IdentityInterface(fields=out_fields), name="reg_output") # Create the workflow object wf = pe.Workflow(name=wf_name) wf.connect([ # get template bounding box to apply to results (reg_input, get_bbox, [("template", "in_file")]), # gunzip some inputs (reg_input, gunzip_input, [("in_file", "in_file")]), (reg_input, gunzip_template, [("template", "in_file")]), # prepare the target parameters of the warp to template (gunzip_template, warp2template, [("out_file", "template")]), (get_bbox, warp2template, [("bbox", "write_bounding_box")]), # directly warp pet to the template (gunzip_input, warp2template, [("out_file", "source")]), # output (warp2template, reg_output, [ ("normalization_parameters", "warp_field"), ("normalized_source", "warped"), ]), ]) return wf
def __init__(self, func_source, struct_source, datasink): # specify input and output nodes self.func_source = func_source self.struct_source = struct_source self.datasink = datasink # specify nodes # structual process self.bet_struct = pe.Node(interface=fsl.BET(), name='non_brain_removal_BET_struct') self.bet_struct.inputs.output_type = "NIFTI" # functional process self.slice_timer = pe.Node(interface=fsl.SliceTimer(), name='time_slice_correction') self.mcflirt = pe.Node(interface=fsl.MCFLIRT(), name='motion_correction') self.mcflirt.inputs.output_type = "NIFTI" self.mcflirt.inputs.mean_vol = True self.fslsplit = pe.Node(interface=fsl.Split(), name='fslsplit') self.fslsplit.inputs.dimension = 't' self.fslsplit.inputs.output_type = "NIFTI" self.fslmerge = pe.Node(interface=fsl.Merge(), name='fslmerge') self.fslmerge.inputs.dimension = 't' self.fslmerge.inputs.output_type = "NIFTI" self.bet_mean = pe.Node(interface=fsl.BET(), name='non_brain_removal_BET_mean') self.bet_mean.inputs.output_type = "NIFTI" # helper function(s) def bet_each(in_files): ''' @param in_files: list of image files @return out_files: list of image files after applied fsl.BET on it ''' from nipype.interfaces import fsl import nipype.pipeline.engine as pe out_files = list() step_no = 0 for file_ in in_files: bet = pe.Node(interface=fsl.BET(), name='BET_for_step_{}'.format(step_no)) bet.inputs.in_file = file_ bet.inputs.out_file = file_[:len(file_) - 4] + '_bet.nii' bet.inputs.output_type = "NIFTI" bet.run() out_files.append(bet.inputs.out_file) step_no += 1 return out_files # bet_func return a list of NIFITI files self.bet_func = pe.Node(interface=Function(input_names=['in_files'], output_names=['out_files'], function=bet_each), name='non_brain_removal_BET_func') self.coregister = pe.Node(interface=spm.Coregister(), name="coregister") self.coregister.inputs.jobtype = 'estimate' self.segment = pe.Node(interface=spm.Segment(), name="segment") self.segment.inputs.affine_regularization = 'mni' self.normalize_func = pe.Node(interface=spm.Normalize(), name="normalize_func") self.normalize_func.inputs.jobtype = "write" # self.fourier = pe.Node(interface=afni.Fourier(), name='temporal_filtering') # self.fourier.inputs.highpass = 0.01 # self.fourier.inputs.lowpass = 0.1 self.smooth = pe.Node(interface=spm.Smooth(), name="smooth") self.smooth.inputs.fwhm = [8, 8, 8] # specify workflow instance self.workflow = pe.Workflow(name='preprocessing_workflow') # connect nodes self.workflow.connect([ (self.struct_source, self.bet_struct, [('outfiles', 'in_file')]), (self.func_source, self.slice_timer, [('outfiles', 'in_file')]), (self.slice_timer, self.mcflirt, [('slice_time_corrected_file', 'in_file')]), (self.mcflirt, self.bet_mean, [('mean_img', 'in_file')]), (self.mcflirt, self.fslsplit, [('out_file', 'in_file')]), (self.fslsplit, self.bet_func, [('out_files', 'in_files')]), (self.bet_func, self.fslmerge, [('out_files', 'in_files') ]), # intersect (self.bet_struct, self.coregister, [('out_file', 'source')]), (self.bet_mean, self.coregister, [('out_file', 'target')]), (self.coregister, self.segment, [('coregistered_source', 'data')]), (self.segment, self.normalize_func, [('transformation_mat', 'parameter_file')]), (self.fslmerge, self.normalize_func, [('merged_file', 'apply_to_files')]), (self.normalize_func, self.smooth, [('normalized_files', 'in_files')]), (self.coregister, self.datasink, [('coregistered_source', 'registered_file')]), (self.normalize_func, self.datasink, [('normalized_files', 'before_smooth')]), (self.smooth, self.datasink, [('smoothed_files', 'final_out')]) ])
def test_normalize(): yield assert_equal, spm.Normalize._jobtype, 'spatial' yield assert_equal, spm.Normalize._jobname, 'normalise' yield assert_equal, spm.Normalize().inputs.jobtype, 'estwrite'
""" Use :class:`nipype.interfaces.freesurfer.ApplyVolTransform` to convert contrast images into freesurfer space. """ normwreg = pe.MapNode(interface=fs.ApplyVolTransform(), iterfield=['source_file'], name='applyreg2con') """ Use :class:`nipype.interfaces.spm.Normalize` to normalize the contrast images to MNI space """ normalize = pe.Node(interface=spm.Normalize(jobtype='write'), name='norm2mni') """ Connect up the volume normalization components """ volnorm.connect([(convert, segment, [('out_file','data')]), (convert2, normwreg, [('out_file', 'source_file')]), (segment, normalize, [('transformation_mat', 'parameter_file')]), (normwreg, normalize, [('transformed_file','apply_to_files')]), ]) """ Preproc + Analysis + VolumeNormalization workflow -------------------------------------------------
def spm_warp_fmri_wf(wf_name="spm_warp_fmri", register_to_grptemplate=False): """ Run SPM to warp resting-state fMRI pre-processed data to MNI or a given template. Tasks: - Warping the inputs to MNI or a template, if `do_group_template` is True Parameters ---------- wf_name: str register_to_grptemplate: bool If True will expect the wfmri_input.epi_template input and use it as a group template for inter-subject registratio. Nipype Inputs ------------- wfmri_input.in_file: traits.File The slice time and motion corrected fMRI file. wfmri_input.reference_file: traits.File The anatomical image in its native space for registration reference. wfmri_input.anat_fmri: traits.File The anatomical image in fMRI space. wfmri_input.anat_to_mni_warp: traits.File The warp field from the transformation of the anatomical image to the standard MNI space. wfmri_input.time_filtered: traits.File The bandpass time filtered fMRI file. wfmri_input.avg_epi: traits.File The average EPI from the fMRI file. wfmri_input.epi_template: traits.File Reference EPI template file for inter subject registration. If `do_group_template` is True you must specify this input. wfmri_input.brain_mask: traits.File Brain mask in fMRI space. wfmri_input.atlas_anat: traits.File Atlas in subject anatomical space. Nipype Outputs -------------- wfmri_output.warped_fmri: traits.File The slice time, motion, and nuisance corrected fMRI file registered to the template. wfmri_output.wtime_filtered: traits.File The bandpass time filtered fMRI file registered to the template. wfmri_output.smooth: traits.File The smooth bandpass time filtered fMRI file registered to the template. wfmri_output.wavg_epi: traits.File The average EPI from the fMRI file registered to the template. wfmri_output.warp_field: traits.File The fMRI to template warp field. wfmri_output.coreg_avg_epi: traits.File The average EPI image in anatomical space. Only if registration.anat2fmri is false. wfmri_output.coreg_others: traits.File Other mid-preprocessing fmri images registered to anatomical space: - wfmri_input.in_file, - wfmri_input.brain_mask, - wfmri_input.time_filtered. Only if registration.anat2fmri is false wfmri_output.wbrain_mask: traits.File Brain mask in fMRI space warped to MNI. Returns ------- wf: nipype Workflow """ # Create the workflow object wf = pe.Workflow(name=wf_name) # specify input and output fields in_fields = ["in_file", "anat_fmri", "anat_to_mni_warp", "brain_mask", "reference_file", "time_filtered", "avg_epi",] out_fields = ["warped_fmri", "wtime_filtered", "smooth", "wavg_epi", "wbrain_mask", "warp_field", "coreg_avg_epi", "coreg_others" ] if register_to_grptemplate: in_fields += ['epi_template'] do_atlas, _ = check_atlas_file() if do_atlas: in_fields += ["atlas_anat"] out_fields += ["atlas_fmri"] # input identities wfmri_input = setup_node(IdentityInterface(fields=in_fields, mandatory_inputs=True), name="wfmri_input") # in file unzipper in_gunzip = pe.Node(Gunzip(), name="in_gunzip") # merge list for normalization input merge_list = pe.Node(Merge(2), name='merge_for_warp') gunzipper = pe.MapNode(Gunzip(), name="gunzip", iterfield=['in_file']) # the template bounding box tpm_bbox = setup_node(Function(function=get_bounding_box, input_names=["in_file"], output_names=["bbox"]), name="tpm_bbox") # smooth the final result smooth = setup_node(fsl.IsotropicSmooth(fwhm=8, output_type='NIFTI'), name="smooth_fmri") # output identities rest_output = setup_node(IdentityInterface(fields=out_fields), name="wfmri_output") # check how to perform the registration, to decide how to build the pipeline anat2fmri = get_config_setting('registration.anat2fmri', False) # register to group template if register_to_grptemplate: gunzip_template = pe.Node(Gunzip(), name="gunzip_template",) warp = setup_node(spm.Normalize(jobtype="estwrite", out_prefix="wgrptmpl_"), name="fmri_grptemplate_warp",) warp_source_arg = "source" warp_outsource_arg = "normalized_source" warp_field_arg = "normalization_parameters" elif anat2fmri: # register to standard template warp = setup_node(spm_normalize(), name="fmri_warp") tpm_bbox.inputs.in_file = spm_tpm_priors_path() warp_source_arg = "image_to_align" warp_outsource_arg = "normalized_image" warp_field_arg = "deformation_field" else: # anat2fmri is False coreg = setup_node(spm_coregister(cost_function="mi"), name="coreg_fmri") warp = setup_node(spm_apply_deformations(), name="fmri_warp") coreg_files = pe.Node(Merge(3), name='merge_for_coreg') warp_files = pe.Node(Merge(2), name='merge_for_warp') tpm_bbox.inputs.in_file = spm_tpm_priors_path() # make the connections if register_to_grptemplate: wf.connect([ # get template bounding box to apply to results (wfmri_input, tpm_bbox, [("epi_template", "in_file")]), # unzip and forward the template file (wfmri_input, gunzip_template, [("epi_template", "in_file")]), (gunzip_template, warp, [("out_file", "template")]), # get template bounding box to apply to results (wfmri_input, tpm_bbox, [("epi_template", "in_file")]), ]) if anat2fmri or register_to_grptemplate: # prepare the inputs wf.connect([ # unzip the in_file input file (wfmri_input, in_gunzip, [("avg_epi", "in_file")]), # warp source file (in_gunzip, warp, [("out_file", warp_source_arg)]), # bounding box (tpm_bbox, warp, [("bbox", "write_bounding_box")]), # merge the other input files into a list (wfmri_input, merge_list, [("in_file", "in1"), ("time_filtered", "in2"), ]), # gunzip them for SPM (merge_list, gunzipper, [("out", "in_file")]), # apply to files (gunzipper, warp, [("out_file", "apply_to_files")]), # outputs (warp, rest_output, [(warp_field_arg, "warp_field"), (warp_outsource_arg, "wavg_epi"), ]), ]) else: # FMRI to ANAT wf.connect([ (wfmri_input, coreg, [("reference_file", "target")]), # unzip the in_file input file (wfmri_input, in_gunzip, [("avg_epi", "in_file")]), (in_gunzip, coreg, [("out_file", "source")]), # merge the other input files into a list (wfmri_input, coreg_files, [("in_file", "in1"), ("time_filtered", "in2"), ("brain_mask", "in3"), ]), # gunzip them for SPM (coreg_files, gunzipper, [("out", "in_file")]), # coregister fmri to anat (gunzipper, coreg, [("out_file", "apply_to_files")]), # anat to mni warp field (wfmri_input, warp, [("anat_to_mni_warp", "deformation_file")]), # bounding box (tpm_bbox, warp, [("bbox", "write_bounding_box")]), # apply to files (coreg, warp_files, [("coregistered_source", "in1")]), (coreg, warp_files, [("coregistered_files", "in2")]), (warp_files, warp, [("out", "apply_to_files")]), # outputs (warp, rest_output, [("normalized_files", "warped_files"),]), (warp, rest_output, [(("normalized_files", selectindex, 0), "wavg_epi"),]), (coreg, rest_output, [("coregistered_source", "coreg_avg_epi")]), (coreg, rest_output, [("coregistered_files", "coreg_others")]), ]) # atlas file in fMRI space if anat2fmri: coreg_atlas = setup_node(spm_coregister(cost_function="mi"), name="coreg_atlas2fmri") # set the registration interpolation to nearest neighbour. coreg_atlas.inputs.write_interp = 0 wf.connect([ (wfmri_input, coreg_atlas, [("reference_file", "source"), ("atlas_anat", "apply_to_files"), ]), (in_gunzip, coreg_atlas, [("out_file", "target")]), (coreg_atlas, rest_output, [("coregistered_files", "atlas_fmri")]), ]) # smooth and sink wf.connect([ # smooth the final bandpassed image (warp, smooth, [(("normalized_files", selectindex, 1), "in_file")]), # output (smooth, rest_output, [("out_file", "smooth")]), (warp, rest_output, [(("normalized_files", selectindex, 0), "warped_fmri"), (("normalized_files", selectindex, 1), "wtime_filtered"), ]), ]) return wf
coregister = pe.Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' segment = pe.Node(interface=spm.Segment(), name="segment") segment.inputs.save_bias_corrected = True """Uncomment the following line for faster execution """ # segment.inputs.gaussians_per_class = [1, 1, 1, 4] """Warp functional and structural data to SPM's T1 template using :class:`nipype.interfaces.spm.Normalize`. The tutorial data set includes the template image, T1.nii. """ normalize_func = pe.Node(interface=spm.Normalize(), name="normalize_func") normalize_func.inputs.jobtype = "write" normalize_struc = pe.Node(interface=spm.Normalize(), name="normalize_struc") normalize_struc.inputs.jobtype = "write" """Smooth the functional data using :class:`nipype.interfaces.spm.Smooth`. """ smooth = pe.Node(interface=spm.Smooth(), name="smooth") """`write_voxel_sizes` is the input of the normalize interface that is recommended to be set to the voxel sizes of the target volume. There is no need to set it manually since we van infer it from data using the following function: """
def create_spm_preproc(c, name='preproc'): """ """ from nipype.workflows.smri.freesurfer.utils import create_getmask_flow import nipype.algorithms.rapidart as ra import nipype.interfaces.spm as spm import nipype.interfaces.utility as niu import nipype.pipeline.engine as pe import nipype.interfaces.io as nio import nipype.interfaces.freesurfer as fs workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=[ 'functionals', 'subject_id', 'subjects_dir', 'fwhm', 'norm_threshold', 'zintensity_threshold', 'tr', 'do_slicetime', 'sliceorder', 'parameters', 'node', 'csf_prob', 'wm_prob', 'gm_prob' ]), name='inputspec') poplist = lambda x: x.pop() sym_func = pe.Node(niu.Function(input_names=['in_file'], output_names=['out_link'], function=do_symlink), name='func_symlink') # REALIGN realign = pe.Node(niu.Function( input_names=[ 'node', 'in_file', 'tr', 'do_slicetime', 'sliceorder', 'parameters' ], output_names=['out_file', 'par_file', 'parameter_source'], function=mod_realign), name="mod_realign") workflow.connect(inputnode, 'parameters', realign, 'parameters') workflow.connect(inputnode, 'functionals', realign, 'in_file') workflow.connect(inputnode, 'tr', realign, 'tr') workflow.connect(inputnode, 'do_slicetime', realign, 'do_slicetime') workflow.connect(inputnode, 'sliceorder', realign, 'sliceorder') workflow.connect(inputnode, 'node', realign, 'node') # TAKE MEAN IMAGE mean = art_mean_workflow() workflow.connect(realign, 'out_file', mean, 'inputspec.realigned_files') workflow.connect(realign, 'par_file', mean, 'inputspec.realignment_parameters') workflow.connect(realign, 'parameter_source', mean, 'inputspec.parameter_source') # CREATE BRAIN MASK maskflow = create_getmask_flow() workflow.connect([(inputnode, maskflow, [('subject_id', 'inputspec.subject_id'), ('subjects_dir', 'inputspec.subjects_dir')])]) maskflow.inputs.inputspec.contrast_type = 't2' workflow.connect(mean, 'outputspec.mean_image', maskflow, 'inputspec.source_file') # SEGMENT segment = pe.Node(spm.Segment(csf_output_type=[True, True, False], gm_output_type=[True, True, False], wm_output_type=[True, True, False]), name='segment') mergefunc = lambda in1, in2, in3: [in1, in2, in3] merge = pe.Node(niu.Function(input_names=['in1', 'in2', 'in3'], output_names=['out'], function=mergefunc), name='merge') workflow.connect(inputnode, 'csf_prob', merge, 'in3') workflow.connect(inputnode, 'wm_prob', merge, 'in2') workflow.connect(inputnode, 'gm_prob', merge, 'in1') sym_prob = sym_func workflow.connect(merge, 'out', sym_prob, 'in_file') workflow.connect(sym_prob, 'out_link', segment, 'tissue_prob_maps') xform_mask = pe.Node(fs.ApplyVolTransform(fs_target=True), name='transform_mask') workflow.connect(maskflow, ('outputspec.reg_file', pickfirst), xform_mask, 'reg_file') workflow.connect(maskflow, ('outputspec.mask_file', pickfirst), xform_mask, 'source_file') workflow.connect(xform_mask, "transformed_file", segment, 'mask_image') fssource = maskflow.get_node('fssource') convert2nii = pe.Node(fs.MRIConvert(in_type='mgz', out_type='nii'), name='convert2nii') workflow.connect(fssource, 'brain', convert2nii, 'in_file') workflow.connect(convert2nii, 'out_file', segment, 'data') # NORMALIZE normalize = pe.MapNode(spm.Normalize(jobtype='write'), name='normalize', iterfield=['apply_to_files']) normalize_struct = normalize.clone('normalize_struct') normalize_mask = normalize.clone('normalize_mask') workflow.connect(segment, 'transformation_mat', normalize, 'parameter_file') workflow.connect(segment, 'transformation_mat', normalize_mask, 'parameter_file') workflow.connect(segment, 'transformation_mat', normalize_struct, 'parameter_file') workflow.connect(convert2nii, 'out_file', normalize_struct, 'apply_to_files') workflow.connect(xform_mask, "transformed_file", normalize_mask, 'apply_to_files') xform_image = pe.MapNode(fs.ApplyVolTransform(fs_target=True), name='xform_image', iterfield=['source_file']) workflow.connect(maskflow, ('outputspec.reg_file', pickfirst), xform_image, 'reg_file') workflow.connect(realign, 'out_file', xform_image, "source_file") workflow.connect(xform_image, "transformed_file", normalize, "apply_to_files") #SMOOTH smooth = pe.Node(spm.Smooth(), name='smooth') workflow.connect(inputnode, 'fwhm', smooth, 'fwhm') workflow.connect(normalize, 'normalized_files', smooth, 'in_files') # ART artdetect = pe.Node(ra.ArtifactDetect(mask_type='file', use_differences=[True, False], use_norm=True, save_plot=True), name='artdetect') workflow.connect(realign, 'parameter_source', artdetect, 'parameter_source') workflow.connect([(inputnode, artdetect, [('norm_threshold', 'norm_threshold'), ('zintensity_threshold', 'zintensity_threshold')])]) workflow.connect([(realign, artdetect, [('out_file', 'realigned_files'), ('par_file', 'realignment_parameters')])]) workflow.connect(maskflow, ('outputspec.mask_file', poplist), artdetect, 'mask_file') # OUTPUTS outputnode = pe.Node(niu.IdentityInterface(fields=[ "realignment_parameters", "smoothed_files", "mask_file", "mean_image", "reg_file", "reg_cost", 'outlier_files', 'outlier_stats', 'outlier_plots', 'norm_components', 'mod_csf', 'unmod_csf', 'mod_wm', 'unmod_wm', 'mod_gm', 'unmod_gm', 'mean', 'normalized_struct', 'normalization_parameters', 'reverse_normalize_parameters' ]), name="outputspec") workflow.connect([ (maskflow, outputnode, [("outputspec.reg_file", "reg_file")]), (maskflow, outputnode, [("outputspec.reg_cost", "reg_cost")]), (realign, outputnode, [('par_file', 'realignment_parameters')]), (smooth, outputnode, [('smoothed_files', 'smoothed_files')]), (artdetect, outputnode, [('outlier_files', 'outlier_files'), ('statistic_files', 'outlier_stats'), ('plot_files', 'outlier_plots'), ('norm_files', 'norm_components')]) ]) workflow.connect(normalize_mask, "normalized_files", outputnode, "mask_file") workflow.connect(segment, 'modulated_csf_image', outputnode, 'mod_csf') workflow.connect(segment, 'modulated_wm_image', outputnode, 'mod_wm') workflow.connect(segment, 'modulated_gm_image', outputnode, 'mod_gm') workflow.connect(segment, 'normalized_csf_image', outputnode, 'unmod_csf') workflow.connect(segment, 'normalized_wm_image', outputnode, 'unmod_wm') workflow.connect(segment, 'normalized_gm_image', outputnode, 'unmod_gm') workflow.connect(mean, 'outputspec.mean_image', outputnode, 'mean') workflow.connect(normalize_struct, 'normalized_files', outputnode, 'normalized_struct') workflow.connect(segment, 'transformation_mat', outputnode, 'normalization_parameters') workflow.connect(segment, 'inverse_transformation_mat', outputnode, 'reverse_normalize_parameters') # CONNECT TO CONFIG workflow.inputs.inputspec.fwhm = c.fwhm workflow.inputs.inputspec.subjects_dir = c.surf_dir workflow.inputs.inputspec.norm_threshold = c.norm_thresh workflow.inputs.inputspec.zintensity_threshold = c.z_thresh workflow.inputs.inputspec.node = c.motion_correct_node workflow.inputs.inputspec.tr = c.TR workflow.inputs.inputspec.do_slicetime = c.do_slicetiming workflow.inputs.inputspec.sliceorder = c.SliceOrder workflow.inputs.inputspec.csf_prob = c.csf_prob workflow.inputs.inputspec.gm_prob = c.grey_prob workflow.inputs.inputspec.wm_prob = c.white_prob workflow.inputs.inputspec.parameters = {"order": c.order} workflow.base_dir = c.working_dir workflow.config = {'execution': {'crashdump_dir': c.crash_dir}} datagrabber = get_dataflow(c) workflow.connect(datagrabber, 'func', inputnode, 'functionals') infosource = pe.Node(niu.IdentityInterface(fields=['subject_id']), name='subject_names') if not c.test_mode: infosource.iterables = ('subject_id', c.subjects) else: infosource.iterables = ('subject_id', c.subjects[:1]) workflow.connect(infosource, 'subject_id', inputnode, 'subject_id') workflow.connect(infosource, 'subject_id', datagrabber, 'subject_id') sub = lambda x: [('_subject_id_%s' % x, '')] sinker = pe.Node(nio.DataSink(), name='sinker') workflow.connect(infosource, 'subject_id', sinker, 'container') workflow.connect(infosource, ('subject_id', sub), sinker, 'substitutions') sinker.inputs.base_directory = c.sink_dir outputspec = workflow.get_node('outputspec') workflow.connect(outputspec, 'realignment_parameters', sinker, 'spm_preproc.realignment_parameters') workflow.connect(outputspec, 'smoothed_files', sinker, 'spm_preproc.smoothed_outputs') workflow.connect(outputspec, 'outlier_files', sinker, 'spm_preproc.art.@outlier_files') workflow.connect(outputspec, 'outlier_stats', sinker, 'spm_preproc.art.@outlier_stats') workflow.connect(outputspec, 'outlier_plots', sinker, 'spm_preproc.art.@outlier_plots') workflow.connect(outputspec, 'norm_components', sinker, 'spm_preproc.art.@norm') workflow.connect(outputspec, 'reg_file', sinker, 'spm_preproc.bbreg.@reg_file') workflow.connect(outputspec, 'reg_cost', sinker, 'spm_preproc.bbreg.@reg_cost') workflow.connect(outputspec, 'mask_file', sinker, 'spm_preproc.mask.@mask_file') workflow.connect(outputspec, 'mod_csf', sinker, 'spm_preproc.segment.mod.@csf') workflow.connect(outputspec, 'mod_wm', sinker, 'spm_preproc.segment.mod.@wm') workflow.connect(outputspec, 'mod_gm', sinker, 'spm_preproc.segment.mod.@gm') workflow.connect(outputspec, 'unmod_csf', sinker, 'spm_preproc.segment.unmod.@csf') workflow.connect(outputspec, 'unmod_wm', sinker, 'spm_preproc.segment.unmod.@wm') workflow.connect(outputspec, 'unmod_gm', sinker, 'spm_preproc.segment.unmod.@gm') workflow.connect(outputspec, 'mean', sinker, 'spm_preproc.mean') workflow.connect(outputspec, 'normalized_struct', sinker, 'spm_preproc.normalized_struct') workflow.connect(outputspec, 'normalization_parameters', sinker, 'spm_preproc.normalization_parameters.@forward') workflow.connect(outputspec, 'reverse_normalize_parameters', sinker, 'spm_preproc.normalization_parameters.@reverse') return workflow