From f20b07fb5f1a2e90f38b5c820a90d69359649513 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Wed, 22 Mar 2017 10:17:59 -0400 Subject: [PATCH] Improve readability of modelgen examples 2. Also, add blank lines between consecutive if/else statements for clarity and restructure several description fields. The changes to FIX seem to be automatic, but they just remove trailing whitespace, so I decided to keep them. --- nipype/algorithms/modelgen.py | 177 ++++++++++++++++++++++------------ nipype/interfaces/fsl/fix.py | 28 +++--- 2 files changed, 127 insertions(+), 78 deletions(-) diff --git a/nipype/algorithms/modelgen.py b/nipype/algorithms/modelgen.py index 349e7557fd..98333ed1b5 100644 --- a/nipype/algorithms/modelgen.py +++ b/nipype/algorithms/modelgen.py @@ -107,7 +107,7 @@ def spm_hrf(RT, P=None, fMRI_T=16): def orth(x_in, y_in): - """Orthoganlize y_in with respect to x_in + """Orthogonalize y_in with respect to x_in. >>> orth_expected = np.array([1.7142857142857144, 0.42857142857142883, \ -0.85714285714285676]) @@ -140,8 +140,10 @@ def scale_timings(timelist, input_units, output_units, time_repetition): """ if input_units == output_units: _scalefactor = 1. + if (input_units == 'scans') and (output_units == 'secs'): _scalefactor = time_repetition + if (input_units == 'secs') and (output_units == 'scans'): _scalefactor = 1. / time_repetition timelist = [np.max([0., _scalefactor * t]) for t in timelist] @@ -160,6 +162,7 @@ def gen_info(run_event_files): name, _ = name.split('.run%03d' % (i + 1)) elif '.txt' in name: name, _ = name.split('.txt') + runinfo.conditions.append(name) event_info = np.atleast_2d(np.loadtxt(event_file)) runinfo.onsets.append(event_info[:, 0].tolist()) @@ -167,6 +170,7 @@ def gen_info(run_event_files): runinfo.durations.append(event_info[:, 1].tolist()) else: runinfo.durations.append([0]) + if event_info.shape[1] > 2: runinfo.amplitudes.append(event_info[:, 2].tolist()) else: @@ -176,40 +180,47 @@ def gen_info(run_event_files): class SpecifyModelInputSpec(BaseInterfaceInputSpec): - subject_info = InputMultiPath(Bunch, mandatory=True, xor=['subject_info', - 'event_files'], - desc=("Bunch or List(Bunch) subject specific condition information. " - "see :ref:`SpecifyModel` or SpecifyModel.__doc__ for details")) + subject_info = InputMultiPath(Bunch, mandatory=True, + xor=['subject_info', 'event_files'], + desc='Bunch or List(Bunch) subject-specific ' + 'condition information. see ' + ':ref:`SpecifyModel` or ' + 'SpecifyModel.__doc__ for details') event_files = InputMultiPath(traits.List(File(exists=True)), mandatory=True, xor=['subject_info', 'event_files'], - desc=('list of event description files 1, 2 or 3 column format ' - 'corresponding to onsets, durations and amplitudes')) + desc='List of event description files 1, 2 or 3 ' + 'column format corresponding to onsets, ' + 'durations and amplitudes') realignment_parameters = InputMultiPath(File(exists=True), - desc="Realignment parameters returned by motion correction algorithm", + desc='Realignment parameters returned ' + 'by motion correction algorithm', copyfile=False) outlier_files = InputMultiPath(File(exists=True), - desc="Files containing scan outlier indices that should be tossed", + desc='Files containing scan outlier indices ' + 'that should be tossed', copyfile=False) functional_runs = InputMultiPath(traits.Either(traits.List(File(exists=True)), File(exists=True)), mandatory=True, - desc=("Data files for model. List of 4D files or list of list of 3D " - "files per session"), copyfile=False) + desc='Data files for model. List of 4D ' + 'files or list of list of 3D ' + 'files per session', + copyfile=False) input_units = traits.Enum('secs', 'scans', mandatory=True, - desc=("Units of event onsets and durations (secs or scans). Output " - "units are always in secs")) + desc='Units of event onsets and durations (secs ' + 'or scans). Output units are always in secs') high_pass_filter_cutoff = traits.Float(mandatory=True, - desc="High-pass filter cutoff in secs") + desc='High-pass filter cutoff in secs') time_repetition = traits.Float(mandatory=True, - desc=("Time between the start of one volume to the start of " - "the next image volume.")) + desc='Time between the start of one volume ' + 'to the start of the next image volume.') # Not implemented yet # polynomial_order = traits.Range(0, low=0, - # desc ="Number of polynomial functions to model high pass filter.") + # desc ='Number of polynomial functions to model high pass filter.') class SpecifyModelOutputSpec(TraitedSpec): - session_info = traits.Any(desc="session info for level1designs") + session_info = traits.Any(desc='Session info for level1designs') class SpecifyModel(BaseInterface): @@ -255,34 +266,33 @@ class SpecifyModel(BaseInterface): Examples -------- + >>> from nipype.algorithms import modelgen >>> from nipype.interfaces.base import Bunch - >>> s = SpecifyModel() + >>> s = modelgen.SpecifyModel() >>> s.inputs.input_units = 'secs' >>> s.inputs.functional_runs = ['functional2.nii', 'functional3.nii'] >>> s.inputs.time_repetition = 6 >>> s.inputs.high_pass_filter_cutoff = 128. - >>> 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 = info + >>> evs_run2 = Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 180]], durations=[[1]]) + >>> evs_run3 = Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], durations=[[1]]) + >>> s.inputs.subject_info = [evs_run2, evs_run3] Using pmod: - >>> info = [Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 50],[100, 180]], \ -durations=[[0],[0]], pmod=[Bunch(name=['amp'], poly=[2], param=[[1, 2]]), \ -None]), Bunch(conditions=['cond1', 'cond2'], onsets=[[20, 120],[80, 160]], \ -durations=[[0],[0]], pmod=[Bunch(name=['amp'], poly=[2], param=[[1, 2]]), \ -None])] - >>> s.inputs.subject_info = info + >>> evs_run2 = Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 50], [100, 180]], \ +durations=[[0], [0]], pmod=[Bunch(name=['amp'], poly=[2], param=[[1, 2]]), \ +None]) + >>> evs_run3 = Bunch(conditions=['cond1', 'cond2'], onsets=[[20, 120], [80, 160]], \ +durations=[[0], [0]], pmod=[Bunch(name=['amp'], poly=[2], param=[[1, 2]]), \ +None]) + >>> s.inputs.subject_info = [evs_run2, evs_run3] """ input_spec = SpecifyModelInputSpec output_spec = SpecifyModelOutputSpec - def _generate_standard_design(self, infolist, - functional_runs=None, - realignment_parameters=None, - outliers=None): + def _generate_standard_design(self, infolist, functional_runs=None, + realignment_parameters=None, outliers=None): """ Generates a standard design matrix paradigm given information about each run """ @@ -290,11 +300,13 @@ def _generate_standard_design(self, infolist, output_units = 'secs' if 'output_units' in self.inputs.traits(): output_units = self.inputs.output_units + for i, info in enumerate(infolist): sessinfo.insert(i, dict(cond=[])) if isdefined(self.inputs.high_pass_filter_cutoff): sessinfo[i]['hpf'] = \ np.float(self.inputs.high_pass_filter_cutoff) + if hasattr(info, 'conditions') and info.conditions is not None: for cid, cond in enumerate(info.conditions): sessinfo[i]['cond'].insert(cid, dict()) @@ -312,9 +324,11 @@ def _generate_standard_design(self, infolist, if hasattr(info, 'amplitudes') and info.amplitudes: sessinfo[i]['cond'][cid]['amplitudes'] = \ info.amplitudes[cid] + if hasattr(info, 'tmod') and info.tmod and \ len(info.tmod) > cid: sessinfo[i]['cond'][cid]['tmod'] = info.tmod[cid] + if hasattr(info, 'pmod') and info.pmod and \ len(info.pmod) > cid: if info.pmod[cid]: @@ -327,6 +341,7 @@ def _generate_standard_design(self, infolist, info.pmod[cid].poly[j] sessinfo[i]['cond'][cid]['pmod'][j]['param'] = \ info.pmod[cid].param[j] + sessinfo[i]['regress'] = [] if hasattr(info, 'regressors') and info.regressors is not None: for j, r in enumerate(info.regressors): @@ -339,6 +354,7 @@ def _generate_standard_design(self, infolist, sessinfo[i]['regress'][j]['name'] = 'UR%d' % (j + 1) sessinfo[i]['regress'][j]['val'] = info.regressors[j] sessinfo[i]['scans'] = functional_runs[i] + if realignment_parameters is not None: for i, rp in enumerate(realignment_parameters): mc = realignment_parameters[i] @@ -347,18 +363,20 @@ def _generate_standard_design(self, infolist, sessinfo[i]['regress'].insert(colidx, dict(name='', val=[])) sessinfo[i]['regress'][colidx]['name'] = 'Realign%d' % (col + 1) sessinfo[i]['regress'][colidx]['val'] = mc[:, col].tolist() + if outliers is not None: for i, out in enumerate(outliers): numscans = 0 for f in filename_to_list(sessinfo[i]['scans']): shape = load(f, mmap=NUMPY_MMAP).shape if len(shape) == 3 or shape[3] == 1: - iflogger.warning(("You are using 3D instead of 4D " - "files. Are you sure this was " - "intended?")) + iflogger.warning(('You are using 3D instead of 4D ' + 'files. Are you sure this was ' + 'intended?')) numscans += 1 else: numscans += shape[3] + for j, scanno in enumerate(out): colidx = len(sessinfo[i]['regress']) sessinfo[i]['regress'].insert(colidx, dict(name='', val=[])) @@ -375,6 +393,7 @@ def _generate_design(self, infolist=None): if isdefined(self.inputs.realignment_parameters): for parfile in self.inputs.realignment_parameters: realignment_parameters.append(np.loadtxt(parfile)) + outliers = [] if isdefined(self.inputs.outlier_files): for filename in self.inputs.outlier_files: @@ -387,6 +406,7 @@ def _generate_design(self, infolist=None): outliers.append([outindices.tolist()]) else: outliers.append(outindices.tolist()) + if infolist is None: if isdefined(self.inputs.subject_info): infolist = self.inputs.subject_info @@ -415,9 +435,11 @@ def _list_outputs(self): class SpecifySPMModelInputSpec(SpecifyModelInputSpec): concatenate_runs = traits.Bool(False, usedefault=True, - desc="Concatenate all runs to look like a single session.") + desc='Concatenate all runs to look like a ' + 'single session.') output_units = traits.Enum('secs', 'scans', usedefault=True, - desc="Units of design event onsets and durations (secs or scans)") + desc='Units of design event onsets and durations ' + '(secs or scans)') class SpecifySPMModel(SpecifyModel): @@ -430,18 +452,18 @@ class SpecifySPMModel(SpecifyModel): Examples -------- + >>> from nipype.algorithms import modelgen >>> from nipype.interfaces.base import Bunch - >>> s = SpecifySPMModel() + >>> s = modelgen.SpecifySPMModel() >>> s.inputs.input_units = 'secs' >>> s.inputs.output_units = 'scans' >>> s.inputs.high_pass_filter_cutoff = 128. >>> s.inputs.functional_runs = ['functional2.nii', 'functional3.nii'] >>> s.inputs.time_repetition = 6 >>> s.inputs.concatenate_runs = True - >>> 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 = info + >>> evs_run2 = Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 180]], durations=[[1]]) + >>> evs_run3 = Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], durations=[[1]]) + >>> s.inputs.subject_info = [evs_run2, evs_run3] """ @@ -458,6 +480,7 @@ def _concatenate_info(self, infolist): else: raise Exception('Functional input not specified correctly') nscans.insert(i, numscans) + # now combine all fields into 1 # names, onsets, durations, amplitudes, pmod, tmod, regressor_names, # regressors @@ -466,6 +489,7 @@ def _concatenate_info(self, infolist): if len(infolist[0].onsets[j]) > 1 and len(val) == 1: infoout.durations[j] = (infolist[0].durations[j] * len(infolist[0].onsets[j])) + for i, info in enumerate(infolist[1:]): # info.[conditions, tmod] remain the same if info.onsets: @@ -479,6 +503,7 @@ def _concatenate_info(self, infolist): onsets = np.array(info.onsets[j]) + \ sum(nscans[0:(i + 1)]) infoout.onsets[j].extend(onsets.tolist()) + for j, val in enumerate(info.durations): if len(info.onsets[j]) > 1 and len(val) == 1: infoout.durations[j].extend(info.durations[j] * @@ -487,21 +512,25 @@ def _concatenate_info(self, infolist): infoout.durations[j].extend(info.durations[j]) else: raise ValueError('Mismatch in number of onsets and \ - durations for run {0}, condition \ - {1}'.format(i + 2, j + 1)) + durations for run {0}, condition \ + {1}'.format(i + 2, j + 1)) + if hasattr(info, 'amplitudes') and info.amplitudes: for j, val in enumerate(info.amplitudes): infoout.amplitudes[j].extend(info.amplitudes[j]) + if hasattr(info, 'pmod') and info.pmod: for j, val in enumerate(info.pmod): if val: for key, data in enumerate(val.param): infoout.pmod[j].param[key].extend(data) + if hasattr(info, 'regressors') and info.regressors: # assumes same ordering of regressors across different # runs and the same names for the regressors for j, v in enumerate(info.regressors): infoout.regressors[j].extend(info.regressors[j]) + # insert session regressors if not hasattr(infoout, 'regressors') or not infoout.regressors: infoout.regressors = [] @@ -516,6 +545,7 @@ def _generate_design(self, infolist=None): not self.inputs.concatenate_runs: super(SpecifySPMModel, self)._generate_design(infolist=infolist) return + if isdefined(self.inputs.subject_info): infolist = self.inputs.subject_info else: @@ -543,7 +573,8 @@ def _generate_design(self, infolist=None): out = np.array([]) if out.size > 0: - iflogger.debug('fname=%s, out=%s, nscans=%d', filename, out, sum(nscans[0:i])) + iflogger.debug('fname=%s, out=%s, nscans=%d', + filename, out, sum(nscans[0:i])) sumscans = out.astype(int) + sum(nscans[0:i]) if out.size == 1: @@ -559,22 +590,24 @@ def _generate_design(self, infolist=None): class SpecifySparseModelInputSpec(SpecifyModelInputSpec): time_acquisition = traits.Float(0, mandatory=True, - desc="Time in seconds to acquire a single image volume") + desc='Time in seconds to acquire a single ' + 'image volume') volumes_in_cluster = traits.Range(1, usedefault=True, - desc="Number of scan volumes in a cluster") - model_hrf = traits.Bool(desc="model sparse events with hrf") + desc='Number of scan volumes in a cluster') + model_hrf = traits.Bool(desc='Model sparse events with hrf') stimuli_as_impulses = traits.Bool(True, - desc="Treat each stimulus to be impulse like.", + desc='Treat each stimulus to be impulse-like', usedefault=True) use_temporal_deriv = traits.Bool(requires=['model_hrf'], - desc="Create a temporal derivative in addition to regular regressor") - scale_regressors = traits.Bool(True, desc="Scale regressors by the peak", + desc='Create a temporal derivative in ' + 'addition to regular regressor') + scale_regressors = traits.Bool(True, desc='Scale regressors by the peak', usedefault=True) scan_onset = traits.Float(0.0, - desc="Start of scanning relative to onset of run in secs", + desc='Start of scanning relative to onset of run in secs', usedefault=True) - save_plot = traits.Bool(desc=('save plot of sparse design calculation ' - '(Requires matplotlib)')) + save_plot = traits.Bool(desc=('Save plot of sparse design calculation ' + '(requires matplotlib)')) class SpecifySparseModelOutputSpec(SpecifyModelOutputSpec): @@ -595,18 +628,20 @@ class SpecifySparseModel(SpecifyModel): Examples -------- + >>> from nipype.algorithms import modelgen >>> from nipype.interfaces.base import Bunch - >>> s = SpecifySparseModel() + >>> s = modelgen.SpecifySparseModel() >>> s.inputs.input_units = 'secs' >>> s.inputs.functional_runs = ['functional2.nii', 'functional3.nii'] >>> s.inputs.time_repetition = 6 >>> s.inputs.time_acquisition = 2 >>> s.inputs.high_pass_filter_cutoff = 128. >>> s.inputs.model_hrf = True - >>> 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 = info + >>> evs_run2 = Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 180]], \ +durations=[[1]]) + >>> evs_run3 = Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], \ +durations=[[1]]) + >>> s.inputs.subject_info = [evs_run2, evs_run3] """ input_spec = SpecifySparseModelInputSpec @@ -619,8 +654,9 @@ def _gen_regress(self, i_onsets, i_durations, i_amplitudes, nscans): if isdefined(self.inputs.save_plot) and self.inputs.save_plot: bplot = True import matplotlib - matplotlib.use(config.get("execution", "matplotlib_backend")) + matplotlib.use(config.get('execution', 'matplotlib_backend')) import matplotlib.pyplot as plt + TR = np.round(self.inputs.time_repetition * 1000) # in ms if self.inputs.time_acquisition: TA = np.round(self.inputs.time_acquisition * 1000) # in ms @@ -639,9 +675,10 @@ def _gen_regress(self, i_onsets, i_durations, i_amplitudes, nscans): if dt < dttemp: if dttemp % dt != 0: dt = float(gcd(dttemp, dt)) + if dt < 1: - raise Exception("Time multiple less than 1 ms") - iflogger.info("Setting dt = %d ms\n" % dt) + raise Exception('Time multiple less than 1 ms') + iflogger.info('Setting dt = %d ms\n' % dt) npts = int(np.ceil(total_time / dt)) times = np.arange(0, total_time, dt) * 1e-3 timeline = np.zeros((npts)) @@ -656,12 +693,14 @@ def _gen_regress(self, i_onsets, i_durations, i_amplitudes, nscans): reg_scale = float(TA / dt) else: boxcar[int(1.0 * 1e3 / dt):int(2.0 * 1e3 / dt)] = 1.0 + if isdefined(self.inputs.model_hrf) and self.inputs.model_hrf: response = np.convolve(boxcar, hrf) reg_scale = 1.0 / response.max() iflogger.info('response sum: %.4f max: %.4f' % (response.sum(), response.max())) iflogger.info('reg_scale: %.4f' % reg_scale) + for i, t in enumerate(onsets): idx = int(np.round(t / dt)) if i_amplitudes: @@ -671,9 +710,11 @@ def _gen_regress(self, i_onsets, i_durations, i_amplitudes, nscans): timeline2[idx] = i_amplitudes[0] else: timeline2[idx] = 1 + if bplot: plt.subplot(4, 1, 1) plt.plot(times, timeline2) + if not self.inputs.stimuli_as_impulses: if durations[i] == 0: durations[i] = TA * nvol @@ -681,15 +722,18 @@ def _gen_regress(self, i_onsets, i_durations, i_amplitudes, nscans): timeline2 = np.convolve(timeline2, stimdur)[0:len(timeline2)] timeline += timeline2 timeline2[:] = 0 + if bplot: plt.subplot(4, 1, 2) plt.plot(times, timeline) + if isdefined(self.inputs.model_hrf) and self.inputs.model_hrf: timeline = np.convolve(timeline, hrf)[0:len(timeline)] if isdefined(self.inputs.use_temporal_deriv) and \ self.inputs.use_temporal_deriv: # create temporal deriv timederiv = np.concatenate(([0], np.diff(timeline))) + if bplot: plt.subplot(4, 1, 3) plt.plot(times, timeline) @@ -708,10 +752,12 @@ def _gen_regress(self, i_onsets, i_durations, i_amplitudes, nscans): if isdefined(self.inputs.use_temporal_deriv) and \ self.inputs.use_temporal_deriv: regderiv.insert(i, np.mean(timederiv[scanidx]) * reg_scale) + if isdefined(self.inputs.use_temporal_deriv) and \ self.inputs.use_temporal_deriv: iflogger.info('orthoganlizing derivative w.r.t. main regressor') regderiv = orth(reg, regderiv) + if bplot: plt.subplot(4, 1, 3) plt.plot(times, timeline2) @@ -719,6 +765,7 @@ def _gen_regress(self, i_onsets, i_durations, i_amplitudes, nscans): plt.bar(np.arange(len(reg)), reg, width=0.5) plt.savefig('sparse.png') plt.savefig('sparse.svg') + if regderiv: return [reg, regderiv] else: @@ -754,7 +801,7 @@ def _cond_to_regress(self, info, nscans): reg.insert(len(reg), regressor[1]) else: reg.insert(len(reg), regressor) - # need to deal with temporal and parametric modulators + # need to deal with temporal and parametric modulators # for sparse-clustered acquisitions enter T1-effect regressors nvol = self.inputs.volumes_in_cluster if nvol > 1: @@ -786,6 +833,7 @@ def _generate_clustered_design(self, infolist): else: infoout[i].regressors = [] infoout[i].regressor_names = [] + for j, r in enumerate(reg): regidx = len(infoout[i].regressors) infoout[i].regressor_names.insert(regidx, regnames[j]) @@ -805,6 +853,7 @@ def _list_outputs(self): if not hasattr(self, '_sessinfo'): self._generate_design() outputs['session_info'] = self._sessinfo + if isdefined(self.inputs.save_plot) and self.inputs.save_plot: outputs['sparse_png_file'] = os.path.join(os.getcwd(), 'sparse.png') outputs['sparse_svg_file'] = os.path.join(os.getcwd(), 'sparse.svg') diff --git a/nipype/interfaces/fsl/fix.py b/nipype/interfaces/fsl/fix.py index ea0d1d38eb..95490f4d2a 100644 --- a/nipype/interfaces/fsl/fix.py +++ b/nipype/interfaces/fsl/fix.py @@ -1,7 +1,7 @@ # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The fix module provides classes for interfacing with the `FSL FIX -` command line tools. +` command line tools. This was written to work with FSL version v5.0 @@ -80,7 +80,7 @@ class TrainingSetCreatorOutputSpec(TraitedSpec): mel_icas_out = OutputMultiPath(Directory(exists=True), copyfile=False, desc='Hand labels for noise vs signal', argstr='%s', position=-1) - + class TrainingSetCreator(BaseInterface): '''Goes through set of provided melodic output directories, to find all @@ -118,7 +118,7 @@ def _list_outputs(self): -class FeatureExtractorInputSpec(CommandLineInputSpec): +class FeatureExtractorInputSpec(CommandLineInputSpec): mel_ica = Directory(exists=True, copyfile=False, desc='Melodic output directory or directories', argstr='%s', position=-1) @@ -147,7 +147,7 @@ class TrainingInputSpec(CommandLineInputSpec): desc='Melodic output directories', argstr='%s', position=-1) - trained_wts_filestem = traits.Str(desc='trained-weights filestem, used for trained_wts_file and output directories', argstr='%s', position=1) + trained_wts_filestem = traits.Str(desc='trained-weights filestem, used for trained_wts_file and output directories', argstr='%s', position=1) loo = traits.Bool(argstr='-l', desc='full leave-one-out test with classifier training', position=2) @@ -180,19 +180,19 @@ class AccuracyTesterInputSpec(CommandLineInputSpec): desc='Melodic output directories', argstr='%s', position=3, mandatory=True) - trained_wts_file = File(desc='trained-weights file', argstr='%s', position=1, mandatory=True) + trained_wts_file = File(desc='trained-weights file', argstr='%s', position=1, mandatory=True) - output_directory = Directory(desc='Path to folder in which to store the results of the accuracy test.', argstr='%s', position=2, mandatory=True) + output_directory = Directory(desc='Path to folder in which to store the results of the accuracy test.', argstr='%s', position=2, mandatory=True) class AccuracyTesterOutputSpec(TraitedSpec): - output_directory = Directory(desc='Path to folder in which to store the results of the accuracy test.', argstr='%s', position=1) + output_directory = Directory(desc='Path to folder in which to store the results of the accuracy test.', argstr='%s', position=1) class AccuracyTester(CommandLine): ''' Test the accuracy of an existing training dataset on a set of hand-labelled subjects. - Note: This may or may not be working. Couldn't presently not confirm because fix fails on this (even outside of nipype) without leaving an error msg. + Note: This may or may not be working. Couldn't presently not confirm because fix fails on this (even outside of nipype) without leaving an error msg. ''' input_spec = AccuracyTesterInputSpec output_spec = AccuracyTesterOutputSpec @@ -212,7 +212,7 @@ class ClassifierInputSpec(CommandLineInputSpec): mel_ica = Directory(exists=True, copyfile=False, desc='Melodic output directory or directories', argstr='%s', position=1) - trained_wts_file = File(exists=True, desc='trained-weights file', argstr='%s', position=2, mandatory=True, copyfile=False) + trained_wts_file = File(exists=True, desc='trained-weights file', argstr='%s', position=2, mandatory=True, copyfile=False) thresh = traits.Int(argstr='%d', desc='Threshold for cleanup.', position=-1, mandatory=True) @@ -231,7 +231,7 @@ class Classifier(CommandLine): cmd = 'fix -c' def _gen_artifacts_list_file(self, mel_ica, thresh): - + _, trained_wts_file = os.path.split(self.inputs.trained_wts_file) trained_wts_filestem = trained_wts_file.split('.')[0] filestem = 'fix4melview_' + trained_wts_filestem + '_thr' @@ -249,10 +249,10 @@ def _list_outputs(self): class CleanerInputSpec(CommandLineInputSpec): - artifacts_list_file = File(exists=True, argstr='%s', position=1, mandatory=True, desc='Text file listing which ICs are artifacts; can be the output from classification or can be created manually') + artifacts_list_file = File(exists=True, argstr='%s', position=1, mandatory=True, desc='Text file listing which ICs are artifacts; can be the output from classification or can be created manually') - cleanup_motion = traits.Bool(argstr='-m', - desc='cleanup motion confounds, looks for design.fsf for highpass filter cut-off', + cleanup_motion = traits.Bool(argstr='-m', + desc='cleanup motion confounds, looks for design.fsf for highpass filter cut-off', position=2) highpass = traits.Float(argstr='-m -h %f', @@ -288,7 +288,7 @@ def _get_cleaned_functional_filename(self, artifacts_list_filename): artifacts_list_file = open(artifacts_list_filename, 'r') functional_filename, extension = artifacts_list_file.readline().split('.') artifacts_list_file_path, artifacts_list_filename = os.path.split(artifacts_list_filename) - + return(os.path.join(artifacts_list_file_path, functional_filename + '_clean.nii.gz')) def _list_outputs(self):