diff --git a/nipype/interfaces/fsl/model.py b/nipype/interfaces/fsl/model.py index 3ec6b4468c..58cf6c8678 100755 --- a/nipype/interfaces/fsl/model.py +++ b/nipype/interfaces/fsl/model.py @@ -23,7 +23,8 @@ TraitedSpec, BaseInterface, Directory, InputMultiPath, OutputMultiPath, BaseInterfaceInputSpec) -from nipype.utils.filemanip import (list_to_filename, filename_to_list, split_filename) +from nipype.utils.filemanip import ( + list_to_filename, filename_to_list, fname_presuffix) from nibabel import load warn = warnings.warn @@ -32,14 +33,17 @@ class Level1DesignInputSpec(BaseInterfaceInputSpec): interscan_interval = traits.Float(mandatory=True, - desc='Interscan interval (in secs)') + desc='Interscan interval (in secs)') session_info = traits.Any(mandatory=True, - desc='Session specific information generated by ``modelgen.SpecifyModel``') - bases = traits.Either(traits.Dict(traits.Enum('dgamma'), traits.Dict(traits.Enum('derivs'), traits.Bool)), - traits.Dict(traits.Enum('gamma'), traits.Dict(traits.Enum('derivs'), traits.Bool)), - traits.Dict(traits.Enum('none'), traits.Enum(None)), - mandatory=True, - desc="name of basis function and options e.g., {'dgamma': {'derivs': True}}") + desc='Session specific information generated by ``modelgen.SpecifyModel``') + bases = traits.Either( + traits.Dict(traits.Enum( + 'dgamma'), traits.Dict(traits.Enum('derivs'), traits.Bool)), + traits.Dict(traits.Enum('gamma'), traits.Dict( + traits.Enum('derivs'), traits.Bool)), + traits.Dict(traits.Enum('none'), traits.Enum(None)), + mandatory=True, + desc="name of basis function and options e.g., {'dgamma': {'derivs': True}}") model_serial_correlations = traits.Bool( desc="Option to model serial correlations using an \ autoregressive estimator (order 1). Setting this option is only \ @@ -57,15 +61,24 @@ class Level1DesignInputSpec(BaseInterfaceInputSpec): traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('F'), - traits.List(traits.Either(traits.Tuple(traits.Str, - traits.Enum('T'), - traits.List(traits.Str), - traits.List(traits.Float)), - traits.Tuple(traits.Str, - traits.Enum('T'), - traits.List(traits.Str), - traits.List(traits.Float), - traits.List(traits.Float)))))), + traits.List( + traits.Either(traits.Tuple(traits.Str, + traits.Enum( + 'T'), + traits.List( + traits.Str), + traits.List( + traits.Float)), + traits.Tuple( + traits.Str, + traits.Enum( + 'T'), + traits.List( + traits.Str), + traits.List( + traits.Float), + traits.List( + traits.Float)))))), desc="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. For F \ @@ -75,9 +88,9 @@ class Level1DesignInputSpec(BaseInterfaceInputSpec): class Level1DesignOutputSpec(TraitedSpec): fsf_files = OutputMultiPath(File(exists=True), - desc='FSL feat specification files') + desc='FSL feat specification files') ev_files = OutputMultiPath(traits.List(File(exists=True)), - desc='condition information files') + desc='condition information files') class Level1Design(BaseInterface): @@ -106,8 +119,9 @@ def _create_ev_file(self, evfname, evinfo): f.write('%f\n' % i[0]) f.close() - def _create_ev_files(self, cwd, runinfo, runidx, usetd, contrasts, no_bases, - do_tempfilter): + def _create_ev_files( + self, cwd, runinfo, runidx, usetd, contrasts, no_bases, + do_tempfilter): """Creates EV files from condition and regressor information. Parameters: @@ -189,10 +203,12 @@ def _create_ev_files(self, cwd, runinfo, runidx, usetd, contrasts, no_bases, contrast_header = load_template('feat_contrast_header.tcl') contrast_prolog = load_template('feat_contrast_prolog.tcl') contrast_element = load_template('feat_contrast_element.tcl') - contrast_ftest_element = load_template('feat_contrast_ftest_element.tcl') + contrast_ftest_element = load_template( + 'feat_contrast_ftest_element.tcl') contrastmask_header = load_template('feat_contrastmask_header.tcl') contrastmask_footer = load_template('feat_contrastmask_footer.tcl') - contrastmask_element = load_template('feat_contrastmask_element.tcl') + contrastmask_element = load_template( + 'feat_contrastmask_element.tcl') # add t/f contrast info ev_txt += contrast_header.substitute() con_names = [] @@ -234,10 +250,11 @@ def _create_ev_files(self, cwd, runinfo, runidx, usetd, contrasts, no_bases, ev_txt += "\n" if con[0] in con_map.keys(): for fconidx in con_map[con[0]]: - ev_txt += contrast_ftest_element.substitute(cnum=ftest_idx.index(fconidx) + 1, - element=tidx, - ctype=ctype, - val=1) + ev_txt += contrast_ftest_element.substitute( + cnum=ftest_idx.index(fconidx) + 1, + element=tidx, + ctype=ctype, + val=1) ev_txt += "\n" # add contrast mask info @@ -306,7 +323,8 @@ def _run_interface(self, runtime): num_evs_real=num_evs[1], num_tcon=n_tcon, num_fcon=n_fcon, - high_pass_filter_cutoff=info['hpf'], + high_pass_filter_cutoff=info[ + 'hpf'], temphp_yn=do_tempfilter, func_file=func_files[i]) fsf_txt += cond_txt @@ -335,12 +353,14 @@ def _list_outputs(self): for i, cond in enumerate(runinfo[field]): name = cond['name'] evname.append(name) - evfname = os.path.join(cwd, 'ev_%s_%d_%d.txt' % (name, runno, - len(evname))) + evfname = os.path.join( + cwd, 'ev_%s_%d_%d.txt' % (name, runno, + len(evname))) if field == 'cond': if usetd: evname.append(name + 'TD') - outputs['ev_files'][runno].append(os.path.join(cwd, evfname)) + outputs['ev_files'][runno].append( + os.path.join(cwd, evfname)) return outputs @@ -371,16 +391,20 @@ class FEATModelInputSpec(FSLCommandInputSpec): desc="File specifying the feat design spec file", copyfile=False) ev_files = traits.List(File(exists=True), - mandatory=True, argstr="%s", - desc="Event spec files generated by level1design", - position=1, copyfile=False) + mandatory=True, argstr="%s", + desc="Event spec files generated by level1design", + position=1, copyfile=False) class FEATModelOutpuSpec(TraitedSpec): - design_file = File(exists=True, desc='Mat file containing ascii matrix for design') - design_image = File(exists=True, desc='Graphical representation of design matrix') - design_cov = File(exists=True, desc='Graphical representation of design covariance') - con_file = File(exists=True, desc='Contrast file containing contrast vectors') + design_file = File( + exists=True, desc='Mat file containing ascii matrix for design') + design_image = File( + exists=True, desc='Graphical representation of design matrix') + design_cov = File( + exists=True, desc='Graphical representation of design covariance') + con_file = File( + exists=True, desc='Contrast file containing contrast vectors') fcon_file = File(desc='Contrast file containing contrast vectors') @@ -404,17 +428,19 @@ def _get_design_root(self, infile): return fname.split('.')[0] def _list_outputs(self): - #TODO: figure out file names and get rid off the globs + # TODO: figure out file names and get rid off the globs outputs = self._outputs().get() root = self._get_design_root(list_to_filename(self.inputs.fsf_file)) design_file = glob(os.path.join(os.getcwd(), '%s*.mat' % root)) assert len(design_file) == 1, 'No mat file generated by FEAT Model' outputs['design_file'] = design_file[0] design_image = glob(os.path.join(os.getcwd(), '%s.png' % root)) - assert len(design_image) == 1, 'No design image generated by FEAT Model' + assert len( + design_image) == 1, 'No design image generated by FEAT Model' outputs['design_image'] = design_image[0] design_cov = glob(os.path.join(os.getcwd(), '%s_cov.png' % root)) - assert len(design_cov) == 1, 'No covariance image generated by FEAT Model' + assert len( + design_cov) == 1, 'No covariance image generated by FEAT Model' outputs['design_cov'] = design_cov[0] con_file = glob(os.path.join(os.getcwd(), '%s*.con' % root)) assert len(con_file) == 1, 'No con file generated by FEAT Model' @@ -431,8 +457,8 @@ def _list_outputs(self): class FILMGLSInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, position=-3, - argstr='%s', - desc='input data file') + argstr='%s', + desc='input data file') design_file = File(exists=True, position=-2, argstr='%s', desc='design matrix file') @@ -444,37 +470,39 @@ class FILMGLSInputSpec(FSLCommandInputSpec): mask_size = traits.Int(argstr='-ms %d', desc="susan mask size") brightness_threshold = traits.Int(min=0, argstr='-epith %d', - desc='susan brightness threshold, otherwise it is estimated') + desc='susan brightness threshold, otherwise it is estimated') full_data = traits.Bool(argstr='-v', desc='output full data') _estimate_xor = ['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'] autocorr_estimate_only = traits.Bool(argstr='-ac', - xor=_estimate_xor, - desc='perform autocorrelation estimatation only') + xor=_estimate_xor, + desc='perform autocorrelation estimatation only') fit_armodel = traits.Bool(argstr='-ar', xor=_estimate_xor, - desc='fits autoregressive model - default is to use tukey with M=sqrt(numvols)') + desc='fits autoregressive model - default is to use tukey with M=sqrt(numvols)') tukey_window = traits.Int(argstr='-tukey %d', xor=_estimate_xor, - desc='tukey window size to estimate autocorr') + desc='tukey window size to estimate autocorr') multitaper_product = traits.Int(argstr='-mt %d', xor=_estimate_xor, - desc='multitapering with slepian tapers and num is the time-bandwidth product') - use_pava = traits.Bool(argstr='-pava', desc='estimates autocorr using PAVA') + desc='multitapering with slepian tapers and num is the time-bandwidth product') + use_pava = traits.Bool( + argstr='-pava', desc='estimates autocorr using PAVA') autocorr_noestimate = traits.Bool(argstr='-noest', xor=_estimate_xor, - desc='do not estimate autocorrs') + desc='do not estimate autocorrs') output_pwdata = traits.Bool(argstr='-output_pwdata', - desc='output prewhitened data and average design matrix') + desc='output prewhitened data and average design matrix') results_dir = Directory('results', argstr='-rn %s', usedefault=True, desc='directory to store results in') class FILMGLSOutputSpec(TraitedSpec): param_estimates = OutputMultiPath(File(exists=True), - desc='Parameter estimates for each column of the design matrix') + desc='Parameter estimates for each column of the design matrix') residual4d = File(exists=True, - desc='Model fit residual mean-squared error for each time point') + desc='Model fit residual mean-squared error for each time point') dof_file = File(exists=True, desc='degrees of freedom') - sigmasquareds = File(exists=True, desc='summary of residuals, See Woolrich, et. al., 2001') + sigmasquareds = File( + exists=True, desc='summary of residuals, See Woolrich, et. al., 2001') results_dir = Directory(exists=True, - desc='directory storing model estimation output') + desc='directory storing model estimation output') corrections = File(exists=True, desc='statistical corrections used within FILM modelling') logfile = File(exists=True, @@ -551,16 +579,19 @@ def _list_outputs(self): class FEATRegisterInputSpec(BaseInterfaceInputSpec): - feat_dirs = InputMultiPath(Directory(), exist=True, desc="Lower level feat dirs", - mandatory=True) - reg_image = File(exist=True, desc="image to register to (will be treated as standard)", - mandatory=True) - reg_dof = traits.Int(12, desc="registration degrees of freedom", usedefault=True) + feat_dirs = InputMultiPath( + Directory(), exist=True, desc="Lower level feat dirs", + mandatory=True) + reg_image = File( + exist=True, desc="image to register to (will be treated as standard)", + mandatory=True) + reg_dof = traits.Int( + 12, desc="registration degrees of freedom", usedefault=True) class FEATRegisterOutputSpec(TraitedSpec): fsf_file = File(exists=True, - desc="FSL feat specification file") + desc="FSL feat specification file") class FEATRegister(BaseInterface): @@ -590,39 +621,44 @@ def _run_interface(self, runtime): def _list_outputs(self): outputs = self._outputs().get() - outputs['fsf_file'] = os.path.abspath(os.path.join(os.getcwd(), 'register.fsf')) + outputs['fsf_file'] = os.path.abspath( + os.path.join(os.getcwd(), 'register.fsf')) return outputs class FLAMEOInputSpec(FSLCommandInputSpec): cope_file = File(exists=True, argstr='--copefile=%s', mandatory=True, - desc='cope regressor data file') + desc='cope regressor data file') var_cope_file = File(exists=True, argstr='--varcopefile=%s', - desc='varcope weightings data file') + desc='varcope weightings data file') dof_var_cope_file = File(exists=True, argstr='--dofvarcopefile=%s', - desc='dof data file for varcope data') + desc='dof data file for varcope data') mask_file = File(exists=True, argstr='--maskfile=%s', mandatory=True, - desc='mask file') + desc='mask file') design_file = File(exists=True, argstr='--designfile=%s', mandatory=True, - desc='design matrix file') - t_con_file = File(exists=True, argstr='--tcontrastsfile=%s', mandatory=True, - desc='ascii matrix specifying t-contrasts') + desc='design matrix file') + t_con_file = File( + exists=True, argstr='--tcontrastsfile=%s', mandatory=True, + desc='ascii matrix specifying t-contrasts') f_con_file = File(exists=True, argstr='--fcontrastsfile=%s', - desc='ascii matrix specifying f-contrasts') - cov_split_file = File(exists=True, argstr='--covsplitfile=%s', mandatory=True, - desc='ascii matrix specifying the groups the covariance is split into') - run_mode = traits.Enum('fe', 'ols', 'flame1', 'flame12', argstr='--runmode=%s', - mandatory=True, desc='inference to perform') - n_jumps = traits.Int(argstr='--njumps=%d', desc='number of jumps made by mcmc') + desc='ascii matrix specifying f-contrasts') + cov_split_file = File( + exists=True, argstr='--covsplitfile=%s', mandatory=True, + desc='ascii matrix specifying the groups the covariance is split into') + run_mode = traits.Enum( + 'fe', 'ols', 'flame1', 'flame12', argstr='--runmode=%s', + mandatory=True, desc='inference to perform') + n_jumps = traits.Int( + argstr='--njumps=%d', desc='number of jumps made by mcmc') burnin = traits.Int(argstr='--burnin=%d', desc='number of jumps at start of mcmc to be discarded') sample_every = traits.Int(argstr='--sampleevery=%d', - desc='number of jumps for each sample') + desc='number of jumps for each sample') fix_mean = traits.Bool(argstr='--fixmean', desc='fix mean for tfit') infer_outliers = traits.Bool(argstr='--inferoutliers', - desc='infer outliers - not for fe') + desc='infer outliers - not for fe') no_pe_outputs = traits.Bool(argstr='--nopeoutput', - desc='do not output pe files') + desc='do not output pe files') sigma_dofs = traits.Int(argstr='--sigma_dofs=%d', desc='sigma (in mm) to use for Gaussian smoothing the DOFs in FLAME 2. Default is 1mm, -1 indicates no smoothing') outlier_iter = traits.Int(argstr='--ioni=%d', @@ -633,16 +669,23 @@ class FLAMEOInputSpec(FSLCommandInputSpec): class FLAMEOOutputSpec(TraitedSpec): pes = OutputMultiPath(exists=True, desc="Parameter estimates for each column of the design matrix" + - "for each voxel") - res4d = OutputMultiPath(exists=True, desc="Model fit residual mean-squared error for each time point") - copes = OutputMultiPath(exists=True, desc="Contrast estimates for each contrast") - var_copes = OutputMultiPath(exists=True, desc="Variance estimates for each contrast") + "for each voxel") + res4d = OutputMultiPath( + exists=True, desc="Model fit residual mean-squared error for each time point") + copes = OutputMultiPath( + exists=True, desc="Contrast estimates for each contrast") + var_copes = OutputMultiPath( + exists=True, desc="Variance estimates for each contrast") zstats = OutputMultiPath(exists=True, desc="z-stat file for each contrast") tstats = OutputMultiPath(exists=True, desc="t-stat file for each contrast") - mrefvars = OutputMultiPath(exists=True, desc="mean random effect variances for each contrast") - tdof = OutputMultiPath(exists=True, desc="temporal dof file for each contrast") - weights = OutputMultiPath(exists=True, desc="weights file for each contrast") - stats_dir = Directory(exists=True, desc="directory storing model estimation output") + mrefvars = OutputMultiPath( + exists=True, desc="mean random effect variances for each contrast") + tdof = OutputMultiPath( + exists=True, desc="temporal dof file for each contrast") + weights = OutputMultiPath( + exists=True, desc="weights file for each contrast") + stats_dir = Directory( + exists=True, desc="directory storing model estimation output") # interface to fsl command line higher level model fit @@ -702,7 +745,8 @@ def _list_outputs(self): outputs['copes'] = copes var_copes = glob(os.path.join(pth, 'varcope[0-9]*.*')) - assert len(var_copes) >= 1, 'No varcope volumes generated by FSL CEstimate' + assert len( + var_copes) >= 1, 'No varcope volumes generated by FSL CEstimate' outputs['var_copes'] = var_copes zstats = glob(os.path.join(pth, 'zstat[0-9]*.*')) @@ -714,7 +758,8 @@ def _list_outputs(self): outputs['tstats'] = tstats mrefs = glob(os.path.join(pth, 'mean_random_effects_var[0-9]*.*')) - assert len(mrefs) >= 1, 'No mean random effects volumes generated by FLAMEO' + assert len( + mrefs) >= 1, 'No mean random effects volumes generated by FLAMEO' outputs['mrefvars'] = mrefs tdof = glob(os.path.join(pth, 'tdof_t[0-9]*.*')) @@ -837,7 +882,8 @@ def _list_outputs(self): for i in range(numtcons): copes.append(self._gen_fname('cope%d.nii' % (base_contrast + i), cwd=pth)) - varcopes.append(self._gen_fname('varcope%d.nii' % (base_contrast + i), + varcopes.append( + self._gen_fname('varcope%d.nii' % (base_contrast + i), cwd=pth)) zstats.append(self._gen_fname('zstat%d.nii' % (base_contrast + i), cwd=pth)) @@ -856,7 +902,8 @@ def _list_outputs(self): for i in range(numfcons): fstats.append(self._gen_fname('fstat%d.nii' % (base_contrast + i), cwd=pth)) - zfstats.append(self._gen_fname('zfstat%d.nii' % (base_contrast + i), + zfstats.append( + self._gen_fname('zfstat%d.nii' % (base_contrast + i), cwd=pth)) if fstats: outputs['fstats'] = fstats @@ -905,7 +952,7 @@ def _run_interface(self, runtime): '/NumContrasts 1', '/PPheights %e' % 1, '/RequiredEffect 100.0', # XX where does this - #number come from + # number come from '', '/Matrix', '%e' % 1] @@ -949,8 +996,10 @@ class MultipleRegressDesignInputSpec(BaseInterfaceInputSpec): traits.Enum('F'), traits.List(traits.Tuple(traits.Str, traits.Enum('T'), - traits.List(traits.Str), - traits.List(traits.Float)), + traits.List( + traits.Str), + traits.List( + traits.Float)), ))), mandatory=True, desc="List of contrasts with each contrast being a list of the form - \ @@ -1018,7 +1067,8 @@ def _run_interface(self, runtime): mat_txt += ['', '/Matrix'] for cidx in range(npoints): - mat_txt.append(' '.join(['%e' % self.inputs.regressors[key][cidx] for key in regs])) + mat_txt.append(' '.join( + ['%e' % self.inputs.regressors[key][cidx] for key in regs])) mat_txt = '\n'.join(mat_txt) # write t-con file con_txt = [] @@ -1031,14 +1081,17 @@ def _run_interface(self, runtime): con_txt += ['/ContrastName%d %s' % (counter, con[0])] con_txt += ['/NumWaves %d' % nwaves, '/NumContrasts %d' % ntcons, - '/PPheights %s' % ' '.join(['%e' % 1 for i in range(counter)]), - '/RequiredEffect %s' % ' '.join(['%.3f' % 100 for i in range(counter)]), + '/PPheights %s' % ' '.join( + ['%e' % 1 for i in range(counter)]), + '/RequiredEffect %s' % ' '.join( + ['%.3f' % 100 for i in range(counter)]), '', '/Matrix'] for idx in sorted(tconmap.keys()): convals = np.zeros((nwaves, 1)) for regidx, reg in enumerate(self.inputs.contrasts[idx][2]): - convals[regs.index(reg)] = self.inputs.contrasts[idx][3][regidx] + convals[regs.index(reg) + ] = self.inputs.contrasts[idx][3][regidx] con_txt.append(' '.join(['%e' % val for val in convals])) con_txt = '\n'.join(con_txt) # write f-con file @@ -1095,7 +1148,8 @@ def _list_outputs(self): class SMMInputSpec(FSLCommandInputSpec): - spatial_data_file = File(exists=True, position=0, argstr='--sdf="%s"', mandatory=True, + spatial_data_file = File( + exists=True, position=0, argstr='--sdf="%s"', mandatory=True, desc="statistics spatial map", copyfile=False) mask = File(exist=True, position=1, argstr='--mask="%s"', mandatory=True, desc="mask file", copyfile=False) @@ -1121,65 +1175,96 @@ class SMM(FSLCommand): def _list_outputs(self): outputs = self._outputs().get() - #TODO get the true logdir from the stdout - outputs['null_p_map'] = self._gen_fname(basename="w1_mean", cwd="logdir") - outputs['activation_p_map'] = self._gen_fname(basename="w2_mean", cwd="logdir") + # TODO get the true logdir from the stdout + outputs['null_p_map'] = self._gen_fname(basename="w1_mean", + cwd="logdir") + outputs['activation_p_map'] = self._gen_fname( + basename="w2_mean", cwd="logdir") if not isdefined(self.inputs.no_deactivation_class) or not self.inputs.no_deactivation_class: - outputs['deactivation_p_map'] = self._gen_fname(basename="w3_mean", cwd="logdir") + outputs['deactivation_p_map'] = self._gen_fname( + basename="w3_mean", cwd="logdir") return outputs class MELODICInputSpec(FSLCommandInputSpec): - in_files = InputMultiPath(File(exists=True), argstr="-i %s", mandatory=True, position=0, + in_files = InputMultiPath( + File(exists=True), argstr="-i %s", mandatory=True, position=0, desc="input file names (either single file name or a list)") - out_dir = Directory(argstr="-o %s", desc="output directory name", genfile=True) - mask = File(exists=True, argstr="-m %s", desc="file name of mask for thresholding") + out_dir = Directory( + argstr="-o %s", desc="output directory name", genfile=True) + mask = File(exists=True, argstr="-m %s", + desc="file name of mask for thresholding") no_mask = traits.Bool(argstr="--nomask", desc="switch off masking") - update_mask = traits.Bool(argstr="--update_mask", desc="switch off mask updating") + update_mask = traits.Bool( + argstr="--update_mask", desc="switch off mask updating") no_bet = traits.Bool(argstr="--nobet", desc="switch off BET") - bg_threshold = traits.Float(argstr="--bgthreshold=%f", desc="brain/non-brain threshold used to mask non-brain voxels, as a percentage (only if --nobet selected)") - dim = traits.Int(argstr="-d %d", desc="dimensionality reduction into #num dimensions"\ + bg_threshold = traits.Float( + argstr="--bgthreshold=%f", desc="brain/non-brain threshold used to mask non-brain voxels, as a percentage (only if --nobet selected)") + dim = traits.Int(argstr="-d %d", desc="dimensionality reduction into #num dimensions" "(default: automatic estimation)") - dim_est = traits.Str(argstr="--dimest=%s", desc="use specific dim. estimation technique:"\ + dim_est = traits.Str(argstr="--dimest=%s", desc="use specific dim. estimation technique:" " lap, bic, mdl, aic, mean (default: lap)") - sep_whiten = traits.Bool(argstr="--sep_whiten", desc="switch on separate whitening") - sep_vn = traits.Bool(argstr="--sep_vn", desc="switch off joined variance normalization") - num_ICs = traits.Int(argstr="-n %d", desc="number of IC's to extract (for deflation approach)") - approach = traits.Str(argstr="-a %s", desc="approach for decomposition, 2D: defl, symm (default), "\ + sep_whiten = traits.Bool( + argstr="--sep_whiten", desc="switch on separate whitening") + sep_vn = traits.Bool( + argstr="--sep_vn", desc="switch off joined variance normalization") + num_ICs = traits.Int( + argstr="-n %d", desc="number of IC's to extract (for deflation approach)") + approach = traits.Str(argstr="-a %s", desc="approach for decomposition, 2D: defl, symm (default), " " 3D: tica (default), concat") - non_linearity = traits.Str(argstr="--nl=%s", desc="nonlinearity: gauss, tanh, pow3, pow4") - var_norm = traits.Bool(argstr="--vn", desc="switch off variance normalization") - pbsc = traits.Bool(argstr="--pbsc", desc="switch off conversion to percent BOLD signal change") - cov_weight = traits.Float(argstr="--covarweight=%f", desc="voxel-wise weights for the covariance "\ + non_linearity = traits.Str( + argstr="--nl=%s", desc="nonlinearity: gauss, tanh, pow3, pow4") + var_norm = traits.Bool( + argstr="--vn", desc="switch off variance normalization") + pbsc = traits.Bool( + argstr="--pbsc", desc="switch off conversion to percent BOLD signal change") + cov_weight = traits.Float(argstr="--covarweight=%f", desc="voxel-wise weights for the covariance " "matrix (e.g. segmentation information)") epsilon = traits.Float(argstr="--eps=%f", desc="minimum error change") - epsilonS = traits.Float(argstr="--epsS=%f", desc="minimum error change for rank-1 approximation in TICA") - maxit = traits.Int(argstr="--maxit=%d", desc="maximum number of iterations before restart") - max_restart = traits.Int(argstr="--maxrestart=%d", desc="maximum number of restarts") - mm_thresh = traits.Float(argstr="--mmthresh=%f", desc="threshold for Mixture Model based inference") - no_mm = traits.Bool(argstr="--no_mm", desc="switch off mixture modelling on IC maps") - ICs = File(exists=True, argstr="--ICs=%s", desc="filename of the IC components file for mixture modelling") - mix = File(exists=True, argstr="--mix=%s", desc="mixing matrix for mixture modelling / filtering") - smode = File(exists=True, argstr="--smode=%s", desc="matrix of session modes for report generation") - rem_cmp = traits.List(traits.Int, argstr="-f %d", desc="component numbers to remove") + epsilonS = traits.Float( + argstr="--epsS=%f", desc="minimum error change for rank-1 approximation in TICA") + maxit = traits.Int(argstr="--maxit=%d", + desc="maximum number of iterations before restart") + max_restart = traits.Int( + argstr="--maxrestart=%d", desc="maximum number of restarts") + mm_thresh = traits.Float( + argstr="--mmthresh=%f", desc="threshold for Mixture Model based inference") + no_mm = traits.Bool( + argstr="--no_mm", desc="switch off mixture modelling on IC maps") + ICs = File(exists=True, argstr="--ICs=%s", + desc="filename of the IC components file for mixture modelling") + mix = File(exists=True, argstr="--mix=%s", + desc="mixing matrix for mixture modelling / filtering") + smode = File(exists=True, argstr="--smode=%s", + desc="matrix of session modes for report generation") + rem_cmp = traits.List( + traits.Int, argstr="-f %d", desc="component numbers to remove") report = traits.Bool(argstr="--report", desc="generate Melodic web report") - bg_image = File(exists=True, argstr="--bgimage=%s", desc="specify background image for report"\ + bg_image = File(exists=True, argstr="--bgimage=%s", desc="specify background image for report" " (default: mean image)") tr_sec = traits.Float(argstr="--tr=%f", desc="TR in seconds") - log_power = traits.Bool(argstr="--logPower", desc="calculate log of power for frequency spectrum") - t_des = File(exists=True, argstr="--Tdes=%s", desc="design matrix across time-domain") - t_con = File(exists=True, argstr="--Tcon=%s", desc="t-contrast matrix across time-domain") - s_des = File(exists=True, argstr="--Sdes=%s", desc="design matrix across subject-domain") - s_con = File(exists=True, argstr="--Scon=%s", desc="t-contrast matrix across subject-domain") + log_power = traits.Bool( + argstr="--logPower", desc="calculate log of power for frequency spectrum") + t_des = File(exists=True, argstr="--Tdes=%s", + desc="design matrix across time-domain") + t_con = File(exists=True, argstr="--Tcon=%s", + desc="t-contrast matrix across time-domain") + s_des = File(exists=True, argstr="--Sdes=%s", + desc="design matrix across subject-domain") + s_con = File(exists=True, argstr="--Scon=%s", + desc="t-contrast matrix across subject-domain") out_all = traits.Bool(argstr="--Oall", desc="output everything") out_unmix = traits.Bool(argstr="--Ounmix", desc="output unmixing matrix") - out_stats = traits.Bool(argstr="--Ostats", desc="output thresholded maps and probability maps") + out_stats = traits.Bool( + argstr="--Ostats", desc="output thresholded maps and probability maps") out_pca = traits.Bool(argstr="--Opca", desc="output PCA results") - out_white = traits.Bool(argstr="--Owhite", desc="output whitening/dewhitening matrices") + out_white = traits.Bool( + argstr="--Owhite", desc="output whitening/dewhitening matrices") out_orig = traits.Bool(argstr="--Oorig", desc="output the original ICs") out_mean = traits.Bool(argstr="--Omean", desc="output mean volume") - report_maps = traits.Str(argstr="--report_maps=%s", desc="control string for spatial map images (see slicer)") - remove_deriv = traits.Bool(argstr="--remove_deriv", desc="removes every second entry in paradigm"\ + report_maps = traits.Str(argstr="--report_maps=%s", + desc="control string for spatial map images (see slicer)") + remove_deriv = traits.Bool(argstr="--remove_deriv", desc="removes every second entry in paradigm" " file (EV derivatives)") @@ -1221,7 +1306,8 @@ def _list_outputs(self): if not isdefined(outputs['out_dir']): outputs['out_dir'] = self._gen_filename("out_dir") if isdefined(self.inputs.report) and self.inputs.report: - outputs['report_dir'] = os.path.join(self._gen_filename("out_dir"), "report") + outputs['report_dir'] = os.path.join( + self._gen_filename("out_dir"), "report") return outputs def _gen_filename(self, name): @@ -1324,7 +1410,8 @@ class ClusterInputSpec(FSLCommandInputSpec): desc='the connectivity of voxels (default 26)') use_mm = traits.Bool('--mm', desc='use mm, not voxel, coordinates') find_min = traits.Bool('--min', desc='find minima instead of maxima') - no_table = traits.Bool('--no_table', desc='suppresses printing of the table info') + no_table = traits.Bool( + '--no_table', desc='suppresses printing of the table info') minclustersize = traits.Bool(argstr='--minclustersize', desc='prints out minimum significant cluster size') xfm_file = File(argstr='--xfm=%s', @@ -1366,7 +1453,7 @@ class Cluster(FSLCommand): output_spec = ClusterOutputSpec _cmd = 'cluster' - filemap = {'out_index_file': 'index', 'out_threshold_file':'threshold', + filemap = {'out_index_file': 'index', 'out_threshold_file': 'threshold', 'out_localmax_txt_file': 'localmax.txt', 'out_localmax_vol_file': 'localmax', 'out_size_file': 'size', 'out_max_file': 'max', @@ -1382,7 +1469,7 @@ def _list_outputs(self): if inval: change_ext = True if suffix.endswith('.txt'): - change_ext=False + change_ext = False outputs[outkey] = self._gen_fname(self.inputs.in_file, suffix='_' + suffix, change_ext=change_ext) @@ -1401,40 +1488,64 @@ def _format_arg(self, name, spec, value): class RandomiseInputSpec(FSLCommandInputSpec): - in_file = File(exists=True, desc='4D input file', argstr='-i %s', position=0, mandatory=True) - base_name = traits.Str('tbss_', desc='the rootname that all generated files will have', + in_file = File(exists=True, desc='4D input file', argstr='-i %s', + position=0, mandatory=True) + base_name = traits.Str( + 'tbss_', desc='the rootname that all generated files will have', argstr='-o "%s"', position=1, usedefault=True) - design_mat = File(exists=True, desc='design matrix file', argstr='-d %s', position=2) - tcon = File(exists=True, desc='t contrasts file', argstr='-t %s', position=3) + design_mat = File( + exists=True, desc='design matrix file', argstr='-d %s', position=2) + tcon = File( + exists=True, desc='t contrasts file', argstr='-t %s', position=3) fcon = File(exists=True, desc='f contrasts file', argstr='-f %s') mask = File(exists=True, desc='mask image', argstr='-m %s') - x_block_labels = File(exists=True, desc='exchangeability block labels file', argstr='-e %s') - demean = traits.Bool(desc='demean data temporally before model fitting', argstr='-D') - one_sample_group_mean = traits.Bool(desc='perform 1-sample group-mean test instead of generic permutation test', + x_block_labels = File( + exists=True, desc='exchangeability block labels file', argstr='-e %s') + demean = traits.Bool( + desc='demean data temporally before model fitting', argstr='-D') + one_sample_group_mean = traits.Bool( + desc='perform 1-sample group-mean test instead of generic permutation test', argstr='-1') - show_total_perms = traits.Bool(desc='print out how many unique permutations would be generated and exit', + show_total_perms = traits.Bool( + desc='print out how many unique permutations would be generated and exit', argstr='-q') - show_info_parallel_mode = traits.Bool(desc='print out information required for parallel mode and exit', + show_info_parallel_mode = traits.Bool( + desc='print out information required for parallel mode and exit', argstr='-Q') - vox_p_values = traits.Bool(desc='output voxelwise (corrected and uncorrected) p-value images', + vox_p_values = traits.Bool( + desc='output voxelwise (corrected and uncorrected) p-value images', argstr='-x') - tfce = traits.Bool(desc='carry out Threshold-Free Cluster Enhancement', argstr='-T') - tfce2D = traits.Bool(desc='carry out Threshold-Free Cluster Enhancement with 2D optimisation', + tfce = traits.Bool( + desc='carry out Threshold-Free Cluster Enhancement', argstr='-T') + tfce2D = traits.Bool( + desc='carry out Threshold-Free Cluster Enhancement with 2D optimisation', argstr='--T2') f_only = traits.Bool(desc='calculate f-statistics only', argstr='--f_only') - raw_stats_imgs = traits.Bool(desc='output raw ( unpermuted ) statistic images', argstr='-R') - p_vec_n_dist_files = traits.Bool(desc='output permutation vector and null distribution text files', + raw_stats_imgs = traits.Bool( + desc='output raw ( unpermuted ) statistic images', argstr='-R') + p_vec_n_dist_files = traits.Bool( + desc='output permutation vector and null distribution text files', argstr='-P') - num_perm = traits.Int(argstr='-n %d', desc='number of permutations (default 5000, set to 0 for exhaustive)') - seed = traits.Int(argstr='--seed %d', desc='specific integer seed for random number generator') - var_smooth = traits.Int(argstr='-v %d', desc='use variance smoothing (std is in mm)') - c_thresh = traits.Float(argstr='-c %.2f', desc='carry out cluster-based thresholding') - cm_thresh = traits.Float(argstr='-C %.2f', desc='carry out cluster-mass-based thresholding') - f_c_thresh = traits.Float(argstr='-F %.2f', desc='carry out f cluster thresholding') - f_cm_thresh = traits.Float(argstr='-S %.2f', desc='carry out f cluster-mass thresholding') - tfce_H = traits.Float(argstr='--tfce_H %.2f', desc='TFCE height parameter (default=2)') - tfce_E = traits.Float(argstr='--tfce_E %.2f', desc='TFCE extent parameter (default=0.5)') - tfce_C = traits.Float(argstr='--tfce_C %.2f', desc='TFCE connectivity (6 or 26; default=6)') + num_perm = traits.Int( + argstr='-n %d', desc='number of permutations (default 5000, set to 0 for exhaustive)') + seed = traits.Int( + argstr='--seed %d', desc='specific integer seed for random number generator') + var_smooth = traits.Int( + argstr='-v %d', desc='use variance smoothing (std is in mm)') + c_thresh = traits.Float( + argstr='-c %.2f', desc='carry out cluster-based thresholding') + cm_thresh = traits.Float( + argstr='-C %.2f', desc='carry out cluster-mass-based thresholding') + f_c_thresh = traits.Float( + argstr='-F %.2f', desc='carry out f cluster thresholding') + f_cm_thresh = traits.Float( + argstr='-S %.2f', desc='carry out f cluster-mass thresholding') + tfce_H = traits.Float( + argstr='--tfce_H %.2f', desc='TFCE height parameter (default=2)') + tfce_E = traits.Float( + argstr='--tfce_E %.2f', desc='TFCE extent parameter (default=0.5)') + tfce_C = traits.Float( + argstr='--tfce_C %.2f', desc='TFCE connectivity (6 or 26; default=6)') vxl = traits.List(traits.Int, argstr='--vxl %d', desc='list of numbers indicating voxelwise EVs' + 'position in the design matrix (list order corresponds to files in vxf option)') vxf = traits.List(traits.Int, argstr='--vxf %d', desc='list of 4D images containing voxelwise EVs' + @@ -1484,9 +1595,9 @@ class Randomise(FSLCommand): def _list_outputs(self): outputs = self.output_spec().get() - outputs['tstat_files'] = glob(self._gen_fname(\ + outputs['tstat_files'] = glob(self._gen_fname( '%s_tstat*.nii' % self.inputs.base_name)) - outputs['fstat_files'] = glob(self._gen_fname(\ + outputs['fstat_files'] = glob(self._gen_fname( '%s_fstat*.nii' % self.inputs.base_name)) prefix = False if self.inputs.tfce or self.inputs.tfce2D: @@ -1498,52 +1609,106 @@ def _list_outputs(self): elif self.inputs.cm_thresh or self.inputs.f_cm_thresh: prefix = 'clusterm' if prefix: - outputs['t_p_files'] = glob(self._gen_fname(\ + outputs['t_p_files'] = glob(self._gen_fname( '%s_%s_p_tstat*' % (self.inputs.base_name, prefix))) - outputs['t_corrected_p_files'] = glob(self._gen_fname(\ + outputs['t_corrected_p_files'] = glob(self._gen_fname( '%s_%s_corrp_tstat*.nii' % (self.inputs.base_name, prefix))) - outputs['f_p_files'] = glob(self._gen_fname(\ + outputs['f_p_files'] = glob(self._gen_fname( '%s_%s_p_fstat*.nii' % (self.inputs.base_name, prefix))) - outputs['f_corrected_p_files'] = glob(self._gen_fname(\ + outputs['f_corrected_p_files'] = glob(self._gen_fname( '%s_%s_corrp_fstat*.nii' % (self.inputs.base_name, prefix))) return outputs class GLMInputSpec(FSLCommandInputSpec): - in_file = File( - exists=True,mandatory=True, - argstr='-i %s', - desc='input 3d+t file',) - design = File( - exists=True, mandatory=True, - argstr='-d %s', - desc='design file or image file') - out_file = File( - genfile=True, argstr="-o %s", - desc="file or image output") - mask = File( - exists=True, - argstr='-m %s', - desc='mask file') - contrasts = File( - exists=True, - argstr='-c %s', - desc='t-contrasts file') - options = traits.String( - argstr='%s', - desc = 'fsl_glm options') + in_file = File(exists=True, argstr='-i %s', mandatory=True, position=1, + desc='input file name (text matrix or 3D/4D image file)') + out_file = File(argstr='-o %s', genfile=True, position=3, + desc=('filename for GLM parameter estimates' + + ' (GLM betas)')) + design = File(exists=True, argstr='-d %s', mandatory=True, position=2, + desc=('file name of the GLM design matrix (text time' + + ' courses for temporal regression or an image' + + ' file for spatial regression)')) + contrasts = File(exists=True, argstr='-c %s', desc=('matrix of t-statics' + + ' contrasts')) + mask = File(exists=True, argstr='-m %s', desc=('mask image file name if' + + ' input is image')) + dof = traits.Int(argstr='--dof %d', desc=('set degrees of freedom' + + ' explicitly')) + des_norm = traits.Bool(argstr='--des_norm', desc=('switch on normalization' + + ' of the design matrix' + + ' columns to unit std' + + ' deviation')) + dat_norm = traits.Bool(argstr='--dat_norm', desc=('switch on normalization' + + ' of the data time' + + ' series to unit std' + + ' deviation')) + var_norm = traits.Bool(argstr='--vn', desc=('perform MELODIC variance-' + + 'normalisation on data')) + demean = traits.Bool(argstr='--demean', desc=('switch on demeaining of ' + + ' design and data')) + out_cope = File(argstr='--out_cope=%s', + desc='output file name for COPE (either as txt or image') + out_z_name = File(argstr='--out_z=%s', + desc='output file name for Z-stats (either as txt or image') + out_t_name = File(argstr='--out_t=%s', + desc='output file name for t-stats (either as txt or image') + + out_p_name = File(argstr='--out_p=%s', + desc=('output file name for p-values of Z-stats (either as' + + ' text file or image)')) + out_f_name = File(argstr='--out_f=%s', + desc='output file name for F-value of full model fit') + out_pf_name = File(argstr='--out_pf=%s', + desc='output file name for p-value for full model fit') + out_res_name = File(argstr='--out_res=%s', + desc='output file name for residuals') + out_varcb_name = File(argstr='--out_varcb=%s', + desc='output file name for variance of COPEs') + + out_sigsq_name = File(argstr='--out_sigsq=%s', + desc=('output file name for residual noise variance' + + ' sigma-square')) + out_data_name = File(argstr='--out_data=%s', + desc='output file name for pre-processed data') + out_vnscales_name = File(argstr='--out_vnscales=%s', + desc=('output file name for scaling factors for variance' + + ' normalisation')) class GLMOutputSpec(TraitedSpec): - out_file = File( - exists=True, - desc = 'file or image output') + out_file = File(exists=True, desc=('file name of GLM parameters' + + ' (if generated)')) + out_cope = OutputMultiPath(exists=True, desc='output file name for COPEs' + + ' (either as text file or image)') + out_z = OutputMultiPath(exists=True, desc='output file name for COPEs' + + ' (either as text file or image)') + out_t = OutputMultiPath(exists=True, desc='output file name for t-stats' + + ' (either as text file or image)') + out_p = OutputMultiPath(exists=True, desc='output file name for p-values' + + ' of Z-stats (either as text file or image)') + out_f = OutputMultiPath(exists=True, desc='output file name for F-value' + + ' of full model fit') + out_pf = OutputMultiPath(exists=True, desc='output file name for p-value' + + ' for full model fit') + out_res = OutputMultiPath(exists=True, desc='output file name for' + + ' residuals') + out_varcb = OutputMultiPath(exists=True, desc='output file name for' + + ' variance of COPEs') + out_sigsq = OutputMultiPath(exists=True, desc='output file name for' + + ' residual noise variance sigma-square') + out_data = OutputMultiPath(exists=True, desc='output file name for' + + ' residual noise variance sigma-square') + out_vnscales = OutputMultiPath(exists=True, desc='output file name' + + ' for scaling factors for variance' + + ' normalisation') class GLM(FSLCommand): """ - FSL GLM: + FSL GLM: Example ------- @@ -1559,15 +1724,51 @@ class GLM(FSLCommand): def _list_outputs(self): outputs = self.output_spec().get() + outputs['out_file'] = self.inputs.out_file # Generate an out_file if one is not provided if not isdefined(outputs['out_file']) and isdefined(self.inputs.in_file): - outputs['out_file'] = os.path.abspath(self._gen_filename('out_file')) + outputs['out_file'] = self._gen_filename('out_file') + outputs['out_file'] = os.path.abspath(outputs['out_file']) + + if isdefined(self.inputs.out_cope): + outputs['out_cope'] = os.path.abspath(self.inputs.out_cope) + + if isdefined(self.inputs.out_z_name): + outputs['out_z'] = os.path.abspath(self.inputs.out_z_name) + + if isdefined(self.inputs.out_t_name): + outputs['out_t'] = os.path.abspath(self.inputs.out_t_name) + + if isdefined(self.inputs.out_p_name): + outputs['out_p'] = os.path.abspath(self.inputs.out_p_name) + + if isdefined(self.inputs.out_f_name): + outputs['out_f'] = os.path.abspath(self.inputs.out_f_name) + + if isdefined(self.inputs.out_pf_name): + outputs['out_pf'] = os.path.abspath(self.inputs.out_pf_name) + + if isdefined(self.inputs.out_res_name): + outputs['out_res'] = os.path.abspath(self.inputs.out_res_name) + + if isdefined(self.inputs.out_varcb_name): + outputs['out_varcb'] = os.path.abspath(self.inputs.out_varcb_name) + + if isdefined(self.inputs.out_sigsq_name): + outputs['out_sigsq'] = os.path.abspath(self.inputs.out_sigsq_name) + + if isdefined(self.inputs.out_data_name): + outputs['out_data'] = os.path.abspath(self.inputs.out_data_name) + + if isdefined(self.inputs.out_vnscales_name): + outputs['out_vnscales'] = os.path.abspath( + self.inputs.out_vnscales_name) + return outputs def _gen_filename(self, name): if name in ('out_file'): - from nipype.utils.filemanip import fname_presuffix return fname_presuffix(self.inputs.in_file, suffix='_glm.txt', use_ext=False) return None