def test_FEATModel_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), fsf_file=dict(copyfile=False, mandatory=True, position=0, argstr='%s', ), args=dict(argstr='%s', ), ev_files=dict(copyfile=False, mandatory=True, position=1, argstr='%s', ), terminal_output=dict(mandatory=True, nohash=True, ), environ=dict(nohash=True, usedefault=True, ), output_type=dict(), ) inputs = FEATModel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value
def test_FEATModel_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ev_files=dict(argstr='%s', copyfile=False, mandatory=True, position=1, ), fsf_file=dict(argstr='%s', copyfile=False, mandatory=True, position=0, ), ignore_exception=dict(nohash=True, usedefault=True, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = FEATModel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value
def test_FEATModel_outputs(): output_map = dict(design_cov=dict(), design_file=dict(), design_image=dict(), con_file=dict(), fcon_file=dict(), ) outputs = FEATModel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value
def test_FEATModel_outputs(): output_map = dict(con_file=dict(), design_cov=dict(), design_file=dict(), design_image=dict(), fcon_file=dict(), ) outputs = FEATModel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value
def firstlevel_wf(subject_id, sink_directory, name='wmaze_frstlvl_wf'): frstlvl_wf = Workflow(name='frstlvl_wf') info = dict( task_mri_files=[['subject_id', 'wmaze']], #dictionary used in datasource motion_noise_files=[['subject_id']]) #function node to call subjectinfo function with name, onset, duration, and amplitude info subject_info = Node(Function(input_names=['subject_id'], output_names=['output'], function=subjectinfo), name='subject_info') subject_info.inputs.ignore_exception = False subject_info.inputs.subject_id = subject_id #function node to define contrasts getcontrasts = Node(Function(input_names=['subject_id', 'info'], output_names=['contrasts'], function=get_contrasts), name='getcontrasts') getcontrasts.inputs.ignore_exception = False getcontrasts.inputs.subject_id = subject_id frstlvl_wf.connect(subject_info, 'output', getcontrasts, 'info') #function node to substitute names of folders and files created during pipeline getsubs = Node( Function( input_names=['cons'], output_names=['subs'], # Calls the function 'get_subs' function=get_subs), name='getsubs') getsubs.inputs.ignore_exception = False getsubs.inputs.subject_id = subject_id frstlvl_wf.connect(subject_info, 'output', getsubs, 'info') frstlvl_wf.connect(getcontrasts, 'contrasts', getsubs, 'cons') #datasource node to get task_mri and motion-noise files datasource = Node(DataGrabber(infields=['subject_id'], outfields=info.keys()), name='datasource') datasource.inputs.template = '*' datasource.inputs.subject_id = subject_id datasource.inputs.base_directory = os.path.abspath( '/home/data/madlab/data/mri/wmaze/preproc/') datasource.inputs.field_template = dict( task_mri_files= '%s/func/smoothed_fullspectrum/_maskfunc2*/*%s*.nii.gz', #functional files motion_noise_files='%s/noise/filter_regressor??.txt' ) #filter regressor noise files datasource.inputs.template_args = info datasource.inputs.sort_filelist = True datasource.inputs.ignore_exception = False datasource.inputs.raise_on_empty = True #function node to remove last three volumes from functional data fslroi_epi = MapNode( ExtractROI(t_min=0, t_size=197), #start from first volume and end on -3 iterfield=['in_file'], name='fslroi_epi') fslroi_epi.output_type = 'NIFTI_GZ' fslroi_epi.terminal_output = 'stream' frstlvl_wf.connect(datasource, 'task_mri_files', fslroi_epi, 'in_file') #function node to modify the motion and noise files to be single regressors motionnoise = Node(Function(input_names=['subjinfo', 'files'], output_names=['subjinfo'], function=motion_noise), name='motionnoise') motionnoise.inputs.ignore_exception = False frstlvl_wf.connect(subject_info, 'output', motionnoise, 'subjinfo') frstlvl_wf.connect(datasource, 'motion_noise_files', motionnoise, 'files') #node to create model specifications compatible with spm/fsl designers (requires subjectinfo to be received in the form of a Bunch) specify_model = Node(SpecifyModel(), name='specify_model') specify_model.inputs.high_pass_filter_cutoff = -1.0 #high-pass filter cutoff in seconds specify_model.inputs.ignore_exception = False specify_model.inputs.input_units = 'secs' #input units in either 'secs' or 'scans' specify_model.inputs.time_repetition = 2.0 #TR frstlvl_wf.connect( fslroi_epi, 'roi_file', specify_model, 'functional_runs') #editted data files for model -- list of 4D files #list of event description files in 3 column format corresponding to onsets, durations, and amplitudes frstlvl_wf.connect(motionnoise, 'subjinfo', specify_model, 'subject_info') #node for basic interface class generating identity mappings modelfit_inputspec = Node(IdentityInterface(fields=[ 'session_info', 'interscan_interval', 'contrasts', 'film_threshold', 'functional_data', 'bases', 'model_serial_correlations' ], mandatory_inputs=True), name='modelfit_inputspec') modelfit_inputspec.inputs.bases = {'dgamma': {'derivs': False}} modelfit_inputspec.inputs.film_threshold = 0.0 modelfit_inputspec.inputs.interscan_interval = 2.0 modelfit_inputspec.inputs.model_serial_correlations = True frstlvl_wf.connect(fslroi_epi, 'roi_file', modelfit_inputspec, 'functional_data') frstlvl_wf.connect(getcontrasts, 'contrasts', modelfit_inputspec, 'contrasts') frstlvl_wf.connect(specify_model, 'session_info', modelfit_inputspec, 'session_info') #node for first level SPM design matrix to demonstrate contrasts and motion/noise regressors level1_design = MapNode(Level1Design(), iterfield=['contrasts', 'session_info'], name='level1_design') level1_design.inputs.ignore_exception = False frstlvl_wf.connect(modelfit_inputspec, 'interscan_interval', level1_design, 'interscan_interval') frstlvl_wf.connect(modelfit_inputspec, 'session_info', level1_design, 'session_info') frstlvl_wf.connect(modelfit_inputspec, 'contrasts', level1_design, 'contrasts') frstlvl_wf.connect(modelfit_inputspec, 'bases', level1_design, 'bases') frstlvl_wf.connect(modelfit_inputspec, 'model_serial_correlations', level1_design, 'model_serial_correlations') #MapNode to generate a design.mat file for each run generate_model = MapNode(FEATModel(), iterfield=['fsf_file', 'ev_files'], name='generate_model') generate_model.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} generate_model.inputs.ignore_exception = False generate_model.inputs.output_type = 'NIFTI_GZ' generate_model.inputs.terminal_output = 'stream' frstlvl_wf.connect(level1_design, 'fsf_files', generate_model, 'fsf_file') frstlvl_wf.connect(level1_design, 'ev_files', generate_model, 'ev_files') #MapNode to estimate the model using FILMGLS -- fits the design matrix to the voxel timeseries estimate_model = MapNode(FILMGLS(), iterfield=['design_file', 'in_file', 'tcon_file'], name='estimate_model') estimate_model.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} estimate_model.inputs.ignore_exception = False estimate_model.inputs.mask_size = 5 #Susan-smooth mask size estimate_model.inputs.output_type = 'NIFTI_GZ' estimate_model.inputs.results_dir = 'results' estimate_model.inputs.smooth_autocorr = True #smooth auto-correlation estimates estimate_model.inputs.terminal_output = 'stream' frstlvl_wf.connect(modelfit_inputspec, 'film_threshold', estimate_model, 'threshold') frstlvl_wf.connect(modelfit_inputspec, 'functional_data', estimate_model, 'in_file') frstlvl_wf.connect( generate_model, 'design_file', estimate_model, 'design_file') #mat file containing ascii matrix for design frstlvl_wf.connect(generate_model, 'con_file', estimate_model, 'tcon_file') #contrast file containing contrast vectors #merge node to merge the contrasts - necessary for fsl 5.0.7 and greater merge_contrasts = MapNode(Merge(2), iterfield=['in1'], name='merge_contrasts') frstlvl_wf.connect(estimate_model, 'zstats', merge_contrasts, 'in1') #MapNode to transform the z2pval z2pval = MapNode(ImageMaths(), iterfield=['in_file'], name='z2pval') z2pval.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} z2pval.inputs.ignore_exception = False z2pval.inputs.op_string = '-ztop' #defines the operation used z2pval.inputs.output_type = 'NIFTI_GZ' z2pval.inputs.suffix = '_pval' z2pval.inputs.terminal_output = 'stream' frstlvl_wf.connect(merge_contrasts, ('out', pop_lambda), z2pval, 'in_file') #outputspec node using IdentityInterface() to receive information from estimate_model, merge_contrasts, z2pval, generate_model, and estimate_model modelfit_outputspec = Node(IdentityInterface(fields=[ 'copes', 'varcopes', 'dof_file', 'pfiles', 'parameter_estimates', 'zstats', 'design_image', 'design_file', 'design_cov', 'sigmasquareds' ], mandatory_inputs=True), name='modelfit_outputspec') frstlvl_wf.connect(estimate_model, 'copes', modelfit_outputspec, 'copes') #lvl1 cope files frstlvl_wf.connect(estimate_model, 'varcopes', modelfit_outputspec, 'varcopes') #lvl1 varcope files frstlvl_wf.connect(merge_contrasts, 'out', modelfit_outputspec, 'zstats') #zstats across runs frstlvl_wf.connect(z2pval, 'out_file', modelfit_outputspec, 'pfiles') frstlvl_wf.connect( generate_model, 'design_image', modelfit_outputspec, 'design_image') #graphical representation of design matrix frstlvl_wf.connect( generate_model, 'design_file', modelfit_outputspec, 'design_file') #mat file containing ascii matrix for design frstlvl_wf.connect( generate_model, 'design_cov', modelfit_outputspec, 'design_cov') #graphical representation of design covariance frstlvl_wf.connect(estimate_model, 'param_estimates', modelfit_outputspec, 'parameter_estimates' ) #parameter estimates for columns of design matrix frstlvl_wf.connect(estimate_model, 'dof_file', modelfit_outputspec, 'dof_file') #degrees of freedom frstlvl_wf.connect(estimate_model, 'sigmasquareds', modelfit_outputspec, 'sigmasquareds') #summary of residuals #datasink node to save output from multiple points in the pipeline sinkd = MapNode(DataSink(), iterfield=[ 'substitutions', 'modelfit.contrasts.@copes', 'modelfit.contrasts.@varcopes', 'modelfit.estimates', 'modelfit.contrasts.@zstats' ], name='sinkd') sinkd.inputs.base_directory = sink_directory sinkd.inputs.container = subject_id frstlvl_wf.connect(getsubs, 'subs', sinkd, 'substitutions') frstlvl_wf.connect(modelfit_outputspec, 'parameter_estimates', sinkd, 'modelfit.estimates') frstlvl_wf.connect(modelfit_outputspec, 'sigmasquareds', sinkd, 'modelfit.estimates.@sigsq') frstlvl_wf.connect(modelfit_outputspec, 'dof_file', sinkd, 'modelfit.dofs') frstlvl_wf.connect(modelfit_outputspec, 'copes', sinkd, 'modelfit.contrasts.@copes') frstlvl_wf.connect(modelfit_outputspec, 'varcopes', sinkd, 'modelfit.contrasts.@varcopes') frstlvl_wf.connect(modelfit_outputspec, 'zstats', sinkd, 'modelfit.contrasts.@zstats') frstlvl_wf.connect(modelfit_outputspec, 'design_image', sinkd, 'modelfit.design') frstlvl_wf.connect(modelfit_outputspec, 'design_cov', sinkd, 'modelfit.design.@cov') frstlvl_wf.connect(modelfit_outputspec, 'design_file', sinkd, 'modelfit.design.@matrix') frstlvl_wf.connect(modelfit_outputspec, 'pfiles', sinkd, 'modelfit.contrasts.@pstats') return frstlvl_wf
def runglmperun(self, subject, trtimeinsec): s = SpecifyModel() # loop on all runs and models within each run modelfiles = subject._modelfiles for model in modelfiles: # Make directory results to store the results of the model results_dir = os.path.join(subject._path, 'model', model[0], 'results', model[1]) dir_util.mkpath(results_dir) os.chdir(results_dir) s.inputs.event_files = model[2] s.inputs.input_units = 'secs' s.inputs.functional_runs = os.path.join(subject._path, 'BOLD', model[1], 'bold_mcf_hp.nii.gz') # use nibable to get the tr of from the .nii file s.inputs.time_repetition = trtimeinsec s.inputs.high_pass_filter_cutoff = 128. # find par file that has motion motionfiles = glob( os.path.join(subject._path, 'BOLD', model[1], "*.par")) s.inputs.realignment_parameters = motionfiles #info = [Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 180]], durations=[[1]]), Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], durations=[[1]])] #s.inputs.subject_info = None res = s.run() res.runtime.cwd print ">>>> preparing evs for model " + model[ 1] + "and run " + model[0] sessionInfo = res.outputs.session_info level1design = Level1Design() level1design.inputs.interscan_interval = trtimeinsec level1design.inputs.bases = {'dgamma': {'derivs': False}} level1design.inputs.session_info = sessionInfo level1design.inputs.model_serial_correlations = True #TODO: add contrasts to level 1 design so that I have just condition vs rest for each ev #TODO: Look into changign this to FILM instead of FEAT - this also has the option of setting output directory # http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FEAT/UserGuide#Contrasts #http://nipy.org/nipype/interfaces/generated/nipype.interfaces.fsl.model.html#filmgls resLevel = level1design.run() featModel = FEATModel() featModel.inputs.fsf_file = resLevel.outputs.fsf_files featModel.inputs.ev_files = resLevel.outputs.ev_files resFeat = featModel.run() print ">>>> creating fsf design files for " + model[ 1] + "and run " + model[0] # TODO: give mask here glm = fsl.GLM(in_file=s.inputs.functional_runs[0], design=resFeat.outputs.design_file, output_type='NIFTI') print ">>>> running glm for " + model[1] + "and run " + model[0] resGlm = glm.run() print ">>>> finished running glm for " + model[ 1] + "and run " + model[0]
def firstlevel_wf(subject_id, sink_directory, name='wmaze_frstlvl_wf'): # Create the frstlvl workflow frstlvl_wf = Workflow(name='frstlvl_wf') # Dictionary holding the wildcard used in datasource info = dict(task_mri_files=[['subject_id', 'wmaze']], motion_noise_files=[['subject_id']]) # Calls the subjectinfo function with the name, onset, duration, and amplitude info subject_info = Node(Function(input_names=['subject_id'], output_names=['output'], function=subjectinfo), name='subject_info') subject_info.inputs.ignore_exception = False subject_info.inputs.subject_id = subject_id # Create another Function node to define the contrasts for the experiment getcontrasts = Node( Function( input_names=['subject_id', 'info'], output_names=['contrasts'], # Calls the function 'get_contrasts' function=get_contrasts), name='getcontrasts') getcontrasts.inputs.ignore_exception = False # Receives subject_id as input getcontrasts.inputs.subject_id = subject_id frstlvl_wf.connect(subject_info, 'output', getcontrasts, 'info') #### subject_info (output) ----> getcontrasts (info) # Create a Function node to substitute names of folders and files created during pipeline getsubs = Node( Function( input_names=['cons'], output_names=['subs'], # Calls the function 'get_subs' function=get_subs), name='getsubs') getsubs.inputs.ignore_exception = False # Receives subject_id as input getsubs.inputs.subject_id = subject_id frstlvl_wf.connect(subject_info, 'output', getsubs, 'info') frstlvl_wf.connect(getcontrasts, 'contrasts', getsubs, 'cons') # Create a datasource node to get the task_mri and motion-noise files datasource = Node(DataGrabber(infields=['subject_id'], outfields=info.keys()), name='datasource') # Indicates the string template to match (in this case, any that match the field template) datasource.inputs.template = '*' # Receives subject_id as an input datasource.inputs.subject_id = subject_id # Base directory to allow branching pathways datasource.inputs.base_directory = os.path.abspath( '/home/data/madlab/data/mri/wmaze/preproc/') datasource.inputs.field_template = dict( task_mri_files='%s/func/smoothed_fullspectrum/_maskfunc2*/*%s*.nii.gz', # Filter regressor noise files motion_noise_files='%s/noise/filter_regressor*.txt') # Inputs from the infields argument ('subject_id') that satisfy the template datasource.inputs.template_args = info # Forces DataGrabber to return data in sorted order when using wildcards datasource.inputs.sort_filelist = True # Do not ignore exceptions datasource.inputs.ignore_exception = False datasource.inputs.raise_on_empty = True # Function to remove last three volumes from functional data # Start from the first volume and end on the -3 volume fslroi_epi = MapNode(ExtractROI(t_min=0, t_size=197), iterfield=['in_file'], name='fslroi_epi') fslroi_epi.output_type = 'NIFTI_GZ' fslroi_epi.terminal_output = 'stream' frstlvl_wf.connect(datasource, 'task_mri_files', fslroi_epi, 'in_file') # Function node to modify the motion and noise files to be single regressors motionnoise = Node( Function( input_names=['subjinfo', 'files'], output_names=['subjinfo'], # Calls the function 'motion_noise' function=motion_noise), name='motionnoise') motionnoise.inputs.ignore_exception = False # The bunch from subject_info function containing regressor names, onsets, durations, and amplitudes frstlvl_wf.connect(subject_info, 'output', motionnoise, 'subjinfo') frstlvl_wf.connect(datasource, 'motion_noise_files', motionnoise, 'files') # Makes a model specification compatible with spm/fsl designers # Requires subjectinfo to be received in the form of a Bunch of a list of Bunch specify_model = Node(SpecifyModel(), name='specify_model') # High-pass filter cutoff in seconds specify_model.inputs.high_pass_filter_cutoff = -1.0 specify_model.inputs.ignore_exception = False # input units in either 'secs' or 'scans' specify_model.inputs.input_units = 'secs' # Time between start of one volume and the start of following volume specify_model.inputs.time_repetition = 2.0 # Editted data files for model -- list of 4D files frstlvl_wf.connect(fslroi_epi, 'roi_file', specify_model, 'functional_runs') # List of event description files in 3 column format corresponding to onsets, durations, and amplitudes frstlvl_wf.connect(motionnoise, 'subjinfo', specify_model, 'subject_info') # Basic interface class generates identity mappings modelfit_inputspec = Node(IdentityInterface(fields=[ 'session_info', 'interscan_interval', 'contrasts', 'film_threshold', 'functional_data', 'bases', 'model_serial_correlations' ], mandatory_inputs=True), name='modelfit_inputspec') # Set bases to a dictionary with a second dictionary setting the value of dgamma derivatives as 'False' modelfit_inputspec.inputs.bases = {'dgamma': {'derivs': False}} # Film threshold modelfit_inputspec.inputs.film_threshold = 0.0 # Interscan_interval modelfit_inputspec.inputs.interscan_interval = 2.0 # Create model serial correlations for Level1Design modelfit_inputspec.inputs.model_serial_correlations = True frstlvl_wf.connect(fslroi_epi, 'roi_file', modelfit_inputspec, 'functional_data') frstlvl_wf.connect(getcontrasts, 'contrasts', modelfit_inputspec, 'contrasts') frstlvl_wf.connect(specify_model, 'session_info', modelfit_inputspec, 'session_info') # Creates a first level SPM design matrix to demonstrate contrasts and motion/noise regressors level1_design = MapNode(Level1Design(), iterfield=['contrasts', 'session_info'], name='level1_design') level1_design.inputs.ignore_exception = False # Inputs the interscan interval (in secs) frstlvl_wf.connect(modelfit_inputspec, 'interscan_interval', level1_design, 'interscan_interval') # Session specific information generated by ``modelgen.SpecifyModel`` frstlvl_wf.connect(modelfit_inputspec, 'session_info', level1_design, 'session_info') # List of contrasts with each contrast being a list of the form -[('name', 'stat', [condition list], [weight list], [session list])]. # If session list is None or not provided, all sessions are used. frstlvl_wf.connect(modelfit_inputspec, 'contrasts', level1_design, 'contrasts') # Name of basis function and options e.g., {'dgamma': {'derivs': True}} frstlvl_wf.connect(modelfit_inputspec, 'bases', level1_design, 'bases') # Option to model serial correlations using an autoregressive estimator (order 1) # Setting this option is only useful in the context of the fsf file frstlvl_wf.connect(modelfit_inputspec, 'model_serial_correlations', level1_design, 'model_serial_correlations') # Create a MapNode to generate a design.mat file for each run generate_model = MapNode(FEATModel(), iterfield=['fsf_file', 'ev_files'], name='generate_model') generate_model.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} generate_model.inputs.ignore_exception = False generate_model.inputs.output_type = 'NIFTI_GZ' generate_model.inputs.terminal_output = 'stream' # File specifying the feat design spec file frstlvl_wf.connect(level1_design, 'fsf_files', generate_model, 'fsf_file') # Event spec files generated by level1design (condition information files) frstlvl_wf.connect(level1_design, 'ev_files', generate_model, 'ev_files') # Create a MapNode to estimate the model using FILMGLS -- fits the design matrix to the voxel timeseries estimate_model = MapNode(FILMGLS(), iterfield=['design_file', 'in_file', 'tcon_file'], name='estimate_model') estimate_model.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} estimate_model.inputs.ignore_exception = False # Susan-smooth mask size estimate_model.inputs.mask_size = 5 estimate_model.inputs.output_type = 'NIFTI_GZ' estimate_model.inputs.results_dir = 'results' # Smooth auto-correlation estimates estimate_model.inputs.smooth_autocorr = True estimate_model.inputs.terminal_output = 'stream' frstlvl_wf.connect(modelfit_inputspec, 'film_threshold', estimate_model, 'threshold') frstlvl_wf.connect(modelfit_inputspec, 'functional_data', estimate_model, 'in_file') # Mat file containing ascii matrix for design frstlvl_wf.connect(generate_model, 'design_file', estimate_model, 'design_file') # Contrast file containing contrast vectors frstlvl_wf.connect(generate_model, 'con_file', estimate_model, 'tcon_file') # Create a merge node to merge the contrasts - necessary for fsl 5.0.7 and greater merge_contrasts = MapNode(Merge(2), iterfield=['in1'], name='merge_contrasts') frstlvl_wf.connect(estimate_model, 'zstats', merge_contrasts, 'in1') # Create a MapNode to transform the z2pval z2pval = MapNode(ImageMaths(), iterfield=['in_file'], name='z2pval') z2pval.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} # Do not ignore exceptions z2pval.inputs.ignore_exception = False # Defines the operation used z2pval.inputs.op_string = '-ztop' # Set the outfile type to nii.gz z2pval.inputs.output_type = 'NIFTI_GZ' # Out-file suffix z2pval.inputs.suffix = '_pval' # Set output to stream in terminal z2pval.inputs.terminal_output = 'stream' frstlvl_wf.connect(merge_contrasts, ('out', pop_lambda), z2pval, 'in_file') # Create an outputspec node using IdentityInterface() to receive information from estimate_model, # merge_contrasts, z2pval, generate_model, and estimate_model modelfit_outputspec = Node(IdentityInterface(fields=[ 'copes', 'varcopes', 'dof_file', 'pfiles', 'parameter_estimates', 'zstats', 'design_image', 'design_file', 'design_cov', 'sigmasquareds' ], mandatory_inputs=True), name='modelfit_outputspec') # All lvl1 cope files frstlvl_wf.connect(estimate_model, 'copes', modelfit_outputspec, 'copes') # All lvl1 varcope files frstlvl_wf.connect(estimate_model, 'varcopes', modelfit_outputspec, 'varcopes') # All zstats across runs frstlvl_wf.connect(merge_contrasts, 'out', modelfit_outputspec, 'zstats') # frstlvl_wf.connect(z2pval, 'out_file', modelfit_outputspec, 'pfiles') # Graphical representation of design matrix frstlvl_wf.connect(generate_model, 'design_image', modelfit_outputspec, 'design_image') # Mat file containing ascii matrix for design frstlvl_wf.connect(generate_model, 'design_file', modelfit_outputspec, 'design_file') # Graphical representation of design covariance frstlvl_wf.connect(generate_model, 'design_cov', modelfit_outputspec, 'design_cov') # Parameter estimates for each column of the design matrix frstlvl_wf.connect(estimate_model, 'param_estimates', modelfit_outputspec, 'parameter_estimates') # Degrees of freedom frstlvl_wf.connect(estimate_model, 'dof_file', modelfit_outputspec, 'dof_file') # Summary of residuals frstlvl_wf.connect(estimate_model, 'sigmasquareds', modelfit_outputspec, 'sigmasquareds') # Create a datasink node to save output from multiple points in the pipeline sinkd = MapNode(DataSink(), iterfield=[ 'substitutions', 'modelfit.contrasts.@copes', 'modelfit.contrasts.@varcopes', 'modelfit.estimates', 'modelfit.contrasts.@zstats' ], name='sinkd') sinkd.inputs.base_directory = sink_directory sinkd.inputs.container = subject_id frstlvl_wf.connect(getsubs, 'subs', sinkd, 'substitutions') frstlvl_wf.connect(modelfit_outputspec, 'parameter_estimates', sinkd, 'modelfit.estimates') frstlvl_wf.connect(modelfit_outputspec, 'sigmasquareds', sinkd, 'modelfit.estimates.@sigsq') frstlvl_wf.connect(modelfit_outputspec, 'dof_file', sinkd, 'modelfit.dofs') frstlvl_wf.connect(modelfit_outputspec, 'copes', sinkd, 'modelfit.contrasts.@copes') frstlvl_wf.connect(modelfit_outputspec, 'varcopes', sinkd, 'modelfit.contrasts.@varcopes') frstlvl_wf.connect(modelfit_outputspec, 'zstats', sinkd, 'modelfit.contrasts.@zstats') frstlvl_wf.connect(modelfit_outputspec, 'design_image', sinkd, 'modelfit.design') frstlvl_wf.connect(modelfit_outputspec, 'design_cov', sinkd, 'modelfit.design.@cov') frstlvl_wf.connect(modelfit_outputspec, 'design_file', sinkd, 'modelfit.design.@matrix') frstlvl_wf.connect(modelfit_outputspec, 'pfiles', sinkd, 'modelfit.contrasts.@pstats') return frstlvl_wf
cont1 = ['Bundling-Control', 'T', ['Bundling', 'Control'], [1, -1]] s = SpecifyModel() s.inputs.input_units = 'secs' s.inputs.functional_runs = results.outputs.func s.inputs.time_repetition = 2 s.inputs.high_pass_filter_cutoff = 128. s.inputs.event_files = results.outputs.evs model = s.run() level1design = Level1Design() level1design.inputs.interscan_interval = 2.5 level1design.inputs.bases = {'dgamma': {'derivs': False}} level1design.inputs.model_serial_correlations = False level1design.inputs.session_info = model.outputs.session_info level1design.inputs.contrasts = [cont1] l1d = level1design.run() print l1d.outputs.ev_files modelgen = FEATModel() modelgen.inputs.ev_files = l1d.outputs.ev_files modelgen.inputs.fsf_file = l1d.outputs.fsf_files model = modelgen.run() fgls = fsl.FILMGLS() fgls.inputs.in_file = results.outputs.func fgls.inputs.design_file = model.outputs.design_file fgls.inputs.threshold = 10 fgls.inputs.results_dir = 'stats' res = fgls.run()
def firstlevel_wf(subject_id, sink_directory, name='ds008_R2_frstlvl_wf'): frstlvl_wf = Workflow(name='frstlvl_wf') info = dict(task_mri_files=[['subject_id', 'stopsignal']], motion_noise_files=[['subject_id', 'filter_regressor']]) # Create a Function node to define stimulus onsets, etc... for each subject subject_info = Node(Function(input_names=['subject_id'], output_names=['output'], function=subjectinfo), name='subject_info') subject_info.inputs.ignore_exception = False subject_info.inputs.subject_id = subject_id # Create another Function node to define the contrasts for the experiment getcontrasts = Node(Function(input_names=['subject_id'], output_names=['contrasts'], function=get_contrasts), name='getcontrasts') getcontrasts.inputs.ignore_exception = False getcontrasts.inputs.subject_id = subject_id # Create a Function node to substitute names of files created during pipeline getsubs = Node(Function(input_names=['subject_id', 'cons', 'info'], output_names=['subs'], function=get_subs), name='getsubs') getsubs.inputs.ignore_exception = False getsubs.inputs.subject_id = subject_id frstlvl_wf.connect(subject_info, 'output', getsubs, 'info') frstlvl_wf.connect(getcontrasts, 'contrasts', getsubs, 'cons') # Create a datasource node to get the task_mri and motion-noise files datasource = Node(DataGrabber(infields=['subject_id'], outfields=info.keys()), name='datasource') datasource.inputs.template = '*' datasource.inputs.subject_id = subject_id #datasource.inputs.base_directory = os.path.abspath('/scratch/PSB6351_2017/ds008_R2.0.0/preproc/') #datasource.inputs.field_template = dict(task_mri_files='%s/func/realigned/*%s*.nii.gz', # motion_noise_files='%s/noise/%s*.txt') datasource.inputs.base_directory = os.path.abspath( '/scratch/PSB6351_2017/students/salo/data/preproc/') datasource.inputs.field_template = dict( task_mri_files= '%s/preproc/func/smoothed/corr_*_task-%s_*_bold_bet_smooth_mask.nii.gz', motion_noise_files='%s/preproc/noise/%s*.txt') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True datasource.inputs.ignore_exception = False datasource.inputs.raise_on_empty = True # Create a Function node to modify the motion and noise files to be single regressors motionnoise = Node(Function(input_names=['subjinfo', 'files'], output_names=['subjinfo'], function=motion_noise), name='motionnoise') motionnoise.inputs.ignore_exception = False frstlvl_wf.connect(subject_info, 'output', motionnoise, 'subjinfo') frstlvl_wf.connect(datasource, 'motion_noise_files', motionnoise, 'files') # Create a specify model node specify_model = Node(SpecifyModel(), name='specify_model') specify_model.inputs.high_pass_filter_cutoff = 128. specify_model.inputs.ignore_exception = False specify_model.inputs.input_units = 'secs' specify_model.inputs.time_repetition = 2. frstlvl_wf.connect(datasource, 'task_mri_files', specify_model, 'functional_runs') frstlvl_wf.connect(motionnoise, 'subjinfo', specify_model, 'subject_info') # Create an InputSpec node for the modelfit node modelfit_inputspec = Node(IdentityInterface(fields=[ 'session_info', 'interscan_interval', 'contrasts', 'film_threshold', 'functional_data', 'bases', 'model_serial_correlations' ], mandatory_inputs=True), name='modelfit_inputspec') modelfit_inputspec.inputs.bases = {'dgamma': {'derivs': False}} modelfit_inputspec.inputs.film_threshold = 0.0 modelfit_inputspec.inputs.interscan_interval = 2.0 modelfit_inputspec.inputs.model_serial_correlations = True frstlvl_wf.connect(datasource, 'task_mri_files', modelfit_inputspec, 'functional_data') frstlvl_wf.connect(getcontrasts, 'contrasts', modelfit_inputspec, 'contrasts') frstlvl_wf.connect(specify_model, 'session_info', modelfit_inputspec, 'session_info') # Create a level1 design node level1_design = Node(Level1Design(), name='level1_design') level1_design.inputs.ignore_exception = False frstlvl_wf.connect(modelfit_inputspec, 'interscan_interval', level1_design, 'interscan_interval') frstlvl_wf.connect(modelfit_inputspec, 'session_info', level1_design, 'session_info') frstlvl_wf.connect(modelfit_inputspec, 'contrasts', level1_design, 'contrasts') frstlvl_wf.connect(modelfit_inputspec, 'bases', level1_design, 'bases') frstlvl_wf.connect(modelfit_inputspec, 'model_serial_correlations', level1_design, 'model_serial_correlations') # Create a MapNode to generate a model for each run generate_model = MapNode(FEATModel(), iterfield=['fsf_file', 'ev_files'], name='generate_model') generate_model.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} generate_model.inputs.ignore_exception = False generate_model.inputs.output_type = 'NIFTI_GZ' generate_model.inputs.terminal_output = 'stream' frstlvl_wf.connect(level1_design, 'fsf_files', generate_model, 'fsf_file') frstlvl_wf.connect(level1_design, 'ev_files', generate_model, 'ev_files') # Create a MapNode to estimate the model using FILMGLS estimate_model = MapNode(FILMGLS(), iterfield=['design_file', 'in_file', 'tcon_file'], name='estimate_model') frstlvl_wf.connect(generate_model, 'design_file', estimate_model, 'design_file') frstlvl_wf.connect(generate_model, 'con_file', estimate_model, 'tcon_file') frstlvl_wf.connect(modelfit_inputspec, 'functional_data', estimate_model, 'in_file') # Create a merge node to merge the contrasts - necessary for fsl 5.0.7 and greater merge_contrasts = MapNode(Merge(2), iterfield=['in1'], name='merge_contrasts') frstlvl_wf.connect(estimate_model, 'zstats', merge_contrasts, 'in1') # Create a MapNode to transform the z2pval z2pval = MapNode(ImageMaths(), iterfield=['in_file'], name='z2pval') z2pval.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} z2pval.inputs.ignore_exception = False z2pval.inputs.op_string = '-ztop' z2pval.inputs.output_type = 'NIFTI_GZ' z2pval.inputs.suffix = '_pval' z2pval.inputs.terminal_output = 'stream' frstlvl_wf.connect(merge_contrasts, ('out', pop_lambda), z2pval, 'in_file') # Create an outputspec node modelfit_outputspec = Node(IdentityInterface(fields=[ 'copes', 'varcopes', 'dof_file', 'pfiles', 'parameter_estimates', 'zstats', 'design_image', 'design_file', 'design_cov', 'sigmasquareds' ], mandatory_inputs=True), name='modelfit_outputspec') frstlvl_wf.connect(estimate_model, 'copes', modelfit_outputspec, 'copes') frstlvl_wf.connect(estimate_model, 'varcopes', modelfit_outputspec, 'varcopes') frstlvl_wf.connect(merge_contrasts, 'out', modelfit_outputspec, 'zstats') frstlvl_wf.connect(z2pval, 'out_file', modelfit_outputspec, 'pfiles') frstlvl_wf.connect(generate_model, 'design_image', modelfit_outputspec, 'design_image') frstlvl_wf.connect(generate_model, 'design_file', modelfit_outputspec, 'design_file') frstlvl_wf.connect(generate_model, 'design_cov', modelfit_outputspec, 'design_cov') frstlvl_wf.connect(estimate_model, 'param_estimates', modelfit_outputspec, 'parameter_estimates') frstlvl_wf.connect(estimate_model, 'dof_file', modelfit_outputspec, 'dof_file') frstlvl_wf.connect(estimate_model, 'sigmasquareds', modelfit_outputspec, 'sigmasquareds') # Create a datasink node sinkd = Node(DataSink(), name='sinkd') sinkd.inputs.base_directory = sink_directory sinkd.inputs.container = subject_id frstlvl_wf.connect(getsubs, 'subs', sinkd, 'substitutions') frstlvl_wf.connect(modelfit_outputspec, 'parameter_estimates', sinkd, 'modelfit.estimates') frstlvl_wf.connect(modelfit_outputspec, 'sigmasquareds', sinkd, 'modelfit.estimates.@sigsq') frstlvl_wf.connect(modelfit_outputspec, 'dof_file', sinkd, 'modelfit.dofs') frstlvl_wf.connect(modelfit_outputspec, 'copes', sinkd, 'modelfit.contrasts.@copes') frstlvl_wf.connect(modelfit_outputspec, 'varcopes', sinkd, 'modelfit.contrasts.@varcopes') frstlvl_wf.connect(modelfit_outputspec, 'zstats', sinkd, 'modelfit.contrasts.@zstats') frstlvl_wf.connect(modelfit_outputspec, 'design_image', sinkd, 'modelfit.design') frstlvl_wf.connect(modelfit_outputspec, 'design_cov', sinkd, 'modelfit.design.@cov') frstlvl_wf.connect(modelfit_outputspec, 'design_file', sinkd, 'modelfit.design.@matrix') frstlvl_wf.connect(modelfit_outputspec, 'pfiles', sinkd, 'modelfit.contrasts.@pstats') return frstlvl_wf