From 7bab56de23d42d5f5de9474377337332a657c4fa Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Fri, 30 Sep 2016 16:07:29 -0400 Subject: [PATCH 1/7] Clean afni/preprocess and afni/base. Sort imports in afni base. Sort classes in afni preprocess, split several long strings, and replace traits.Str with base Str throughout all classes. --- nipype/interfaces/afni/__init__.py | 16 +- nipype/interfaces/afni/preprocess.py | 4284 +++++++++++++------------- 2 files changed, 2153 insertions(+), 2147 deletions(-) diff --git a/nipype/interfaces/afni/__init__.py b/nipype/interfaces/afni/__init__.py index a34106c182..0648c070f0 100644 --- a/nipype/interfaces/afni/__init__.py +++ b/nipype/interfaces/afni/__init__.py @@ -8,12 +8,12 @@ """ from .base import Info -from .preprocess import (To3D, Refit, Resample, TStat, Automask, Volreg, Merge, - ZCutUp, Calc, TShift, Warp, Detrend, Despike, - DegreeCentrality, ECM, LFCD, Copy, Fourier, Allineate, - Maskave, SkullStrip, TCat, ClipLevel, MaskTool, Seg, - Fim, BlurInMask, Autobox, TCorrMap, Bandpass, Retroicor, - TCorrelate, TCorr1D, BrickStat, ROIStats, AutoTcorrelate, - AFNItoNIFTI, Eval, Means, Hist, FWHMx, OutlierCount, - QualityIndex, Notes) +from .preprocess import (AFNItoNIFTI, Allineate, AutoTcorrelate, Autobox, + Automask, Bandpass, BlurInMask, BlurToFWHM, BrickStat, + Calc, ClipLevel, Copy, DegreeCentrality, Despike, + Detrend, ECM, Eval, FWHMx, Fim, Fourier, Hist, LFCD, + MaskTool, Maskave, Means, Merge, Notes, OutlierCount, + QualityIndex, ROIStats, Refit, Resample, Retroicor, + Seg, SkullStrip, TCat, TCorr1D, TCorrMap, TCorrelate, + TShift, TStat, To3D, Volreg, Warp, ZCutUp) from .svm import (SVMTest, SVMTrain) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index 59ae5e0398..ce6b27f0ca 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -27,350 +27,314 @@ Info, no_afni) - -class BlurToFWHMInputSpec(AFNICommandInputSpec): - in_file = File(desc='The dataset that will be smoothed', argstr='-input %s', mandatory=True, exists=True) - - automask = traits.Bool(desc='Create an automask from the input dataset.', argstr='-automask') - fwhm = traits.Float(desc='Blur until the 3D FWHM reaches this value (in mm)', argstr='-FWHM %f') - fwhmxy = traits.Float(desc='Blur until the 2D (x,y)-plane FWHM reaches this value (in mm)', argstr='-FWHMxy %f') - blurmaster = File(desc='The dataset whose smoothness controls the process.', argstr='-blurmaster %s', exists=True) - mask = File(desc='Mask dataset, if desired. Voxels NOT in mask will be set to zero in output.', argstr='-blurmaster %s', exists=True) - - - -class BlurToFWHM(AFNICommand): - """Blurs a 'master' dataset until it reaches a specified FWHM smoothness (approximately). - - For complete details, see the `to3d Documentation - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni - >>> blur = afni.preprocess.BlurToFWHM() - >>> blur.inputs.in_file = 'epi.nii' - >>> blur.inputs.fwhm = 2.5 - >>> blur.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dBlurToFWHM -FWHM 2.500000 -input epi.nii -prefix epi_afni' - +class CentralityInputSpec(AFNICommandInputSpec): + """Common input spec class for all centrality-related commmands """ - _cmd = '3dBlurToFWHM' - input_spec = BlurToFWHMInputSpec - output_spec = AFNICommandOutputSpec - -class To3DInputSpec(AFNICommandInputSpec): - out_file = File(name_template="%s", desc='output image file name', - argstr='-prefix %s', name_source=["in_folder"]) - in_folder = Directory(desc='folder with DICOM images to convert', - argstr='%s/*.dcm', - position=-1, - mandatory=True, - exists=True) - - filetype = traits.Enum('spgr', 'fse', 'epan', 'anat', 'ct', 'spct', - 'pet', 'mra', 'bmap', 'diff', - 'omri', 'abuc', 'fim', 'fith', 'fico', 'fitt', 'fift', - 'fizt', 'fict', 'fibt', - 'fibn', 'figt', 'fipt', - 'fbuc', argstr='-%s', desc='type of datafile being converted') - - skipoutliers = traits.Bool(desc='skip the outliers check', - argstr='-skip_outliers') - - assumemosaic = traits.Bool(desc='assume that Siemens image is mosaic', - argstr='-assume_dicom_mosaic') - - datatype = traits.Enum('short', 'float', 'byte', 'complex', - desc='set output file datatype', argstr='-datum %s') - - funcparams = traits.Str(desc='parameters for functional data', - argstr='-time:zt %s alt+z2') - - - -class To3D(AFNICommand): - """Create a 3D dataset from 2D image files using AFNI to3d command + + mask = File(desc='mask file to mask input data', + argstr="-mask %s", + exists=True) - For complete details, see the `to3d Documentation - `_ + thresh = traits.Float(desc='threshold to exclude connections where corr <= thresh', + argstr='-thresh %f') - Examples - ======== + polort = traits.Int(desc='', argstr='-polort %d') - >>> from nipype.interfaces import afni - >>> To3D = afni.To3D() - >>> To3D.inputs.datatype = 'float' - >>> To3D.inputs.in_folder = '.' - >>> To3D.inputs.out_file = 'dicomdir.nii' - >>> To3D.inputs.filetype = "anat" - >>> To3D.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - 'to3d -datum float -anat -prefix dicomdir.nii ./*.dcm' - >>> res = To3D.run() #doctest: +SKIP + autoclip = traits.Bool(desc='Clip off low-intensity regions in the dataset', + argstr='-autoclip') - """ - _cmd = 'to3d' - input_spec = To3DInputSpec - output_spec = AFNICommandOutputSpec + automask = traits.Bool(desc='Mask the dataset to target brain-only voxels', + argstr='-automask') -class TShiftInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dTShift', +class AFNItoNIFTIInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dAFNItoNIFTI', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) - - out_file = File(name_template="%s_tshift", desc='output image file name', + out_file = File(name_template="%s.nii", desc='output image file name', argstr='-prefix %s', name_source="in_file") - - tr = traits.Str(desc='manually set the TR' + - 'You can attach suffix "s" for seconds or "ms" for milliseconds.', - argstr='-TR %s') - - tzero = traits.Float(desc='align each slice to given time offset', - argstr='-tzero %s', - xor=['tslice']) - - tslice = traits.Int(desc='align each slice to time offset of given slice', - argstr='-slice %s', - xor=['tzero']) - - ignore = traits.Int(desc='ignore the first set of points specified', - argstr='-ignore %s') - - interp = traits.Enum(('Fourier', 'linear', 'cubic', 'quintic', 'heptic'), - desc='different interpolation methods (see 3dTShift for details)' + - ' default = Fourier', argstr='-%s') - - tpattern = traits.Str(desc='use specified slice time pattern rather than one in header', - argstr='-tpattern %s') - - rlt = traits.Bool(desc='Before shifting, remove the mean and linear trend', - argstr="-rlt") - - rltplus = traits.Bool(desc='Before shifting,' + - ' remove the mean and linear trend and ' + - 'later put back the mean', - argstr="-rlt+") - + hash_files = False -class TShift(AFNICommand): - """Shifts voxel time series from input - so that seperate slices are aligned to the same - temporal origin +class AFNItoNIFTI(AFNICommand): + """Changes AFNI format files to NIFTI format using 3dAFNItoNIFTI - For complete details, see the `3dTshift Documentation. - + see AFNI Documentation: + + this can also convert 2D or 1D data, which you can numpy.squeeze() to + remove extra dimensions Examples ======== >>> from nipype.interfaces import afni as afni - >>> tshift = afni.TShift() - >>> tshift.inputs.in_file = 'functional.nii' - >>> tshift.inputs.tpattern = 'alt+z' - >>> tshift.inputs.tzero = 0.0 - >>> tshift.cmdline #doctest: +IGNORE_UNICODE - '3dTshift -prefix functional_tshift -tpattern alt+z -tzero 0.0 functional.nii' - >>> res = tshift.run() # doctest: +SKIP + >>> a2n = afni.AFNItoNIFTI() + >>> a2n.inputs.in_file = 'afni_output.3D' + >>> a2n.inputs.out_file = 'afni_output.nii' + >>> a2n.cmdline # doctest: +IGNORE_UNICODE + '3dAFNItoNIFTI -prefix afni_output.nii afni_output.3D' """ - _cmd = '3dTshift' - input_spec = TShiftInputSpec - output_spec = AFNICommandOutputSpec - - -class RefitInputSpec(CommandLineInputSpec): - in_file = File(desc='input file to 3drefit', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=True) - - deoblique = traits.Bool(desc='replace current transformation' + - ' matrix with cardinal matrix', - argstr='-deoblique') - - xorigin = traits.Str(desc='x distance for edge voxel offset', - argstr='-xorigin %s') - - yorigin = traits.Str(desc='y distance for edge voxel offset', - argstr='-yorigin %s') - zorigin = traits.Str(desc='z distance for edge voxel offset', - argstr='-zorigin %s') - - xdel = traits.Float(desc='new x voxel dimension in mm', - argstr='-xdel %f') - - ydel = traits.Float(desc='new y voxel dimension in mm', - argstr='-ydel %f') - - zdel = traits.Float(desc='new z voxel dimension in mm', - argstr='-zdel %f') - - space = traits.Enum('TLRC', 'MNI', 'ORIG', - argstr='-space %s', - desc='Associates the dataset with a specific' + - ' template type, e.g. TLRC, MNI, ORIG') - - -class Refit(AFNICommandBase): - """Changes some of the information inside a 3D dataset's header - - For complete details, see the `3drefit Documentation. - - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> refit = afni.Refit() - >>> refit.inputs.in_file = 'structural.nii' - >>> refit.inputs.deoblique = True - >>> refit.cmdline # doctest: +IGNORE_UNICODE - '3drefit -deoblique structural.nii' - >>> res = refit.run() # doctest: +SKIP - - """ - _cmd = '3drefit' - input_spec = RefitInputSpec + _cmd = '3dAFNItoNIFTI' + input_spec = AFNItoNIFTIInputSpec output_spec = AFNICommandOutputSpec - def _list_outputs(self): - outputs = self.output_spec().get() - outputs["out_file"] = os.path.abspath(self.inputs.in_file) - return outputs + def _overload_extension(self, value): + path, base, ext = split_filename(value) + if ext.lower() not in [".1d", ".nii.gz", ".1D"]: + ext = ext + ".nii" + return os.path.join(path, base + ext) + def _gen_filename(self, name): + return os.path.abspath(super(AFNItoNIFTI, self)._gen_filename(name)) -class WarpInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dWarp', - argstr='%s', +class AllineateInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dAllineate', + argstr='-source %s', position=-1, mandatory=True, exists=True, copyfile=False) + reference = File( + exists=True, + argstr='-base %s', + desc='file to be used as reference, the first volume will be used if '\ + 'not given the reference will be the first volume of in_file.') + out_file = File( + desc='output file from 3dAllineate', + argstr='-prefix %s', + position=-2, + name_source='%s_allineate', + genfile=True) - out_file = File(name_template="%s_warp", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - tta2mni = traits.Bool(desc='transform dataset from Talairach to MNI152', - argstr='-tta2mni') + out_param_file = File( + argstr='-1Dparam_save %s', + desc='Save the warp parameters in ASCII (.1D) format.') + in_param_file = File( + exists=True, + argstr='-1Dparam_apply %s', + desc="""Read warp parameters from file and apply them to + the source dataset, and produce a new dataset""") + out_matrix = File( + argstr='-1Dmatrix_save %s', + desc='Save the transformation matrix for each volume.') + in_matrix = File(desc='matrix to align input file', + argstr='-1Dmatrix_apply %s', + position=-3) - mni2tta = traits.Bool(desc='transform dataset from MNI152 to Talaraich', - argstr='-mni2tta') + _cost_funcs = [ + 'leastsq', 'ls', + 'mutualinfo', 'mi', + 'corratio_mul', 'crM', + 'norm_mutualinfo', 'nmi', + 'hellinger', 'hel', + 'corratio_add', 'crA', + 'corratio_uns', 'crU'] - matparent = File(desc="apply transformation from 3dWarpDrive", - argstr="-matparent %s", - exists=True) + cost = traits.Enum( + *_cost_funcs, argstr='-cost %s', + desc="""Defines the 'cost' function that defines the matching + between the source and the base""") + _interp_funcs = [ + 'nearestneighbour', 'linear', 'cubic', 'quintic', 'wsinc5'] + interpolation = traits.Enum( + *_interp_funcs[:-1], argstr='-interp %s', + desc='Defines interpolation method to use during matching') + final_interpolation = traits.Enum( + *_interp_funcs, argstr='-final %s', + desc='Defines interpolation method used to create the output dataset') - deoblique = traits.Bool(desc='transform dataset from oblique to cardinal', - argstr='-deoblique') + # TECHNICAL OPTIONS (used for fine control of the program): + nmatch = traits.Int( + argstr='-nmatch %d', + desc='Use at most n scattered points to match the datasets.') + no_pad = traits.Bool( + argstr='-nopad', + desc='Do not use zero-padding on the base image.') + zclip = traits.Bool( + argstr='-zclip', + desc='Replace negative values in the input datasets (source & base) '\ + 'with zero.') + convergence = traits.Float( + argstr='-conv %f', + desc='Convergence test in millimeters (default 0.05mm).') + usetemp = traits.Bool(argstr='-usetemp', desc='temporary file use') + check = traits.List( + traits.Enum(*_cost_funcs), argstr='-check %s', + desc="""After cost functional optimization is done, start at the + final parameters and RE-optimize using this new cost functions. + If the results are too different, a warning message will be + printed. However, the final parameters from the original + optimization will be used to create the output dataset.""") - interp = traits.Enum(('linear', 'cubic', 'NN', 'quintic'), - desc='spatial interpolation methods [default = linear]', - argstr='-%s') + # ** PARAMETERS THAT AFFECT THE COST OPTIMIZATION STRATEGY ** + one_pass = traits.Bool( + argstr='-onepass', + desc="""Use only the refining pass -- do not try a coarse + resolution pass first. Useful if you know that only + small amounts of image alignment are needed.""") + two_pass = traits.Bool( + argstr='-twopass', + desc="""Use a two pass alignment strategy for all volumes, searching + for a large rotation+shift and then refining the alignment.""") + two_blur = traits.Float( + argstr='-twoblur', + desc='Set the blurring radius for the first pass in mm.') + two_first = traits.Bool( + argstr='-twofirst', + desc="""Use -twopass on the first image to be registered, and + then on all subsequent images from the source dataset, + use results from the first image's coarse pass to start + the fine pass.""") + two_best = traits.Int( + argstr='-twobest %d', + desc="""In the coarse pass, use the best 'bb' set of initial + points to search for the starting point for the fine + pass. If bb==0, then no search is made for the best + starting point, and the identity transformation is + used as the starting point. [Default=5; min=0 max=11]""") + fine_blur = traits.Float( + argstr='-fineblur %f', + desc="""Set the blurring radius to use in the fine resolution + pass to 'x' mm. A small amount (1-2 mm?) of blurring at + the fine step may help with convergence, if there is + some problem, especially if the base volume is very noisy. + [Default == 0 mm = no blurring at the final alignment pass]""") - gridset = File(desc="copy grid of specified dataset", - argstr="-gridset %s", - exists=True) + center_of_mass = Str( + argstr='-cmass%s', + desc='Use the center-of-mass calculation to bracket the shifts.') + autoweight = Str( + argstr='-autoweight%s', + desc="""Compute a weight function using the 3dAutomask + algorithm plus some blurring of the base image.""") + automask = traits.Int( + argstr='-automask+%d', + desc="""Compute a mask function, set a value for dilation or 0.""") + autobox = traits.Bool( + argstr='-autobox', + desc="""Expand the -automask function to enclose a rectangular + box that holds the irregular mask.""") + nomask = traits.Bool( + argstr='-nomask', + desc="""Don't compute the autoweight/mask; if -weight is not + also used, then every voxel will be counted equally.""") + weight_file = File( + argstr='-weight %s', exists=True, + desc="""Set the weighting for each voxel in the base dataset; + larger weights mean that voxel count more in the cost function. + Must be defined on the same grid as the base dataset""") + out_weight_file = traits.File( + argstr='-wtprefix %s', + desc="""Write the weight volume to disk as a dataset""") - newgrid = traits.Float(desc="specify grid of this size (mm)", - argstr="-newgrid %f") + source_mask = File( + exists=True, argstr='-source_mask %s', + desc='mask the input dataset') + source_automask = traits.Int( + argstr='-source_automask+%d', + desc='Automatically mask the source dataset with dilation or 0.') + warp_type = traits.Enum( + 'shift_only', 'shift_rotate', 'shift_rotate_scale', 'affine_general', + argstr='-warp %s', + desc='Set the warp type.') + warpfreeze = traits.Bool( + argstr='-warpfreeze', + desc='Freeze the non-rigid body parameters after first volume.') + replacebase = traits.Bool( + argstr='-replacebase', + desc="""If the source has more than one volume, then after the first + volume is aligned to the base""") + replacemeth = traits.Enum( + *_cost_funcs, + argstr='-replacemeth %s', + desc="""After first volume is aligned, switch method for later volumes. + For use with '-replacebase'.""") + epi = traits.Bool( + argstr='-EPI', + desc="""Treat the source dataset as being composed of warped + EPI slices, and the base as comprising anatomically + 'true' images. Only phase-encoding direction image + shearing and scaling will be allowed with this option.""") + master = File( + exists=True, argstr='-master %s', + desc='Write the output dataset on the same grid as this file') + newgrid = traits.Float( + argstr='-newgrid %f', + desc='Write the output dataset using isotropic grid spacing in mm') - zpad = traits.Int(desc="pad input dataset with N planes" + - " of zero on all sides.", - argstr="-zpad %d") + # Non-linear experimental + _nwarp_types = ['bilinear', + 'cubic', 'quintic', 'heptic', 'nonic', + 'poly3', 'poly5', 'poly7', 'poly9'] # same non-hellenistic + nwarp = traits.Enum( + *_nwarp_types, argstr='-nwarp %s', + desc='Experimental nonlinear warping: bilinear or legendre poly.') + _dirs = ['X', 'Y', 'Z', 'I', 'J', 'K'] + nwarp_fixmot = traits.List( + traits.Enum(*_dirs), + argstr='-nwarp_fixmot%s', + desc='To fix motion along directions.') + nwarp_fixdep = traits.List( + traits.Enum(*_dirs), + argstr='-nwarp_fixdep%s', + desc='To fix non-linear warp dependency along directions.') +class AllineateOutputSpec(TraitedSpec): + out_file = File(desc='output image file name') + matrix = File(desc='matrix to align input file') -class Warp(AFNICommand): - """Use 3dWarp for spatially transforming a dataset - For complete details, see the `3dWarp Documentation. - `_ +class Allineate(AFNICommand): + """Program to align one dataset (the 'source') to a base dataset + + For complete details, see the `3dAllineate Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> warp = afni.Warp() - >>> warp.inputs.in_file = 'structural.nii' - >>> warp.inputs.deoblique = True - >>> warp.inputs.out_file = "trans.nii.gz" - >>> warp.cmdline # doctest: +IGNORE_UNICODE - '3dWarp -deoblique -prefix trans.nii.gz structural.nii' - - >>> warp_2 = afni.Warp() - >>> warp_2.inputs.in_file = 'structural.nii' - >>> warp_2.inputs.newgrid = 1.0 - >>> warp_2.inputs.out_file = "trans.nii.gz" - >>> warp_2.cmdline # doctest: +IGNORE_UNICODE - '3dWarp -newgrid 1.000000 -prefix trans.nii.gz structural.nii' + >>> allineate = afni.Allineate() + >>> allineate.inputs.in_file = 'functional.nii' + >>> allineate.inputs.out_file= 'functional_allineate.nii' + >>> allineate.inputs.in_matrix= 'cmatrix.mat' + >>> res = allineate.run() # doctest: +SKIP """ - _cmd = '3dWarp' - input_spec = WarpInputSpec - output_spec = AFNICommandOutputSpec - - -class ResampleInputSpec(AFNICommandInputSpec): - - in_file = File(desc='input file to 3dresample', - argstr='-inset %s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_resample", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - orientation = traits.Str(desc='new orientation code', - argstr='-orient %s') - - resample_mode = traits.Enum('NN', 'Li', 'Cu', 'Bk', - argstr='-rmode %s', - desc="resampling method from set {'NN', 'Li', 'Cu', 'Bk'}. These are for 'Nearest Neighbor', 'Linear', 'Cubic' and 'Blocky' interpolation, respectively. Default is NN.") - - voxel_size = traits.Tuple(*[traits.Float()] * 3, - argstr='-dxyz %f %f %f', - desc="resample to new dx, dy and dz") - master = traits.File(argstr='-master %s', - desc='align dataset grid to a reference file') - - - -class Resample(AFNICommand): - """Resample or reorient an image using AFNI 3dresample command - - For complete details, see the `3dresample Documentation. - `_ + _cmd = '3dAllineate' + input_spec = AllineateInputSpec + output_spec = AllineateOutputSpec - Examples - ======== + def _format_arg(self, name, trait_spec, value): + if name == 'nwarp_fixmot' or name == 'nwarp_fixdep': + arg = ' '.join([trait_spec.argstr % v for v in value]) + return arg + return super(Allineate, self)._format_arg(name, trait_spec, value) - >>> from nipype.interfaces import afni as afni - >>> resample = afni.Resample() - >>> resample.inputs.in_file = 'functional.nii' - >>> resample.inputs.orientation= 'RPI' - >>> resample.inputs.outputtype = "NIFTI" - >>> resample.cmdline # doctest: +IGNORE_UNICODE - '3dresample -orient RPI -prefix functional_resample.nii -inset functional.nii' - >>> res = resample.run() # doctest: +SKIP + def _list_outputs(self): + outputs = self.output_spec().get() + if not isdefined(self.inputs.out_file): + outputs['out_file'] = self._gen_filename(self.inputs.in_file, + suffix=self.inputs.suffix) + else: + outputs['out_file'] = os.path.abspath(self.inputs.out_file) - """ + if isdefined(self.inputs.out_matrix): + outputs['matrix'] = os.path.abspath(os.path.join(os.getcwd(),\ + self.inputs.out_matrix +".aff12.1D")) + return outputs - _cmd = '3dresample' - input_spec = ResampleInputSpec - output_spec = AFNICommandOutputSpec + def _gen_filename(self, name): + if name == 'out_file': + return self._list_outputs()[name] class AutoTcorrelateInputSpec(AFNICommandInputSpec): @@ -396,9 +360,9 @@ class AutoTcorrelateInputSpec(AFNICommandInputSpec): argstr="-mask_source %s", xor=['mask_only_targets']) - out_file = File(name_template="%s_similarity_matrix.1D", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - + out_file = File(name_template='%s_similarity_matrix.1D', + desc='output image file name', + argstr='-prefix %s', name_source='in_file') class AutoTcorrelate(AFNICommand): @@ -431,500 +395,553 @@ def _overload_extension(self, value, name=None): return os.path.join(path, base + ext) -class TStatInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dTstat', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_tstat", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - mask = File(desc='mask file', - argstr='-mask %s', - exists=True) - options = traits.Str(desc='selected statistical output', - argstr='%s') - - +class AutoboxInputSpec(AFNICommandInputSpec): + in_file = File(exists=True, mandatory=True, argstr='-input %s', + desc='input file', copyfile=False) + padding = traits.Int( + argstr='-npad %d', + desc='Number of extra voxels to pad on each side of box') + out_file = File(argstr="-prefix %s", name_source="in_file") + no_clustering = traits.Bool( + argstr='-noclust', + desc="""Don't do any clustering to find box. Any non-zero + voxel will be preserved in the cropped volume. + The default method uses some clustering to find the + cropping box, and will clip off small isolated blobs.""") -class TStat(AFNICommand): - """Compute voxel-wise statistics using AFNI 3dTstat command - For complete details, see the `3dTstat Documentation. - `_ +class AutoboxOutputSpec(TraitedSpec): # out_file not mandatory + x_min = traits.Int() + x_max = traits.Int() + y_min = traits.Int() + y_max = traits.Int() + z_min = traits.Int() + z_max = traits.Int() + + out_file = File(desc='output file') + + +class Autobox(AFNICommand): + """ Computes size of a box that fits around the volume. + Also can be used to crop the volume to that box. + + For complete details, see the `3dAutobox Documentation. + Examples ======== >>> from nipype.interfaces import afni as afni - >>> tstat = afni.TStat() - >>> tstat.inputs.in_file = 'functional.nii' - >>> tstat.inputs.args= '-mean' - >>> tstat.inputs.out_file = "stats" - >>> tstat.cmdline # doctest: +IGNORE_UNICODE - '3dTstat -mean -prefix stats functional.nii' - >>> res = tstat.run() # doctest: +SKIP + >>> abox = afni.Autobox() + >>> abox.inputs.in_file = 'structural.nii' + >>> abox.inputs.padding = 5 + >>> res = abox.run() # doctest: +SKIP """ - _cmd = '3dTstat' - input_spec = TStatInputSpec - output_spec = AFNICommandOutputSpec + _cmd = '3dAutobox' + input_spec = AutoboxInputSpec + output_spec = AutoboxOutputSpec + def aggregate_outputs(self, runtime=None, needed_outputs=None): + outputs = self._outputs() + pattern = 'x=(?P-?\d+)\.\.(?P-?\d+) '\ + 'y=(?P-?\d+)\.\.(?P-?\d+) '\ + 'z=(?P-?\d+)\.\.(?P-?\d+)' + for line in runtime.stderr.split('\n'): + m = re.search(pattern, line) + if m: + d = m.groupdict() + for k in list(d.keys()): + d[k] = int(d[k]) + outputs.set(**d) + outputs.set(out_file=self._gen_filename('out_file')) + return outputs -class DetrendInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dDetrend', + def _gen_filename(self, name): + if name == 'out_file' and (not isdefined(self.inputs.out_file)): + return Undefined + return super(Autobox, self)._gen_filename(name) + + +class AutomaskInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dAutomask', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) - out_file = File(name_template="%s_detrend", desc='output image file name', + out_file = File(name_template="%s_mask", desc='output image file name', argstr='-prefix %s', name_source="in_file") + brain_file = File(name_template="%s_masked", + desc="output file from 3dAutomask", + argstr='-apply_prefix %s', + name_source="in_file") + clfrac = traits.Float(desc='sets the clip level fraction (must be '\ + '0.1-0.9). A small value will tend to make '\ + 'the mask larger [default = 0.5].', + argstr="-clfrac %s") -class Detrend(AFNICommand): - """This program removes components from voxel time series using - linear least squares + dilate = traits.Int(desc='dilate the mask outwards', + argstr="-dilate %s") + + erode = traits.Int(desc='erode the mask inwards', + argstr="-erode %s") + + +class AutomaskOutputSpec(TraitedSpec): + out_file = File(desc='mask file', + exists=True) + + brain_file = File(desc='brain file (skull stripped)', exists=True) - For complete details, see the `3dDetrend Documentation. - `_ + +class Automask(AFNICommand): + """Create a brain-only mask of the image using AFNI 3dAutomask command + + For complete details, see the `3dAutomask Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> detrend = afni.Detrend() - >>> detrend.inputs.in_file = 'functional.nii' - >>> detrend.inputs.args = '-polort 2' - >>> detrend.inputs.outputtype = "AFNI" - >>> detrend.cmdline # doctest: +IGNORE_UNICODE - '3dDetrend -polort 2 -prefix functional_detrend functional.nii' - >>> res = detrend.run() # doctest: +SKIP + >>> automask = afni.Automask() + >>> automask.inputs.in_file = 'functional.nii' + >>> automask.inputs.dilate = 1 + >>> automask.inputs.outputtype = "NIFTI" + >>> automask.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dAutomask -apply_prefix functional_masked.nii -dilate 1 -prefix functional_mask.nii functional.nii' + >>> res = automask.run() # doctest: +SKIP """ - _cmd = '3dDetrend' - input_spec = DetrendInputSpec - output_spec = AFNICommandOutputSpec - - -class DespikeInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dDespike', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) + _cmd = '3dAutomask' + input_spec = AutomaskInputSpec + output_spec = AutomaskOutputSpec - out_file = File(name_template="%s_despike", desc='output image file name', - argstr='-prefix %s', name_source="in_file") +class BandpassInputSpec(AFNICommandInputSpec): + in_file = File( + desc='input file to 3dBandpass', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_bp', + desc='output file from 3dBandpass', + argstr='-prefix %s', + position=1, + name_source='in_file', + genfile=True) + lowpass = traits.Float( + desc='lowpass', + argstr='%f', + position=-2, + mandatory=True) + highpass = traits.Float( + desc='highpass', + argstr='%f', + position=-3, + mandatory=True) + mask = File( + desc='mask file', + position=2, + argstr='-mask %s', + exists=True) + despike = traits.Bool( + argstr='-despike', + desc="""Despike each time series before other processing. + ++ Hopefully, you don't actually need to do this, + which is why it is optional.""") + orthogonalize_file = InputMultiPath( + File(exists=True), + argstr="-ort %s", + desc="""Also orthogonalize input to columns in f.1D + ++ Multiple '-ort' options are allowed.""") + orthogonalize_dset = File( + exists=True, + argstr="-dsort %s", + desc="""Orthogonalize each voxel to the corresponding + voxel time series in dataset 'fset', which must + have the same spatial and temporal grid structure + as the main input dataset. + ++ At present, only one '-dsort' option is allowed.""") + no_detrend = traits.Bool( + argstr='-nodetrend', + desc="""Skip the quadratic detrending of the input that + occurs before the FFT-based bandpassing. + ++ You would only want to do this if the dataset + had been detrended already in some other program.""") + tr = traits.Float( + argstr="-dt %f", + desc="set time step (TR) in sec [default=from dataset header]") + nfft = traits.Int( + argstr='-nfft %d', + desc="set the FFT length [must be a legal value]") + normalize = traits.Bool( + argstr='-norm', + desc="""Make all output time series have L2 norm = 1 + ++ i.e., sum of squares = 1""") + automask = traits.Bool( + argstr='-automask', + desc="Create a mask from the input dataset") + blur = traits.Float( + argstr='-blur %f', + desc="""Blur (inside the mask only) with a filter + width (FWHM) of 'fff' millimeters.""") + localPV = traits.Float( + argstr='-localPV %f', + desc="""Replace each vector by the local Principal Vector + (AKA first singular vector) from a neighborhood + of radius 'rrr' millimiters. + ++ Note that the PV time series is L2 normalized. + ++ This option is mostly for Bob Cox to have fun with.""") + notrans = traits.Bool( + argstr='-notrans', + desc="""Don't check for initial positive transients in the data: + ++ The test is a little slow, so skipping it is OK, + if you KNOW the data time series are transient-free.""") -class Despike(AFNICommand): - """Removes 'spikes' from the 3D+time input dataset +class Bandpass(AFNICommand): + """Program to lowpass and/or highpass each voxel time series in a + dataset, offering more/different options than Fourier - For complete details, see the `3dDespike Documentation. - `_ + For complete details, see the `3dBandpass Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> despike = afni.Despike() - >>> despike.inputs.in_file = 'functional.nii' - >>> despike.cmdline # doctest: +IGNORE_UNICODE - '3dDespike -prefix functional_despike functional.nii' - >>> res = despike.run() # doctest: +SKIP + >>> from nipype.testing import example_data + >>> bandpass = afni.Bandpass() + >>> bandpass.inputs.in_file = example_data('functional.nii') + >>> bandpass.inputs.highpass = 0.005 + >>> bandpass.inputs.lowpass = 0.1 + >>> res = bandpass.run() # doctest: +SKIP """ - _cmd = '3dDespike' - input_spec = DespikeInputSpec + _cmd = '3dBandpass' + input_spec = BandpassInputSpec output_spec = AFNICommandOutputSpec -class CentralityInputSpec(AFNICommandInputSpec): - """Common input spec class for all centrality-related commmands - """ - - - mask = File(desc='mask file to mask input data', - argstr="-mask %s", - exists=True) - - thresh = traits.Float(desc='threshold to exclude connections where corr <= thresh', - argstr='-thresh %f') - - polort = traits.Int(desc='', argstr='-polort %d') - - autoclip = traits.Bool(desc='Clip off low-intensity regions in the dataset', - argstr='-autoclip') +class BlurInMaskInputSpec(AFNICommandInputSpec): + in_file = File( + desc='input file to 3dSkullStrip', + argstr='-input %s', + position=1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File(name_template='%s_blur', desc='output to the file', + argstr='-prefix %s', name_source='in_file', position=-1) + mask = File( + desc='Mask dataset, if desired. Blurring will occur only within the '\ + 'mask. Voxels NOT in the mask will be set to zero in the output.', + argstr='-mask %s') + multimask = File( + desc='Multi-mask dataset -- each distinct nonzero value in dataset '\ + 'will be treated as a separate mask for blurring purposes.', + argstr='-Mmask %s') + automask = traits.Bool( + desc='Create an automask from the input dataset.', + argstr='-automask') + fwhm = traits.Float( + desc='fwhm kernel size', + argstr='-FWHM %f', + mandatory=True) + preserve = traits.Bool( + desc='Normally, voxels not in the mask will be set to zero in the '\ + 'output. If you want the original values in the dataset to be '\ + 'preserved in the output, use this option.', + argstr='-preserve') + float_out = traits.Bool( + desc='Save dataset as floats, no matter what the input data type is.', + argstr='-float') + options = Str(desc='options', argstr='%s', position=2) - automask = traits.Bool(desc='Mask the dataset to target brain-only voxels', - argstr='-automask') +class BlurInMask(AFNICommand): + """ Blurs a dataset spatially inside a mask. That's all. Experimental. -class DegreeCentralityInputSpec(CentralityInputSpec): - """DegreeCentrality inputspec - """ + For complete details, see the `3dBlurInMask Documentation. + - in_file = File(desc='input file to 3dDegreeCentrality', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) + Examples + ======== - sparsity = traits.Float(desc='only take the top percent of connections', - argstr='-sparsity %f') + >>> from nipype.interfaces import afni as afni + >>> bim = afni.BlurInMask() + >>> bim.inputs.in_file = 'functional.nii' + >>> bim.inputs.mask = 'mask.nii' + >>> bim.inputs.fwhm = 5.0 + >>> bim.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dBlurInMask -input functional.nii -FWHM 5.000000 -mask mask.nii -prefix functional_blur' + >>> res = bim.run() # doctest: +SKIP - oned_file = traits.Str(desc='output filepath to text dump of correlation matrix', - argstr='-out1D %s') + """ + _cmd = '3dBlurInMask' + input_spec = BlurInMaskInputSpec + output_spec = AFNICommandOutputSpec -class DegreeCentralityOutputSpec(AFNICommandOutputSpec): - """DegreeCentrality outputspec - """ - oned_file = File(desc='The text output of the similarity matrix computed'\ - 'after thresholding with one-dimensional and '\ - 'ijk voxel indices, correlations, image extents, '\ - 'and affine matrix') +class BlurToFWHMInputSpec(AFNICommandInputSpec): + in_file = File(desc='The dataset that will be smoothed', + argstr='-input %s', mandatory=True, exists=True) + automask = traits.Bool(desc='Create an automask from the input dataset.', + argstr='-automask') + fwhm = traits.Float(desc='Blur until the 3D FWHM reaches this value (in mm)', + argstr='-FWHM %f') + fwhmxy = traits.Float(desc='Blur until the 2D (x,y)-plane FWHM reaches '\ + 'this value (in mm)', + argstr='-FWHMxy %f') + blurmaster = File(desc='The dataset whose smoothness controls the process.', + argstr='-blurmaster %s', exists=True) + mask = File(desc='Mask dataset, if desired. Voxels NOT in mask will be '\ + 'set to zero in output.', argstr='-blurmaster %s', + exists=True) -class DegreeCentrality(AFNICommand): - """Performs degree centrality on a dataset using a given maskfile - via 3dDegreeCentrality +class BlurToFWHM(AFNICommand): + """Blurs a 'master' dataset until it reaches a specified FWHM smoothness + (approximately). - For complete details, see the `3dDegreeCentrality Documentation. - + For complete details, see the `to3d Documentation + `_ Examples ======== - >>> from nipype.interfaces import afni as afni - >>> degree = afni.DegreeCentrality() - >>> degree.inputs.in_file = 'functional.nii' - >>> degree.inputs.mask = 'mask.nii' - >>> degree.inputs.sparsity = 1 # keep the top one percent of connections - >>> degree.inputs.out_file = 'out.nii' - >>> degree.cmdline # doctest: +IGNORE_UNICODE - '3dDegreeCentrality -mask mask.nii -prefix out.nii -sparsity 1.000000 functional.nii' - >>> res = degree.run() # doctest: +SKIP - """ - - _cmd = '3dDegreeCentrality' - input_spec = DegreeCentralityInputSpec - output_spec = DegreeCentralityOutputSpec - - # Re-define generated inputs - def _list_outputs(self): - # Import packages - import os - - # Update outputs dictionary if oned file is defined - outputs = super(DegreeCentrality, self)._list_outputs() - if self.inputs.oned_file: - outputs['oned_file'] = os.path.abspath(self.inputs.oned_file) - - return outputs - + >>> from nipype.interfaces import afni + >>> blur = afni.preprocess.BlurToFWHM() + >>> blur.inputs.in_file = 'epi.nii' + >>> blur.inputs.fwhm = 2.5 + >>> blur.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dBlurToFWHM -FWHM 2.500000 -input epi.nii -prefix epi_afni' -class ECMInputSpec(CentralityInputSpec): - """ECM inputspec """ + _cmd = '3dBlurToFWHM' + input_spec = BlurToFWHMInputSpec + output_spec = AFNICommandOutputSpec - in_file = File(desc='input file to 3dECM', + +class BrickStatInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dmaskave', argstr='%s', position=-1, mandatory=True, - exists=True, - copyfile=False) - - sparsity = traits.Float(desc='only take the top percent of connections', - argstr='-sparsity %f') - - full = traits.Bool(desc='Full power method; enables thresholding; '\ - 'automatically selected if -thresh or -sparsity '\ - 'are set', - argstr='-full') - - fecm = traits.Bool(desc='Fast centrality method; substantial speed '\ - 'increase but cannot accomodate thresholding; '\ - 'automatically selected if -thresh or -sparsity '\ - 'are not set', - argstr='-fecm') - - shift = traits.Float(desc='shift correlation coefficients in similarity '\ - 'matrix to enforce non-negativity, s >= 0.0; '\ - 'default = 0.0 for -full, 1.0 for -fecm', - argstr='-shift %f') - - scale = traits.Float(desc='scale correlation coefficients in similarity '\ - 'matrix to after shifting, x >= 0.0; '\ - 'default = 1.0 for -full, 0.5 for -fecm', - argstr='-scale %f') + exists=True) - eps = traits.Float(desc='sets the stopping criterion for the power '\ - 'iteration; l2|v_old - v_new| < eps*|v_old|; '\ - 'default = 0.001', - argstr='-eps %f') + mask = File(desc='-mask dset = use dset as mask to include/exclude voxels', + argstr='-mask %s', + position=2, + exists=True) - max_iter = traits.Int(desc='sets the maximum number of iterations to use '\ - 'in the power iteration; default = 1000', - argstr='-max_iter %d') + min = traits.Bool(desc='print the minimum value in dataset', + argstr='-min', + position=1) - memory = traits.Float(desc='Limit memory consumption on system by setting '\ - 'the amount of GB to limit the algorithm to; '\ - 'default = 2GB', - argstr='-memory %f') +class BrickStatOutputSpec(TraitedSpec): + min_val = traits.Float(desc='output') -class ECM(AFNICommand): - """Performs degree centrality on a dataset using a given maskfile - via the 3dLFCD command +class BrickStat(AFNICommand): + """Compute maximum and/or minimum voxel values of an input dataset - For complete details, see the `3dECM Documentation. - + For complete details, see the `3dBrickStat Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> ecm = afni.ECM() - >>> ecm.inputs.in_file = 'functional.nii' - >>> ecm.inputs.mask = 'mask.nii' - >>> ecm.inputs.sparsity = 0.1 # keep top 0.1% of connections - >>> ecm.inputs.out_file = 'out.nii' - >>> ecm.cmdline # doctest: +IGNORE_UNICODE - '3dECM -mask mask.nii -prefix out.nii -sparsity 0.100000 functional.nii' - >>> res = ecm.run() # doctest: +SKIP + >>> brickstat = afni.BrickStat() + >>> brickstat.inputs.in_file = 'functional.nii' + >>> brickstat.inputs.mask = 'skeleton_mask.nii.gz' + >>> brickstat.inputs.min = True + >>> res = brickstat.run() # doctest: +SKIP + """ + _cmd = '3dBrickStat' + input_spec = BrickStatInputSpec + output_spec = BrickStatOutputSpec - _cmd = '3dECM' - input_spec = ECMInputSpec - output_spec = AFNICommandOutputSpec + def aggregate_outputs(self, runtime=None, needed_outputs=None): + outputs = self._outputs() -class LFCDInputSpec(CentralityInputSpec): - """LFCD inputspec - """ + outfile = os.path.join(os.getcwd(), 'stat_result.json') - in_file = File(desc='input file to 3dLFCD', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) + if runtime is None: + try: + min_val = load_json(outfile)['stat'] + except IOError: + return self.run().outputs + else: + min_val = [] + for line in runtime.stdout.split('\n'): + if line: + values = line.split() + if len(values) > 1: + min_val.append([float(val) for val in values]) + else: + min_val.extend([float(val) for val in values]) + if len(min_val) == 1: + min_val = min_val[0] + save_json(outfile, dict(stat=min_val)) + outputs.min_val = min_val + return outputs -class LFCD(AFNICommand): - """Performs degree centrality on a dataset using a given maskfile - via the 3dLFCD command - For complete details, see the `3dLFCD Documentation. - +class CalcInputSpec(AFNICommandInputSpec): + in_file_a = File(desc='input file to 3dcalc', + argstr='-a %s', position=0, mandatory=True, exists=True) + in_file_b = File(desc='operand file to 3dcalc', + argstr=' -b %s', position=1, exists=True) + in_file_c = File(desc='operand file to 3dcalc', + argstr=' -c %s', position=2, exists=True) + out_file = File(name_template="%s_calc", desc='output image file name', + argstr='-prefix %s', name_source="in_file_a") + expr = Str(desc='expr', argstr='-expr "%s"', position=3, + mandatory=True) + start_idx = traits.Int(desc='start index for in_file_a', + requires=['stop_idx']) + stop_idx = traits.Int(desc='stop index for in_file_a', + requires=['start_idx']) + single_idx = traits.Int(desc='volume index for in_file_a') + other = File(desc='other options', argstr='') + + +class Calc(AFNICommand): + """This program does voxel-by-voxel arithmetic on 3D datasets + + For complete details, see the `3dcalc Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> lfcd = afni.LFCD() - >>> lfcd.inputs.in_file = 'functional.nii' - >>> lfcd.inputs.mask = 'mask.nii' - >>> lfcd.inputs.thresh = 0.8 # keep all connections with corr >= 0.8 - >>> lfcd.inputs.out_file = 'out.nii' - >>> lfcd.cmdline # doctest: +IGNORE_UNICODE - '3dLFCD -mask mask.nii -prefix out.nii -thresh 0.800000 functional.nii' - >>> res = lfcd.run() # doctest: +SKIP + >>> calc = afni.Calc() + >>> calc.inputs.in_file_a = 'functional.nii' + >>> calc.inputs.in_file_b = 'functional2.nii' + >>> calc.inputs.expr='a*b' + >>> calc.inputs.out_file = 'functional_calc.nii.gz' + >>> calc.inputs.outputtype = "NIFTI" + >>> calc.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dcalc -a functional.nii -b functional2.nii -expr "a*b" -prefix functional_calc.nii.gz' + """ - _cmd = '3dLFCD' - input_spec = LFCDInputSpec + _cmd = '3dcalc' + input_spec = CalcInputSpec output_spec = AFNICommandOutputSpec + def _format_arg(self, name, trait_spec, value): + if name == 'in_file_a': + arg = trait_spec.argstr % value + if isdefined(self.inputs.start_idx): + arg += '[%d..%d]' % (self.inputs.start_idx, + self.inputs.stop_idx) + if isdefined(self.inputs.single_idx): + arg += '[%d]' % (self.inputs.single_idx) + return arg + return super(Calc, self)._format_arg(name, trait_spec, value) -class AutomaskInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dAutomask', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_mask", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - brain_file = File(name_template="%s_masked", - desc="output file from 3dAutomask", - argstr='-apply_prefix %s', - name_source="in_file") - - clfrac = traits.Float(desc='sets the clip level fraction' + - ' (must be 0.1-0.9). ' + - 'A small value will tend to make the mask larger [default = 0.5].', - argstr="-clfrac %s") - - dilate = traits.Int(desc='dilate the mask outwards', - argstr="-dilate %s") - - erode = traits.Int(desc='erode the mask inwards', - argstr="-erode %s") - - -class AutomaskOutputSpec(TraitedSpec): - out_file = File(desc='mask file', - exists=True) - - brain_file = File(desc='brain file (skull stripped)', exists=True) - - - -class Automask(AFNICommand): - """Create a brain-only mask of the image using AFNI 3dAutomask command - - For complete details, see the `3dAutomask Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> automask = afni.Automask() - >>> automask.inputs.in_file = 'functional.nii' - >>> automask.inputs.dilate = 1 - >>> automask.inputs.outputtype = "NIFTI" - >>> automask.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dAutomask -apply_prefix functional_masked.nii -dilate 1 -prefix functional_mask.nii functional.nii' - >>> res = automask.run() # doctest: +SKIP - - """ - - _cmd = '3dAutomask' - input_spec = AutomaskInputSpec - output_spec = AutomaskOutputSpec - + def _parse_inputs(self, skip=None): + """Skip the arguments without argstr metadata + """ + return super(Calc, self)._parse_inputs( + skip=('start_idx', 'stop_idx', 'other')) -class VolregInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dvolreg', +class ClipLevelInputSpec(CommandLineInputSpec): + in_file = File(desc='input file to 3dClipLevel', argstr='%s', position=-1, mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_volreg", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - basefile = File(desc='base file for registration', - argstr='-base %s', - position=-6, - exists=True) - zpad = traits.Int(desc='Zeropad around the edges' + - ' by \'n\' voxels during rotations', - argstr='-zpad %d', - position=-5) - md1d_file = File(name_template='%s_md.1D', desc='max displacement output file', - argstr='-maxdisp1D %s', name_source="in_file", - keep_extension=True, position=-4) - oned_file = File(name_template='%s.1D', desc='1D movement parameters output file', - argstr='-1Dfile %s', - name_source="in_file", - keep_extension=True) - verbose = traits.Bool(desc='more detailed description of the process', - argstr='-verbose') - timeshift = traits.Bool(desc='time shift to mean slice time offset', - argstr='-tshift 0') - copyorigin = traits.Bool(desc='copy base file origin coords to output', - argstr='-twodup') - oned_matrix_save = File(name_template='%s.aff12.1D', - desc='Save the matrix transformation', - argstr='-1Dmatrix_save %s', - keep_extension=True, - name_source="in_file") + exists=True) + mfrac = traits.Float(desc='Use the number ff instead of 0.50 in the algorithm', + argstr='-mfrac %s', + position=2) -class VolregOutputSpec(TraitedSpec): - out_file = File(desc='registered file', exists=True) - md1d_file = File(desc='max displacement info file', exists=True) - oned_file = File(desc='movement parameters info file', exists=True) - oned_matrix_save = File(desc='matrix transformation from base to input', exists=True) + doall = traits.Bool(desc='Apply the algorithm to each sub-brick separately', + argstr='-doall', + position=3, + xor=('grad')) + + grad = traits.File(desc='also compute a \'gradual\' clip level as a function of voxel position, and output that to a dataset', + argstr='-grad %s', + position=3, + xor=('doall')) +class ClipLevelOutputSpec(TraitedSpec): + clip_val = traits.Float(desc='output') -class Volreg(AFNICommand): - """Register input volumes to a base volume using AFNI 3dvolreg command - For complete details, see the `3dvolreg Documentation. - `_ +class ClipLevel(AFNICommandBase): + """Estimates the value at which to clip the anatomical dataset so + that background regions are set to zero. + + For complete details, see the `3dClipLevel Documentation. + `_ Examples ======== - >>> from nipype.interfaces import afni as afni - >>> volreg = afni.Volreg() - >>> volreg.inputs.in_file = 'functional.nii' - >>> volreg.inputs.args = '-Fourier -twopass' - >>> volreg.inputs.zpad = 4 - >>> volreg.inputs.outputtype = "NIFTI" - >>> volreg.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dvolreg -Fourier -twopass -1Dfile functional.1D -1Dmatrix_save functional.aff12.1D -prefix functional_volreg.nii -zpad 4 -maxdisp1D functional_md.1D functional.nii' - >>> res = volreg.run() # doctest: +SKIP + >>> from nipype.interfaces.afni import preprocess + >>> cliplevel = preprocess.ClipLevel() + >>> cliplevel.inputs.in_file = 'anatomical.nii' + >>> res = cliplevel.run() # doctest: +SKIP """ + _cmd = '3dClipLevel' + input_spec = ClipLevelInputSpec + output_spec = ClipLevelOutputSpec - _cmd = '3dvolreg' - input_spec = VolregInputSpec - output_spec = VolregOutputSpec - - -class MergeInputSpec(AFNICommandInputSpec): - in_files = InputMultiPath( - File(desc='input file to 3dmerge', exists=True), - argstr='%s', - position=-1, - mandatory=True, - copyfile=False) - out_file = File(name_template="%s_merge", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - doall = traits.Bool(desc='apply options to all sub-bricks in dataset', - argstr='-doall') - blurfwhm = traits.Int(desc='FWHM blur value (mm)', - argstr='-1blur_fwhm %d', - units='mm') - - -class Merge(AFNICommand): - """Merge or edit volumes using AFNI 3dmerge command + def aggregate_outputs(self, runtime=None, needed_outputs=None): - For complete details, see the `3dmerge Documentation. - `_ + outputs = self._outputs() - Examples - ======== + outfile = os.path.join(os.getcwd(), 'stat_result.json') - >>> from nipype.interfaces import afni as afni - >>> merge = afni.Merge() - >>> merge.inputs.in_files = ['functional.nii', 'functional2.nii'] - >>> merge.inputs.blurfwhm = 4 - >>> merge.inputs.doall = True - >>> merge.inputs.out_file = 'e7.nii' - >>> res = merge.run() # doctest: +SKIP + if runtime is None: + try: + clip_val = load_json(outfile)['stat'] + except IOError: + return self.run().outputs + else: + clip_val = [] + for line in runtime.stdout.split('\n'): + if line: + values = line.split() + if len(values) > 1: + clip_val.append([float(val) for val in values]) + else: + clip_val.extend([float(val) for val in values]) - """ + if len(clip_val) == 1: + clip_val = clip_val[0] + save_json(outfile, dict(stat=clip_val)) + outputs.clip_val = clip_val - _cmd = '3dmerge' - input_spec = MergeInputSpec - output_spec = AFNICommandOutputSpec + return outputs class CopyInputSpec(AFNICommandInputSpec): @@ -938,7 +955,6 @@ class CopyInputSpec(AFNICommandInputSpec): argstr='%s', position=-1, name_source="in_file") - class Copy(AFNICommand): """Copies an image of one type to an image of the same or different type using 3dcopy command @@ -977,563 +993,492 @@ class Copy(AFNICommand): output_spec = AFNICommandOutputSpec -class FourierInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dFourier', +class DegreeCentralityInputSpec(CentralityInputSpec): + """DegreeCentrality inputspec + """ + + in_file = File(desc='input file to 3dDegreeCentrality', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) - out_file = File(name_template="%s_fourier", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - lowpass = traits.Float(desc='lowpass', - argstr='-lowpass %f', - position=0, - mandatory=True) - highpass = traits.Float(desc='highpass', - argstr='-highpass %f', - position=1, - mandatory=True) + sparsity = traits.Float(desc='only take the top percent of connections', + argstr='-sparsity %f') -class Fourier(AFNICommand): - """Program to lowpass and/or highpass each voxel time series in a - dataset, via the FFT + oned_file = Str(desc='output filepath to text dump of correlation matrix', + argstr='-out1D %s') - For complete details, see the `3dFourier Documentation. - `_ - Examples - ======== +class DegreeCentralityOutputSpec(AFNICommandOutputSpec): + """DegreeCentrality outputspec + """ - >>> from nipype.interfaces import afni as afni - >>> fourier = afni.Fourier() - >>> fourier.inputs.in_file = 'functional.nii' - >>> fourier.inputs.args = '-retrend' - >>> fourier.inputs.highpass = 0.005 - >>> fourier.inputs.lowpass = 0.1 - >>> res = fourier.run() # doctest: +SKIP + oned_file = File(desc='The text output of the similarity matrix computed'\ + 'after thresholding with one-dimensional and '\ + 'ijk voxel indices, correlations, image extents, '\ + 'and affine matrix') + + +class DegreeCentrality(AFNICommand): + """Performs degree centrality on a dataset using a given maskfile + via 3dDegreeCentrality + For complete details, see the `3dDegreeCentrality Documentation. + + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> degree = afni.DegreeCentrality() + >>> degree.inputs.in_file = 'functional.nii' + >>> degree.inputs.mask = 'mask.nii' + >>> degree.inputs.sparsity = 1 # keep the top one percent of connections + >>> degree.inputs.out_file = 'out.nii' + >>> degree.cmdline # doctest: +IGNORE_UNICODE + '3dDegreeCentrality -mask mask.nii -prefix out.nii -sparsity 1.000000 functional.nii' + >>> res = degree.run() # doctest: +SKIP """ - _cmd = '3dFourier' - input_spec = FourierInputSpec - output_spec = AFNICommandOutputSpec + _cmd = '3dDegreeCentrality' + input_spec = DegreeCentralityInputSpec + output_spec = DegreeCentralityOutputSpec + # Re-define generated inputs + def _list_outputs(self): + # Import packages + import os -class BandpassInputSpec(AFNICommandInputSpec): - in_file = File( - desc='input file to 3dBandpass', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File( - name_template='%s_bp', - desc='output file from 3dBandpass', - argstr='-prefix %s', - position=1, - name_source='in_file', - genfile=True) - lowpass = traits.Float( - desc='lowpass', - argstr='%f', - position=-2, - mandatory=True) - highpass = traits.Float( - desc='highpass', - argstr='%f', - position=-3, - mandatory=True) - mask = File( - desc='mask file', - position=2, - argstr='-mask %s', - exists=True) - despike = traits.Bool( - argstr='-despike', - desc="""Despike each time series before other processing. - ++ Hopefully, you don't actually need to do this, - which is why it is optional.""") - orthogonalize_file = InputMultiPath( - File(exists=True), - argstr="-ort %s", - desc="""Also orthogonalize input to columns in f.1D - ++ Multiple '-ort' options are allowed.""") - orthogonalize_dset = File( - exists=True, - argstr="-dsort %s", - desc="""Orthogonalize each voxel to the corresponding - voxel time series in dataset 'fset', which must - have the same spatial and temporal grid structure - as the main input dataset. - ++ At present, only one '-dsort' option is allowed.""") - no_detrend = traits.Bool( - argstr='-nodetrend', - desc="""Skip the quadratic detrending of the input that - occurs before the FFT-based bandpassing. - ++ You would only want to do this if the dataset - had been detrended already in some other program.""") - tr = traits.Float( - argstr="-dt %f", - desc="set time step (TR) in sec [default=from dataset header]") - nfft = traits.Int( - argstr='-nfft %d', - desc="set the FFT length [must be a legal value]") - normalize = traits.Bool( - argstr='-norm', - desc="""Make all output time series have L2 norm = 1 - ++ i.e., sum of squares = 1""") - automask = traits.Bool( - argstr='-automask', - desc="Create a mask from the input dataset") - blur = traits.Float( - argstr='-blur %f', - desc="""Blur (inside the mask only) with a filter - width (FWHM) of 'fff' millimeters.""") - localPV = traits.Float( - argstr='-localPV %f', - desc="""Replace each vector by the local Principal Vector - (AKA first singular vector) from a neighborhood - of radius 'rrr' millimiters. - ++ Note that the PV time series is L2 normalized. - ++ This option is mostly for Bob Cox to have fun with.""") - notrans = traits.Bool( - argstr='-notrans', - desc="""Don't check for initial positive transients in the data: - ++ The test is a little slow, so skipping it is OK, - if you KNOW the data time series are transient-free.""") + # Update outputs dictionary if oned file is defined + outputs = super(DegreeCentrality, self)._list_outputs() + if self.inputs.oned_file: + outputs['oned_file'] = os.path.abspath(self.inputs.oned_file) + return outputs -class Bandpass(AFNICommand): - """Program to lowpass and/or highpass each voxel time series in a - dataset, offering more/different options than Fourier - For complete details, see the `3dBandpass Documentation. - `_ +class DespikeInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dDespike', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + + out_file = File(name_template="%s_despike", desc='output image file name', + argstr='-prefix %s', name_source="in_file") + + +class Despike(AFNICommand): + """Removes 'spikes' from the 3D+time input dataset + + For complete details, see the `3dDespike Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> from nipype.testing import example_data - >>> bandpass = afni.Bandpass() - >>> bandpass.inputs.in_file = example_data('functional.nii') - >>> bandpass.inputs.highpass = 0.005 - >>> bandpass.inputs.lowpass = 0.1 - >>> res = bandpass.run() # doctest: +SKIP + >>> despike = afni.Despike() + >>> despike.inputs.in_file = 'functional.nii' + >>> despike.cmdline # doctest: +IGNORE_UNICODE + '3dDespike -prefix functional_despike functional.nii' + >>> res = despike.run() # doctest: +SKIP """ - _cmd = '3dBandpass' - input_spec = BandpassInputSpec + _cmd = '3dDespike' + input_spec = DespikeInputSpec output_spec = AFNICommandOutputSpec -class ZCutUpInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dZcutup', +class DetrendInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dDetrend', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) - out_file = File(name_template="%s_zcupup", desc='output image file name', + + out_file = File(name_template="%s_detrend", desc='output image file name', argstr='-prefix %s', name_source="in_file") - keep = traits.Str(desc='slice range to keep in output', - argstr='-keep %s') -class ZCutUp(AFNICommand): - """Cut z-slices from a volume using AFNI 3dZcutup command +class Detrend(AFNICommand): + """This program removes components from voxel time series using + linear least squares - For complete details, see the `3dZcutup Documentation. - `_ + For complete details, see the `3dDetrend Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> zcutup = afni.ZCutUp() - >>> zcutup.inputs.in_file = 'functional.nii' - >>> zcutup.inputs.out_file = 'functional_zcutup.nii' - >>> zcutup.inputs.keep= '0 10' - >>> res = zcutup.run() # doctest: +SKIP + >>> detrend = afni.Detrend() + >>> detrend.inputs.in_file = 'functional.nii' + >>> detrend.inputs.args = '-polort 2' + >>> detrend.inputs.outputtype = "AFNI" + >>> detrend.cmdline # doctest: +IGNORE_UNICODE + '3dDetrend -polort 2 -prefix functional_detrend functional.nii' + >>> res = detrend.run() # doctest: +SKIP """ - _cmd = '3dZcutup' - input_spec = ZCutUpInputSpec + _cmd = '3dDetrend' + input_spec = DetrendInputSpec output_spec = AFNICommandOutputSpec -class AllineateInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dAllineate', - argstr='-source %s', +class ECMInputSpec(CentralityInputSpec): + """ECM inputspec + """ + + in_file = File(desc='input file to 3dECM', + argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) - reference = File( - exists=True, - argstr='-base %s', - desc="""file to be used as reference, the first volume will be used -if not given the reference will be the first volume of in_file.""") - out_file = File( - desc='output file from 3dAllineate', - argstr='-prefix %s', - position=-2, - name_source='%s_allineate', - genfile=True) - out_param_file = File( - argstr='-1Dparam_save %s', - desc='Save the warp parameters in ASCII (.1D) format.') - in_param_file = File( - exists=True, - argstr='-1Dparam_apply %s', - desc="""Read warp parameters from file and apply them to - the source dataset, and produce a new dataset""") - out_matrix = File( - argstr='-1Dmatrix_save %s', - desc='Save the transformation matrix for each volume.') - in_matrix = File(desc='matrix to align input file', - argstr='-1Dmatrix_apply %s', - position=-3) + sparsity = traits.Float(desc='only take the top percent of connections', + argstr='-sparsity %f') - _cost_funcs = [ - 'leastsq', 'ls', - 'mutualinfo', 'mi', - 'corratio_mul', 'crM', - 'norm_mutualinfo', 'nmi', - 'hellinger', 'hel', - 'corratio_add', 'crA', - 'corratio_uns', 'crU'] + full = traits.Bool(desc='Full power method; enables thresholding; '\ + 'automatically selected if -thresh or -sparsity '\ + 'are set', + argstr='-full') - cost = traits.Enum( - *_cost_funcs, argstr='-cost %s', - desc="""Defines the 'cost' function that defines the matching - between the source and the base""") - _interp_funcs = [ - 'nearestneighbour', 'linear', 'cubic', 'quintic', 'wsinc5'] - interpolation = traits.Enum( - *_interp_funcs[:-1], argstr='-interp %s', - desc='Defines interpolation method to use during matching') - final_interpolation = traits.Enum( - *_interp_funcs, argstr='-final %s', - desc='Defines interpolation method used to create the output dataset') + fecm = traits.Bool(desc='Fast centrality method; substantial speed '\ + 'increase but cannot accomodate thresholding; '\ + 'automatically selected if -thresh or -sparsity '\ + 'are not set', + argstr='-fecm') - # TECHNICAL OPTIONS (used for fine control of the program): - nmatch = traits.Int( - argstr='-nmatch %d', - desc='Use at most n scattered points to match the datasets.') - no_pad = traits.Bool( - argstr='-nopad', - desc='Do not use zero-padding on the base image.') - zclip = traits.Bool( - argstr='-zclip', - desc='Replace negative values in the input datasets (source & base) with zero.') - convergence = traits.Float( - argstr='-conv %f', - desc='Convergence test in millimeters (default 0.05mm).') - usetemp = traits.Bool(argstr='-usetemp', desc='temporary file use') - check = traits.List( - traits.Enum(*_cost_funcs), argstr='-check %s', - desc="""After cost functional optimization is done, start at the - final parameters and RE-optimize using this new cost functions. - If the results are too different, a warning message will be - printed. However, the final parameters from the original - optimization will be used to create the output dataset.""") + shift = traits.Float(desc='shift correlation coefficients in similarity '\ + 'matrix to enforce non-negativity, s >= 0.0; '\ + 'default = 0.0 for -full, 1.0 for -fecm', + argstr='-shift %f') - # ** PARAMETERS THAT AFFECT THE COST OPTIMIZATION STRATEGY ** - one_pass = traits.Bool( - argstr='-onepass', - desc="""Use only the refining pass -- do not try a coarse - resolution pass first. Useful if you know that only - small amounts of image alignment are needed.""") - two_pass = traits.Bool( - argstr='-twopass', - desc="""Use a two pass alignment strategy for all volumes, searching - for a large rotation+shift and then refining the alignment.""") - two_blur = traits.Float( - argstr='-twoblur', - desc='Set the blurring radius for the first pass in mm.') - two_first = traits.Bool( - argstr='-twofirst', - desc="""Use -twopass on the first image to be registered, and - then on all subsequent images from the source dataset, - use results from the first image's coarse pass to start - the fine pass.""") - two_best = traits.Int( - argstr='-twobest %d', - desc="""In the coarse pass, use the best 'bb' set of initial - points to search for the starting point for the fine - pass. If bb==0, then no search is made for the best - starting point, and the identity transformation is - used as the starting point. [Default=5; min=0 max=11]""") - fine_blur = traits.Float( - argstr='-fineblur %f', - desc="""Set the blurring radius to use in the fine resolution - pass to 'x' mm. A small amount (1-2 mm?) of blurring at - the fine step may help with convergence, if there is - some problem, especially if the base volume is very noisy. - [Default == 0 mm = no blurring at the final alignment pass]""") + scale = traits.Float(desc='scale correlation coefficients in similarity '\ + 'matrix to after shifting, x >= 0.0; '\ + 'default = 1.0 for -full, 0.5 for -fecm', + argstr='-scale %f') - center_of_mass = traits.Str( - argstr='-cmass%s', - desc='Use the center-of-mass calculation to bracket the shifts.') - autoweight = traits.Str( - argstr='-autoweight%s', - desc="""Compute a weight function using the 3dAutomask - algorithm plus some blurring of the base image.""") - automask = traits.Int( - argstr='-automask+%d', - desc="""Compute a mask function, set a value for dilation or 0.""") - autobox = traits.Bool( - argstr='-autobox', - desc="""Expand the -automask function to enclose a rectangular - box that holds the irregular mask.""") - nomask = traits.Bool( - argstr='-nomask', - desc="""Don't compute the autoweight/mask; if -weight is not - also used, then every voxel will be counted equally.""") - weight_file = File( - argstr='-weight %s', exists=True, - desc="""Set the weighting for each voxel in the base dataset; - larger weights mean that voxel count more in the cost function. - Must be defined on the same grid as the base dataset""") - out_weight_file = traits.File( - argstr='-wtprefix %s', - desc="""Write the weight volume to disk as a dataset""") + eps = traits.Float(desc='sets the stopping criterion for the power '\ + 'iteration; l2|v_old - v_new| < eps*|v_old|; '\ + 'default = 0.001', + argstr='-eps %f') - source_mask = File( - exists=True, argstr='-source_mask %s', - desc='mask the input dataset') - source_automask = traits.Int( - argstr='-source_automask+%d', - desc='Automatically mask the source dataset with dilation or 0.') - warp_type = traits.Enum( - 'shift_only', 'shift_rotate', 'shift_rotate_scale', 'affine_general', - argstr='-warp %s', - desc='Set the warp type.') - warpfreeze = traits.Bool( - argstr='-warpfreeze', - desc='Freeze the non-rigid body parameters after first volume.') - replacebase = traits.Bool( - argstr='-replacebase', - desc="""If the source has more than one volume, then after the first - volume is aligned to the base""") - replacemeth = traits.Enum( - *_cost_funcs, - argstr='-replacemeth %s', - desc="""After first volume is aligned, switch method for later volumes. - For use with '-replacebase'.""") - epi = traits.Bool( - argstr='-EPI', - desc="""Treat the source dataset as being composed of warped - EPI slices, and the base as comprising anatomically - 'true' images. Only phase-encoding direction image - shearing and scaling will be allowed with this option.""") - master = File( - exists=True, argstr='-master %s', - desc='Write the output dataset on the same grid as this file') - newgrid = traits.Float( - argstr='-newgrid %f', - desc='Write the output dataset using isotropic grid spacing in mm') + max_iter = traits.Int(desc='sets the maximum number of iterations to use '\ + 'in the power iteration; default = 1000', + argstr='-max_iter %d') - # Non-linear experimental - _nwarp_types = ['bilinear', - 'cubic', 'quintic', 'heptic', 'nonic', - 'poly3', 'poly5', 'poly7', 'poly9'] # same non-hellenistic - nwarp = traits.Enum( - *_nwarp_types, argstr='-nwarp %s', - desc='Experimental nonlinear warping: bilinear or legendre poly.') - _dirs = ['X', 'Y', 'Z', 'I', 'J', 'K'] - nwarp_fixmot = traits.List( - traits.Enum(*_dirs), - argstr='-nwarp_fixmot%s', - desc='To fix motion along directions.') - nwarp_fixdep = traits.List( - traits.Enum(*_dirs), - argstr='-nwarp_fixdep%s', - desc='To fix non-linear warp dependency along directions.') + memory = traits.Float(desc='Limit memory consumption on system by setting '\ + 'the amount of GB to limit the algorithm to; '\ + 'default = 2GB', + argstr='-memory %f') -class AllineateOutputSpec(TraitedSpec): - out_file = File(desc='output image file name') - matrix = File(desc='matrix to align input file') +class ECM(AFNICommand): + """Performs degree centrality on a dataset using a given maskfile + via the 3dLFCD command + For complete details, see the `3dECM Documentation. + -class Allineate(AFNICommand): - """Program to align one dataset (the 'source') to a base dataset + Examples + ======== - For complete details, see the `3dAllineate Documentation. - `_ + >>> from nipype.interfaces import afni as afni + >>> ecm = afni.ECM() + >>> ecm.inputs.in_file = 'functional.nii' + >>> ecm.inputs.mask = 'mask.nii' + >>> ecm.inputs.sparsity = 0.1 # keep top 0.1% of connections + >>> ecm.inputs.out_file = 'out.nii' + >>> ecm.cmdline # doctest: +IGNORE_UNICODE + '3dECM -mask mask.nii -prefix out.nii -sparsity 0.100000 functional.nii' + >>> res = ecm.run() # doctest: +SKIP + """ + + _cmd = '3dECM' + input_spec = ECMInputSpec + output_spec = AFNICommandOutputSpec + + +class EvalInputSpec(AFNICommandInputSpec): + in_file_a = File(desc='input file to 1deval', + argstr='-a %s', position=0, mandatory=True, exists=True) + in_file_b = File(desc='operand file to 1deval', + argstr=' -b %s', position=1, exists=True) + in_file_c = File(desc='operand file to 1deval', + argstr=' -c %s', position=2, exists=True) + out_file = File(name_template="%s_calc", desc='output image file name', + argstr='-prefix %s', name_source="in_file_a") + out1D = traits.Bool(desc="output in 1D", + argstr='-1D') + expr = Str(desc='expr', argstr='-expr "%s"', position=3, + mandatory=True) + start_idx = traits.Int(desc='start index for in_file_a', + requires=['stop_idx']) + stop_idx = traits.Int(desc='stop index for in_file_a', + requires=['start_idx']) + single_idx = traits.Int(desc='volume index for in_file_a') + other = File(desc='other options', argstr='') + + +class Eval(AFNICommand): + """Evaluates an expression that may include columns of data from one or more text files + + see AFNI Documentation: Examples ======== >>> from nipype.interfaces import afni as afni - >>> allineate = afni.Allineate() - >>> allineate.inputs.in_file = 'functional.nii' - >>> allineate.inputs.out_file= 'functional_allineate.nii' - >>> allineate.inputs.in_matrix= 'cmatrix.mat' - >>> res = allineate.run() # doctest: +SKIP + >>> eval = afni.Eval() + >>> eval.inputs.in_file_a = 'seed.1D' + >>> eval.inputs.in_file_b = 'resp.1D' + >>> eval.inputs.expr='a*b' + >>> eval.inputs.out1D = True + >>> eval.inputs.out_file = 'data_calc.1D' + >>> calc.cmdline #doctest: +SKIP +IGNORE_UNICODE + '3deval -a timeseries1.1D -b timeseries2.1D -expr "a*b" -1D -prefix data_calc.1D' """ - _cmd = '3dAllineate' - input_spec = AllineateInputSpec - output_spec = AllineateOutputSpec + _cmd = '1deval' + input_spec = EvalInputSpec + output_spec = AFNICommandOutputSpec def _format_arg(self, name, trait_spec, value): - if name == 'nwarp_fixmot' or name == 'nwarp_fixdep': - arg = ' '.join([trait_spec.argstr % v for v in value]) + if name == 'in_file_a': + arg = trait_spec.argstr % value + if isdefined(self.inputs.start_idx): + arg += '[%d..%d]' % (self.inputs.start_idx, + self.inputs.stop_idx) + if isdefined(self.inputs.single_idx): + arg += '[%d]' % (self.inputs.single_idx) return arg - return super(Allineate, self)._format_arg(name, trait_spec, value) + return super(Eval, self)._format_arg(name, trait_spec, value) - def _list_outputs(self): - outputs = self.output_spec().get() - if not isdefined(self.inputs.out_file): - outputs['out_file'] = self._gen_filename(self.inputs.in_file, - suffix=self.inputs.suffix) - else: - outputs['out_file'] = os.path.abspath(self.inputs.out_file) + def _parse_inputs(self, skip=None): + """Skip the arguments without argstr metadata + """ + return super(Eval, self)._parse_inputs( + skip=('start_idx', 'stop_idx', 'out1D', 'other')) - if isdefined(self.inputs.out_matrix): - outputs['matrix'] = os.path.abspath(os.path.join(os.getcwd(),\ - self.inputs.out_matrix +".aff12.1D")) - return outputs - def _gen_filename(self, name): - if name == 'out_file': - return self._list_outputs()[name] +class FWHMxInputSpec(CommandLineInputSpec): + in_file = File(desc='input dataset', argstr='-input %s', mandatory=True, exists=True) + out_file = File(argstr='> %s', name_source='in_file', name_template='%s_fwhmx.out', + position=-1, keep_extension=False, desc='output file') + out_subbricks = File(argstr='-out %s', name_source='in_file', name_template='%s_subbricks.out', + keep_extension=False, desc='output file listing the subbricks FWHM') + mask = File(desc='use only voxels that are nonzero in mask', argstr='-mask %s', exists=True) + automask = traits.Bool(False, usedefault=True, argstr='-automask', + desc='compute a mask from THIS dataset, a la 3dAutomask') + detrend = traits.Either( + traits.Bool(), traits.Int(), default=False, argstr='-detrend', xor=['demed'], usedefault=True, + desc='instead of demed (0th order detrending), detrend to the specified order. If order ' + 'is not given, the program picks q=NT/30. -detrend disables -demed, and includes ' + '-unif.') + demed = traits.Bool( + False, argstr='-demed', xor=['detrend'], + desc='If the input dataset has more than one sub-brick (e.g., has a time axis), then ' + 'subtract the median of each voxel\'s time series before processing FWHM. This will ' + 'tend to remove intrinsic spatial structure and leave behind the noise.') + unif = traits.Bool(False, argstr='-unif', + desc='If the input dataset has more than one sub-brick, then normalize each' + ' voxel\'s time series to have the same MAD before processing FWHM.') + out_detrend = File(argstr='-detprefix %s', name_source='in_file', name_template='%s_detrend', + keep_extension=False, desc='Save the detrended file into a dataset') + geom = traits.Bool(argstr='-geom', xor=['arith'], + desc='if in_file has more than one sub-brick, compute the final estimate as' + 'the geometric mean of the individual sub-brick FWHM estimates') + arith = traits.Bool(argstr='-arith', xor=['geom'], + desc='if in_file has more than one sub-brick, compute the final estimate as' + 'the arithmetic mean of the individual sub-brick FWHM estimates') + combine = traits.Bool(argstr='-combine', desc='combine the final measurements along each axis') + compat = traits.Bool(argstr='-compat', desc='be compatible with the older 3dFWHM') + acf = traits.Either( + traits.Bool(), File(), traits.Tuple(File(exists=True), traits.Float()), + default=False, usedefault=True, argstr='-acf', desc='computes the spatial autocorrelation') -class MaskaveInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dmaskave', - argstr='%s', - position=-2, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_maskave.1D", desc='output image file name', - keep_extension=True, - argstr="> %s", name_source="in_file", position=-1) - mask = File(desc='matrix to align input file', - argstr='-mask %s', - position=1, - exists=True) - quiet = traits.Bool(desc='matrix to align input file', - argstr='-quiet', - position=2) +class FWHMxOutputSpec(TraitedSpec): + out_file = File(exists=True, desc='output file') + out_subbricks = File(exists=True, desc='output file (subbricks)') + out_detrend = File(desc='output file, detrended') + fwhm = traits.Either( + traits.Tuple(traits.Float(), traits.Float(), traits.Float()), + traits.Tuple(traits.Float(), traits.Float(), traits.Float(), traits.Float()), + desc='FWHM along each axis') + acf_param = traits.Either( + traits.Tuple(traits.Float(), traits.Float(), traits.Float()), + traits.Tuple(traits.Float(), traits.Float(), traits.Float(), traits.Float()), + desc='fitted ACF model parameters') + out_acf = File(exists=True, desc='output acf file') +class FWHMx(AFNICommandBase): + """ + Unlike the older 3dFWHM, this program computes FWHMs for all sub-bricks + in the input dataset, each one separately. The output for each one is + written to the file specified by '-out'. The mean (arithmetic or geometric) + of all the FWHMs along each axis is written to stdout. (A non-positive + output value indicates something bad happened; e.g., FWHM in z is meaningless + for a 2D dataset; the estimation method computed incoherent intermediate results.) -class Maskave(AFNICommand): - """Computes average of all voxels in the input dataset - which satisfy the criterion in the options list + Examples + -------- - For complete details, see the `3dmaskave Documentation. - `_ + >>> from nipype.interfaces import afni as afp + >>> fwhm = afp.FWHMx() + >>> fwhm.inputs.in_file = 'functional.nii' + >>> fwhm.cmdline # doctest: +IGNORE_UNICODE + '3dFWHMx -input functional.nii -out functional_subbricks.out > functional_fwhmx.out' - Examples - ======== - >>> from nipype.interfaces import afni as afni - >>> maskave = afni.Maskave() - >>> maskave.inputs.in_file = 'functional.nii' - >>> maskave.inputs.mask= 'seed_mask.nii' - >>> maskave.inputs.quiet= True - >>> maskave.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dmaskave -mask seed_mask.nii -quiet functional.nii > functional_maskave.1D' - >>> res = maskave.run() # doctest: +SKIP + (Classic) METHOD: - """ + * Calculate ratio of variance of first differences to data variance. + * Should be the same as 3dFWHM for a 1-brick dataset. + (But the output format is simpler to use in a script.) - _cmd = '3dmaskave' - input_spec = MaskaveInputSpec - output_spec = AFNICommandOutputSpec + .. note:: IMPORTANT NOTE [AFNI > 16] -class SkullStripInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dSkullStrip', - argstr='-input %s', - position=1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_skullstrip", desc='output image file name', - argstr='-prefix %s', name_source="in_file") + A completely new method for estimating and using noise smoothness values is + now available in 3dFWHMx and 3dClustSim. This method is implemented in the + '-acf' options to both programs. 'ACF' stands for (spatial) AutoCorrelation + Function, and it is estimated by calculating moments of differences out to + a larger radius than before. + Notably, real FMRI data does not actually have a Gaussian-shaped ACF, so the + estimated ACF is then fit (in 3dFWHMx) to a mixed model (Gaussian plus + mono-exponential) of the form -class SkullStrip(AFNICommand): - """A program to extract the brain from surrounding - tissue from MRI T1-weighted images + .. math:: - For complete details, see the `3dSkullStrip Documentation. - `_ + ACF(r) = a * exp(-r*r/(2*b*b)) + (1-a)*exp(-r/c) - Examples - ======== - >>> from nipype.interfaces import afni as afni - >>> skullstrip = afni.SkullStrip() - >>> skullstrip.inputs.in_file = 'functional.nii' - >>> skullstrip.inputs.args = '-o_ply' - >>> res = skullstrip.run() # doctest: +SKIP + where :math:`r` is the radius, and :math:`a, b, c` are the fitted parameters. + The apparent FWHM from this model is usually somewhat larger in real data + than the FWHM estimated from just the nearest-neighbor differences used + in the 'classic' analysis. - """ - _cmd = '3dSkullStrip' - _redirect_x = True - input_spec = SkullStripInputSpec - output_spec = AFNICommandOutputSpec + The longer tails provided by the mono-exponential are also significant. + 3dClustSim has also been modified to use the ACF model given above to generate + noise random fields. - def __init__(self, **inputs): - super(SkullStrip, self).__init__(**inputs) - if not no_afni(): - v = Info.version() - # As of AFNI 16.0.00, redirect_x is not needed - if isinstance(v[0], int) and v[0] > 15: - self._redirect_x = False + .. note:: TL;DR or summary + The take-awaymessage is that the 'classic' 3dFWHMx and + 3dClustSim analysis, using a pure Gaussian ACF, is not very correct for + FMRI data -- I cannot speak for PET or MEG data. -class TCatInputSpec(AFNICommandInputSpec): - in_files = InputMultiPath( - File(exists=True), - desc='input file to 3dTcat', - argstr=' %s', - position=-1, - mandatory=True, - copyfile=False) - out_file = File(name_template="%s_tcat", desc='output image file name', - argstr='-prefix %s', name_source="in_files") - rlt = traits.Str(desc='options', argstr='-rlt%s', position=1) + .. warning:: -class TCat(AFNICommand): - """Concatenate sub-bricks from input datasets into - one big 3D+time dataset + Do NOT use 3dFWHMx on the statistical results (e.g., '-bucket') from + 3dDeconvolve or 3dREMLfit!!! The function of 3dFWHMx is to estimate + the smoothness of the time series NOISE, not of the statistics. This + proscription is especially true if you plan to use 3dClustSim next!! + + + .. note:: Recommendations + + * For FMRI statistical purposes, you DO NOT want the FWHM to reflect + the spatial structure of the underlying anatomy. Rather, you want + the FWHM to reflect the spatial structure of the noise. This means + that the input dataset should not have anatomical (spatial) structure. + * One good form of input is the output of '3dDeconvolve -errts', which is + the dataset of residuals left over after the GLM fitted signal model is + subtracted out from each voxel's time series. + * If you don't want to go to that much trouble, use '-detrend' to approximately + subtract out the anatomical spatial structure, OR use the output of 3dDetrend + for the same purpose. + * If you do not use '-detrend', the program attempts to find non-zero spatial + structure in the input, and will print a warning message if it is detected. + + + .. note:: Notes on -demend + + * I recommend this option, and it is not the default only for historical + compatibility reasons. It may become the default someday. + * It is already the default in program 3dBlurToFWHM. This is the same detrending + as done in 3dDespike; using 2*q+3 basis functions for q > 0. + * If you don't use '-detrend', the program now [Aug 2010] checks if a large number + of voxels are have significant nonzero means. If so, the program will print a + warning message suggesting the use of '-detrend', since inherent spatial + structure in the image will bias the estimation of the FWHM of the image time + series NOISE (which is usually the point of using 3dFWHMx). + + + """ + _cmd = '3dFWHMx' + input_spec = FWHMxInputSpec + output_spec = FWHMxOutputSpec + _acf = True + + def _parse_inputs(self, skip=None): + if not self.inputs.detrend: + if skip is None: + skip = [] + skip += ['out_detrend'] + return super(FWHMx, self)._parse_inputs(skip=skip) + + def _format_arg(self, name, trait_spec, value): + if name == 'detrend': + if isinstance(value, bool): + if value: + return trait_spec.argstr + else: + return None + elif isinstance(value, int): + return trait_spec.argstr + ' %d' % value + + if name == 'acf': + if isinstance(value, bool): + if value: + return trait_spec.argstr + else: + self._acf = False + return None + elif isinstance(value, tuple): + return trait_spec.argstr + ' %s %f' % value + elif isinstance(value, (str, bytes)): + return trait_spec.argstr + ' ' + value + return super(FWHMx, self)._format_arg(name, trait_spec, value) - For complete details, see the `3dTcat Documentation. - `_ + def _list_outputs(self): + outputs = super(FWHMx, self)._list_outputs() - Examples - ======== + if self.inputs.detrend: + fname, ext = op.splitext(self.inputs.in_file) + if '.gz' in ext: + _, ext2 = op.splitext(fname) + ext = ext2 + ext + outputs['out_detrend'] += ext + else: + outputs['out_detrend'] = Undefined - >>> from nipype.interfaces import afni as afni - >>> tcat = afni.TCat() - >>> tcat.inputs.in_files = ['functional.nii', 'functional2.nii'] - >>> tcat.inputs.out_file= 'functional_tcat.nii' - >>> tcat.inputs.rlt = '+' - >>> res = tcat.run() # doctest: +SKIP + sout = np.loadtxt(outputs['out_file']) #pylint: disable=E1101 + if self._acf: + outputs['acf_param'] = tuple(sout[1]) + sout = tuple(sout[0]) - """ + outputs['out_acf'] = op.abspath('3dFWHMx.1D') + if isinstance(self.inputs.acf, (str, bytes)): + outputs['out_acf'] = op.abspath(self.inputs.acf) - _cmd = '3dTcat' - input_spec = TCatInputSpec - output_spec = AFNICommandOutputSpec + outputs['fwhm'] = tuple(sout) + return outputs class FimInputSpec(AFNICommandInputSpec): @@ -1552,8 +1497,8 @@ class FimInputSpec(AFNICommandInputSpec): exists=True) fim_thr = traits.Float(desc='fim internal mask threshold value', argstr='-fim_thr %f', position=3) - out = traits.Str(desc='Flag to output the specified parameter', - argstr='-out %s', position=4) + out = Str(desc='Flag to output the specified parameter', + argstr='-out %s', position=4) class Fim(AFNICommand): @@ -1583,264 +1528,159 @@ class Fim(AFNICommand): output_spec = AFNICommandOutputSpec -class TCorrelateInputSpec(AFNICommandInputSpec): - xset = File(desc='input xset', - argstr=' %s', - position=-2, - mandatory=True, - exists=True, - copyfile=False) - yset = File(desc='input yset', - argstr=' %s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_tcorr", desc='output image file name', - argstr='-prefix %s', name_source="xset") - pearson = traits.Bool(desc='Correlation is the normal' + - ' Pearson correlation coefficient', - argstr='-pearson', - position=1) - polort = traits.Int(desc='Remove polynomical trend of order m', - argstr='-polort %d', position=2) +class FourierInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dFourier', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File(name_template="%s_fourier", desc='output image file name', + argstr='-prefix %s', name_source="in_file") + lowpass = traits.Float(desc='lowpass', + argstr='-lowpass %f', + position=0, + mandatory=True) + highpass = traits.Float(desc='highpass', + argstr='-highpass %f', + position=1, + mandatory=True) -class TCorrelate(AFNICommand): - """Computes the correlation coefficient between corresponding voxel - time series in two input 3D+time datasets 'xset' and 'yset' +class Fourier(AFNICommand): + """Program to lowpass and/or highpass each voxel time series in a + dataset, via the FFT - For complete details, see the `3dTcorrelate Documentation. - `_ + For complete details, see the `3dFourier Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> tcorrelate = afni.TCorrelate() - >>> tcorrelate.inputs.xset= 'u_rc1s1_Template.nii' - >>> tcorrelate.inputs.yset = 'u_rc1s2_Template.nii' - >>> tcorrelate.inputs.out_file = 'functional_tcorrelate.nii.gz' - >>> tcorrelate.inputs.polort = -1 - >>> tcorrelate.inputs.pearson = True - >>> res = tcarrelate.run() # doctest: +SKIP + >>> fourier = afni.Fourier() + >>> fourier.inputs.in_file = 'functional.nii' + >>> fourier.inputs.args = '-retrend' + >>> fourier.inputs.highpass = 0.005 + >>> fourier.inputs.lowpass = 0.1 + >>> res = fourier.run() # doctest: +SKIP """ - _cmd = '3dTcorrelate' - input_spec = TCorrelateInputSpec + _cmd = '3dFourier' + input_spec = FourierInputSpec output_spec = AFNICommandOutputSpec -class TCorr1DInputSpec(AFNICommandInputSpec): - xset = File(desc='3d+time dataset input', - argstr=' %s', - position=-2, - mandatory=True, - exists=True, - copyfile=False) - y_1d = File(desc='1D time series file input', - argstr=' %s', - position=-1, - mandatory=True, - exists=True) - out_file = File(desc='output filename prefix', - name_template='%s_correlation.nii.gz', - argstr='-prefix %s', - name_source='xset', - keep_extension=True) - pearson = traits.Bool(desc='Correlation is the normal' + - ' Pearson correlation coefficient', - argstr=' -pearson', - xor=['spearman', 'quadrant', 'ktaub'], - position=1) - spearman = traits.Bool(desc='Correlation is the' + - ' Spearman (rank) correlation coefficient', - argstr=' -spearman', - xor=['pearson', 'quadrant', 'ktaub'], - position=1) - quadrant = traits.Bool(desc='Correlation is the' + - ' quadrant correlation coefficient', - argstr=' -quadrant', - xor=['pearson', 'spearman', 'ktaub'], - position=1) - ktaub = traits.Bool(desc='Correlation is the' + - ' Kendall\'s tau_b correlation coefficient', - argstr=' -ktaub', - xor=['pearson', 'spearman', 'quadrant'], - position=1) - - -class TCorr1DOutputSpec(TraitedSpec): - out_file = File(desc='output file containing correlations', - exists=True) - - - -class TCorr1D(AFNICommand): - """Computes the correlation coefficient between each voxel time series - in the input 3D+time dataset. - For complete details, see the `3dTcorr1D Documentation. - `_ - - >>> from nipype.interfaces import afni as afni - >>> tcorr1D = afni.TCorr1D() - >>> tcorr1D.inputs.xset= 'u_rc1s1_Template.nii' - >>> tcorr1D.inputs.y_1d = 'seed.1D' - >>> tcorr1D.cmdline # doctest: +IGNORE_UNICODE - '3dTcorr1D -prefix u_rc1s1_Template_correlation.nii.gz u_rc1s1_Template.nii seed.1D' - >>> res = tcorr1D.run() # doctest: +SKIP - """ - - _cmd = '3dTcorr1D' - input_spec = TCorr1DInputSpec - output_spec = TCorr1DOutputSpec - - -class BrickStatInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dmaskave', - argstr='%s', - position=-1, - mandatory=True, - exists=True) - - mask = File(desc='-mask dset = use dset as mask to include/exclude voxels', - argstr='-mask %s', - position=2, - exists=True) - - min = traits.Bool(desc='print the minimum value in dataset', - argstr='-min', - position=1) +class HistInputSpec(CommandLineInputSpec): + in_file = File( + desc='input file to 3dHist', argstr='-input %s', position=1, mandatory=True, + exists=True, copyfile=False) + out_file = File( + desc='Write histogram to niml file with this prefix', name_template='%s_hist', + keep_extension=False, argstr='-prefix %s', name_source=['in_file']) + showhist = traits.Bool(False, usedefault=True, desc='write a text visual histogram', + argstr='-showhist') + out_show = File( + name_template="%s_hist.out", desc='output image file name', keep_extension=False, + argstr="> %s", name_source="in_file", position=-1) + mask = File(desc='matrix to align input file', argstr='-mask %s', exists=True) + nbin = traits.Int(desc='number of bins', argstr='-nbin %d') + max_value = traits.Float(argstr='-max %f', desc='maximum intensity value') + min_value = traits.Float(argstr='-min %f', desc='minimum intensity value') + bin_width = traits.Float(argstr='-binwidth %f', desc='bin width') -class BrickStatOutputSpec(TraitedSpec): - min_val = traits.Float(desc='output') +class HistOutputSpec(TraitedSpec): + out_file = File(desc='output file', exists=True) + out_show = File(desc='output visual histogram') -class BrickStat(AFNICommand): - """Compute maximum and/or minimum voxel values of an input dataset +class Hist(AFNICommandBase): + """Computes average of all voxels in the input dataset + which satisfy the criterion in the options list - For complete details, see the `3dBrickStat Documentation. - `_ + For complete details, see the `3dHist Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> brickstat = afni.BrickStat() - >>> brickstat.inputs.in_file = 'functional.nii' - >>> brickstat.inputs.mask = 'skeleton_mask.nii.gz' - >>> brickstat.inputs.min = True - >>> res = brickstat.run() # doctest: +SKIP + >>> hist = afni.Hist() + >>> hist.inputs.in_file = 'functional.nii' + >>> hist.cmdline # doctest: +IGNORE_UNICODE + '3dHist -input functional.nii -prefix functional_hist' + >>> res = hist.run() # doctest: +SKIP """ - _cmd = '3dBrickStat' - input_spec = BrickStatInputSpec - output_spec = BrickStatOutputSpec - def aggregate_outputs(self, runtime=None, needed_outputs=None): + _cmd = '3dHist' + input_spec = HistInputSpec + output_spec = HistOutputSpec + _redirect_x = True - outputs = self._outputs() + def __init__(self, **inputs): + super(Hist, self).__init__(**inputs) + if not no_afni(): + version = Info.version() - outfile = os.path.join(os.getcwd(), 'stat_result.json') + # As of AFNI 16.0.00, redirect_x is not needed + if isinstance(version[0], int) and version[0] > 15: + self._redirect_x = False - if runtime is None: - try: - min_val = load_json(outfile)['stat'] - except IOError: - return self.run().outputs - else: - min_val = [] - for line in runtime.stdout.split('\n'): - if line: - values = line.split() - if len(values) > 1: - min_val.append([float(val) for val in values]) - else: - min_val.extend([float(val) for val in values]) + def _parse_inputs(self, skip=None): + if not self.inputs.showhist: + if skip is None: + skip = [] + skip += ['out_show'] + return super(Hist, self)._parse_inputs(skip=skip) - if len(min_val) == 1: - min_val = min_val[0] - save_json(outfile, dict(stat=min_val)) - outputs.min_val = min_val + def _list_outputs(self): + outputs = super(Hist, self)._list_outputs() + outputs['out_file'] += '.niml.hist' + if not self.inputs.showhist: + outputs['out_show'] = Undefined return outputs -class ClipLevelInputSpec(CommandLineInputSpec): - in_file = File(desc='input file to 3dClipLevel', +class LFCDInputSpec(CentralityInputSpec): + """LFCD inputspec + """ + + in_file = File(desc='input file to 3dLFCD', argstr='%s', position=-1, mandatory=True, - exists=True) - - mfrac = traits.Float(desc='Use the number ff instead of 0.50 in the algorithm', - argstr='-mfrac %s', - position=2) - - doall = traits.Bool(desc='Apply the algorithm to each sub-brick separately', - argstr='-doall', - position=3, - xor=('grad')) - - grad = traits.File(desc='also compute a \'gradual\' clip level as a function of voxel position, and output that to a dataset', - argstr='-grad %s', - position=3, - xor=('doall')) - - -class ClipLevelOutputSpec(TraitedSpec): - clip_val = traits.Float(desc='output') + exists=True, + copyfile=False) -class ClipLevel(AFNICommandBase): - """Estimates the value at which to clip the anatomical dataset so - that background regions are set to zero. +class LFCD(AFNICommand): + """Performs degree centrality on a dataset using a given maskfile + via the 3dLFCD command - For complete details, see the `3dClipLevel Documentation. - `_ + For complete details, see the `3dLFCD Documentation. + Examples ======== - >>> from nipype.interfaces.afni import preprocess - >>> cliplevel = preprocess.ClipLevel() - >>> cliplevel.inputs.in_file = 'anatomical.nii' - >>> res = cliplevel.run() # doctest: +SKIP - + >>> from nipype.interfaces import afni as afni + >>> lfcd = afni.LFCD() + >>> lfcd.inputs.in_file = 'functional.nii' + >>> lfcd.inputs.mask = 'mask.nii' + >>> lfcd.inputs.thresh = 0.8 # keep all connections with corr >= 0.8 + >>> lfcd.inputs.out_file = 'out.nii' + >>> lfcd.cmdline # doctest: +IGNORE_UNICODE + '3dLFCD -mask mask.nii -prefix out.nii -thresh 0.800000 functional.nii' + >>> res = lfcd.run() # doctest: +SKIP """ - _cmd = '3dClipLevel' - input_spec = ClipLevelInputSpec - output_spec = ClipLevelOutputSpec - - def aggregate_outputs(self, runtime=None, needed_outputs=None): - - outputs = self._outputs() - - outfile = os.path.join(os.getcwd(), 'stat_result.json') - - if runtime is None: - try: - clip_val = load_json(outfile)['stat'] - except IOError: - return self.run().outputs - else: - clip_val = [] - for line in runtime.stdout.split('\n'): - if line: - values = line.split() - if len(values) > 1: - clip_val.append([float(val) for val in values]) - else: - clip_val.extend([float(val) for val in values]) - - if len(clip_val) == 1: - clip_val = clip_val[0] - save_json(outfile, dict(stat=clip_val)) - outputs.clip_val = clip_val - return outputs + _cmd = '3dLFCD' + input_spec = LFCDInputSpec + output_spec = AFNICommandOutputSpec class MaskToolInputSpec(AFNICommandInputSpec): @@ -1866,14 +1706,14 @@ class MaskToolInputSpec(AFNICommandInputSpec): desc='specify data type for output. Valid types are '+ '\'byte\', \'short\' and \'float\'.') - dilate_inputs = traits.Str(desc='Use this option to dilate and/or erode '+ - 'datasets as they are read. ex. ' + - '\'5 -5\' to dilate and erode 5 times', - argstr='-dilate_inputs %s') + dilate_inputs = Str(desc='Use this option to dilate and/or erode '+ + 'datasets as they are read. ex. ' + + '\'5 -5\' to dilate and erode 5 times', + argstr='-dilate_inputs %s') - dilate_results = traits.Str(desc='dilate and/or erode combined mask at ' + - 'the given levels.', - argstr='-dilate_results %s') + dilate_results = Str(desc='dilate and/or erode combined mask at ' + + 'the given levels.', + argstr='-dilate_results %s') frac = traits.Float(desc='When combining masks (across datasets and ' + 'sub-bricks), use this option to restrict the ' + @@ -1892,14 +1732,14 @@ class MaskToolInputSpec(AFNICommandInputSpec): 'other processing has been done.', argstr='-fill_holes') - fill_dirs = traits.Str(desc='fill holes only in the given directions. ' + - 'This option is for use with -fill holes. ' + - 'should be a single string that specifies ' + - '1-3 of the axes using {x,y,z} labels (i.e. '+ - 'dataset axis order), or using the labels ' + - 'in {R,L,A,P,I,S}.', - argstr='-fill_dirs %s', - requires=['fill_holes']) + fill_dirs = Str(desc='fill holes only in the given directions. ' + + 'This option is for use with -fill holes. ' + + 'should be a single string that specifies ' + + '1-3 of the axes using {x,y,z} labels (i.e. '+ + 'dataset axis order), or using the labels ' + + 'in {R,L,A,P,I,S}.', + argstr='-fill_dirs %s', + requires=['fill_holes']) class MaskToolOutputSpec(TraitedSpec): @@ -1907,7 +1747,6 @@ class MaskToolOutputSpec(TraitedSpec): exists=True) - class MaskTool(AFNICommand): """3dmask_tool - for combining/dilating/eroding/filling masks @@ -1933,448 +1772,499 @@ class MaskTool(AFNICommand): output_spec = MaskToolOutputSpec -class SegInputSpec(CommandLineInputSpec): - in_file = File(desc='ANAT is the volume to segment', - argstr='-anat %s', - position=-1, +class MaskaveInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dmaskave', + argstr='%s', + position=-2, mandatory=True, exists=True, - copyfile=True) + copyfile=False) + out_file = File(name_template="%s_maskave.1D", desc='output image file name', + keep_extension=True, + argstr="> %s", name_source="in_file", position=-1) + mask = File(desc='matrix to align input file', + argstr='-mask %s', + position=1, + exists=True) + quiet = traits.Bool(desc='matrix to align input file', + argstr='-quiet', + position=2) - mask = traits.Either(traits.Enum('AUTO'), - File(exists=True), - desc=('only non-zero voxels in mask are analyzed. ' - 'mask can either be a dataset or the string ' - '"AUTO" which would use AFNI\'s automask ' - 'function to create the mask.'), - argstr='-mask %s', - position=-2, - mandatory=True) - blur_meth = traits.Enum('BFT', 'BIM', - argstr='-blur_meth %s', - desc='set the blurring method for bias field estimation') +class Maskave(AFNICommand): + """Computes average of all voxels in the input dataset + which satisfy the criterion in the options list - bias_fwhm = traits.Float(desc='The amount of blurring used when estimating the field bias with the Wells method', - argstr='-bias_fwhm %f') + For complete details, see the `3dmaskave Documentation. + `_ - classes = traits.Str(desc='CLASS_STRING is a semicolon delimited string of class labels', - argstr='-classes %s') + Examples + ======== - bmrf = traits.Float(desc='Weighting factor controlling spatial homogeneity of the classifications', - argstr='-bmrf %f') + >>> from nipype.interfaces import afni as afni + >>> maskave = afni.Maskave() + >>> maskave.inputs.in_file = 'functional.nii' + >>> maskave.inputs.mask= 'seed_mask.nii' + >>> maskave.inputs.quiet= True + >>> maskave.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dmaskave -mask seed_mask.nii -quiet functional.nii > functional_maskave.1D' + >>> res = maskave.run() # doctest: +SKIP - bias_classes = traits.Str(desc='A semcolon demlimited string of classes that contribute to the estimation of the bias field', - argstr='-bias_classes %s') + """ - prefix = traits.Str(desc='the prefix for the output folder containing all output volumes', - argstr='-prefix %s') + _cmd = '3dmaskave' + input_spec = MaskaveInputSpec + output_spec = AFNICommandOutputSpec - mixfrac = traits.Str(desc='MIXFRAC sets up the volume-wide (within mask) tissue fractions while initializing the segmentation (see IGNORE for exception)', - argstr='-mixfrac %s') - mixfloor = traits.Float(desc='Set the minimum value for any class\'s mixing fraction', - argstr='-mixfloor %f') +class MeansInputSpec(AFNICommandInputSpec): + in_file_a = File(desc='input file to 3dMean', + argstr='%s', + position=0, + mandatory=True, + exists=True) + in_file_b = File(desc='another input file to 3dMean', + argstr='%s', + position=1, + exists=True) + out_file = File(name_template="%s_mean", desc='output image file name', + argstr='-prefix %s', name_source="in_file_a") + scale = Str(desc='scaling of output', argstr='-%sscale') + non_zero = traits.Bool(desc='use only non-zero values', argstr='-non_zero') + std_dev = traits.Bool(desc='calculate std dev', argstr='-stdev') + sqr = traits.Bool(desc='mean square instead of value', argstr='-sqr') + summ = traits.Bool(desc='take sum, (not average)', argstr='-sum') + count = traits.Bool(desc='compute count of non-zero voxels', argstr='-count') + mask_inter = traits.Bool(desc='create intersection mask', argstr='-mask_inter') + mask_union = traits.Bool(desc='create union mask', argstr='-mask_union') - main_N = traits.Int(desc='Number of iterations to perform.', - argstr='-main_N %d') + +class Means(AFNICommand): + """Takes the voxel-by-voxel mean of all input datasets using 3dMean + + see AFNI Documentation: + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> means = afni.Means() + >>> means.inputs.in_file_a = 'im1.nii' + >>> means.inputs.in_file_b = 'im2.nii' + >>> means.inputs.out_file = 'output.nii' + >>> means.cmdline # doctest: +IGNORE_UNICODE + '3dMean im1.nii im2.nii -prefix output.nii' + + """ + + _cmd = '3dMean' + input_spec = MeansInputSpec + output_spec = AFNICommandOutputSpec + + +class MergeInputSpec(AFNICommandInputSpec): + in_files = InputMultiPath( + File(desc='input file to 3dmerge', exists=True), + argstr='%s', + position=-1, + mandatory=True, + copyfile=False) + out_file = File(name_template="%s_merge", desc='output image file name', + argstr='-prefix %s', name_source="in_file") + doall = traits.Bool(desc='apply options to all sub-bricks in dataset', + argstr='-doall') + blurfwhm = traits.Int(desc='FWHM blur value (mm)', + argstr='-1blur_fwhm %d', + units='mm') + + +class Merge(AFNICommand): + """Merge or edit volumes using AFNI 3dmerge command + + For complete details, see the `3dmerge Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> merge = afni.Merge() + >>> merge.inputs.in_files = ['functional.nii', 'functional2.nii'] + >>> merge.inputs.blurfwhm = 4 + >>> merge.inputs.doall = True + >>> merge.inputs.out_file = 'e7.nii' + >>> res = merge.run() # doctest: +SKIP + + """ + + _cmd = '3dmerge' + input_spec = MergeInputSpec + output_spec = AFNICommandOutputSpec + + +class NotesInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dNotes', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + add = Str(desc='note to add', + argstr='-a "%s"') + add_history = Str(desc='note to add to history', + argstr='-h "%s"', + xor=['rep_history']) + rep_history = Str(desc='note with which to replace history', + argstr='-HH "%s"', + xor=['add_history']) + delete = traits.Int(desc='delete note number num', + argstr='-d %d') + ses = traits.Bool(desc='print to stdout the expanded notes', + argstr='-ses') + out_file = File(desc='output image file name', + argstr='%s') -class Seg(AFNICommandBase): - """3dSeg segments brain volumes into tissue classes. The program allows - for adding a variety of global and voxelwise priors. However for the - moment, only mixing fractions and MRF are documented. +class Notes(CommandLine): + """ + A program to add, delete, and show notes for AFNI datasets. - For complete details, see the `3dSeg Documentation. - + For complete details, see the `3dNotes Documentation. + Examples ======== - >>> from nipype.interfaces.afni import preprocess - >>> seg = preprocess.Seg() - >>> seg.inputs.in_file = 'structural.nii' - >>> seg.inputs.mask = 'AUTO' - >>> res = seg.run() # doctest: +SKIP - + >>> from nipype.interfaces import afni + >>> notes = afni.Notes() + >>> notes.inputs.in_file = "functional.HEAD" + >>> notes.inputs.add = "This note is added." + >>> notes.inputs.add_history = "This note is added to history." + >>> notes.cmdline #doctest: +IGNORE_UNICODE + '3dNotes -a "This note is added." -h "This note is added to history." functional.HEAD' + >>> res = notes.run() # doctest: +SKIP """ - _cmd = '3dSeg' - input_spec = SegInputSpec + _cmd = '3dNotes' + input_spec = NotesInputSpec output_spec = AFNICommandOutputSpec - def aggregate_outputs(self, runtime=None, needed_outputs=None): - - import glob + def _list_outputs(self): + outputs = self.output_spec().get() + outputs['out_file'] = os.path.abspath(self.inputs.in_file) + return outputs - outputs = self._outputs() - if isdefined(self.inputs.prefix): - outfile = os.path.join(os.getcwd(), self.inputs.prefix, 'Classes+*.BRIK') - else: - outfile = os.path.join(os.getcwd(), 'Segsy', 'Classes+*.BRIK') +class OutlierCountInputSpec(CommandLineInputSpec): + in_file = File(argstr='%s', mandatory=True, exists=True, position=-2, desc='input dataset') + mask = File(exists=True, argstr='-mask %s', xor=['autoclip', 'automask'], + desc='only count voxels within the given mask') + qthr = traits.Range(value=1e-3, low=0.0, high=1.0, argstr='-qthr %.5f', + desc='indicate a value for q to compute alpha') - outputs.out_file = glob.glob(outfile)[0] + autoclip = traits.Bool(False, usedefault=True, argstr='-autoclip', xor=['in_file'], + desc='clip off small voxels') + automask = traits.Bool(False, usedefault=True, argstr='-automask', xor=['in_file'], + desc='clip off small voxels') - return outputs + fraction = traits.Bool(False, usedefault=True, argstr='-fraction', + desc='write out the fraction of masked voxels' + ' which are outliers at each timepoint') + interval = traits.Bool(False, usedefault=True, argstr='-range', + desc='write out the median + 3.5 MAD of outlier' + ' count with each timepoint') + save_outliers = traits.Bool(False, usedefault=True, desc='enables out_file option') + outliers_file = File( + name_template="%s_outliers", argstr='-save %s', name_source=["in_file"], + output_name='out_outliers', keep_extension=True, desc='output image file name') + polort = traits.Int(argstr='-polort %d', + desc='detrend each voxel timeseries with polynomials') + legendre = traits.Bool(False, usedefault=True, argstr='-legendre', + desc='use Legendre polynomials') + out_file = File( + name_template='%s_outliers', name_source=['in_file'], argstr='> %s', + keep_extension=False, position=-1, desc='capture standard output') -class ROIStatsInputSpec(CommandLineInputSpec): - in_file = File(desc='input file to 3dROIstats', - argstr='%s', - position=-1, - mandatory=True, - exists=True) - mask = File(desc='input mask', - argstr='-mask %s', - position=3, - exists=True) +class OutlierCountOutputSpec(TraitedSpec): + out_outliers = File(exists=True, desc='output image file name') + out_file = File( + name_template='%s_tqual', name_source=['in_file'], argstr='> %s', + keep_extension=False, position=-1, desc='capture standard output') - mask_f2short = traits.Bool( - desc='Tells the program to convert a float mask ' + - 'to short integers, by simple rounding.', - argstr='-mask_f2short', - position=2) - quiet = traits.Bool(desc='execute quietly', - argstr='-quiet', - position=1) +class OutlierCount(CommandLine): + """Create a 3D dataset from 2D image files using AFNI to3d command - terminal_output = traits.Enum('allatonce', - desc=('Control terminal output:' - '`allatonce` - waits till command is ' - 'finished to display output'), - nohash=True, mandatory=True, usedefault=True) + For complete details, see the `to3d Documentation + `_ + Examples + ======== -class ROIStatsOutputSpec(TraitedSpec): - stats = File(desc='output tab separated values file', exists=True) + >>> from nipype.interfaces import afni + >>> toutcount = afni.OutlierCount() + >>> toutcount.inputs.in_file = 'functional.nii' + >>> toutcount.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dToutcount functional.nii > functional_outliers' + >>> res = toutcount.run() #doctest: +SKIP + """ -class ROIStats(AFNICommandBase): - """Display statistics over masked regions + _cmd = '3dToutcount' + input_spec = OutlierCountInputSpec + output_spec = OutlierCountOutputSpec - For complete details, see the `3dROIstats Documentation. - `_ + def _parse_inputs(self, skip=None): + if skip is None: + skip = [] - Examples - ======== + if not self.inputs.save_outliers: + skip += ['outliers_file'] + return super(OutlierCount, self)._parse_inputs(skip) - >>> from nipype.interfaces import afni as afni - >>> roistats = afni.ROIStats() - >>> roistats.inputs.in_file = 'functional.nii' - >>> roistats.inputs.mask = 'skeleton_mask.nii.gz' - >>> roistats.inputs.quiet=True - >>> res = roistats.run() # doctest: +SKIP + def _list_outputs(self): + outputs = self.output_spec().get() + if self.inputs.save_outliers: + outputs['out_outliers'] = op.abspath(self.inputs.outliers_file) + outputs['out_file'] = op.abspath(self.inputs.out_file) + return outputs - """ - _cmd = '3dROIstats' - input_spec = ROIStatsInputSpec - output_spec = ROIStatsOutputSpec - def aggregate_outputs(self, runtime=None, needed_outputs=None): - outputs = self._outputs() - output_filename = "roi_stats.csv" - with open(output_filename, "w") as f: - f.write(runtime.stdout) +class QualityIndexInputSpec(CommandLineInputSpec): + in_file = File(argstr='%s', mandatory=True, exists=True, position=-2, desc='input dataset') + mask = File(exists=True, argstr='-mask %s', xor=['autoclip', 'automask'], + desc='compute correlation only across masked voxels') + spearman = traits.Bool(False, usedefault=True, argstr='-spearman', + desc='Quality index is 1 minus the Spearman (rank) ' + 'correlation coefficient of each sub-brick ' + 'with the median sub-brick. (default)') + quadrant = traits.Bool(False, usedefault=True, argstr='-quadrant', + desc='Similar to -spearman, but using 1 minus the ' + 'quadrant correlation coefficient as the ' + 'quality index.') + autoclip = traits.Bool(False, usedefault=True, argstr='-autoclip', xor=['mask'], + desc='clip off small voxels') + automask = traits.Bool(False, usedefault=True, argstr='-automask', xor=['mask'], + desc='clip off small voxels') + clip = traits.Float(argstr='-clip %f', desc='clip off values below') - outputs.stats = os.path.abspath(output_filename) - return outputs + interval = traits.Bool(False, usedefault=True, argstr='-range', + desc='write out the median + 3.5 MAD of outlier' + ' count with each timepoint') + out_file = File( + name_template='%s_tqual', name_source=['in_file'], argstr='> %s', + keep_extension=False, position=-1, desc='capture standard output') -class CalcInputSpec(AFNICommandInputSpec): - in_file_a = File(desc='input file to 3dcalc', - argstr='-a %s', position=0, mandatory=True, exists=True) - in_file_b = File(desc='operand file to 3dcalc', - argstr=' -b %s', position=1, exists=True) - in_file_c = File(desc='operand file to 3dcalc', - argstr=' -c %s', position=2, exists=True) - out_file = File(name_template="%s_calc", desc='output image file name', - argstr='-prefix %s', name_source="in_file_a") - expr = traits.Str(desc='expr', argstr='-expr "%s"', position=3, - mandatory=True) - start_idx = traits.Int(desc='start index for in_file_a', - requires=['stop_idx']) - stop_idx = traits.Int(desc='stop index for in_file_a', - requires=['start_idx']) - single_idx = traits.Int(desc='volume index for in_file_a') - other = File(desc='other options', argstr='') +class QualityIndexOutputSpec(TraitedSpec): + out_file = File(desc='file containing the captured standard output') -class Calc(AFNICommand): - """This program does voxel-by-voxel arithmetic on 3D datasets +class QualityIndex(CommandLine): + """Create a 3D dataset from 2D image files using AFNI to3d command - For complete details, see the `3dcalc Documentation. - `_ + For complete details, see the `to3d Documentation + `_ Examples ======== - >>> from nipype.interfaces import afni as afni - >>> calc = afni.Calc() - >>> calc.inputs.in_file_a = 'functional.nii' - >>> calc.inputs.in_file_b = 'functional2.nii' - >>> calc.inputs.expr='a*b' - >>> calc.inputs.out_file = 'functional_calc.nii.gz' - >>> calc.inputs.outputtype = "NIFTI" - >>> calc.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dcalc -a functional.nii -b functional2.nii -expr "a*b" -prefix functional_calc.nii.gz' + >>> from nipype.interfaces import afni + >>> tqual = afni.QualityIndex() + >>> tqual.inputs.in_file = 'functional.nii' + >>> tqual.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dTqual functional.nii > functional_tqual' + >>> res = tqual.run() #doctest: +SKIP """ + _cmd = '3dTqual' + input_spec = QualityIndexInputSpec + output_spec = QualityIndexOutputSpec - _cmd = '3dcalc' - input_spec = CalcInputSpec - output_spec = AFNICommandOutputSpec - def _format_arg(self, name, trait_spec, value): - if name == 'in_file_a': - arg = trait_spec.argstr % value - if isdefined(self.inputs.start_idx): - arg += '[%d..%d]' % (self.inputs.start_idx, - self.inputs.stop_idx) - if isdefined(self.inputs.single_idx): - arg += '[%d]' % (self.inputs.single_idx) - return arg - return super(Calc, self)._format_arg(name, trait_spec, value) +class ROIStatsInputSpec(CommandLineInputSpec): + in_file = File(desc='input file to 3dROIstats', + argstr='%s', + position=-1, + mandatory=True, + exists=True) - def _parse_inputs(self, skip=None): - """Skip the arguments without argstr metadata - """ - return super(Calc, self)._parse_inputs( - skip=('start_idx', 'stop_idx', 'other')) + mask = File(desc='input mask', + argstr='-mask %s', + position=3, + exists=True) + + mask_f2short = traits.Bool( + desc='Tells the program to convert a float mask ' + + 'to short integers, by simple rounding.', + argstr='-mask_f2short', + position=2) + quiet = traits.Bool(desc='execute quietly', + argstr='-quiet', + position=1) -class BlurInMaskInputSpec(AFNICommandInputSpec): - in_file = File( - desc='input file to 3dSkullStrip', - argstr='-input %s', - position=1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template='%s_blur', desc='output to the file', argstr='-prefix %s', - name_source='in_file', position=-1) - mask = File( - desc='Mask dataset, if desired. Blurring will occur only within the mask. Voxels NOT in the mask will be set to zero in the output.', - argstr='-mask %s') - multimask = File( - desc='Multi-mask dataset -- each distinct nonzero value in dataset will be treated as a separate mask for blurring purposes.', - argstr='-Mmask %s') - automask = traits.Bool( - desc='Create an automask from the input dataset.', - argstr='-automask') - fwhm = traits.Float( - desc='fwhm kernel size', - argstr='-FWHM %f', - mandatory=True) - preserve = traits.Bool( - desc='Normally, voxels not in the mask will be set to zero in the output. If you want the original values in the dataset to be preserved in the output, use this option.', - argstr='-preserve') - float_out = traits.Bool( - desc='Save dataset as floats, no matter what the input data type is.', - argstr='-float') - options = traits.Str(desc='options', argstr='%s', position=2) + terminal_output = traits.Enum('allatonce', + desc=('Control terminal output:' + '`allatonce` - waits till command is ' + 'finished to display output'), + nohash=True, mandatory=True, usedefault=True) +class ROIStatsOutputSpec(TraitedSpec): + stats = File(desc='output tab separated values file', exists=True) -class BlurInMask(AFNICommand): - """ Blurs a dataset spatially inside a mask. That's all. Experimental. - For complete details, see the `3dBlurInMask Documentation. - +class ROIStats(AFNICommandBase): + """Display statistics over masked regions + + For complete details, see the `3dROIstats Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> bim = afni.BlurInMask() - >>> bim.inputs.in_file = 'functional.nii' - >>> bim.inputs.mask = 'mask.nii' - >>> bim.inputs.fwhm = 5.0 - >>> bim.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dBlurInMask -input functional.nii -FWHM 5.000000 -mask mask.nii -prefix functional_blur' - >>> res = bim.run() # doctest: +SKIP + >>> roistats = afni.ROIStats() + >>> roistats.inputs.in_file = 'functional.nii' + >>> roistats.inputs.mask = 'skeleton_mask.nii.gz' + >>> roistats.inputs.quiet=True + >>> res = roistats.run() # doctest: +SKIP """ + _cmd = '3dROIstats' + input_spec = ROIStatsInputSpec + output_spec = ROIStatsOutputSpec - _cmd = '3dBlurInMask' - input_spec = BlurInMaskInputSpec - output_spec = AFNICommandOutputSpec + def aggregate_outputs(self, runtime=None, needed_outputs=None): + outputs = self._outputs() + output_filename = "roi_stats.csv" + with open(output_filename, "w") as f: + f.write(runtime.stdout) + outputs.stats = os.path.abspath(output_filename) + return outputs -class TCorrMapInputSpec(AFNICommandInputSpec): - in_file = File(exists=True, argstr='-input %s', mandatory=True, copyfile=False) - seeds = File(exists=True, argstr='-seed %s', xor=('seeds_width')) - mask = File(exists=True, argstr='-mask %s') - automask = traits.Bool(argstr='-automask') - polort = traits.Int(argstr='-polort %d') - bandpass = traits.Tuple((traits.Float(), traits.Float()), - argstr='-bpass %f %f') - regress_out_timeseries = traits.File(exists=True, argstr='-ort %s') - blur_fwhm = traits.Float(argstr='-Gblur %f') - seeds_width = traits.Float(argstr='-Mseed %f', xor=('seeds')) - # outputs - mean_file = File(argstr='-Mean %s', suffix='_mean', name_source="in_file") - zmean = File(argstr='-Zmean %s', suffix='_zmean', name_source="in_file") - qmean = File(argstr='-Qmean %s', suffix='_qmean', name_source="in_file") - pmean = File(argstr='-Pmean %s', suffix='_pmean', name_source="in_file") +class RefitInputSpec(CommandLineInputSpec): + in_file = File(desc='input file to 3drefit', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=True) - _thresh_opts = ('absolute_threshold', - 'var_absolute_threshold', - 'var_absolute_threshold_normalize') - thresholds = traits.List(traits.Int()) - absolute_threshold = File( - argstr='-Thresh %f %s', suffix='_thresh', - name_source="in_file", xor=_thresh_opts) - var_absolute_threshold = File( - argstr='-VarThresh %f %f %f %s', suffix='_varthresh', - name_source="in_file", xor=_thresh_opts) - var_absolute_threshold_normalize = File( - argstr='-VarThreshN %f %f %f %s', suffix='_varthreshn', - name_source="in_file", xor=_thresh_opts) + deoblique = traits.Bool(desc='replace current transformation'\ + ' matrix with cardinal matrix', + argstr='-deoblique') - correlation_maps = File( - argstr='-CorrMap %s', name_source="in_file") - correlation_maps_masked = File( - argstr='-CorrMask %s', name_source="in_file") + xorigin = Str(desc='x distance for edge voxel offset', + argstr='-xorigin %s') - _expr_opts = ('average_expr', 'average_expr_nonzero', 'sum_expr') - expr = traits.Str() - average_expr = File( - argstr='-Aexpr %s %s', suffix='_aexpr', - name_source='in_file', xor=_expr_opts) - average_expr_nonzero = File( - argstr='-Cexpr %s %s', suffix='_cexpr', - name_source='in_file', xor=_expr_opts) - sum_expr = File( - argstr='-Sexpr %s %s', suffix='_sexpr', - name_source='in_file', xor=_expr_opts) - histogram_bin_numbers = traits.Int() - histogram = File( - name_source='in_file', argstr='-Hist %d %s', suffix='_hist') + yorigin = Str(desc='y distance for edge voxel offset', + argstr='-yorigin %s') + zorigin = Str(desc='z distance for edge voxel offset', + argstr='-zorigin %s') + xdel = traits.Float(desc='new x voxel dimension in mm', + argstr='-xdel %f') -class TCorrMapOutputSpec(TraitedSpec): + ydel = traits.Float(desc='new y voxel dimension in mm', + argstr='-ydel %f') - mean_file = File() - zmean = File() - qmean = File() - pmean = File() - absolute_threshold = File() - var_absolute_threshold = File() - var_absolute_threshold_normalize = File() - correlation_maps = File() - correlation_maps_masked = File() - average_expr = File() - average_expr_nonzero = File() - sum_expr = File() - histogram = File() + zdel = traits.Float(desc='new z voxel dimension in mm', + argstr='-zdel %f') + space = traits.Enum('TLRC', 'MNI', 'ORIG', + argstr='-space %s', + desc='Associates the dataset with a specific'\ + ' template type, e.g. TLRC, MNI, ORIG') -class TCorrMap(AFNICommand): - """ For each voxel time series, computes the correlation between it - and all other voxels, and combines this set of values into the - output dataset(s) in some way. - For complete details, see the `3dTcorrMap Documentation. - +class Refit(AFNICommandBase): + """Changes some of the information inside a 3D dataset's header + + For complete details, see the `3drefit Documentation. + Examples ======== >>> from nipype.interfaces import afni as afni - >>> tcm = afni.TCorrMap() - >>> tcm.inputs.in_file = 'functional.nii' - >>> tcm.inputs.mask = 'mask.nii' - >>> tcm.mean_file = '%s_meancorr.nii' - >>> res = tcm.run() # doctest: +SKIP + >>> refit = afni.Refit() + >>> refit.inputs.in_file = 'structural.nii' + >>> refit.inputs.deoblique = True + >>> refit.cmdline # doctest: +IGNORE_UNICODE + '3drefit -deoblique structural.nii' + >>> res = refit.run() # doctest: +SKIP """ + _cmd = '3drefit' + input_spec = RefitInputSpec + output_spec = AFNICommandOutputSpec - _cmd = '3dTcorrMap' - input_spec = TCorrMapInputSpec - output_spec = TCorrMapOutputSpec - _additional_metadata = ['suffix'] + def _list_outputs(self): + outputs = self.output_spec().get() + outputs["out_file"] = os.path.abspath(self.inputs.in_file) + return outputs - def _format_arg(self, name, trait_spec, value): - if name in self.inputs._thresh_opts: - return trait_spec.argstr % self.inputs.thresholds + [value] - elif name in self.inputs._expr_opts: - return trait_spec.argstr % (self.inputs.expr, value) - elif name == 'histogram': - return trait_spec.argstr % (self.inputs.histogram_bin_numbers, - value) - else: - return super(TCorrMap, self)._format_arg(name, trait_spec, value) +class ResampleInputSpec(AFNICommandInputSpec): + + in_file = File(desc='input file to 3dresample', + argstr='-inset %s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) -class AutoboxInputSpec(AFNICommandInputSpec): - in_file = File(exists=True, mandatory=True, argstr='-input %s', - desc='input file', copyfile=False) - padding = traits.Int( - argstr='-npad %d', - desc='Number of extra voxels to pad on each side of box') - out_file = File(argstr="-prefix %s", name_source="in_file") - no_clustering = traits.Bool( - argstr='-noclust', - desc="""Don't do any clustering to find box. Any non-zero - voxel will be preserved in the cropped volume. - The default method uses some clustering to find the - cropping box, and will clip off small isolated blobs.""") + out_file = File(name_template="%s_resample", desc='output image file name', + argstr='-prefix %s', name_source="in_file") + orientation = Str(desc='new orientation code', + argstr='-orient %s') -class AutoboxOutputSpec(TraitedSpec): # out_file not mandatory - x_min = traits.Int() - x_max = traits.Int() - y_min = traits.Int() - y_max = traits.Int() - z_min = traits.Int() - z_max = traits.Int() + resample_mode = traits.Enum('NN', 'Li', 'Cu', 'Bk', + argstr='-rmode %s', + desc="resampling method from set {'NN', "\ + "'Li', 'Cu', 'Bk'}. These are for "\ + "'Nearest Neighbor', 'Linear', 'Cubic' "\ + "and 'Blocky' interpolation, respectively. "\ + "Default is NN.") - out_file = File(desc='output file') + voxel_size = traits.Tuple(*[traits.Float()] * 3, + argstr='-dxyz %f %f %f', + desc="resample to new dx, dy and dz") + master = traits.File(argstr='-master %s', + desc='align dataset grid to a reference file') -class Autobox(AFNICommand): - """ Computes size of a box that fits around the volume. - Also can be used to crop the volume to that box. - For complete details, see the `3dAutobox Documentation. - +class Resample(AFNICommand): + """Resample or reorient an image using AFNI 3dresample command + + For complete details, see the `3dresample Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> abox = afni.Autobox() - >>> abox.inputs.in_file = 'structural.nii' - >>> abox.inputs.padding = 5 - >>> res = abox.run() # doctest: +SKIP - - """ - - _cmd = '3dAutobox' - input_spec = AutoboxInputSpec - output_spec = AutoboxOutputSpec + >>> resample = afni.Resample() + >>> resample.inputs.in_file = 'functional.nii' + >>> resample.inputs.orientation= 'RPI' + >>> resample.inputs.outputtype = "NIFTI" + >>> resample.cmdline # doctest: +IGNORE_UNICODE + '3dresample -orient RPI -prefix functional_resample.nii -inset functional.nii' + >>> res = resample.run() # doctest: +SKIP - def aggregate_outputs(self, runtime=None, needed_outputs=None): - outputs = self._outputs() - pattern = 'x=(?P-?\d+)\.\.(?P-?\d+) y=(?P-?\d+)\.\.(?P-?\d+) z=(?P-?\d+)\.\.(?P-?\d+)' - for line in runtime.stderr.split('\n'): - m = re.search(pattern, line) - if m: - d = m.groupdict() - for k in list(d.keys()): - d[k] = int(d[k]) - outputs.set(**d) - outputs.set(out_file=self._gen_filename('out_file')) - return outputs + """ - def _gen_filename(self, name): - if name == 'out_file' and (not isdefined(self.inputs.out_file)): - return Undefined - return super(Autobox, self)._gen_filename(name) + _cmd = '3dresample' + input_spec = ResampleInputSpec + output_spec = AFNICommandOutputSpec class RetroicorInputSpec(AFNICommandInputSpec): @@ -2393,7 +2283,10 @@ class RetroicorInputSpec(AFNICommandInputSpec): argstr='-resp %s', position=-3, exists=True) - threshold = traits.Int(desc='Threshold for detection of R-wave peaks in input (Make sure it is above the background noise level, Try 3/4 or 4/5 times range plus minimum)', + threshold = traits.Int(desc='Threshold for detection of R-wave peaks in '\ + 'input (Make sure it is above the background '\ + 'noise level, Try 3/4 or 4/5 times range '\ + 'plus minimum)', argstr='-threshold %d', position=-4) order = traits.Int(desc='The order of the correction (2 is typical)', @@ -2446,483 +2339,536 @@ class Retroicor(AFNICommand): output_spec = AFNICommandOutputSpec -class AFNItoNIFTIInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dAFNItoNIFTI', - argstr='%s', +class SegInputSpec(CommandLineInputSpec): + in_file = File(desc='ANAT is the volume to segment', + argstr='-anat %s', position=-1, mandatory=True, exists=True, - copyfile=False) - out_file = File(name_template="%s.nii", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - hash_files = False + copyfile=True) + + mask = traits.Either(traits.Enum('AUTO'), + File(exists=True), + desc=('only non-zero voxels in mask are analyzed. ' + 'mask can either be a dataset or the string ' + '"AUTO" which would use AFNI\'s automask ' + 'function to create the mask.'), + argstr='-mask %s', + position=-2, + mandatory=True) + blur_meth = traits.Enum('BFT', 'BIM', + argstr='-blur_meth %s', + desc='set the blurring method for bias field estimation') -class AFNItoNIFTI(AFNICommand): - """Changes AFNI format files to NIFTI format using 3dAFNItoNIFTI + bias_fwhm = traits.Float(desc='The amount of blurring used when estimating the field bias with the Wells method', + argstr='-bias_fwhm %f') + + classes = Str(desc='CLASS_STRING is a semicolon delimited string of class labels', + argstr='-classes %s') + + bmrf = traits.Float(desc='Weighting factor controlling spatial homogeneity of the classifications', + argstr='-bmrf %f') + + bias_classes = Str(desc='A semicolon delimited string of classes that '\ + 'contribute to the estimation of the bias field', + argstr='-bias_classes %s') + + prefix = Str(desc='the prefix for the output folder containing all output volumes', + argstr='-prefix %s') + + mixfrac = Str(desc='MIXFRAC sets up the volume-wide (within mask) tissue '\ + 'fractions while initializing the segmentation (see '\ + 'IGNORE for exception)', + argstr='-mixfrac %s') + + mixfloor = traits.Float(desc='Set the minimum value for any class\'s mixing fraction', + argstr='-mixfloor %f') + + main_N = traits.Int(desc='Number of iterations to perform.', + argstr='-main_N %d') + + +class Seg(AFNICommandBase): + """3dSeg segments brain volumes into tissue classes. The program allows + for adding a variety of global and voxelwise priors. However for the + moment, only mixing fractions and MRF are documented. - see AFNI Documentation: - this can also convert 2D or 1D data, which you can numpy.squeeze() to remove extra dimensions + For complete details, see the `3dSeg Documentation. + Examples ======== - >>> from nipype.interfaces import afni as afni - >>> a2n = afni.AFNItoNIFTI() - >>> a2n.inputs.in_file = 'afni_output.3D' - >>> a2n.inputs.out_file = 'afni_output.nii' - >>> a2n.cmdline # doctest: +IGNORE_UNICODE - '3dAFNItoNIFTI -prefix afni_output.nii afni_output.3D' + >>> from nipype.interfaces.afni import preprocess + >>> seg = preprocess.Seg() + >>> seg.inputs.in_file = 'structural.nii' + >>> seg.inputs.mask = 'AUTO' + >>> res = seg.run() # doctest: +SKIP """ - _cmd = '3dAFNItoNIFTI' - input_spec = AFNItoNIFTIInputSpec + _cmd = '3dSeg' + input_spec = SegInputSpec output_spec = AFNICommandOutputSpec - def _overload_extension(self, value): - path, base, ext = split_filename(value) - if ext.lower() not in [".1d", ".nii.gz", ".1D"]: - ext = ext + ".nii" - return os.path.join(path, base + ext) + def aggregate_outputs(self, runtime=None, needed_outputs=None): - def _gen_filename(self, name): - return os.path.abspath(super(AFNItoNIFTI, self)._gen_filename(name)) + import glob + outputs = self._outputs() -class EvalInputSpec(AFNICommandInputSpec): - in_file_a = File(desc='input file to 1deval', - argstr='-a %s', position=0, mandatory=True, exists=True) - in_file_b = File(desc='operand file to 1deval', - argstr=' -b %s', position=1, exists=True) - in_file_c = File(desc='operand file to 1deval', - argstr=' -c %s', position=2, exists=True) - out_file = File(name_template="%s_calc", desc='output image file name', - argstr='-prefix %s', name_source="in_file_a") - out1D = traits.Bool(desc="output in 1D", - argstr='-1D') - expr = traits.Str(desc='expr', argstr='-expr "%s"', position=3, - mandatory=True) - start_idx = traits.Int(desc='start index for in_file_a', - requires=['stop_idx']) - stop_idx = traits.Int(desc='stop index for in_file_a', - requires=['start_idx']) - single_idx = traits.Int(desc='volume index for in_file_a') - other = File(desc='other options', argstr='') + if isdefined(self.inputs.prefix): + outfile = os.path.join(os.getcwd(), self.inputs.prefix, 'Classes+*.BRIK') + else: + outfile = os.path.join(os.getcwd(), 'Segsy', 'Classes+*.BRIK') + outputs.out_file = glob.glob(outfile)[0] + return outputs -class Eval(AFNICommand): - """Evaluates an expression that may include columns of data from one or more text files - see AFNI Documentation: +class SkullStripInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dSkullStrip', + argstr='-input %s', + position=1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File(name_template="%s_skullstrip", desc='output image file name', + argstr='-prefix %s', name_source="in_file") + + +class SkullStrip(AFNICommand): + """A program to extract the brain from surrounding + tissue from MRI T1-weighted images + + For complete details, see the `3dSkullStrip Documentation. + `_ Examples ======== >>> from nipype.interfaces import afni as afni - >>> eval = afni.Eval() - >>> eval.inputs.in_file_a = 'seed.1D' - >>> eval.inputs.in_file_b = 'resp.1D' - >>> eval.inputs.expr='a*b' - >>> eval.inputs.out1D = True - >>> eval.inputs.out_file = 'data_calc.1D' - >>> calc.cmdline #doctest: +SKIP +IGNORE_UNICODE - '3deval -a timeseries1.1D -b timeseries2.1D -expr "a*b" -1D -prefix data_calc.1D' + >>> skullstrip = afni.SkullStrip() + >>> skullstrip.inputs.in_file = 'functional.nii' + >>> skullstrip.inputs.args = '-o_ply' + >>> res = skullstrip.run() # doctest: +SKIP """ - - _cmd = '1deval' - input_spec = EvalInputSpec + _cmd = '3dSkullStrip' + _redirect_x = True + input_spec = SkullStripInputSpec output_spec = AFNICommandOutputSpec - def _format_arg(self, name, trait_spec, value): - if name == 'in_file_a': - arg = trait_spec.argstr % value - if isdefined(self.inputs.start_idx): - arg += '[%d..%d]' % (self.inputs.start_idx, - self.inputs.stop_idx) - if isdefined(self.inputs.single_idx): - arg += '[%d]' % (self.inputs.single_idx) - return arg - return super(Eval, self)._format_arg(name, trait_spec, value) + def __init__(self, **inputs): + super(SkullStrip, self).__init__(**inputs) + if not no_afni(): + v = Info.version() - def _parse_inputs(self, skip=None): - """Skip the arguments without argstr metadata - """ - return super(Eval, self)._parse_inputs( - skip=('start_idx', 'stop_idx', 'out1D', 'other')) + # As of AFNI 16.0.00, redirect_x is not needed + if isinstance(v[0], int) and v[0] > 15: + self._redirect_x = False -class MeansInputSpec(AFNICommandInputSpec): - in_file_a = File(desc='input file to 3dMean', - argstr='%s', - position=0, - mandatory=True, - exists=True) - in_file_b = File(desc='another input file to 3dMean', - argstr='%s', - position=1, - exists=True) - out_file = File(name_template="%s_mean", desc='output image file name', - argstr='-prefix %s', name_source="in_file_a") - scale = traits.Str(desc='scaling of output', argstr='-%sscale') - non_zero = traits.Bool(desc='use only non-zero values', argstr='-non_zero') - std_dev = traits.Bool(desc='calculate std dev', argstr='-stdev') - sqr = traits.Bool(desc='mean square instead of value', argstr='-sqr') - summ = traits.Bool(desc='take sum, (not average)', argstr='-sum') - count = traits.Bool(desc='compute count of non-zero voxels', argstr='-count') - mask_inter = traits.Bool(desc='create intersection mask', argstr='-mask_inter') - mask_union = traits.Bool(desc='create union mask', argstr='-mask_union') +class TCatInputSpec(AFNICommandInputSpec): + in_files = InputMultiPath( + File(exists=True), + desc='input file to 3dTcat', + argstr=' %s', + position=-1, + mandatory=True, + copyfile=False) + out_file = File(name_template="%s_tcat", desc='output image file name', + argstr='-prefix %s', name_source="in_files") + rlt = Str(desc='options', argstr='-rlt%s', position=1) + + +class TCat(AFNICommand): + """Concatenate sub-bricks from input datasets into + one big 3D+time dataset + + For complete details, see the `3dTcat Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> tcat = afni.TCat() + >>> tcat.inputs.in_files = ['functional.nii', 'functional2.nii'] + >>> tcat.inputs.out_file= 'functional_tcat.nii' + >>> tcat.inputs.rlt = '+' + >>> res = tcat.run() # doctest: +SKIP + + """ + + _cmd = '3dTcat' + input_spec = TCatInputSpec + output_spec = AFNICommandOutputSpec + +class TCorr1DInputSpec(AFNICommandInputSpec): + xset = File(desc='3d+time dataset input', + argstr=' %s', + position=-2, + mandatory=True, + exists=True, + copyfile=False) + y_1d = File(desc='1D time series file input', + argstr=' %s', + position=-1, + mandatory=True, + exists=True) + out_file = File(desc='output filename prefix', + name_template='%s_correlation.nii.gz', + argstr='-prefix %s', + name_source='xset', + keep_extension=True) + pearson = traits.Bool(desc='Correlation is the normal' + + ' Pearson correlation coefficient', + argstr=' -pearson', + xor=['spearman', 'quadrant', 'ktaub'], + position=1) + spearman = traits.Bool(desc='Correlation is the' + + ' Spearman (rank) correlation coefficient', + argstr=' -spearman', + xor=['pearson', 'quadrant', 'ktaub'], + position=1) + quadrant = traits.Bool(desc='Correlation is the' + + ' quadrant correlation coefficient', + argstr=' -quadrant', + xor=['pearson', 'spearman', 'ktaub'], + position=1) + ktaub = traits.Bool(desc='Correlation is the' + + ' Kendall\'s tau_b correlation coefficient', + argstr=' -ktaub', + xor=['pearson', 'spearman', 'quadrant'], + position=1) -class Means(AFNICommand): - """Takes the voxel-by-voxel mean of all input datasets using 3dMean +class TCorr1DOutputSpec(TraitedSpec): + out_file = File(desc='output file containing correlations', + exists=True) - see AFNI Documentation: - Examples - ======== +class TCorr1D(AFNICommand): + """Computes the correlation coefficient between each voxel time series + in the input 3D+time dataset. + For complete details, see the `3dTcorr1D Documentation. + `_ >>> from nipype.interfaces import afni as afni - >>> means = afni.Means() - >>> means.inputs.in_file_a = 'im1.nii' - >>> means.inputs.in_file_b = 'im2.nii' - >>> means.inputs.out_file = 'output.nii' - >>> means.cmdline # doctest: +IGNORE_UNICODE - '3dMean im1.nii im2.nii -prefix output.nii' - + >>> tcorr1D = afni.TCorr1D() + >>> tcorr1D.inputs.xset= 'u_rc1s1_Template.nii' + >>> tcorr1D.inputs.y_1d = 'seed.1D' + >>> tcorr1D.cmdline # doctest: +IGNORE_UNICODE + '3dTcorr1D -prefix u_rc1s1_Template_correlation.nii.gz u_rc1s1_Template.nii seed.1D' + >>> res = tcorr1D.run() # doctest: +SKIP """ - _cmd = '3dMean' - input_spec = MeansInputSpec - output_spec = AFNICommandOutputSpec - + _cmd = '3dTcorr1D' + input_spec = TCorr1DInputSpec + output_spec = TCorr1DOutputSpec -class HistInputSpec(CommandLineInputSpec): - in_file = File( - desc='input file to 3dHist', argstr='-input %s', position=1, mandatory=True, - exists=True, copyfile=False) - out_file = File( - desc='Write histogram to niml file with this prefix', name_template='%s_hist', - keep_extension=False, argstr='-prefix %s', name_source=['in_file']) - showhist = traits.Bool(False, usedefault=True, desc='write a text visual histogram', - argstr='-showhist') - out_show = File( - name_template="%s_hist.out", desc='output image file name', keep_extension=False, - argstr="> %s", name_source="in_file", position=-1) - mask = File(desc='matrix to align input file', argstr='-mask %s', exists=True) - nbin = traits.Int(desc='number of bins', argstr='-nbin %d') - max_value = traits.Float(argstr='-max %f', desc='maximum intensity value') - min_value = traits.Float(argstr='-min %f', desc='minimum intensity value') - bin_width = traits.Float(argstr='-binwidth %f', desc='bin width') -class HistOutputSpec(TraitedSpec): - out_file = File(desc='output file', exists=True) - out_show = File(desc='output visual histogram') +class TCorrMapInputSpec(AFNICommandInputSpec): + in_file = File(exists=True, argstr='-input %s', mandatory=True, copyfile=False) + seeds = File(exists=True, argstr='-seed %s', xor=('seeds_width')) + mask = File(exists=True, argstr='-mask %s') + automask = traits.Bool(argstr='-automask') + polort = traits.Int(argstr='-polort %d') + bandpass = traits.Tuple((traits.Float(), traits.Float()), + argstr='-bpass %f %f') + regress_out_timeseries = traits.File(exists=True, argstr='-ort %s') + blur_fwhm = traits.Float(argstr='-Gblur %f') + seeds_width = traits.Float(argstr='-Mseed %f', xor=('seeds')) + # outputs + mean_file = File(argstr='-Mean %s', suffix='_mean', name_source="in_file") + zmean = File(argstr='-Zmean %s', suffix='_zmean', name_source="in_file") + qmean = File(argstr='-Qmean %s', suffix='_qmean', name_source="in_file") + pmean = File(argstr='-Pmean %s', suffix='_pmean', name_source="in_file") -class Hist(AFNICommandBase): - """Computes average of all voxels in the input dataset - which satisfy the criterion in the options list + _thresh_opts = ('absolute_threshold', + 'var_absolute_threshold', + 'var_absolute_threshold_normalize') + thresholds = traits.List(traits.Int()) + absolute_threshold = File( + argstr='-Thresh %f %s', suffix='_thresh', + name_source="in_file", xor=_thresh_opts) + var_absolute_threshold = File( + argstr='-VarThresh %f %f %f %s', suffix='_varthresh', + name_source="in_file", xor=_thresh_opts) + var_absolute_threshold_normalize = File( + argstr='-VarThreshN %f %f %f %s', suffix='_varthreshn', + name_source="in_file", xor=_thresh_opts) - For complete details, see the `3dHist Documentation. - `_ + correlation_maps = File( + argstr='-CorrMap %s', name_source="in_file") + correlation_maps_masked = File( + argstr='-CorrMask %s', name_source="in_file") - Examples - ======== + _expr_opts = ('average_expr', 'average_expr_nonzero', 'sum_expr') + expr = Str() + average_expr = File( + argstr='-Aexpr %s %s', suffix='_aexpr', + name_source='in_file', xor=_expr_opts) + average_expr_nonzero = File( + argstr='-Cexpr %s %s', suffix='_cexpr', + name_source='in_file', xor=_expr_opts) + sum_expr = File( + argstr='-Sexpr %s %s', suffix='_sexpr', + name_source='in_file', xor=_expr_opts) + histogram_bin_numbers = traits.Int() + histogram = File( + name_source='in_file', argstr='-Hist %d %s', suffix='_hist') - >>> from nipype.interfaces import afni as afni - >>> hist = afni.Hist() - >>> hist.inputs.in_file = 'functional.nii' - >>> hist.cmdline # doctest: +IGNORE_UNICODE - '3dHist -input functional.nii -prefix functional_hist' - >>> res = hist.run() # doctest: +SKIP - """ +class TCorrMapOutputSpec(TraitedSpec): + mean_file = File() + zmean = File() + qmean = File() + pmean = File() + absolute_threshold = File() + var_absolute_threshold = File() + var_absolute_threshold_normalize = File() + correlation_maps = File() + correlation_maps_masked = File() + average_expr = File() + average_expr_nonzero = File() + sum_expr = File() + histogram = File() - _cmd = '3dHist' - input_spec = HistInputSpec - output_spec = HistOutputSpec - _redirect_x = True - def __init__(self, **inputs): - super(Hist, self).__init__(**inputs) - if not no_afni(): - version = Info.version() +class TCorrMap(AFNICommand): + """ For each voxel time series, computes the correlation between it + and all other voxels, and combines this set of values into the + output dataset(s) in some way. - # As of AFNI 16.0.00, redirect_x is not needed - if isinstance(version[0], int) and version[0] > 15: - self._redirect_x = False + For complete details, see the `3dTcorrMap Documentation. + - def _parse_inputs(self, skip=None): - if not self.inputs.showhist: - if skip is None: - skip = [] - skip += ['out_show'] - return super(Hist, self)._parse_inputs(skip=skip) + Examples + ======== + >>> from nipype.interfaces import afni as afni + >>> tcm = afni.TCorrMap() + >>> tcm.inputs.in_file = 'functional.nii' + >>> tcm.inputs.mask = 'mask.nii' + >>> tcm.mean_file = '%s_meancorr.nii' + >>> res = tcm.run() # doctest: +SKIP - def _list_outputs(self): - outputs = super(Hist, self)._list_outputs() - outputs['out_file'] += '.niml.hist' - if not self.inputs.showhist: - outputs['out_show'] = Undefined - return outputs + """ + _cmd = '3dTcorrMap' + input_spec = TCorrMapInputSpec + output_spec = TCorrMapOutputSpec + _additional_metadata = ['suffix'] -class FWHMxInputSpec(CommandLineInputSpec): - in_file = File(desc='input dataset', argstr='-input %s', mandatory=True, exists=True) - out_file = File(argstr='> %s', name_source='in_file', name_template='%s_fwhmx.out', - position=-1, keep_extension=False, desc='output file') - out_subbricks = File(argstr='-out %s', name_source='in_file', name_template='%s_subbricks.out', - keep_extension=False, desc='output file listing the subbricks FWHM') - mask = File(desc='use only voxels that are nonzero in mask', argstr='-mask %s', exists=True) - automask = traits.Bool(False, usedefault=True, argstr='-automask', - desc='compute a mask from THIS dataset, a la 3dAutomask') - detrend = traits.Either( - traits.Bool(), traits.Int(), default=False, argstr='-detrend', xor=['demed'], usedefault=True, - desc='instead of demed (0th order detrending), detrend to the specified order. If order ' - 'is not given, the program picks q=NT/30. -detrend disables -demed, and includes ' - '-unif.') - demed = traits.Bool( - False, argstr='-demed', xor=['detrend'], - desc='If the input dataset has more than one sub-brick (e.g., has a time axis), then ' - 'subtract the median of each voxel\'s time series before processing FWHM. This will ' - 'tend to remove intrinsic spatial structure and leave behind the noise.') - unif = traits.Bool(False, argstr='-unif', - desc='If the input dataset has more than one sub-brick, then normalize each' - ' voxel\'s time series to have the same MAD before processing FWHM.') - out_detrend = File(argstr='-detprefix %s', name_source='in_file', name_template='%s_detrend', - keep_extension=False, desc='Save the detrended file into a dataset') - geom = traits.Bool(argstr='-geom', xor=['arith'], - desc='if in_file has more than one sub-brick, compute the final estimate as' - 'the geometric mean of the individual sub-brick FWHM estimates') - arith = traits.Bool(argstr='-arith', xor=['geom'], - desc='if in_file has more than one sub-brick, compute the final estimate as' - 'the arithmetic mean of the individual sub-brick FWHM estimates') - combine = traits.Bool(argstr='-combine', desc='combine the final measurements along each axis') - compat = traits.Bool(argstr='-compat', desc='be compatible with the older 3dFWHM') - acf = traits.Either( - traits.Bool(), File(), traits.Tuple(File(exists=True), traits.Float()), - default=False, usedefault=True, argstr='-acf', desc='computes the spatial autocorrelation') + def _format_arg(self, name, trait_spec, value): + if name in self.inputs._thresh_opts: + return trait_spec.argstr % self.inputs.thresholds + [value] + elif name in self.inputs._expr_opts: + return trait_spec.argstr % (self.inputs.expr, value) + elif name == 'histogram': + return trait_spec.argstr % (self.inputs.histogram_bin_numbers, + value) + else: + return super(TCorrMap, self)._format_arg(name, trait_spec, value) -class FWHMxOutputSpec(TraitedSpec): - out_file = File(exists=True, desc='output file') - out_subbricks = File(exists=True, desc='output file (subbricks)') - out_detrend = File(desc='output file, detrended') - fwhm = traits.Either( - traits.Tuple(traits.Float(), traits.Float(), traits.Float()), - traits.Tuple(traits.Float(), traits.Float(), traits.Float(), traits.Float()), - desc='FWHM along each axis') - acf_param = traits.Either( - traits.Tuple(traits.Float(), traits.Float(), traits.Float()), - traits.Tuple(traits.Float(), traits.Float(), traits.Float(), traits.Float()), - desc='fitted ACF model parameters') - out_acf = File(exists=True, desc='output acf file') +class TCorrelateInputSpec(AFNICommandInputSpec): + xset = File(desc='input xset', + argstr=' %s', + position=-2, + mandatory=True, + exists=True, + copyfile=False) + yset = File(desc='input yset', + argstr=' %s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File(name_template="%s_tcorr", desc='output image file name', + argstr='-prefix %s', name_source="xset") + pearson = traits.Bool(desc='Correlation is the normal' + + ' Pearson correlation coefficient', + argstr='-pearson', + position=1) + polort = traits.Int(desc='Remove polynomical trend of order m', + argstr='-polort %d', position=2) +class TCorrelate(AFNICommand): + """Computes the correlation coefficient between corresponding voxel + time series in two input 3D+time datasets 'xset' and 'yset' -class FWHMx(AFNICommandBase): - """ - Unlike the older 3dFWHM, this program computes FWHMs for all sub-bricks - in the input dataset, each one separately. The output for each one is - written to the file specified by '-out'. The mean (arithmetic or geometric) - of all the FWHMs along each axis is written to stdout. (A non-positive - output value indicates something bad happened; e.g., FWHM in z is meaningless - for a 2D dataset; the estimation method computed incoherent intermediate results.) + For complete details, see the `3dTcorrelate Documentation. + `_ Examples - -------- - - >>> from nipype.interfaces import afni as afp - >>> fwhm = afp.FWHMx() - >>> fwhm.inputs.in_file = 'functional.nii' - >>> fwhm.cmdline # doctest: +IGNORE_UNICODE - '3dFWHMx -input functional.nii -out functional_subbricks.out > functional_fwhmx.out' - - - (Classic) METHOD: - - * Calculate ratio of variance of first differences to data variance. - * Should be the same as 3dFWHM for a 1-brick dataset. - (But the output format is simpler to use in a script.) + ======== + >>> from nipype.interfaces import afni as afni + >>> tcorrelate = afni.TCorrelate() + >>> tcorrelate.inputs.xset= 'u_rc1s1_Template.nii' + >>> tcorrelate.inputs.yset = 'u_rc1s2_Template.nii' + >>> tcorrelate.inputs.out_file = 'functional_tcorrelate.nii.gz' + >>> tcorrelate.inputs.polort = -1 + >>> tcorrelate.inputs.pearson = True + >>> res = tcarrelate.run() # doctest: +SKIP - .. note:: IMPORTANT NOTE [AFNI > 16] + """ - A completely new method for estimating and using noise smoothness values is - now available in 3dFWHMx and 3dClustSim. This method is implemented in the - '-acf' options to both programs. 'ACF' stands for (spatial) AutoCorrelation - Function, and it is estimated by calculating moments of differences out to - a larger radius than before. + _cmd = '3dTcorrelate' + input_spec = TCorrelateInputSpec + output_spec = AFNICommandOutputSpec - Notably, real FMRI data does not actually have a Gaussian-shaped ACF, so the - estimated ACF is then fit (in 3dFWHMx) to a mixed model (Gaussian plus - mono-exponential) of the form - .. math:: +class TShiftInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dTShift', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) - ACF(r) = a * exp(-r*r/(2*b*b)) + (1-a)*exp(-r/c) + out_file = File(name_template="%s_tshift", desc='output image file name', + argstr='-prefix %s', name_source="in_file") + tr = Str(desc='manually set the TR. You can attach suffix "s" for seconds'\ + ' or "ms" for milliseconds.', + argstr='-TR %s') - where :math:`r` is the radius, and :math:`a, b, c` are the fitted parameters. - The apparent FWHM from this model is usually somewhat larger in real data - than the FWHM estimated from just the nearest-neighbor differences used - in the 'classic' analysis. + tzero = traits.Float(desc='align each slice to given time offset', + argstr='-tzero %s', + xor=['tslice']) - The longer tails provided by the mono-exponential are also significant. - 3dClustSim has also been modified to use the ACF model given above to generate - noise random fields. + tslice = traits.Int(desc='align each slice to time offset of given slice', + argstr='-slice %s', + xor=['tzero']) + ignore = traits.Int(desc='ignore the first set of points specified', + argstr='-ignore %s') - .. note:: TL;DR or summary + interp = traits.Enum(('Fourier', 'linear', 'cubic', 'quintic', 'heptic'), + desc='different interpolation methods (see 3dTShift '\ + 'for details) default = Fourier', argstr='-%s') - The take-awaymessage is that the 'classic' 3dFWHMx and - 3dClustSim analysis, using a pure Gaussian ACF, is not very correct for - FMRI data -- I cannot speak for PET or MEG data. + tpattern = Str(desc='use specified slice time pattern rather than one in '\ + 'header', + argstr='-tpattern %s') + rlt = traits.Bool(desc='Before shifting, remove the mean and linear trend', + argstr="-rlt") - .. warning:: + rltplus = traits.Bool(desc='Before shifting, remove the mean and linear '\ + 'trend and later put back the mean', + argstr="-rlt+") - Do NOT use 3dFWHMx on the statistical results (e.g., '-bucket') from - 3dDeconvolve or 3dREMLfit!!! The function of 3dFWHMx is to estimate - the smoothness of the time series NOISE, not of the statistics. This - proscription is especially true if you plan to use 3dClustSim next!! +class TShift(AFNICommand): + """Shifts voxel time series from input + so that seperate slices are aligned to the same + temporal origin - .. note:: Recommendations + For complete details, see the `3dTshift Documentation. + - * For FMRI statistical purposes, you DO NOT want the FWHM to reflect - the spatial structure of the underlying anatomy. Rather, you want - the FWHM to reflect the spatial structure of the noise. This means - that the input dataset should not have anatomical (spatial) structure. - * One good form of input is the output of '3dDeconvolve -errts', which is - the dataset of residuals left over after the GLM fitted signal model is - subtracted out from each voxel's time series. - * If you don't want to go to that much trouble, use '-detrend' to approximately - subtract out the anatomical spatial structure, OR use the output of 3dDetrend - for the same purpose. - * If you do not use '-detrend', the program attempts to find non-zero spatial - structure in the input, and will print a warning message if it is detected. + Examples + ======== + >>> from nipype.interfaces import afni as afni + >>> tshift = afni.TShift() + >>> tshift.inputs.in_file = 'functional.nii' + >>> tshift.inputs.tpattern = 'alt+z' + >>> tshift.inputs.tzero = 0.0 + >>> tshift.cmdline #doctest: +IGNORE_UNICODE + '3dTshift -prefix functional_tshift -tpattern alt+z -tzero 0.0 functional.nii' + >>> res = tshift.run() # doctest: +SKIP - .. note:: Notes on -demend + """ + _cmd = '3dTshift' + input_spec = TShiftInputSpec + output_spec = AFNICommandOutputSpec - * I recommend this option, and it is not the default only for historical - compatibility reasons. It may become the default someday. - * It is already the default in program 3dBlurToFWHM. This is the same detrending - as done in 3dDespike; using 2*q+3 basis functions for q > 0. - * If you don't use '-detrend', the program now [Aug 2010] checks if a large number - of voxels are have significant nonzero means. If so, the program will print a - warning message suggesting the use of '-detrend', since inherent spatial - structure in the image will bias the estimation of the FWHM of the image time - series NOISE (which is usually the point of using 3dFWHMx). +class TStatInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dTstat', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) - """ - _cmd = '3dFWHMx' - input_spec = FWHMxInputSpec - output_spec = FWHMxOutputSpec - _acf = True + out_file = File(name_template="%s_tstat", desc='output image file name', + argstr='-prefix %s', name_source="in_file") - def _parse_inputs(self, skip=None): - if not self.inputs.detrend: - if skip is None: - skip = [] - skip += ['out_detrend'] - return super(FWHMx, self)._parse_inputs(skip=skip) + mask = File(desc='mask file', + argstr='-mask %s', + exists=True) + options = Str(desc='selected statistical output', + argstr='%s') - def _format_arg(self, name, trait_spec, value): - if name == 'detrend': - if isinstance(value, bool): - if value: - return trait_spec.argstr - else: - return None - elif isinstance(value, int): - return trait_spec.argstr + ' %d' % value - if name == 'acf': - if isinstance(value, bool): - if value: - return trait_spec.argstr - else: - self._acf = False - return None - elif isinstance(value, tuple): - return trait_spec.argstr + ' %s %f' % value - elif isinstance(value, (str, bytes)): - return trait_spec.argstr + ' ' + value - return super(FWHMx, self)._format_arg(name, trait_spec, value) +class TStat(AFNICommand): + """Compute voxel-wise statistics using AFNI 3dTstat command - def _list_outputs(self): - outputs = super(FWHMx, self)._list_outputs() + For complete details, see the `3dTstat Documentation. + `_ - if self.inputs.detrend: - fname, ext = op.splitext(self.inputs.in_file) - if '.gz' in ext: - _, ext2 = op.splitext(fname) - ext = ext2 + ext - outputs['out_detrend'] += ext - else: - outputs['out_detrend'] = Undefined + Examples + ======== - sout = np.loadtxt(outputs['out_file']) #pylint: disable=E1101 - if self._acf: - outputs['acf_param'] = tuple(sout[1]) - sout = tuple(sout[0]) + >>> from nipype.interfaces import afni as afni + >>> tstat = afni.TStat() + >>> tstat.inputs.in_file = 'functional.nii' + >>> tstat.inputs.args= '-mean' + >>> tstat.inputs.out_file = "stats" + >>> tstat.cmdline # doctest: +IGNORE_UNICODE + '3dTstat -mean -prefix stats functional.nii' + >>> res = tstat.run() # doctest: +SKIP - outputs['out_acf'] = op.abspath('3dFWHMx.1D') - if isinstance(self.inputs.acf, (str, bytes)): - outputs['out_acf'] = op.abspath(self.inputs.acf) + """ - outputs['fwhm'] = tuple(sout) - return outputs + _cmd = '3dTstat' + input_spec = TStatInputSpec + output_spec = AFNICommandOutputSpec -class OutlierCountInputSpec(CommandLineInputSpec): - in_file = File(argstr='%s', mandatory=True, exists=True, position=-2, desc='input dataset') - mask = File(exists=True, argstr='-mask %s', xor=['autoclip', 'automask'], - desc='only count voxels within the given mask') - qthr = traits.Range(value=1e-3, low=0.0, high=1.0, argstr='-qthr %.5f', - desc='indicate a value for q to compute alpha') +class To3DInputSpec(AFNICommandInputSpec): + out_file = File(name_template="%s", desc='output image file name', + argstr='-prefix %s', name_source=["in_folder"]) + in_folder = Directory(desc='folder with DICOM images to convert', + argstr='%s/*.dcm', + position=-1, + mandatory=True, + exists=True) - autoclip = traits.Bool(False, usedefault=True, argstr='-autoclip', xor=['in_file'], - desc='clip off small voxels') - automask = traits.Bool(False, usedefault=True, argstr='-automask', xor=['in_file'], - desc='clip off small voxels') + filetype = traits.Enum('spgr', 'fse', 'epan', 'anat', 'ct', 'spct', + 'pet', 'mra', 'bmap', 'diff', + 'omri', 'abuc', 'fim', 'fith', 'fico', 'fitt', + 'fift', 'fizt', 'fict', 'fibt', + 'fibn', 'figt', 'fipt', + 'fbuc', argstr='-%s', + desc='type of datafile being converted') - fraction = traits.Bool(False, usedefault=True, argstr='-fraction', - desc='write out the fraction of masked voxels' - ' which are outliers at each timepoint') - interval = traits.Bool(False, usedefault=True, argstr='-range', - desc='write out the median + 3.5 MAD of outlier' - ' count with each timepoint') - save_outliers = traits.Bool(False, usedefault=True, desc='enables out_file option') - outliers_file = File( - name_template="%s_outliers", argstr='-save %s', name_source=["in_file"], - output_name='out_outliers', keep_extension=True, desc='output image file name') + skipoutliers = traits.Bool(desc='skip the outliers check', + argstr='-skip_outliers') - polort = traits.Int(argstr='-polort %d', - desc='detrend each voxel timeseries with polynomials') - legendre = traits.Bool(False, usedefault=True, argstr='-legendre', - desc='use Legendre polynomials') - out_file = File( - name_template='%s_outliers', name_source=['in_file'], argstr='> %s', - keep_extension=False, position=-1, desc='capture standard output') + assumemosaic = traits.Bool(desc='assume that Siemens image is mosaic', + argstr='-assume_dicom_mosaic') + datatype = traits.Enum('short', 'float', 'byte', 'complex', + desc='set output file datatype', argstr='-datum %s') -class OutlierCountOutputSpec(TraitedSpec): - out_outliers = File(exists=True, desc='output image file name') - out_file = File( - name_template='%s_tqual', name_source=['in_file'], argstr='> %s', - keep_extension=False, position=-1, desc='capture standard output') + funcparams = Str(desc='parameters for functional data', + argstr='-time:zt %s alt+z2') -class OutlierCount(CommandLine): +class To3D(AFNICommand): """Create a 3D dataset from 2D image files using AFNI to3d command For complete details, see the `to3d Documentation @@ -2932,134 +2878,194 @@ class OutlierCount(CommandLine): ======== >>> from nipype.interfaces import afni - >>> toutcount = afni.OutlierCount() - >>> toutcount.inputs.in_file = 'functional.nii' - >>> toutcount.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dToutcount functional.nii > functional_outliers' - >>> res = toutcount.run() #doctest: +SKIP + >>> To3D = afni.To3D() + >>> To3D.inputs.datatype = 'float' + >>> To3D.inputs.in_folder = '.' + >>> To3D.inputs.out_file = 'dicomdir.nii' + >>> To3D.inputs.filetype = "anat" + >>> To3D.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + 'to3d -datum float -anat -prefix dicomdir.nii ./*.dcm' + >>> res = To3D.run() #doctest: +SKIP """ + _cmd = 'to3d' + input_spec = To3DInputSpec + output_spec = AFNICommandOutputSpec - _cmd = '3dToutcount' - input_spec = OutlierCountInputSpec - output_spec = OutlierCountOutputSpec - def _parse_inputs(self, skip=None): - if skip is None: - skip = [] +class VolregInputSpec(AFNICommandInputSpec): - if not self.inputs.save_outliers: - skip += ['outliers_file'] - return super(OutlierCount, self)._parse_inputs(skip) + in_file = File(desc='input file to 3dvolreg', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File(name_template="%s_volreg", desc='output image file name', + argstr='-prefix %s', name_source="in_file") + basefile = File(desc='base file for registration', + argstr='-base %s', + position=-6, + exists=True) + zpad = traits.Int(desc='Zeropad around the edges' + + ' by \'n\' voxels during rotations', + argstr='-zpad %d', + position=-5) + md1d_file = File(name_template='%s_md.1D', desc='max displacement output file', + argstr='-maxdisp1D %s', name_source="in_file", + keep_extension=True, position=-4) + oned_file = File(name_template='%s.1D', desc='1D movement parameters output file', + argstr='-1Dfile %s', + name_source="in_file", + keep_extension=True) + verbose = traits.Bool(desc='more detailed description of the process', + argstr='-verbose') + timeshift = traits.Bool(desc='time shift to mean slice time offset', + argstr='-tshift 0') + copyorigin = traits.Bool(desc='copy base file origin coords to output', + argstr='-twodup') + oned_matrix_save = File(name_template='%s.aff12.1D', + desc='Save the matrix transformation', + argstr='-1Dmatrix_save %s', + keep_extension=True, + name_source="in_file") - def _list_outputs(self): - outputs = self.output_spec().get() - if self.inputs.save_outliers: - outputs['out_outliers'] = op.abspath(self.inputs.outliers_file) - outputs['out_file'] = op.abspath(self.inputs.out_file) - return outputs +class VolregOutputSpec(TraitedSpec): + out_file = File(desc='registered file', exists=True) + md1d_file = File(desc='max displacement info file', exists=True) + oned_file = File(desc='movement parameters info file', exists=True) + oned_matrix_save = File(desc='matrix transformation from base to input', exists=True) -class QualityIndexInputSpec(CommandLineInputSpec): - in_file = File(argstr='%s', mandatory=True, exists=True, position=-2, desc='input dataset') - mask = File(exists=True, argstr='-mask %s', xor=['autoclip', 'automask'], - desc='compute correlation only across masked voxels') - spearman = traits.Bool(False, usedefault=True, argstr='-spearman', - desc='Quality index is 1 minus the Spearman (rank) ' - 'correlation coefficient of each sub-brick ' - 'with the median sub-brick. (default)') - quadrant = traits.Bool(False, usedefault=True, argstr='-quadrant', - desc='Similar to -spearman, but using 1 minus the ' - 'quadrant correlation coefficient as the ' - 'quality index.') - autoclip = traits.Bool(False, usedefault=True, argstr='-autoclip', xor=['mask'], - desc='clip off small voxels') - automask = traits.Bool(False, usedefault=True, argstr='-automask', xor=['mask'], - desc='clip off small voxels') - clip = traits.Float(argstr='-clip %f', desc='clip off values below') - interval = traits.Bool(False, usedefault=True, argstr='-range', - desc='write out the median + 3.5 MAD of outlier' - ' count with each timepoint') - out_file = File( - name_template='%s_tqual', name_source=['in_file'], argstr='> %s', - keep_extension=False, position=-1, desc='capture standard output') +class Volreg(AFNICommand): + """Register input volumes to a base volume using AFNI 3dvolreg command + For complete details, see the `3dvolreg Documentation. + `_ -class QualityIndexOutputSpec(TraitedSpec): - out_file = File(desc='file containing the captured standard output') + Examples + ======== + >>> from nipype.interfaces import afni as afni + >>> volreg = afni.Volreg() + >>> volreg.inputs.in_file = 'functional.nii' + >>> volreg.inputs.args = '-Fourier -twopass' + >>> volreg.inputs.zpad = 4 + >>> volreg.inputs.outputtype = "NIFTI" + >>> volreg.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dvolreg -Fourier -twopass -1Dfile functional.1D -1Dmatrix_save functional.aff12.1D -prefix functional_volreg.nii -zpad 4 -maxdisp1D functional_md.1D functional.nii' + >>> res = volreg.run() # doctest: +SKIP -class QualityIndex(CommandLine): - """Create a 3D dataset from 2D image files using AFNI to3d command + """ - For complete details, see the `to3d Documentation - `_ + _cmd = '3dvolreg' + input_spec = VolregInputSpec + output_spec = VolregOutputSpec + + +class WarpInputSpec(AFNICommandInputSpec): + + in_file = File(desc='input file to 3dWarp', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + + out_file = File(name_template="%s_warp", desc='output image file name', + argstr='-prefix %s', name_source="in_file") + + tta2mni = traits.Bool(desc='transform dataset from Talairach to MNI152', + argstr='-tta2mni') + + mni2tta = traits.Bool(desc='transform dataset from MNI152 to Talaraich', + argstr='-mni2tta') + + matparent = File(desc="apply transformation from 3dWarpDrive", + argstr="-matparent %s", + exists=True) + + deoblique = traits.Bool(desc='transform dataset from oblique to cardinal', + argstr='-deoblique') + + interp = traits.Enum(('linear', 'cubic', 'NN', 'quintic'), + desc='spatial interpolation methods [default = linear]', + argstr='-%s') + + gridset = File(desc="copy grid of specified dataset", + argstr="-gridset %s", + exists=True) + + newgrid = traits.Float(desc="specify grid of this size (mm)", + argstr="-newgrid %f") + + zpad = traits.Int(desc="pad input dataset with N planes" + + " of zero on all sides.", + argstr="-zpad %d") + + +class Warp(AFNICommand): + """Use 3dWarp for spatially transforming a dataset + + For complete details, see the `3dWarp Documentation. + `_ Examples ======== - >>> from nipype.interfaces import afni - >>> tqual = afni.QualityIndex() - >>> tqual.inputs.in_file = 'functional.nii' - >>> tqual.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dTqual functional.nii > functional_tqual' - >>> res = tqual.run() #doctest: +SKIP + >>> from nipype.interfaces import afni as afni + >>> warp = afni.Warp() + >>> warp.inputs.in_file = 'structural.nii' + >>> warp.inputs.deoblique = True + >>> warp.inputs.out_file = "trans.nii.gz" + >>> warp.cmdline # doctest: +IGNORE_UNICODE + '3dWarp -deoblique -prefix trans.nii.gz structural.nii' + + >>> warp_2 = afni.Warp() + >>> warp_2.inputs.in_file = 'structural.nii' + >>> warp_2.inputs.newgrid = 1.0 + >>> warp_2.inputs.out_file = "trans.nii.gz" + >>> warp_2.cmdline # doctest: +IGNORE_UNICODE + '3dWarp -newgrid 1.000000 -prefix trans.nii.gz structural.nii' """ - _cmd = '3dTqual' - input_spec = QualityIndexInputSpec - output_spec = QualityIndexOutputSpec + _cmd = '3dWarp' + input_spec = WarpInputSpec + output_spec = AFNICommandOutputSpec -class NotesInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dNotes', +class ZCutUpInputSpec(AFNICommandInputSpec): + in_file = File(desc='input file to 3dZcutup', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) - add = Str(desc='note to add', - argstr='-a "%s"') - add_history = Str(desc='note to add to history', - argstr='-h "%s"', - xor=['rep_history']) - rep_history = Str(desc='note with which to replace history', - argstr='-HH "%s"', - xor=['add_history']) - delete = traits.Int(desc='delete note number num', - argstr='-d %d') - ses = traits.Bool(desc='print to stdout the expanded notes', - argstr='-ses') - out_file = File(desc='output image file name', - argstr='%s') + out_file = File(name_template="%s_zcupup", desc='output image file name', + argstr='-prefix %s', name_source="in_file") + keep = Str(desc='slice range to keep in output', + argstr='-keep %s') -class Notes(CommandLine): - """ - A program to add, delete, and show notes for AFNI datasets. +class ZCutUp(AFNICommand): + """Cut z-slices from a volume using AFNI 3dZcutup command - For complete details, see the `3dNotes Documentation. - + For complete details, see the `3dZcutup Documentation. + `_ Examples ======== - >>> from nipype.interfaces import afni - >>> notes = afni.Notes() - >>> notes.inputs.in_file = "functional.HEAD" - >>> notes.inputs.add = "This note is added." - >>> notes.inputs.add_history = "This note is added to history." - >>> notes.cmdline #doctest: +IGNORE_UNICODE - '3dNotes -a "This note is added." -h "This note is added to history." functional.HEAD' - >>> res = notes.run() # doctest: +SKIP + >>> from nipype.interfaces import afni as afni + >>> zcutup = afni.ZCutUp() + >>> zcutup.inputs.in_file = 'functional.nii' + >>> zcutup.inputs.out_file = 'functional_zcutup.nii' + >>> zcutup.inputs.keep= '0 10' + >>> res = zcutup.run() # doctest: +SKIP + """ - _cmd = '3dNotes' - input_spec = NotesInputSpec + _cmd = '3dZcutup' + input_spec = ZCutUpInputSpec output_spec = AFNICommandOutputSpec - - def _list_outputs(self): - outputs = self.output_spec().get() - outputs['out_file'] = os.path.abspath(self.inputs.in_file) - return outputs From 3c075660456df22c9a662df09446bd2804e58034 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Sat, 8 Oct 2016 17:46:06 -0400 Subject: [PATCH 2/7] Reorganize afni interface. Create utils.py and move several functions from preprocess to utils. Also, add optional arguments to AFNItoNIFTI, standardize long strings and standardize spacing. --- .cache/v/cache/lastfailed | 4 + nipype/interfaces/afni/__init__.py | 20 +- nipype/interfaces/afni/preprocess.py | 2822 ++++++----------- .../afni/tests/test_auto_AFNItoNIFTI.py | 13 +- .../afni/tests/test_auto_Autobox.py | 2 +- .../afni/tests/test_auto_BrickStat.py | 2 +- .../interfaces/afni/tests/test_auto_Calc.py | 6 +- .../interfaces/afni/tests/test_auto_Copy.py | 2 +- .../interfaces/afni/tests/test_auto_Eval.py | 6 +- .../interfaces/afni/tests/test_auto_FWHMx.py | 2 +- .../afni/tests/test_auto_MaskTool.py | 2 +- .../interfaces/afni/tests/test_auto_Merge.py | 2 +- .../interfaces/afni/tests/test_auto_Notes.py | 2 +- .../interfaces/afni/tests/test_auto_Refit.py | 2 +- .../afni/tests/test_auto_Resample.py | 2 +- .../interfaces/afni/tests/test_auto_TCat.py | 2 +- .../afni/tests/test_auto_TCorrelate.py | 4 +- .../interfaces/afni/tests/test_auto_TStat.py | 2 +- .../interfaces/afni/tests/test_auto_To3D.py | 2 +- .../interfaces/afni/tests/test_auto_ZCutUp.py | 4 +- nipype/interfaces/afni/utils.py | 1244 ++++++++ von-ray_errmap.nii.gz | Bin 0 -> 107 bytes von_errmap.nii.gz | Bin 0 -> 96 bytes 23 files changed, 2323 insertions(+), 1824 deletions(-) create mode 100644 .cache/v/cache/lastfailed create mode 100644 nipype/interfaces/afni/utils.py create mode 100644 von-ray_errmap.nii.gz create mode 100644 von_errmap.nii.gz diff --git a/.cache/v/cache/lastfailed b/.cache/v/cache/lastfailed new file mode 100644 index 0000000000..f27711958e --- /dev/null +++ b/.cache/v/cache/lastfailed @@ -0,0 +1,4 @@ +{ + "nipype/algorithms/tests/test_mesh_ops.py::test_ident_distances": true, + "nipype/algorithms/tests/test_mesh_ops.py::test_trans_distances": true +} \ No newline at end of file diff --git a/nipype/interfaces/afni/__init__.py b/nipype/interfaces/afni/__init__.py index 0648c070f0..dfc0d794f5 100644 --- a/nipype/interfaces/afni/__init__.py +++ b/nipype/interfaces/afni/__init__.py @@ -8,12 +8,16 @@ """ from .base import Info -from .preprocess import (AFNItoNIFTI, Allineate, AutoTcorrelate, Autobox, - Automask, Bandpass, BlurInMask, BlurToFWHM, BrickStat, - Calc, ClipLevel, Copy, DegreeCentrality, Despike, - Detrend, ECM, Eval, FWHMx, Fim, Fourier, Hist, LFCD, - MaskTool, Maskave, Means, Merge, Notes, OutlierCount, - QualityIndex, ROIStats, Refit, Resample, Retroicor, - Seg, SkullStrip, TCat, TCorr1D, TCorrMap, TCorrelate, - TShift, TStat, To3D, Volreg, Warp, ZCutUp) +from .preprocess import (Allineate, Automask, AutoTcorrelate, + Bandpass, BlurInMask, BlurToFWHM, + ClipLevel, DegreeCentrality, Despike, + Detrend, ECM, Fim, Fourier, Hist, LFCD, + Maskave, Means, OutlierCount, + QualityIndex, ROIStats, Retroicor, + Seg, SkullStrip, TCorr1D, TCorrMap, TCorrelate, + TShift, Volreg, Warp) from .svm import (SVMTest, SVMTrain) +from .utils import (AFNItoNIFTI, Autobox, BrickStat, Calc, Copy, + Eval, FWHMx, + MaskTool, Merge, Notes, Refit, Resample, TCat, TStat, To3D, + ZCutUp,) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index ce6b27f0ca..8605b7ae35 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft = python sts = 4 ts = 4 sw = 4 et: -"""Afni preprocessing interfaces +"""AFNI preprocessing interfaces Change directory to provide relative paths for doctests >>> import os @@ -30,80 +30,37 @@ class CentralityInputSpec(AFNICommandInputSpec): """Common input spec class for all centrality-related commmands """ - - mask = File(desc='mask file to mask input data', - argstr="-mask %s", - exists=True) - thresh = traits.Float(desc='threshold to exclude connections where corr <= thresh', - argstr='-thresh %f') - - polort = traits.Int(desc='', argstr='-polort %d') - - autoclip = traits.Bool(desc='Clip off low-intensity regions in the dataset', - argstr='-autoclip') - - automask = traits.Bool(desc='Mask the dataset to target brain-only voxels', - argstr='-automask') - - -class AFNItoNIFTIInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dAFNItoNIFTI', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s.nii", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - hash_files = False - - -class AFNItoNIFTI(AFNICommand): - """Changes AFNI format files to NIFTI format using 3dAFNItoNIFTI - - see AFNI Documentation: - - this can also convert 2D or 1D data, which you can numpy.squeeze() to - remove extra dimensions - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> a2n = afni.AFNItoNIFTI() - >>> a2n.inputs.in_file = 'afni_output.3D' - >>> a2n.inputs.out_file = 'afni_output.nii' - >>> a2n.cmdline # doctest: +IGNORE_UNICODE - '3dAFNItoNIFTI -prefix afni_output.nii afni_output.3D' - - """ - - _cmd = '3dAFNItoNIFTI' - input_spec = AFNItoNIFTIInputSpec - output_spec = AFNICommandOutputSpec - - def _overload_extension(self, value): - path, base, ext = split_filename(value) - if ext.lower() not in [".1d", ".nii.gz", ".1D"]: - ext = ext + ".nii" - return os.path.join(path, base + ext) - - def _gen_filename(self, name): - return os.path.abspath(super(AFNItoNIFTI, self)._gen_filename(name)) + mask = File( + desc='mask file to mask input data', + argstr='-mask %s', + exists=True) + thresh = traits.Float( + desc='threshold to exclude connections where corr <= thresh', + argstr='-thresh %f') + polort = traits.Int( + desc='', + argstr='-polort %d') + autoclip = traits.Bool( + desc='Clip off low-intensity regions in the dataset', + argstr='-autoclip') + automask = traits.Bool( + desc='Mask the dataset to target brain-only voxels', + argstr='-automask') class AllineateInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dAllineate', - argstr='-source %s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) + in_file = File( + desc='input file to 3dAllineate', + argstr='-source %s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) reference = File( exists=True, argstr='-base %s', - desc='file to be used as reference, the first volume will be used if '\ + desc='file to be used as reference, the first volume will be used if ' 'not given the reference will be the first volume of in_file.') out_file = File( desc='output file from 3dAllineate', @@ -111,21 +68,21 @@ class AllineateInputSpec(AFNICommandInputSpec): position=-2, name_source='%s_allineate', genfile=True) - out_param_file = File( argstr='-1Dparam_save %s', desc='Save the warp parameters in ASCII (.1D) format.') in_param_file = File( exists=True, argstr='-1Dparam_apply %s', - desc="""Read warp parameters from file and apply them to - the source dataset, and produce a new dataset""") + desc='Read warp parameters from file and apply them to ' + 'the source dataset, and produce a new dataset') out_matrix = File( argstr='-1Dmatrix_save %s', desc='Save the transformation matrix for each volume.') - in_matrix = File(desc='matrix to align input file', - argstr='-1Dmatrix_apply %s', - position=-3) + in_matrix = File( + desc='matrix to align input file', + argstr='-1Dmatrix_apply %s', + position=-3) _cost_funcs = [ 'leastsq', 'ls', @@ -137,16 +94,19 @@ class AllineateInputSpec(AFNICommandInputSpec): 'corratio_uns', 'crU'] cost = traits.Enum( - *_cost_funcs, argstr='-cost %s', - desc="""Defines the 'cost' function that defines the matching - between the source and the base""") + *_cost_funcs, + argstr='-cost %s', + desc='Defines the \'cost\' function that defines the matching between ' + 'the source and the base') _interp_funcs = [ 'nearestneighbour', 'linear', 'cubic', 'quintic', 'wsinc5'] interpolation = traits.Enum( - *_interp_funcs[:-1], argstr='-interp %s', + *_interp_funcs[:-1], + argstr='-interp %s', desc='Defines interpolation method to use during matching') final_interpolation = traits.Enum( - *_interp_funcs, argstr='-final %s', + *_interp_funcs, + argstr='-final %s', desc='Defines interpolation method used to create the output dataset') # TECHNICAL OPTIONS (used for fine control of the program): @@ -158,83 +118,86 @@ class AllineateInputSpec(AFNICommandInputSpec): desc='Do not use zero-padding on the base image.') zclip = traits.Bool( argstr='-zclip', - desc='Replace negative values in the input datasets (source & base) '\ + desc='Replace negative values in the input datasets (source & base) ' 'with zero.') convergence = traits.Float( argstr='-conv %f', desc='Convergence test in millimeters (default 0.05mm).') - usetemp = traits.Bool(argstr='-usetemp', desc='temporary file use') + usetemp = traits.Bool( + argstr='-usetemp', + desc='temporary file use') check = traits.List( - traits.Enum(*_cost_funcs), argstr='-check %s', - desc="""After cost functional optimization is done, start at the - final parameters and RE-optimize using this new cost functions. - If the results are too different, a warning message will be - printed. However, the final parameters from the original - optimization will be used to create the output dataset.""") + traits.Enum(*_cost_funcs), + argstr='-check %s', + desc='After cost functional optimization is done, start at the final ' + 'parameters and RE-optimize using this new cost functions. If ' + 'the results are too different, a warning message will be ' + 'printed. However, the final parameters from the original ' + 'optimization will be used to create the output dataset.') # ** PARAMETERS THAT AFFECT THE COST OPTIMIZATION STRATEGY ** one_pass = traits.Bool( argstr='-onepass', - desc="""Use only the refining pass -- do not try a coarse - resolution pass first. Useful if you know that only - small amounts of image alignment are needed.""") + desc='Use only the refining pass -- do not try a coarse resolution ' + 'pass first. Useful if you know that only small amounts of ' + 'image alignment are needed.') two_pass = traits.Bool( argstr='-twopass', - desc="""Use a two pass alignment strategy for all volumes, searching - for a large rotation+shift and then refining the alignment.""") + desc='Use a two pass alignment strategy for all volumes, searching ' + 'for a large rotation+shift and then refining the alignment.') two_blur = traits.Float( argstr='-twoblur', desc='Set the blurring radius for the first pass in mm.') two_first = traits.Bool( argstr='-twofirst', - desc="""Use -twopass on the first image to be registered, and - then on all subsequent images from the source dataset, - use results from the first image's coarse pass to start - the fine pass.""") + desc='Use -twopass on the first image to be registered, and ' + 'then on all subsequent images from the source dataset, ' + 'use results from the first image\'s coarse pass to start ' + 'the fine pass.') two_best = traits.Int( argstr='-twobest %d', - desc="""In the coarse pass, use the best 'bb' set of initial - points to search for the starting point for the fine - pass. If bb==0, then no search is made for the best - starting point, and the identity transformation is - used as the starting point. [Default=5; min=0 max=11]""") + desc='In the coarse pass, use the best \'bb\' set of initial' + 'points to search for the starting point for the fine' + 'pass. If bb==0, then no search is made for the best' + 'starting point, and the identity transformation is' + 'used as the starting point. [Default=5; min=0 max=11]') fine_blur = traits.Float( argstr='-fineblur %f', - desc="""Set the blurring radius to use in the fine resolution - pass to 'x' mm. A small amount (1-2 mm?) of blurring at - the fine step may help with convergence, if there is - some problem, especially if the base volume is very noisy. - [Default == 0 mm = no blurring at the final alignment pass]""") - + desc='Set the blurring radius to use in the fine resolution ' + 'pass to \'x\' mm. A small amount (1-2 mm?) of blurring at ' + 'the fine step may help with convergence, if there is ' + 'some problem, especially if the base volume is very noisy. ' + '[Default == 0 mm = no blurring at the final alignment pass]') center_of_mass = Str( argstr='-cmass%s', desc='Use the center-of-mass calculation to bracket the shifts.') autoweight = Str( argstr='-autoweight%s', - desc="""Compute a weight function using the 3dAutomask - algorithm plus some blurring of the base image.""") + desc='Compute a weight function using the 3dAutomask ' + 'algorithm plus some blurring of the base image.') automask = traits.Int( argstr='-automask+%d', - desc="""Compute a mask function, set a value for dilation or 0.""") + desc='Compute a mask function, set a value for dilation or 0.') autobox = traits.Bool( argstr='-autobox', - desc="""Expand the -automask function to enclose a rectangular - box that holds the irregular mask.""") + desc='Expand the -automask function to enclose a rectangular ' + 'box that holds the irregular mask.') nomask = traits.Bool( argstr='-nomask', - desc="""Don't compute the autoweight/mask; if -weight is not - also used, then every voxel will be counted equally.""") + desc='Don\'t compute the autoweight/mask; if -weight is not ' + 'also used, then every voxel will be counted equally.') weight_file = File( - argstr='-weight %s', exists=True, - desc="""Set the weighting for each voxel in the base dataset; - larger weights mean that voxel count more in the cost function. - Must be defined on the same grid as the base dataset""") + argstr='-weight %s', + exists=True, + desc='Set the weighting for each voxel in the base dataset; ' + 'larger weights mean that voxel count more in the cost function. ' + 'Must be defined on the same grid as the base dataset') out_weight_file = traits.File( argstr='-wtprefix %s', - desc="""Write the weight volume to disk as a dataset""") - + desc='Write the weight volume to disk as a dataset') source_mask = File( - exists=True, argstr='-source_mask %s', + exists=True, + argstr='-source_mask %s', desc='mask the input dataset') source_automask = traits.Int( argstr='-source_automask+%d', @@ -248,32 +211,34 @@ class AllineateInputSpec(AFNICommandInputSpec): desc='Freeze the non-rigid body parameters after first volume.') replacebase = traits.Bool( argstr='-replacebase', - desc="""If the source has more than one volume, then after the first - volume is aligned to the base""") + desc='If the source has more than one volume, then after the first ' + 'volume is aligned to the base.') replacemeth = traits.Enum( *_cost_funcs, argstr='-replacemeth %s', - desc="""After first volume is aligned, switch method for later volumes. - For use with '-replacebase'.""") + desc='After first volume is aligned, switch method for later volumes. ' + 'For use with \'-replacebase\'.') epi = traits.Bool( argstr='-EPI', - desc="""Treat the source dataset as being composed of warped - EPI slices, and the base as comprising anatomically - 'true' images. Only phase-encoding direction image - shearing and scaling will be allowed with this option.""") + desc='Treat the source dataset as being composed of warped ' + 'EPI slices, and the base as comprising anatomically ' + '\'true\' images. Only phase-encoding direction image ' + 'shearing and scaling will be allowed with this option.') master = File( - exists=True, argstr='-master %s', - desc='Write the output dataset on the same grid as this file') + exists=True, + argstr='-master %s', + desc='Write the output dataset on the same grid as this file.') newgrid = traits.Float( argstr='-newgrid %f', - desc='Write the output dataset using isotropic grid spacing in mm') + desc='Write the output dataset using isotropic grid spacing in mm.') # Non-linear experimental _nwarp_types = ['bilinear', 'cubic', 'quintic', 'heptic', 'nonic', 'poly3', 'poly5', 'poly7', 'poly9'] # same non-hellenistic nwarp = traits.Enum( - *_nwarp_types, argstr='-nwarp %s', + *_nwarp_types, + argstr='-nwarp %s', desc='Experimental nonlinear warping: bilinear or legendre poly.') _dirs = ['X', 'Y', 'Z', 'I', 'J', 'K'] nwarp_fixmot = traits.List( @@ -329,7 +294,7 @@ def _list_outputs(self): if isdefined(self.inputs.out_matrix): outputs['matrix'] = os.path.abspath(os.path.join(os.getcwd(),\ - self.inputs.out_matrix +".aff12.1D")) + self.inputs.out_matrix +'.aff12.1D')) return outputs def _gen_filename(self, name): @@ -338,31 +303,37 @@ def _gen_filename(self, name): class AutoTcorrelateInputSpec(AFNICommandInputSpec): - in_file = File(desc='timeseries x space (volume or surface) file', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - + in_file = File( + desc='timeseries x space (volume or surface) file', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) polort = traits.Int( desc='Remove polynomical trend of order m or -1 for no detrending', - argstr="-polort %d") - eta2 = traits.Bool(desc='eta^2 similarity', - argstr="-eta2") - mask = File(exists=True, desc="mask of voxels", - argstr="-mask %s") - mask_only_targets = traits.Bool(desc="use mask only on targets voxels", - argstr="-mask_only_targets", - xor=['mask_source']) - mask_source = File(exists=True, - desc="mask for source voxels", - argstr="-mask_source %s", - xor=['mask_only_targets']) - - out_file = File(name_template='%s_similarity_matrix.1D', - desc='output image file name', - argstr='-prefix %s', name_source='in_file') + argstr='-polort %d') + eta2 = traits.Bool( + desc='eta^2 similarity', + argstr='-eta2') + mask = File( + exists=True, + desc='mask of voxels', + argstr='-mask %s') + mask_only_targets = traits.Bool( + desc='use mask only on targets voxels', + argstr='-mask_only_targets', + xor=['mask_source']) + mask_source = File( + exists=True, + desc='mask for source voxels', + argstr='-mask_source %s', + xor=['mask_only_targets']) + out_file = File( + name_template='%s_similarity_matrix.1D', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') class AutoTcorrelate(AFNICommand): @@ -390,113 +361,48 @@ class AutoTcorrelate(AFNICommand): def _overload_extension(self, value, name=None): path, base, ext = split_filename(value) - if ext.lower() not in [".1d", ".nii.gz", ".nii"]: - ext = ext + ".1D" + if ext.lower() not in ['.1d', '.nii.gz', '.nii']: + ext = ext + '.1D' return os.path.join(path, base + ext) -class AutoboxInputSpec(AFNICommandInputSpec): - in_file = File(exists=True, mandatory=True, argstr='-input %s', - desc='input file', copyfile=False) - padding = traits.Int( - argstr='-npad %d', - desc='Number of extra voxels to pad on each side of box') - out_file = File(argstr="-prefix %s", name_source="in_file") - no_clustering = traits.Bool( - argstr='-noclust', - desc="""Don't do any clustering to find box. Any non-zero - voxel will be preserved in the cropped volume. - The default method uses some clustering to find the - cropping box, and will clip off small isolated blobs.""") - - -class AutoboxOutputSpec(TraitedSpec): # out_file not mandatory - x_min = traits.Int() - x_max = traits.Int() - y_min = traits.Int() - y_max = traits.Int() - z_min = traits.Int() - z_max = traits.Int() - - out_file = File(desc='output file') - - -class Autobox(AFNICommand): - """ Computes size of a box that fits around the volume. - Also can be used to crop the volume to that box. - - For complete details, see the `3dAutobox Documentation. - - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> abox = afni.Autobox() - >>> abox.inputs.in_file = 'structural.nii' - >>> abox.inputs.padding = 5 - >>> res = abox.run() # doctest: +SKIP - - """ - - _cmd = '3dAutobox' - input_spec = AutoboxInputSpec - output_spec = AutoboxOutputSpec - - def aggregate_outputs(self, runtime=None, needed_outputs=None): - outputs = self._outputs() - pattern = 'x=(?P-?\d+)\.\.(?P-?\d+) '\ - 'y=(?P-?\d+)\.\.(?P-?\d+) '\ - 'z=(?P-?\d+)\.\.(?P-?\d+)' - for line in runtime.stderr.split('\n'): - m = re.search(pattern, line) - if m: - d = m.groupdict() - for k in list(d.keys()): - d[k] = int(d[k]) - outputs.set(**d) - outputs.set(out_file=self._gen_filename('out_file')) - return outputs - - def _gen_filename(self, name): - if name == 'out_file' and (not isdefined(self.inputs.out_file)): - return Undefined - return super(Autobox, self)._gen_filename(name) - - class AutomaskInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dAutomask', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_mask", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - brain_file = File(name_template="%s_masked", - desc="output file from 3dAutomask", - argstr='-apply_prefix %s', - name_source="in_file") - - clfrac = traits.Float(desc='sets the clip level fraction (must be '\ - '0.1-0.9). A small value will tend to make '\ - 'the mask larger [default = 0.5].', - argstr="-clfrac %s") - - dilate = traits.Int(desc='dilate the mask outwards', - argstr="-dilate %s") - - erode = traits.Int(desc='erode the mask inwards', - argstr="-erode %s") + in_file = File( + desc='input file to 3dAutomask', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_mask', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + brain_file = File( + name_template='%s_masked', + desc='output file from 3dAutomask', + argstr='-apply_prefix %s', + name_source='in_file') + clfrac = traits.Float( + desc='sets the clip level fraction (must be 0.1-0.9). A small value ' + 'will tend to make the mask larger [default = 0.5].', + argstr='-clfrac %s') + dilate = traits.Int( + desc='dilate the mask outwards', + argstr='-dilate %s') + erode = traits.Int( + desc='erode the mask inwards', + argstr='-erode %s') class AutomaskOutputSpec(TraitedSpec): - out_file = File(desc='mask file', - exists=True) - - brain_file = File(desc='brain file (skull stripped)', exists=True) + out_file = File( + desc='mask file', + exists=True) + brain_file = File( + desc='brain file (skull stripped)', + exists=True) class Automask(AFNICommand): @@ -512,7 +418,7 @@ class Automask(AFNICommand): >>> automask = afni.Automask() >>> automask.inputs.in_file = 'functional.nii' >>> automask.inputs.dilate = 1 - >>> automask.inputs.outputtype = "NIFTI" + >>> automask.inputs.outputtype = 'NIFTI' >>> automask.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE '3dAutomask -apply_prefix functional_masked.nii -dilate 1 -prefix functional_mask.nii functional.nii' >>> res = automask.run() # doctest: +SKIP @@ -556,57 +462,54 @@ class BandpassInputSpec(AFNICommandInputSpec): exists=True) despike = traits.Bool( argstr='-despike', - desc="""Despike each time series before other processing. - ++ Hopefully, you don't actually need to do this, - which is why it is optional.""") + desc='Despike each time series before other processing. Hopefully, ' + 'you don\'t actually need to do this, which is why it is ' + 'optional.') orthogonalize_file = InputMultiPath( File(exists=True), - argstr="-ort %s", - desc="""Also orthogonalize input to columns in f.1D - ++ Multiple '-ort' options are allowed.""") + argstr='-ort %s', + desc='Also orthogonalize input to columns in f.1D. Multiple \'-ort\' ' + 'options are allowed.') orthogonalize_dset = File( exists=True, - argstr="-dsort %s", - desc="""Orthogonalize each voxel to the corresponding - voxel time series in dataset 'fset', which must - have the same spatial and temporal grid structure - as the main input dataset. - ++ At present, only one '-dsort' option is allowed.""") + argstr='-dsort %s', + desc='Orthogonalize each voxel to the corresponding voxel time series ' + 'in dataset \'fset\', which must have the same spatial and ' + 'temporal grid structure as the main input dataset. At present, ' + 'only one \'-dsort\' option is allowed.') no_detrend = traits.Bool( argstr='-nodetrend', - desc="""Skip the quadratic detrending of the input that - occurs before the FFT-based bandpassing. - ++ You would only want to do this if the dataset - had been detrended already in some other program.""") + desc='Skip the quadratic detrending of the input that occurs before ' + 'the FFT-based bandpassing. You would only want to do this if ' + 'the dataset had been detrended already in some other program.') tr = traits.Float( - argstr="-dt %f", - desc="set time step (TR) in sec [default=from dataset header]") + argstr='-dt %f', + desc='Set time step (TR) in sec [default=from dataset header].') nfft = traits.Int( argstr='-nfft %d', - desc="set the FFT length [must be a legal value]") + desc='Set the FFT length [must be a legal value].') normalize = traits.Bool( argstr='-norm', - desc="""Make all output time series have L2 norm = 1 - ++ i.e., sum of squares = 1""") + desc='Make all output time series have L2 norm = 1 (i.e., sum of ' + 'squares = 1).') automask = traits.Bool( argstr='-automask', - desc="Create a mask from the input dataset") + desc='Create a mask from the input dataset.') blur = traits.Float( argstr='-blur %f', - desc="""Blur (inside the mask only) with a filter - width (FWHM) of 'fff' millimeters.""") + desc='Blur (inside the mask only) with a filter width (FWHM) of ' + '\'fff\' millimeters.') localPV = traits.Float( argstr='-localPV %f', - desc="""Replace each vector by the local Principal Vector - (AKA first singular vector) from a neighborhood - of radius 'rrr' millimiters. - ++ Note that the PV time series is L2 normalized. - ++ This option is mostly for Bob Cox to have fun with.""") + desc='Replace each vector by the local Principal Vector (AKA first ' + 'singular vector) from a neighborhood of radius \'rrr\' ' + 'millimeters. Note that the PV time series is L2 normalized. ' + 'This option is mostly for Bob Cox to have fun with.') notrans = traits.Bool( argstr='-notrans', - desc="""Don't check for initial positive transients in the data: - ++ The test is a little slow, so skipping it is OK, - if you KNOW the data time series are transient-free.""") + desc='Don\'t check for initial positive transients in the data. ' + 'The test is a little slow, so skipping it is OK, if you KNOW ' + 'the data time series are transient-free.') class Bandpass(AFNICommand): @@ -642,14 +545,18 @@ class BlurInMaskInputSpec(AFNICommandInputSpec): mandatory=True, exists=True, copyfile=False) - out_file = File(name_template='%s_blur', desc='output to the file', - argstr='-prefix %s', name_source='in_file', position=-1) + out_file = File( + name_template='%s_blur', + desc='output to the file', + argstr='-prefix %s', + name_source='in_file', + position=-1) mask = File( - desc='Mask dataset, if desired. Blurring will occur only within the '\ + desc='Mask dataset, if desired. Blurring will occur only within the ' 'mask. Voxels NOT in the mask will be set to zero in the output.', argstr='-mask %s') multimask = File( - desc='Multi-mask dataset -- each distinct nonzero value in dataset '\ + desc='Multi-mask dataset -- each distinct nonzero value in dataset ' 'will be treated as a separate mask for blurring purposes.', argstr='-Mmask %s') automask = traits.Bool( @@ -660,14 +567,17 @@ class BlurInMaskInputSpec(AFNICommandInputSpec): argstr='-FWHM %f', mandatory=True) preserve = traits.Bool( - desc='Normally, voxels not in the mask will be set to zero in the '\ - 'output. If you want the original values in the dataset to be '\ - 'preserved in the output, use this option.', + desc='Normally, voxels not in the mask will be set to zero in the ' + 'output. If you want the original values in the dataset to be ' + 'preserved in the output, use this option.', argstr='-preserve') float_out = traits.Bool( desc='Save dataset as floats, no matter what the input data type is.', argstr='-float') - options = Str(desc='options', argstr='%s', position=2) + options = Str( + desc='options', + argstr='%s', + position=2) class BlurInMask(AFNICommand): @@ -696,21 +606,29 @@ class BlurInMask(AFNICommand): class BlurToFWHMInputSpec(AFNICommandInputSpec): - in_file = File(desc='The dataset that will be smoothed', - argstr='-input %s', mandatory=True, exists=True) - - automask = traits.Bool(desc='Create an automask from the input dataset.', - argstr='-automask') - fwhm = traits.Float(desc='Blur until the 3D FWHM reaches this value (in mm)', - argstr='-FWHM %f') - fwhmxy = traits.Float(desc='Blur until the 2D (x,y)-plane FWHM reaches '\ - 'this value (in mm)', - argstr='-FWHMxy %f') - blurmaster = File(desc='The dataset whose smoothness controls the process.', - argstr='-blurmaster %s', exists=True) - mask = File(desc='Mask dataset, if desired. Voxels NOT in mask will be '\ - 'set to zero in output.', argstr='-blurmaster %s', - exists=True) + in_file = File( + desc='The dataset that will be smoothed', + argstr='-input %s', + mandatory=True, + exists=True) + automask = traits.Bool( + desc='Create an automask from the input dataset.', + argstr='-automask') + fwhm = traits.Float( + desc='Blur until the 3D FWHM reaches this value (in mm)', + argstr='-FWHM %f') + fwhmxy = traits.Float( + desc='Blur until the 2D (x,y)-plane FWHM reaches this value (in mm)', + argstr='-FWHMxy %f') + blurmaster = File( + desc='The dataset whose smoothness controls the process.', + argstr='-blurmaster %s', + exists=True) + mask = File( + desc='Mask dataset, if desired. Voxels NOT in mask will be set to zero ' + 'in output.', + argstr='-blurmaster %s', + exists=True) class BlurToFWHM(AFNICommand): @@ -736,159 +654,28 @@ class BlurToFWHM(AFNICommand): output_spec = AFNICommandOutputSpec -class BrickStatInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dmaskave', - argstr='%s', - position=-1, - mandatory=True, - exists=True) - - mask = File(desc='-mask dset = use dset as mask to include/exclude voxels', - argstr='-mask %s', - position=2, - exists=True) - - min = traits.Bool(desc='print the minimum value in dataset', - argstr='-min', - position=1) - - -class BrickStatOutputSpec(TraitedSpec): - min_val = traits.Float(desc='output') - - -class BrickStat(AFNICommand): - """Compute maximum and/or minimum voxel values of an input dataset - - For complete details, see the `3dBrickStat Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> brickstat = afni.BrickStat() - >>> brickstat.inputs.in_file = 'functional.nii' - >>> brickstat.inputs.mask = 'skeleton_mask.nii.gz' - >>> brickstat.inputs.min = True - >>> res = brickstat.run() # doctest: +SKIP - - """ - _cmd = '3dBrickStat' - input_spec = BrickStatInputSpec - output_spec = BrickStatOutputSpec - - def aggregate_outputs(self, runtime=None, needed_outputs=None): - - outputs = self._outputs() - - outfile = os.path.join(os.getcwd(), 'stat_result.json') - - if runtime is None: - try: - min_val = load_json(outfile)['stat'] - except IOError: - return self.run().outputs - else: - min_val = [] - for line in runtime.stdout.split('\n'): - if line: - values = line.split() - if len(values) > 1: - min_val.append([float(val) for val in values]) - else: - min_val.extend([float(val) for val in values]) - - if len(min_val) == 1: - min_val = min_val[0] - save_json(outfile, dict(stat=min_val)) - outputs.min_val = min_val - - return outputs - - -class CalcInputSpec(AFNICommandInputSpec): - in_file_a = File(desc='input file to 3dcalc', - argstr='-a %s', position=0, mandatory=True, exists=True) - in_file_b = File(desc='operand file to 3dcalc', - argstr=' -b %s', position=1, exists=True) - in_file_c = File(desc='operand file to 3dcalc', - argstr=' -c %s', position=2, exists=True) - out_file = File(name_template="%s_calc", desc='output image file name', - argstr='-prefix %s', name_source="in_file_a") - expr = Str(desc='expr', argstr='-expr "%s"', position=3, - mandatory=True) - start_idx = traits.Int(desc='start index for in_file_a', - requires=['stop_idx']) - stop_idx = traits.Int(desc='stop index for in_file_a', - requires=['start_idx']) - single_idx = traits.Int(desc='volume index for in_file_a') - other = File(desc='other options', argstr='') - - -class Calc(AFNICommand): - """This program does voxel-by-voxel arithmetic on 3D datasets - - For complete details, see the `3dcalc Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> calc = afni.Calc() - >>> calc.inputs.in_file_a = 'functional.nii' - >>> calc.inputs.in_file_b = 'functional2.nii' - >>> calc.inputs.expr='a*b' - >>> calc.inputs.out_file = 'functional_calc.nii.gz' - >>> calc.inputs.outputtype = "NIFTI" - >>> calc.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dcalc -a functional.nii -b functional2.nii -expr "a*b" -prefix functional_calc.nii.gz' - - """ - - _cmd = '3dcalc' - input_spec = CalcInputSpec - output_spec = AFNICommandOutputSpec - - def _format_arg(self, name, trait_spec, value): - if name == 'in_file_a': - arg = trait_spec.argstr % value - if isdefined(self.inputs.start_idx): - arg += '[%d..%d]' % (self.inputs.start_idx, - self.inputs.stop_idx) - if isdefined(self.inputs.single_idx): - arg += '[%d]' % (self.inputs.single_idx) - return arg - return super(Calc, self)._format_arg(name, trait_spec, value) - - def _parse_inputs(self, skip=None): - """Skip the arguments without argstr metadata - """ - return super(Calc, self)._parse_inputs( - skip=('start_idx', 'stop_idx', 'other')) - - class ClipLevelInputSpec(CommandLineInputSpec): - in_file = File(desc='input file to 3dClipLevel', - argstr='%s', - position=-1, - mandatory=True, - exists=True) - - mfrac = traits.Float(desc='Use the number ff instead of 0.50 in the algorithm', - argstr='-mfrac %s', - position=2) - - doall = traits.Bool(desc='Apply the algorithm to each sub-brick separately', - argstr='-doall', - position=3, - xor=('grad')) - - grad = traits.File(desc='also compute a \'gradual\' clip level as a function of voxel position, and output that to a dataset', - argstr='-grad %s', - position=3, - xor=('doall')) + in_file = File( + desc='input file to 3dClipLevel', + argstr='%s', + position=-1, + mandatory=True, + exists=True) + mfrac = traits.Float( + desc='Use the number ff instead of 0.50 in the algorithm', + argstr='-mfrac %s', + position=2) + doall = traits.Bool( + desc='Apply the algorithm to each sub-brick separately.', + argstr='-doall', + position=3, + xor=('grad')) + grad = traits.File( + desc='Also compute a \'gradual\' clip level as a function of voxel ' + 'position, and output that to a dataset.', + argstr='-grad %s', + position=3, + xor=('doall')) class ClipLevelOutputSpec(TraitedSpec): @@ -944,81 +731,33 @@ def aggregate_outputs(self, runtime=None, needed_outputs=None): return outputs -class CopyInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dcopy', - argstr='%s', - position=-2, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_copy", desc='output image file name', - argstr='%s', position=-1, name_source="in_file") - - -class Copy(AFNICommand): - """Copies an image of one type to an image of the same - or different type using 3dcopy command - - For complete details, see the `3dcopy Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> copy3d = afni.Copy() - >>> copy3d.inputs.in_file = 'functional.nii' - >>> copy3d.cmdline # doctest: +IGNORE_UNICODE - '3dcopy functional.nii functional_copy' - - >>> from copy import deepcopy - >>> copy3d_2 = deepcopy(copy3d) - >>> copy3d_2.inputs.outputtype = 'NIFTI' - >>> copy3d_2.cmdline # doctest: +IGNORE_UNICODE - '3dcopy functional.nii functional_copy.nii' - - >>> copy3d_3 = deepcopy(copy3d) - >>> copy3d_3.inputs.outputtype = 'NIFTI_GZ' - >>> copy3d_3.cmdline # doctest: +IGNORE_UNICODE - '3dcopy functional.nii functional_copy.nii.gz' - - >>> copy3d_4 = deepcopy(copy3d) - >>> copy3d_4.inputs.out_file = 'new_func.nii' - >>> copy3d_4.cmdline # doctest: +IGNORE_UNICODE - '3dcopy functional.nii new_func.nii' - """ - - _cmd = '3dcopy' - input_spec = CopyInputSpec - output_spec = AFNICommandOutputSpec - - class DegreeCentralityInputSpec(CentralityInputSpec): """DegreeCentrality inputspec """ - in_file = File(desc='input file to 3dDegreeCentrality', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - sparsity = traits.Float(desc='only take the top percent of connections', - argstr='-sparsity %f') - - oned_file = Str(desc='output filepath to text dump of correlation matrix', - argstr='-out1D %s') + in_file = File( + desc='input file to 3dDegreeCentrality', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + sparsity = traits.Float( + desc='only take the top percent of connections', + argstr='-sparsity %f') + oned_file = Str( + desc='output filepath to text dump of correlation matrix', + argstr='-out1D %s') class DegreeCentralityOutputSpec(AFNICommandOutputSpec): """DegreeCentrality outputspec """ - oned_file = File(desc='The text output of the similarity matrix computed'\ - 'after thresholding with one-dimensional and '\ - 'ijk voxel indices, correlations, image extents, '\ - 'and affine matrix') + oned_file = File( + desc='The text output of the similarity matrix computed after ' + 'thresholding with one-dimensional and ijk voxel indices, ' + 'correlations, image extents, and affine matrix.') class DegreeCentrality(AFNICommand): @@ -1060,15 +799,18 @@ def _list_outputs(self): class DespikeInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dDespike', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_despike", desc='output image file name', - argstr='-prefix %s', name_source="in_file") + in_file = File( + desc='input file to 3dDespike', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_despike', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') class Despike(AFNICommand): @@ -1095,15 +837,18 @@ class Despike(AFNICommand): class DetrendInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dDetrend', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_detrend", desc='output image file name', - argstr='-prefix %s', name_source="in_file") + in_file = File( + desc='input file to 3dDetrend', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_detrend', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') class Detrend(AFNICommand): @@ -1120,7 +865,7 @@ class Detrend(AFNICommand): >>> detrend = afni.Detrend() >>> detrend.inputs.in_file = 'functional.nii' >>> detrend.inputs.args = '-polort 2' - >>> detrend.inputs.outputtype = "AFNI" + >>> detrend.inputs.outputtype = 'AFNI' >>> detrend.cmdline # doctest: +IGNORE_UNICODE '3dDetrend -polort 2 -prefix functional_detrend functional.nii' >>> res = detrend.run() # doctest: +SKIP @@ -1136,55 +881,50 @@ class ECMInputSpec(CentralityInputSpec): """ECM inputspec """ - in_file = File(desc='input file to 3dECM', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - sparsity = traits.Float(desc='only take the top percent of connections', - argstr='-sparsity %f') - - full = traits.Bool(desc='Full power method; enables thresholding; '\ - 'automatically selected if -thresh or -sparsity '\ - 'are set', - argstr='-full') - - fecm = traits.Bool(desc='Fast centrality method; substantial speed '\ - 'increase but cannot accomodate thresholding; '\ - 'automatically selected if -thresh or -sparsity '\ - 'are not set', - argstr='-fecm') - - shift = traits.Float(desc='shift correlation coefficients in similarity '\ - 'matrix to enforce non-negativity, s >= 0.0; '\ - 'default = 0.0 for -full, 1.0 for -fecm', - argstr='-shift %f') - - scale = traits.Float(desc='scale correlation coefficients in similarity '\ - 'matrix to after shifting, x >= 0.0; '\ - 'default = 1.0 for -full, 0.5 for -fecm', - argstr='-scale %f') - - eps = traits.Float(desc='sets the stopping criterion for the power '\ - 'iteration; l2|v_old - v_new| < eps*|v_old|; '\ - 'default = 0.001', - argstr='-eps %f') - - max_iter = traits.Int(desc='sets the maximum number of iterations to use '\ - 'in the power iteration; default = 1000', - argstr='-max_iter %d') - - memory = traits.Float(desc='Limit memory consumption on system by setting '\ - 'the amount of GB to limit the algorithm to; '\ - 'default = 2GB', - argstr='-memory %f') + in_file = File( + desc='input file to 3dECM', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + sparsity = traits.Float( + desc='only take the top percent of connections', + argstr='-sparsity %f') + full = traits.Bool( + desc='Full power method; enables thresholding; automatically selected ' + 'if -thresh or -sparsity are set', + argstr='-full') + fecm = traits.Bool( + desc='Fast centrality method; substantial speed increase but cannot ' + 'accomodate thresholding; automatically selected if -thresh or ' + '-sparsity are not set', + argstr='-fecm') + shift = traits.Float( + desc='shift correlation coefficients in similarity matrix to enforce ' + 'non-negativity, s >= 0.0; default = 0.0 for -full, 1.0 for -fecm', + argstr='-shift %f') + scale = traits.Float( + desc='scale correlation coefficients in similarity matrix to after ' + 'shifting, x >= 0.0; default = 1.0 for -full, 0.5 for -fecm', + argstr='-scale %f') + eps = traits.Float( + desc='sets the stopping criterion for the power iteration; ' + 'l2|v_old - v_new| < eps*|v_old|; default = 0.001', + argstr='-eps %f') + max_iter = traits.Int( + desc='sets the maximum number of iterations to use in the power ' + 'iteration; default = 1000', + argstr='-max_iter %d') + memory = traits.Float( + desc='Limit memory consumption on system by setting the amount of GB ' + 'to limit the algorithm to; default = 2GB', + argstr='-memory %f') class ECM(AFNICommand): """Performs degree centrality on a dataset using a given maskfile - via the 3dLFCD command + via the 3dECM command For complete details, see the `3dECM Documentation. @@ -1208,297 +948,33 @@ class ECM(AFNICommand): output_spec = AFNICommandOutputSpec -class EvalInputSpec(AFNICommandInputSpec): - in_file_a = File(desc='input file to 1deval', - argstr='-a %s', position=0, mandatory=True, exists=True) - in_file_b = File(desc='operand file to 1deval', - argstr=' -b %s', position=1, exists=True) - in_file_c = File(desc='operand file to 1deval', - argstr=' -c %s', position=2, exists=True) - out_file = File(name_template="%s_calc", desc='output image file name', - argstr='-prefix %s', name_source="in_file_a") - out1D = traits.Bool(desc="output in 1D", - argstr='-1D') - expr = Str(desc='expr', argstr='-expr "%s"', position=3, - mandatory=True) - start_idx = traits.Int(desc='start index for in_file_a', - requires=['stop_idx']) - stop_idx = traits.Int(desc='stop index for in_file_a', - requires=['start_idx']) - single_idx = traits.Int(desc='volume index for in_file_a') - other = File(desc='other options', argstr='') - - -class Eval(AFNICommand): - """Evaluates an expression that may include columns of data from one or more text files - - see AFNI Documentation: - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> eval = afni.Eval() - >>> eval.inputs.in_file_a = 'seed.1D' - >>> eval.inputs.in_file_b = 'resp.1D' - >>> eval.inputs.expr='a*b' - >>> eval.inputs.out1D = True - >>> eval.inputs.out_file = 'data_calc.1D' - >>> calc.cmdline #doctest: +SKIP +IGNORE_UNICODE - '3deval -a timeseries1.1D -b timeseries2.1D -expr "a*b" -1D -prefix data_calc.1D' - - """ - - _cmd = '1deval' - input_spec = EvalInputSpec - output_spec = AFNICommandOutputSpec - - def _format_arg(self, name, trait_spec, value): - if name == 'in_file_a': - arg = trait_spec.argstr % value - if isdefined(self.inputs.start_idx): - arg += '[%d..%d]' % (self.inputs.start_idx, - self.inputs.stop_idx) - if isdefined(self.inputs.single_idx): - arg += '[%d]' % (self.inputs.single_idx) - return arg - return super(Eval, self)._format_arg(name, trait_spec, value) - - def _parse_inputs(self, skip=None): - """Skip the arguments without argstr metadata - """ - return super(Eval, self)._parse_inputs( - skip=('start_idx', 'stop_idx', 'out1D', 'other')) - - -class FWHMxInputSpec(CommandLineInputSpec): - in_file = File(desc='input dataset', argstr='-input %s', mandatory=True, exists=True) - out_file = File(argstr='> %s', name_source='in_file', name_template='%s_fwhmx.out', - position=-1, keep_extension=False, desc='output file') - out_subbricks = File(argstr='-out %s', name_source='in_file', name_template='%s_subbricks.out', - keep_extension=False, desc='output file listing the subbricks FWHM') - mask = File(desc='use only voxels that are nonzero in mask', argstr='-mask %s', exists=True) - automask = traits.Bool(False, usedefault=True, argstr='-automask', - desc='compute a mask from THIS dataset, a la 3dAutomask') - detrend = traits.Either( - traits.Bool(), traits.Int(), default=False, argstr='-detrend', xor=['demed'], usedefault=True, - desc='instead of demed (0th order detrending), detrend to the specified order. If order ' - 'is not given, the program picks q=NT/30. -detrend disables -demed, and includes ' - '-unif.') - demed = traits.Bool( - False, argstr='-demed', xor=['detrend'], - desc='If the input dataset has more than one sub-brick (e.g., has a time axis), then ' - 'subtract the median of each voxel\'s time series before processing FWHM. This will ' - 'tend to remove intrinsic spatial structure and leave behind the noise.') - unif = traits.Bool(False, argstr='-unif', - desc='If the input dataset has more than one sub-brick, then normalize each' - ' voxel\'s time series to have the same MAD before processing FWHM.') - out_detrend = File(argstr='-detprefix %s', name_source='in_file', name_template='%s_detrend', - keep_extension=False, desc='Save the detrended file into a dataset') - geom = traits.Bool(argstr='-geom', xor=['arith'], - desc='if in_file has more than one sub-brick, compute the final estimate as' - 'the geometric mean of the individual sub-brick FWHM estimates') - arith = traits.Bool(argstr='-arith', xor=['geom'], - desc='if in_file has more than one sub-brick, compute the final estimate as' - 'the arithmetic mean of the individual sub-brick FWHM estimates') - combine = traits.Bool(argstr='-combine', desc='combine the final measurements along each axis') - compat = traits.Bool(argstr='-compat', desc='be compatible with the older 3dFWHM') - acf = traits.Either( - traits.Bool(), File(), traits.Tuple(File(exists=True), traits.Float()), - default=False, usedefault=True, argstr='-acf', desc='computes the spatial autocorrelation') - - -class FWHMxOutputSpec(TraitedSpec): - out_file = File(exists=True, desc='output file') - out_subbricks = File(exists=True, desc='output file (subbricks)') - out_detrend = File(desc='output file, detrended') - fwhm = traits.Either( - traits.Tuple(traits.Float(), traits.Float(), traits.Float()), - traits.Tuple(traits.Float(), traits.Float(), traits.Float(), traits.Float()), - desc='FWHM along each axis') - acf_param = traits.Either( - traits.Tuple(traits.Float(), traits.Float(), traits.Float()), - traits.Tuple(traits.Float(), traits.Float(), traits.Float(), traits.Float()), - desc='fitted ACF model parameters') - out_acf = File(exists=True, desc='output acf file') - - -class FWHMx(AFNICommandBase): - """ - Unlike the older 3dFWHM, this program computes FWHMs for all sub-bricks - in the input dataset, each one separately. The output for each one is - written to the file specified by '-out'. The mean (arithmetic or geometric) - of all the FWHMs along each axis is written to stdout. (A non-positive - output value indicates something bad happened; e.g., FWHM in z is meaningless - for a 2D dataset; the estimation method computed incoherent intermediate results.) - - Examples - -------- - - >>> from nipype.interfaces import afni as afp - >>> fwhm = afp.FWHMx() - >>> fwhm.inputs.in_file = 'functional.nii' - >>> fwhm.cmdline # doctest: +IGNORE_UNICODE - '3dFWHMx -input functional.nii -out functional_subbricks.out > functional_fwhmx.out' - - - (Classic) METHOD: - - * Calculate ratio of variance of first differences to data variance. - * Should be the same as 3dFWHM for a 1-brick dataset. - (But the output format is simpler to use in a script.) - - - .. note:: IMPORTANT NOTE [AFNI > 16] - - A completely new method for estimating and using noise smoothness values is - now available in 3dFWHMx and 3dClustSim. This method is implemented in the - '-acf' options to both programs. 'ACF' stands for (spatial) AutoCorrelation - Function, and it is estimated by calculating moments of differences out to - a larger radius than before. - - Notably, real FMRI data does not actually have a Gaussian-shaped ACF, so the - estimated ACF is then fit (in 3dFWHMx) to a mixed model (Gaussian plus - mono-exponential) of the form - - .. math:: - - ACF(r) = a * exp(-r*r/(2*b*b)) + (1-a)*exp(-r/c) - - - where :math:`r` is the radius, and :math:`a, b, c` are the fitted parameters. - The apparent FWHM from this model is usually somewhat larger in real data - than the FWHM estimated from just the nearest-neighbor differences used - in the 'classic' analysis. - - The longer tails provided by the mono-exponential are also significant. - 3dClustSim has also been modified to use the ACF model given above to generate - noise random fields. - - - .. note:: TL;DR or summary - - The take-awaymessage is that the 'classic' 3dFWHMx and - 3dClustSim analysis, using a pure Gaussian ACF, is not very correct for - FMRI data -- I cannot speak for PET or MEG data. - - - .. warning:: - - Do NOT use 3dFWHMx on the statistical results (e.g., '-bucket') from - 3dDeconvolve or 3dREMLfit!!! The function of 3dFWHMx is to estimate - the smoothness of the time series NOISE, not of the statistics. This - proscription is especially true if you plan to use 3dClustSim next!! - - - .. note:: Recommendations - - * For FMRI statistical purposes, you DO NOT want the FWHM to reflect - the spatial structure of the underlying anatomy. Rather, you want - the FWHM to reflect the spatial structure of the noise. This means - that the input dataset should not have anatomical (spatial) structure. - * One good form of input is the output of '3dDeconvolve -errts', which is - the dataset of residuals left over after the GLM fitted signal model is - subtracted out from each voxel's time series. - * If you don't want to go to that much trouble, use '-detrend' to approximately - subtract out the anatomical spatial structure, OR use the output of 3dDetrend - for the same purpose. - * If you do not use '-detrend', the program attempts to find non-zero spatial - structure in the input, and will print a warning message if it is detected. - - - .. note:: Notes on -demend - - * I recommend this option, and it is not the default only for historical - compatibility reasons. It may become the default someday. - * It is already the default in program 3dBlurToFWHM. This is the same detrending - as done in 3dDespike; using 2*q+3 basis functions for q > 0. - * If you don't use '-detrend', the program now [Aug 2010] checks if a large number - of voxels are have significant nonzero means. If so, the program will print a - warning message suggesting the use of '-detrend', since inherent spatial - structure in the image will bias the estimation of the FWHM of the image time - series NOISE (which is usually the point of using 3dFWHMx). - - - """ - _cmd = '3dFWHMx' - input_spec = FWHMxInputSpec - output_spec = FWHMxOutputSpec - _acf = True - - def _parse_inputs(self, skip=None): - if not self.inputs.detrend: - if skip is None: - skip = [] - skip += ['out_detrend'] - return super(FWHMx, self)._parse_inputs(skip=skip) - - def _format_arg(self, name, trait_spec, value): - if name == 'detrend': - if isinstance(value, bool): - if value: - return trait_spec.argstr - else: - return None - elif isinstance(value, int): - return trait_spec.argstr + ' %d' % value - - if name == 'acf': - if isinstance(value, bool): - if value: - return trait_spec.argstr - else: - self._acf = False - return None - elif isinstance(value, tuple): - return trait_spec.argstr + ' %s %f' % value - elif isinstance(value, (str, bytes)): - return trait_spec.argstr + ' ' + value - return super(FWHMx, self)._format_arg(name, trait_spec, value) - - def _list_outputs(self): - outputs = super(FWHMx, self)._list_outputs() - - if self.inputs.detrend: - fname, ext = op.splitext(self.inputs.in_file) - if '.gz' in ext: - _, ext2 = op.splitext(fname) - ext = ext2 + ext - outputs['out_detrend'] += ext - else: - outputs['out_detrend'] = Undefined - - sout = np.loadtxt(outputs['out_file']) #pylint: disable=E1101 - if self._acf: - outputs['acf_param'] = tuple(sout[1]) - sout = tuple(sout[0]) - - outputs['out_acf'] = op.abspath('3dFWHMx.1D') - if isinstance(self.inputs.acf, (str, bytes)): - outputs['out_acf'] = op.abspath(self.inputs.acf) - - outputs['fwhm'] = tuple(sout) - return outputs - - class FimInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dfim+', - argstr=' -input %s', - position=1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_fim", desc='output image file name', - argstr='-bucket %s', name_source="in_file") - ideal_file = File(desc='ideal time series file name', - argstr='-ideal_file %s', - position=2, - mandatory=True, - exists=True) - fim_thr = traits.Float(desc='fim internal mask threshold value', - argstr='-fim_thr %f', position=3) - out = Str(desc='Flag to output the specified parameter', - argstr='-out %s', position=4) + in_file = File( + desc='input file to 3dfim+', + argstr=' -input %s', + position=1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_fim', + desc='output image file name', + argstr='-bucket %s', + name_source='in_file') + ideal_file = File( + desc='ideal time series file name', + argstr='-ideal_file %s', + position=2, + mandatory=True, + exists=True) + fim_thr = traits.Float( + desc='fim internal mask threshold value', + argstr='-fim_thr %f', + position=3) + out = Str( + desc='Flag to output the specified parameter', + argstr='-out %s', + position=4) class Fim(AFNICommand): @@ -1529,22 +1005,28 @@ class Fim(AFNICommand): class FourierInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dFourier', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_fourier", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - lowpass = traits.Float(desc='lowpass', - argstr='-lowpass %f', - position=0, - mandatory=True) - highpass = traits.Float(desc='highpass', - argstr='-highpass %f', - position=1, - mandatory=True) + in_file = File( + desc='input file to 3dFourier', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_fourier', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + lowpass = traits.Float( + desc='lowpass', + argstr='-lowpass %f', + position=0, + mandatory=True) + highpass = traits.Float( + desc='highpass', + argstr='-highpass %f', + position=1, + mandatory=True) class Fourier(AFNICommand): @@ -1574,21 +1056,46 @@ class Fourier(AFNICommand): class HistInputSpec(CommandLineInputSpec): in_file = File( - desc='input file to 3dHist', argstr='-input %s', position=1, mandatory=True, - exists=True, copyfile=False) + desc='input file to 3dHist', + argstr='-input %s', + position=1, + mandatory=True, + exists=True, + copyfile=False) out_file = File( - desc='Write histogram to niml file with this prefix', name_template='%s_hist', - keep_extension=False, argstr='-prefix %s', name_source=['in_file']) - showhist = traits.Bool(False, usedefault=True, desc='write a text visual histogram', - argstr='-showhist') + desc='Write histogram to niml file with this prefix', + name_template='%s_hist', + keep_extension=False, + argstr='-prefix %s', + name_source=['in_file']) + showhist = traits.Bool( + False, + usedefault=True, + desc='write a text visual histogram', + argstr='-showhist') out_show = File( - name_template="%s_hist.out", desc='output image file name', keep_extension=False, - argstr="> %s", name_source="in_file", position=-1) - mask = File(desc='matrix to align input file', argstr='-mask %s', exists=True) - nbin = traits.Int(desc='number of bins', argstr='-nbin %d') - max_value = traits.Float(argstr='-max %f', desc='maximum intensity value') - min_value = traits.Float(argstr='-min %f', desc='minimum intensity value') - bin_width = traits.Float(argstr='-binwidth %f', desc='bin width') + name_template='%s_hist.out', + desc='output image file name', + keep_extension=False, + argstr='> %s', + name_source='in_file', + position=-1) + mask = File( + desc='matrix to align input file', + argstr='-mask %s', + exists=True) + nbin = traits.Int( + desc='number of bins', + argstr='-nbin %d') + max_value = traits.Float( + argstr='-max %f', + desc='maximum intensity value') + min_value = traits.Float( + argstr='-min %f', + desc='minimum intensity value') + bin_width = traits.Float( + argstr='-binwidth %f', + desc='bin width') class HistOutputSpec(TraitedSpec): @@ -1683,112 +1190,30 @@ class LFCD(AFNICommand): output_spec = AFNICommandOutputSpec -class MaskToolInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file or files to 3dmask_tool', - argstr='-input %s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_mask", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - count = traits.Bool(desc='Instead of created a binary 0/1 mask dataset, '+ - 'create one with. counts of voxel overlap, i.e '+ - 'each voxel will contain the number of masks ' + - 'that it is set in.', - argstr='-count', - position=2) - - datum = traits.Enum('byte','short','float', - argstr='-datum %s', - desc='specify data type for output. Valid types are '+ - '\'byte\', \'short\' and \'float\'.') - - dilate_inputs = Str(desc='Use this option to dilate and/or erode '+ - 'datasets as they are read. ex. ' + - '\'5 -5\' to dilate and erode 5 times', - argstr='-dilate_inputs %s') - - dilate_results = Str(desc='dilate and/or erode combined mask at ' + - 'the given levels.', - argstr='-dilate_results %s') - - frac = traits.Float(desc='When combining masks (across datasets and ' + - 'sub-bricks), use this option to restrict the ' + - 'result to a certain fraction of the set of ' + - 'volumes', - argstr='-frac %s') - - inter = traits.Bool(desc='intersection, this means -frac 1.0', - argstr='-inter') - - union = traits.Bool(desc='union, this means -frac 0', - argstr='-union') - - fill_holes = traits.Bool(desc='This option can be used to fill holes ' + - 'in the resulting mask, i.e. after all ' + - 'other processing has been done.', - argstr='-fill_holes') - - fill_dirs = Str(desc='fill holes only in the given directions. ' + - 'This option is for use with -fill holes. ' + - 'should be a single string that specifies ' + - '1-3 of the axes using {x,y,z} labels (i.e. '+ - 'dataset axis order), or using the labels ' + - 'in {R,L,A,P,I,S}.', - argstr='-fill_dirs %s', - requires=['fill_holes']) - - -class MaskToolOutputSpec(TraitedSpec): - out_file = File(desc='mask file', - exists=True) - - -class MaskTool(AFNICommand): - """3dmask_tool - for combining/dilating/eroding/filling masks - - For complete details, see the `3dmask_tool Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> automask = afni.Automask() - >>> automask.inputs.in_file = 'functional.nii' - >>> automask.inputs.dilate = 1 - >>> automask.inputs.outputtype = "NIFTI" - >>> automask.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - '3dAutomask -apply_prefix functional_masked.nii -dilate 1 -prefix functional_mask.nii functional.nii' - >>> res = automask.run() # doctest: +SKIP - - """ - - _cmd = '3dmask_tool' - input_spec = MaskToolInputSpec - output_spec = MaskToolOutputSpec - - class MaskaveInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dmaskave', - argstr='%s', - position=-2, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_maskave.1D", desc='output image file name', - keep_extension=True, - argstr="> %s", name_source="in_file", position=-1) - mask = File(desc='matrix to align input file', - argstr='-mask %s', - position=1, - exists=True) - quiet = traits.Bool(desc='matrix to align input file', - argstr='-quiet', - position=2) + in_file = File( + desc='input file to 3dmaskave', + argstr='%s', + position=-2, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_maskave.1D', + desc='output image file name', + keep_extension=True, + argstr='> %s', + name_source='in_file', + position=-1) + mask = File( + desc='matrix to align input file', + argstr='-mask %s', + position=1, + exists=True) + quiet = traits.Bool( + desc='matrix to align input file', + argstr='-quiet', + position=2) class Maskave(AFNICommand): @@ -1818,25 +1243,46 @@ class Maskave(AFNICommand): class MeansInputSpec(AFNICommandInputSpec): - in_file_a = File(desc='input file to 3dMean', - argstr='%s', - position=0, - mandatory=True, - exists=True) - in_file_b = File(desc='another input file to 3dMean', - argstr='%s', - position=1, - exists=True) - out_file = File(name_template="%s_mean", desc='output image file name', - argstr='-prefix %s', name_source="in_file_a") - scale = Str(desc='scaling of output', argstr='-%sscale') - non_zero = traits.Bool(desc='use only non-zero values', argstr='-non_zero') - std_dev = traits.Bool(desc='calculate std dev', argstr='-stdev') - sqr = traits.Bool(desc='mean square instead of value', argstr='-sqr') - summ = traits.Bool(desc='take sum, (not average)', argstr='-sum') - count = traits.Bool(desc='compute count of non-zero voxels', argstr='-count') - mask_inter = traits.Bool(desc='create intersection mask', argstr='-mask_inter') - mask_union = traits.Bool(desc='create union mask', argstr='-mask_union') + in_file_a = File( + desc='input file to 3dMean', + argstr='%s', + position=0, + mandatory=True, + exists=True) + in_file_b = File( + desc='another input file to 3dMean', + argstr='%s', + position=1, + exists=True) + out_file = File( + name_template='%s_mean', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file_a') + scale = Str( + desc='scaling of output', + argstr='-%sscale') + non_zero = traits.Bool( + desc='use only non-zero values', + argstr='-non_zero') + std_dev = traits.Bool( + desc='calculate std dev', + argstr='-stdev') + sqr = traits.Bool( + desc='mean square instead of value', + argstr='-sqr') + summ = traits.Bool( + desc='take sum, (not average)', + argstr='-sum') + count = traits.Bool( + desc='compute count of non-zero voxels', + argstr='-count') + mask_inter = traits.Bool( + desc='create intersection mask', + argstr='-mask_inter') + mask_union = traits.Bool( + desc='create union mask', + argstr='-mask_union') class Means(AFNICommand): @@ -1862,143 +1308,95 @@ class Means(AFNICommand): output_spec = AFNICommandOutputSpec -class MergeInputSpec(AFNICommandInputSpec): - in_files = InputMultiPath( - File(desc='input file to 3dmerge', exists=True), +class OutlierCountInputSpec(CommandLineInputSpec): + in_file = File( argstr='%s', - position=-1, mandatory=True, - copyfile=False) - out_file = File(name_template="%s_merge", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - doall = traits.Bool(desc='apply options to all sub-bricks in dataset', - argstr='-doall') - blurfwhm = traits.Int(desc='FWHM blur value (mm)', - argstr='-1blur_fwhm %d', - units='mm') - - -class Merge(AFNICommand): - """Merge or edit volumes using AFNI 3dmerge command - - For complete details, see the `3dmerge Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> merge = afni.Merge() - >>> merge.inputs.in_files = ['functional.nii', 'functional2.nii'] - >>> merge.inputs.blurfwhm = 4 - >>> merge.inputs.doall = True - >>> merge.inputs.out_file = 'e7.nii' - >>> res = merge.run() # doctest: +SKIP - - """ - - _cmd = '3dmerge' - input_spec = MergeInputSpec - output_spec = AFNICommandOutputSpec - - -class NotesInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dNotes', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - add = Str(desc='note to add', - argstr='-a "%s"') - add_history = Str(desc='note to add to history', - argstr='-h "%s"', - xor=['rep_history']) - rep_history = Str(desc='note with which to replace history', - argstr='-HH "%s"', - xor=['add_history']) - delete = traits.Int(desc='delete note number num', - argstr='-d %d') - ses = traits.Bool(desc='print to stdout the expanded notes', - argstr='-ses') - out_file = File(desc='output image file name', - argstr='%s') - - -class Notes(CommandLine): - """ - A program to add, delete, and show notes for AFNI datasets. - - For complete details, see the `3dNotes Documentation. - - - Examples - ======== - - >>> from nipype.interfaces import afni - >>> notes = afni.Notes() - >>> notes.inputs.in_file = "functional.HEAD" - >>> notes.inputs.add = "This note is added." - >>> notes.inputs.add_history = "This note is added to history." - >>> notes.cmdline #doctest: +IGNORE_UNICODE - '3dNotes -a "This note is added." -h "This note is added to history." functional.HEAD' - >>> res = notes.run() # doctest: +SKIP - """ - - _cmd = '3dNotes' - input_spec = NotesInputSpec - output_spec = AFNICommandOutputSpec - - def _list_outputs(self): - outputs = self.output_spec().get() - outputs['out_file'] = os.path.abspath(self.inputs.in_file) - return outputs - - -class OutlierCountInputSpec(CommandLineInputSpec): - in_file = File(argstr='%s', mandatory=True, exists=True, position=-2, desc='input dataset') - mask = File(exists=True, argstr='-mask %s', xor=['autoclip', 'automask'], - desc='only count voxels within the given mask') - qthr = traits.Range(value=1e-3, low=0.0, high=1.0, argstr='-qthr %.5f', - desc='indicate a value for q to compute alpha') - - autoclip = traits.Bool(False, usedefault=True, argstr='-autoclip', xor=['in_file'], - desc='clip off small voxels') - automask = traits.Bool(False, usedefault=True, argstr='-automask', xor=['in_file'], - desc='clip off small voxels') - - fraction = traits.Bool(False, usedefault=True, argstr='-fraction', - desc='write out the fraction of masked voxels' - ' which are outliers at each timepoint') - interval = traits.Bool(False, usedefault=True, argstr='-range', - desc='write out the median + 3.5 MAD of outlier' - ' count with each timepoint') - save_outliers = traits.Bool(False, usedefault=True, desc='enables out_file option') + exists=True, + position=-2, + desc='input dataset') + mask = File( + exists=True, + argstr='-mask %s', + xor=['autoclip', 'automask'], + desc='only count voxels within the given mask') + qthr = traits.Range( + value=1e-3, + low=0.0, + high=1.0, + argstr='-qthr %.5f', + desc='indicate a value for q to compute alpha') + autoclip = traits.Bool( + False, + usedefault=True, + argstr='-autoclip', + xor=['in_file'], + desc='clip off small voxels') + automask = traits.Bool( + False, + usedefault=True, + argstr='-automask', + xor=['in_file'], + desc='clip off small voxels') + fraction = traits.Bool( + False, + usedefault=True, + argstr='-fraction', + desc='write out the fraction of masked voxels which are outliers at ' + 'each timepoint') + interval = traits.Bool( + False, + usedefault=True, + argstr='-range', + desc='write out the median + 3.5 MAD of outlier count with each ' + 'timepoint') + save_outliers = traits.Bool( + False, + usedefault=True, + desc='enables out_file option') outliers_file = File( - name_template="%s_outliers", argstr='-save %s', name_source=["in_file"], - output_name='out_outliers', keep_extension=True, desc='output image file name') - - polort = traits.Int(argstr='-polort %d', - desc='detrend each voxel timeseries with polynomials') - legendre = traits.Bool(False, usedefault=True, argstr='-legendre', - desc='use Legendre polynomials') + name_template='%s_outliers', + argstr='-save %s', + name_source=['in_file'], + output_name='out_outliers', + keep_extension=True, + desc='output image file name') + polort = traits.Int( + argstr='-polort %d', + desc='detrend each voxel timeseries with polynomials') + legendre = traits.Bool( + False, + usedefault=True, + argstr='-legendre', + desc='use Legendre polynomials') out_file = File( - name_template='%s_outliers', name_source=['in_file'], argstr='> %s', - keep_extension=False, position=-1, desc='capture standard output') + name_template='%s_outliers', + name_source=['in_file'], + argstr='> %s', + keep_extension=False, + position=-1, + desc='capture standard output') class OutlierCountOutputSpec(TraitedSpec): - out_outliers = File(exists=True, desc='output image file name') + out_outliers = File( + exists=True, + desc='output image file name') out_file = File( - name_template='%s_tqual', name_source=['in_file'], argstr='> %s', - keep_extension=False, position=-1, desc='capture standard output') + name_template='%s_tqual', + name_source=['in_file'], + argstr='> %s', + keep_extension=False, + position=-1, + desc='capture standard output') class OutlierCount(CommandLine): - """Create a 3D dataset from 2D image files using AFNI to3d command + """Calculates number of 'outliers' a 3D+time dataset, at each + time point, and writes the results to stdout. - For complete details, see the `to3d Documentation - `_ + For complete details, see the `3dToutcount Documentation + `_ Examples ======== @@ -2033,29 +1431,58 @@ def _list_outputs(self): class QualityIndexInputSpec(CommandLineInputSpec): - in_file = File(argstr='%s', mandatory=True, exists=True, position=-2, desc='input dataset') - mask = File(exists=True, argstr='-mask %s', xor=['autoclip', 'automask'], - desc='compute correlation only across masked voxels') - spearman = traits.Bool(False, usedefault=True, argstr='-spearman', - desc='Quality index is 1 minus the Spearman (rank) ' - 'correlation coefficient of each sub-brick ' - 'with the median sub-brick. (default)') - quadrant = traits.Bool(False, usedefault=True, argstr='-quadrant', - desc='Similar to -spearman, but using 1 minus the ' - 'quadrant correlation coefficient as the ' - 'quality index.') - autoclip = traits.Bool(False, usedefault=True, argstr='-autoclip', xor=['mask'], - desc='clip off small voxels') - automask = traits.Bool(False, usedefault=True, argstr='-automask', xor=['mask'], - desc='clip off small voxels') - clip = traits.Float(argstr='-clip %f', desc='clip off values below') - - interval = traits.Bool(False, usedefault=True, argstr='-range', - desc='write out the median + 3.5 MAD of outlier' - ' count with each timepoint') + in_file = File( + argstr='%s', + mandatory=True, + exists=True, + position=-2, + desc='input dataset') + mask = File( + exists=True, + argstr='-mask %s', + xor=['autoclip', 'automask'], + desc='compute correlation only across masked voxels') + spearman = traits.Bool( + False, + usedefault=True, + argstr='-spearman', + desc='Quality index is 1 minus the Spearman (rank) correlation ' + 'coefficient of each sub-brick with the median sub-brick. ' + '(default).') + quadrant = traits.Bool( + False, + usedefault=True, + argstr='-quadrant', + desc='Similar to -spearman, but using 1 minus the quadrant correlation ' + 'coefficient as the quality index.') + autoclip = traits.Bool( + False, + usedefault=True, + argstr='-autoclip', + xor=['mask'], + desc='clip off small voxels') + automask = traits.Bool( + False, + usedefault=True, + argstr='-automask', + xor=['mask'], + desc='clip off small voxels') + clip = traits.Float( + argstr='-clip %f', + desc='clip off values below') + interval = traits.Bool( + False, + usedefault=True, + argstr='-range', + desc='write out the median + 3.5 MAD of outlier count with each ' + 'timepoint') out_file = File( - name_template='%s_tqual', name_source=['in_file'], argstr='> %s', - keep_extension=False, position=-1, desc='capture standard output') + name_template='%s_tqual', + name_source=['in_file'], + argstr='> %s', + keep_extension=False, + position=-1, + desc='capture standard output') class QualityIndexOutputSpec(TraitedSpec): @@ -2063,10 +1490,12 @@ class QualityIndexOutputSpec(TraitedSpec): class QualityIndex(CommandLine): - """Create a 3D dataset from 2D image files using AFNI to3d command + """Computes a `quality index' for each sub-brick in a 3D+time dataset. + The output is a 1D time series with the index for each sub-brick. + The results are written to stdout. - For complete details, see the `to3d Documentation - `_ + For complete details, see the `3dTqual Documentation + `_ Examples ======== @@ -2085,32 +1514,33 @@ class QualityIndex(CommandLine): class ROIStatsInputSpec(CommandLineInputSpec): - in_file = File(desc='input file to 3dROIstats', - argstr='%s', - position=-1, - mandatory=True, - exists=True) - - mask = File(desc='input mask', - argstr='-mask %s', - position=3, - exists=True) - + in_file = File( + desc='input file to 3dROIstats', + argstr='%s', + position=-1, + mandatory=True, + exists=True) + mask = File( + desc='input mask', + argstr='-mask %s', + position=3, + exists=True) mask_f2short = traits.Bool( - desc='Tells the program to convert a float mask ' + - 'to short integers, by simple rounding.', + desc='Tells the program to convert a float mask to short integers, ' + 'by simple rounding.', argstr='-mask_f2short', position=2) - - quiet = traits.Bool(desc='execute quietly', - argstr='-quiet', - position=1) - - terminal_output = traits.Enum('allatonce', - desc=('Control terminal output:' - '`allatonce` - waits till command is ' - 'finished to display output'), - nohash=True, mandatory=True, usedefault=True) + quiet = traits.Bool( + desc='execute quietly', + argstr='-quiet', + position=1) + terminal_output = traits.Enum( + 'allatonce', + desc='Control terminal output:`allatonce` - waits till command is ' + 'finished to display output', + nohash=True, + mandatory=True, + usedefault=True) class ROIStatsOutputSpec(TraitedSpec): @@ -2140,167 +1570,57 @@ class ROIStats(AFNICommandBase): def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = self._outputs() - output_filename = "roi_stats.csv" - with open(output_filename, "w") as f: + output_filename = 'roi_stats.csv' + with open(output_filename, 'w') as f: f.write(runtime.stdout) outputs.stats = os.path.abspath(output_filename) return outputs -class RefitInputSpec(CommandLineInputSpec): - in_file = File(desc='input file to 3drefit', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=True) - - deoblique = traits.Bool(desc='replace current transformation'\ - ' matrix with cardinal matrix', - argstr='-deoblique') - - xorigin = Str(desc='x distance for edge voxel offset', - argstr='-xorigin %s') - - yorigin = Str(desc='y distance for edge voxel offset', - argstr='-yorigin %s') - zorigin = Str(desc='z distance for edge voxel offset', - argstr='-zorigin %s') - - xdel = traits.Float(desc='new x voxel dimension in mm', - argstr='-xdel %f') - - ydel = traits.Float(desc='new y voxel dimension in mm', - argstr='-ydel %f') - - zdel = traits.Float(desc='new z voxel dimension in mm', - argstr='-zdel %f') - - space = traits.Enum('TLRC', 'MNI', 'ORIG', - argstr='-space %s', - desc='Associates the dataset with a specific'\ - ' template type, e.g. TLRC, MNI, ORIG') - - -class Refit(AFNICommandBase): - """Changes some of the information inside a 3D dataset's header - - For complete details, see the `3drefit Documentation. - - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> refit = afni.Refit() - >>> refit.inputs.in_file = 'structural.nii' - >>> refit.inputs.deoblique = True - >>> refit.cmdline # doctest: +IGNORE_UNICODE - '3drefit -deoblique structural.nii' - >>> res = refit.run() # doctest: +SKIP - - """ - _cmd = '3drefit' - input_spec = RefitInputSpec - output_spec = AFNICommandOutputSpec - - def _list_outputs(self): - outputs = self.output_spec().get() - outputs["out_file"] = os.path.abspath(self.inputs.in_file) - return outputs - - -class ResampleInputSpec(AFNICommandInputSpec): - - in_file = File(desc='input file to 3dresample', - argstr='-inset %s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_resample", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - orientation = Str(desc='new orientation code', - argstr='-orient %s') - - resample_mode = traits.Enum('NN', 'Li', 'Cu', 'Bk', - argstr='-rmode %s', - desc="resampling method from set {'NN', "\ - "'Li', 'Cu', 'Bk'}. These are for "\ - "'Nearest Neighbor', 'Linear', 'Cubic' "\ - "and 'Blocky' interpolation, respectively. "\ - "Default is NN.") - - voxel_size = traits.Tuple(*[traits.Float()] * 3, - argstr='-dxyz %f %f %f', - desc="resample to new dx, dy and dz") - - master = traits.File(argstr='-master %s', - desc='align dataset grid to a reference file') - - -class Resample(AFNICommand): - """Resample or reorient an image using AFNI 3dresample command - - For complete details, see the `3dresample Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> resample = afni.Resample() - >>> resample.inputs.in_file = 'functional.nii' - >>> resample.inputs.orientation= 'RPI' - >>> resample.inputs.outputtype = "NIFTI" - >>> resample.cmdline # doctest: +IGNORE_UNICODE - '3dresample -orient RPI -prefix functional_resample.nii -inset functional.nii' - >>> res = resample.run() # doctest: +SKIP - - """ - - _cmd = '3dresample' - input_spec = ResampleInputSpec - output_spec = AFNICommandOutputSpec - - class RetroicorInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dretroicor', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(desc='output image file name', argstr='-prefix %s', mandatory=True, position=1) - card = File(desc='1D cardiac data file for cardiac correction', - argstr='-card %s', - position=-2, - exists=True) - resp = File(desc='1D respiratory waveform data for correction', - argstr='-resp %s', - position=-3, - exists=True) - threshold = traits.Int(desc='Threshold for detection of R-wave peaks in '\ - 'input (Make sure it is above the background '\ - 'noise level, Try 3/4 or 4/5 times range '\ - 'plus minimum)', - argstr='-threshold %d', - position=-4) - order = traits.Int(desc='The order of the correction (2 is typical)', - argstr='-order %s', - position=-5) - - cardphase = File(desc='Filename for 1D cardiac phase output', - argstr='-cardphase %s', - position=-6, - hash_files=False) - respphase = File(desc='Filename for 1D resp phase output', - argstr='-respphase %s', - position=-7, - hash_files=False) + in_file = File( + desc='input file to 3dretroicor', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + desc='output image file name', + argstr='-prefix %s', + mandatory=True, + position=1) + card = File( + desc='1D cardiac data file for cardiac correction', + argstr='-card %s', + position=-2, + exists=True) + resp = File( + desc='1D respiratory waveform data for correction', + argstr='-resp %s', + position=-3, + exists=True) + threshold = traits.Int( + desc='Threshold for detection of R-wave peaks in input (Make sure it ' + 'is above the background noise level, Try 3/4 or 4/5 times range ' + 'plus minimum)', + argstr='-threshold %d', + position=-4) + order = traits.Int( + desc='The order of the correction (2 is typical)', + argstr='-order %s', + position=-5) + cardphase = File( + desc='Filename for 1D cardiac phase output', + argstr='-cardphase %s', + position=-6, + hash_files=False) + respphase = File( + desc='Filename for 1D resp phase output', + argstr='-respphase %s', + position=-7, + hash_files=False) class Retroicor(AFNICommand): @@ -2340,53 +1660,54 @@ class Retroicor(AFNICommand): class SegInputSpec(CommandLineInputSpec): - in_file = File(desc='ANAT is the volume to segment', - argstr='-anat %s', - position=-1, - mandatory=True, - exists=True, - copyfile=True) - - mask = traits.Either(traits.Enum('AUTO'), - File(exists=True), - desc=('only non-zero voxels in mask are analyzed. ' - 'mask can either be a dataset or the string ' - '"AUTO" which would use AFNI\'s automask ' - 'function to create the mask.'), - argstr='-mask %s', - position=-2, - mandatory=True) - - blur_meth = traits.Enum('BFT', 'BIM', - argstr='-blur_meth %s', - desc='set the blurring method for bias field estimation') - - bias_fwhm = traits.Float(desc='The amount of blurring used when estimating the field bias with the Wells method', - argstr='-bias_fwhm %f') - - classes = Str(desc='CLASS_STRING is a semicolon delimited string of class labels', - argstr='-classes %s') - - bmrf = traits.Float(desc='Weighting factor controlling spatial homogeneity of the classifications', - argstr='-bmrf %f') - - bias_classes = Str(desc='A semicolon delimited string of classes that '\ - 'contribute to the estimation of the bias field', - argstr='-bias_classes %s') - - prefix = Str(desc='the prefix for the output folder containing all output volumes', - argstr='-prefix %s') - - mixfrac = Str(desc='MIXFRAC sets up the volume-wide (within mask) tissue '\ - 'fractions while initializing the segmentation (see '\ - 'IGNORE for exception)', - argstr='-mixfrac %s') - - mixfloor = traits.Float(desc='Set the minimum value for any class\'s mixing fraction', - argstr='-mixfloor %f') - - main_N = traits.Int(desc='Number of iterations to perform.', - argstr='-main_N %d') + in_file = File( + desc='ANAT is the volume to segment', + argstr='-anat %s', + position=-1, + mandatory=True, + exists=True, + copyfile=True) + mask = traits.Either( + traits.Enum('AUTO'), + File(exists=True), + desc='only non-zero voxels in mask are analyzed. mask can either be a ' + 'dataset or the string "AUTO" which would use AFNI\'s automask ' + 'function to create the mask.', + argstr='-mask %s', + position=-2, + mandatory=True) + blur_meth = traits.Enum( + 'BFT', 'BIM', + argstr='-blur_meth %s', + desc='set the blurring method for bias field estimation') + bias_fwhm = traits.Float( + desc='The amount of blurring used when estimating the field bias with ' + 'the Wells method', + argstr='-bias_fwhm %f') + classes = Str( + desc='CLASS_STRING is a semicolon delimited string of class labels', + argstr='-classes %s') + bmrf = traits.Float( + desc='Weighting factor controlling spatial homogeneity of the ' + 'classifications', + argstr='-bmrf %f') + bias_classes = Str( + desc='A semicolon delimited string of classes that contribute to the ' + 'estimation of the bias field', + argstr='-bias_classes %s') + prefix = Str( + desc='the prefix for the output folder containing all output volumes', + argstr='-prefix %s') + mixfrac = Str( + desc='MIXFRAC sets up the volume-wide (within mask) tissue fractions ' + 'while initializing the segmentation (see IGNORE for exception)', + argstr='-mixfrac %s') + mixfloor = traits.Float( + desc='Set the minimum value for any class\'s mixing fraction', + argstr='-mixfloor %f') + main_N = traits.Int( + desc='Number of iterations to perform.', + argstr='-main_N %d') class Seg(AFNICommandBase): @@ -2429,14 +1750,18 @@ def aggregate_outputs(self, runtime=None, needed_outputs=None): class SkullStripInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dSkullStrip', - argstr='-input %s', - position=1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_skullstrip", desc='output image file name', - argstr='-prefix %s', name_source="in_file") + in_file = File( + desc='input file to 3dSkullStrip', + argstr='-input %s', + position=1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_skullstrip', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') class SkullStrip(AFNICommand): @@ -2471,80 +1796,46 @@ def __init__(self, **inputs): self._redirect_x = False -class TCatInputSpec(AFNICommandInputSpec): - in_files = InputMultiPath( - File(exists=True), - desc='input file to 3dTcat', +class TCorr1DInputSpec(AFNICommandInputSpec): + xset = File( + desc='3d+time dataset input', argstr=' %s', - position=-1, + position=-2, mandatory=True, + exists=True, copyfile=False) - out_file = File(name_template="%s_tcat", desc='output image file name', - argstr='-prefix %s', name_source="in_files") - rlt = Str(desc='options', argstr='-rlt%s', position=1) - - -class TCat(AFNICommand): - """Concatenate sub-bricks from input datasets into - one big 3D+time dataset - - For complete details, see the `3dTcat Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> tcat = afni.TCat() - >>> tcat.inputs.in_files = ['functional.nii', 'functional2.nii'] - >>> tcat.inputs.out_file= 'functional_tcat.nii' - >>> tcat.inputs.rlt = '+' - >>> res = tcat.run() # doctest: +SKIP - - """ - - _cmd = '3dTcat' - input_spec = TCatInputSpec - output_spec = AFNICommandOutputSpec - - -class TCorr1DInputSpec(AFNICommandInputSpec): - xset = File(desc='3d+time dataset input', - argstr=' %s', - position=-2, - mandatory=True, - exists=True, - copyfile=False) - y_1d = File(desc='1D time series file input', - argstr=' %s', - position=-1, - mandatory=True, - exists=True) - out_file = File(desc='output filename prefix', - name_template='%s_correlation.nii.gz', - argstr='-prefix %s', - name_source='xset', - keep_extension=True) - pearson = traits.Bool(desc='Correlation is the normal' + - ' Pearson correlation coefficient', - argstr=' -pearson', - xor=['spearman', 'quadrant', 'ktaub'], - position=1) - spearman = traits.Bool(desc='Correlation is the' + - ' Spearman (rank) correlation coefficient', - argstr=' -spearman', - xor=['pearson', 'quadrant', 'ktaub'], - position=1) - quadrant = traits.Bool(desc='Correlation is the' + - ' quadrant correlation coefficient', - argstr=' -quadrant', - xor=['pearson', 'spearman', 'ktaub'], - position=1) - ktaub = traits.Bool(desc='Correlation is the' + - ' Kendall\'s tau_b correlation coefficient', - argstr=' -ktaub', - xor=['pearson', 'spearman', 'quadrant'], - position=1) + y_1d = File( + desc='1D time series file input', + argstr=' %s', + position=-1, + mandatory=True, + exists=True) + out_file = File( + desc='output filename prefix', + name_template='%s_correlation.nii.gz', + argstr='-prefix %s', + name_source='xset', + keep_extension=True) + pearson = traits.Bool( + desc='Correlation is the normal Pearson correlation coefficient', + argstr=' -pearson', + xor=['spearman', 'quadrant', 'ktaub'], + position=1) + spearman = traits.Bool( + desc='Correlation is the Spearman (rank) correlation coefficient', + argstr=' -spearman', + xor=['pearson', 'quadrant', 'ktaub'], + position=1) + quadrant = traits.Bool( + desc='Correlation is the quadrant correlation coefficient', + argstr=' -quadrant', + xor=['pearson', 'spearman', 'ktaub'], + position=1) + ktaub = traits.Bool( + desc='Correlation is the Kendall\'s tau_b correlation coefficient', + argstr=' -ktaub', + xor=['pearson', 'spearman', 'quadrant'], + position=1) class TCorr1DOutputSpec(TraitedSpec): @@ -2573,56 +1864,102 @@ class TCorr1D(AFNICommand): class TCorrMapInputSpec(AFNICommandInputSpec): - in_file = File(exists=True, argstr='-input %s', mandatory=True, copyfile=False) - seeds = File(exists=True, argstr='-seed %s', xor=('seeds_width')) - mask = File(exists=True, argstr='-mask %s') - automask = traits.Bool(argstr='-automask') - polort = traits.Int(argstr='-polort %d') - bandpass = traits.Tuple((traits.Float(), traits.Float()), - argstr='-bpass %f %f') - regress_out_timeseries = traits.File(exists=True, argstr='-ort %s') - blur_fwhm = traits.Float(argstr='-Gblur %f') - seeds_width = traits.Float(argstr='-Mseed %f', xor=('seeds')) + in_file = File( + exists=True, + argstr='-input %s', + mandatory=True, + copyfile=False) + seeds = File( + exists=True, + argstr='-seed %s', + xor=('seeds_width')) + mask = File( + exists=True, + argstr='-mask %s') + automask = traits.Bool( + argstr='-automask') + polort = traits.Int( + argstr='-polort %d') + bandpass = traits.Tuple( + (traits.Float(), traits.Float()), + argstr='-bpass %f %f') + regress_out_timeseries = traits.File( + exists=True, + argstr='-ort %s') + blur_fwhm = traits.Float( + argstr='-Gblur %f') + seeds_width = traits.Float( + argstr='-Mseed %f', + xor=('seeds')) # outputs - mean_file = File(argstr='-Mean %s', suffix='_mean', name_source="in_file") - zmean = File(argstr='-Zmean %s', suffix='_zmean', name_source="in_file") - qmean = File(argstr='-Qmean %s', suffix='_qmean', name_source="in_file") - pmean = File(argstr='-Pmean %s', suffix='_pmean', name_source="in_file") + mean_file = File( + argstr='-Mean %s', + suffix='_mean', + name_source='in_file') + zmean = File( + argstr='-Zmean %s', + suffix='_zmean', + name_source='in_file') + qmean = File( + argstr='-Qmean %s', + suffix='_qmean', + name_source='in_file') + pmean = File( + argstr='-Pmean %s', + suffix='_pmean', + name_source='in_file') _thresh_opts = ('absolute_threshold', 'var_absolute_threshold', 'var_absolute_threshold_normalize') - thresholds = traits.List(traits.Int()) + thresholds = traits.List( + traits.Int()) absolute_threshold = File( - argstr='-Thresh %f %s', suffix='_thresh', - name_source="in_file", xor=_thresh_opts) + argstr='-Thresh %f %s', + suffix='_thresh', + name_source='in_file', + xor=_thresh_opts) var_absolute_threshold = File( - argstr='-VarThresh %f %f %f %s', suffix='_varthresh', - name_source="in_file", xor=_thresh_opts) + argstr='-VarThresh %f %f %f %s', + suffix='_varthresh', + name_source='in_file', + xor=_thresh_opts) var_absolute_threshold_normalize = File( - argstr='-VarThreshN %f %f %f %s', suffix='_varthreshn', - name_source="in_file", xor=_thresh_opts) + argstr='-VarThreshN %f %f %f %s', + suffix='_varthreshn', + name_source='in_file', + xor=_thresh_opts) correlation_maps = File( - argstr='-CorrMap %s', name_source="in_file") + argstr='-CorrMap %s', + name_source='in_file') correlation_maps_masked = File( - argstr='-CorrMask %s', name_source="in_file") + argstr='-CorrMask %s', + name_source='in_file') _expr_opts = ('average_expr', 'average_expr_nonzero', 'sum_expr') expr = Str() average_expr = File( - argstr='-Aexpr %s %s', suffix='_aexpr', - name_source='in_file', xor=_expr_opts) + argstr='-Aexpr %s %s', + suffix='_aexpr', + name_source='in_file', + xor=_expr_opts) average_expr_nonzero = File( - argstr='-Cexpr %s %s', suffix='_cexpr', - name_source='in_file', xor=_expr_opts) + argstr='-Cexpr %s %s', + suffix='_cexpr', + name_source='in_file', + xor=_expr_opts) sum_expr = File( - argstr='-Sexpr %s %s', suffix='_sexpr', - name_source='in_file', xor=_expr_opts) + argstr='-Sexpr %s %s', + suffix='_sexpr', + name_source='in_file', + xor=_expr_opts) histogram_bin_numbers = traits.Int() histogram = File( - name_source='in_file', argstr='-Hist %d %s', suffix='_hist') + name_source='in_file', + argstr='-Hist %d %s', + suffix='_hist') class TCorrMapOutputSpec(TraitedSpec): @@ -2679,26 +2016,33 @@ def _format_arg(self, name, trait_spec, value): class TCorrelateInputSpec(AFNICommandInputSpec): - xset = File(desc='input xset', - argstr=' %s', - position=-2, - mandatory=True, - exists=True, - copyfile=False) - yset = File(desc='input yset', - argstr=' %s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_tcorr", desc='output image file name', - argstr='-prefix %s', name_source="xset") - pearson = traits.Bool(desc='Correlation is the normal' + - ' Pearson correlation coefficient', - argstr='-pearson', - position=1) - polort = traits.Int(desc='Remove polynomical trend of order m', - argstr='-polort %d', position=2) + xset = File( + desc='input xset', + argstr='%s', + position=-2, + mandatory=True, + exists=True, + copyfile=False) + yset = File( + desc='input yset', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_tcorr', + desc='output image file name', + argstr='-prefix %s', + name_source='xset') + pearson = traits.Bool( + desc='Correlation is the normal Pearson correlation coefficient', + argstr='-pearson', + position=1) + polort = traits.Int( + desc='Remove polynomical trend of order m', + argstr='-polort %d', + position=2) class TCorrelate(AFNICommand): @@ -2728,45 +2072,48 @@ class TCorrelate(AFNICommand): class TShiftInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dTShift', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_tshift", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - tr = Str(desc='manually set the TR. You can attach suffix "s" for seconds'\ - ' or "ms" for milliseconds.', - argstr='-TR %s') - - tzero = traits.Float(desc='align each slice to given time offset', - argstr='-tzero %s', - xor=['tslice']) - - tslice = traits.Int(desc='align each slice to time offset of given slice', - argstr='-slice %s', - xor=['tzero']) - - ignore = traits.Int(desc='ignore the first set of points specified', - argstr='-ignore %s') - - interp = traits.Enum(('Fourier', 'linear', 'cubic', 'quintic', 'heptic'), - desc='different interpolation methods (see 3dTShift '\ - 'for details) default = Fourier', argstr='-%s') - - tpattern = Str(desc='use specified slice time pattern rather than one in '\ - 'header', - argstr='-tpattern %s') - - rlt = traits.Bool(desc='Before shifting, remove the mean and linear trend', - argstr="-rlt") - - rltplus = traits.Bool(desc='Before shifting, remove the mean and linear '\ - 'trend and later put back the mean', - argstr="-rlt+") + in_file = File( + desc='input file to 3dTShift', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_tshift', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + tr = Str( + desc='manually set the TR. You can attach suffix "s" for seconds ' + 'or "ms" for milliseconds.', + argstr='-TR %s') + tzero = traits.Float( + desc='align each slice to given time offset', + argstr='-tzero %s', + xor=['tslice']) + tslice = traits.Int( + desc='align each slice to time offset of given slice', + argstr='-slice %s', + xor=['tzero']) + ignore = traits.Int( + desc='ignore the first set of points specified', + argstr='-ignore %s') + interp = traits.Enum( + ('Fourier', 'linear', 'cubic', 'quintic', 'heptic'), + desc='different interpolation methods (see 3dTShift for details) ' + 'default = Fourier', + argstr='-%s') + tpattern = Str( + desc='use specified slice time pattern rather than one in header', + argstr='-tpattern %s') + rlt = traits.Bool( + desc='Before shifting, remove the mean and linear trend', + argstr='-rlt') + rltplus = traits.Bool( + desc='Before shifting, remove the mean and linear trend and later put ' + 'back the mean', + argstr='-rlt+') class TShift(AFNICommand): @@ -2795,147 +2142,71 @@ class TShift(AFNICommand): output_spec = AFNICommandOutputSpec -class TStatInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dTstat', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_tstat", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - mask = File(desc='mask file', - argstr='-mask %s', - exists=True) - options = Str(desc='selected statistical output', - argstr='%s') - - -class TStat(AFNICommand): - """Compute voxel-wise statistics using AFNI 3dTstat command - - For complete details, see the `3dTstat Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> tstat = afni.TStat() - >>> tstat.inputs.in_file = 'functional.nii' - >>> tstat.inputs.args= '-mean' - >>> tstat.inputs.out_file = "stats" - >>> tstat.cmdline # doctest: +IGNORE_UNICODE - '3dTstat -mean -prefix stats functional.nii' - >>> res = tstat.run() # doctest: +SKIP - - """ - - _cmd = '3dTstat' - input_spec = TStatInputSpec - output_spec = AFNICommandOutputSpec - - -class To3DInputSpec(AFNICommandInputSpec): - out_file = File(name_template="%s", desc='output image file name', - argstr='-prefix %s', name_source=["in_folder"]) - in_folder = Directory(desc='folder with DICOM images to convert', - argstr='%s/*.dcm', - position=-1, - mandatory=True, - exists=True) - - filetype = traits.Enum('spgr', 'fse', 'epan', 'anat', 'ct', 'spct', - 'pet', 'mra', 'bmap', 'diff', - 'omri', 'abuc', 'fim', 'fith', 'fico', 'fitt', - 'fift', 'fizt', 'fict', 'fibt', - 'fibn', 'figt', 'fipt', - 'fbuc', argstr='-%s', - desc='type of datafile being converted') - - skipoutliers = traits.Bool(desc='skip the outliers check', - argstr='-skip_outliers') - - assumemosaic = traits.Bool(desc='assume that Siemens image is mosaic', - argstr='-assume_dicom_mosaic') - - datatype = traits.Enum('short', 'float', 'byte', 'complex', - desc='set output file datatype', argstr='-datum %s') - - funcparams = Str(desc='parameters for functional data', - argstr='-time:zt %s alt+z2') - - -class To3D(AFNICommand): - """Create a 3D dataset from 2D image files using AFNI to3d command - - For complete details, see the `to3d Documentation - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni - >>> To3D = afni.To3D() - >>> To3D.inputs.datatype = 'float' - >>> To3D.inputs.in_folder = '.' - >>> To3D.inputs.out_file = 'dicomdir.nii' - >>> To3D.inputs.filetype = "anat" - >>> To3D.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE - 'to3d -datum float -anat -prefix dicomdir.nii ./*.dcm' - >>> res = To3D.run() #doctest: +SKIP - - """ - _cmd = 'to3d' - input_spec = To3DInputSpec - output_spec = AFNICommandOutputSpec - - class VolregInputSpec(AFNICommandInputSpec): - - in_file = File(desc='input file to 3dvolreg', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_volreg", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - basefile = File(desc='base file for registration', - argstr='-base %s', - position=-6, - exists=True) - zpad = traits.Int(desc='Zeropad around the edges' + - ' by \'n\' voxels during rotations', - argstr='-zpad %d', - position=-5) - md1d_file = File(name_template='%s_md.1D', desc='max displacement output file', - argstr='-maxdisp1D %s', name_source="in_file", - keep_extension=True, position=-4) - oned_file = File(name_template='%s.1D', desc='1D movement parameters output file', - argstr='-1Dfile %s', - name_source="in_file", - keep_extension=True) - verbose = traits.Bool(desc='more detailed description of the process', - argstr='-verbose') - timeshift = traits.Bool(desc='time shift to mean slice time offset', - argstr='-tshift 0') - copyorigin = traits.Bool(desc='copy base file origin coords to output', - argstr='-twodup') - oned_matrix_save = File(name_template='%s.aff12.1D', - desc='Save the matrix transformation', - argstr='-1Dmatrix_save %s', - keep_extension=True, - name_source="in_file") + in_file = File( + desc='input file to 3dvolreg', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_volreg', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + basefile = File( + desc='base file for registration', + argstr='-base %s', + position=-6, + exists=True) + zpad = traits.Int( + desc='Zeropad around the edges by \'n\' voxels during rotations', + argstr='-zpad %d', + position=-5) + md1d_file = File( + name_template='%s_md.1D', + desc='max displacement output file', + argstr='-maxdisp1D %s', + name_source='in_file', + keep_extension=True, + position=-4) + oned_file = File( + name_template='%s.1D', + desc='1D movement parameters output file', + argstr='-1Dfile %s', + name_source='in_file', + keep_extension=True) + verbose = traits.Bool( + desc='more detailed description of the process', + argstr='-verbose') + timeshift = traits.Bool( + desc='time shift to mean slice time offset', + argstr='-tshift 0') + copyorigin = traits.Bool( + desc='copy base file origin coords to output', + argstr='-twodup') + oned_matrix_save = File( + name_template='%s.aff12.1D', + desc='Save the matrix transformation', + argstr='-1Dmatrix_save %s', + keep_extension=True, + name_source='in_file') class VolregOutputSpec(TraitedSpec): - out_file = File(desc='registered file', exists=True) - md1d_file = File(desc='max displacement info file', exists=True) - oned_file = File(desc='movement parameters info file', exists=True) - oned_matrix_save = File(desc='matrix transformation from base to input', exists=True) + out_file = File( + desc='registered file', + exists=True) + md1d_file = File( + desc='max displacement info file', + exists=True) + oned_file = File( + desc='movement parameters info file', + exists=True) + oned_matrix_save = File( + desc='matrix transformation from base to input', + exists=True) class Volreg(AFNICommand): @@ -2952,7 +2223,7 @@ class Volreg(AFNICommand): >>> volreg.inputs.in_file = 'functional.nii' >>> volreg.inputs.args = '-Fourier -twopass' >>> volreg.inputs.zpad = 4 - >>> volreg.inputs.outputtype = "NIFTI" + >>> volreg.inputs.outputtype = 'NIFTI' >>> volreg.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE '3dvolreg -Fourier -twopass -1Dfile functional.1D -1Dmatrix_save functional.aff12.1D -prefix functional_volreg.nii -zpad 4 -maxdisp1D functional_md.1D functional.nii' >>> res = volreg.run() # doctest: +SKIP @@ -2965,44 +2236,45 @@ class Volreg(AFNICommand): class WarpInputSpec(AFNICommandInputSpec): - - in_file = File(desc='input file to 3dWarp', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - - out_file = File(name_template="%s_warp", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - - tta2mni = traits.Bool(desc='transform dataset from Talairach to MNI152', - argstr='-tta2mni') - - mni2tta = traits.Bool(desc='transform dataset from MNI152 to Talaraich', - argstr='-mni2tta') - - matparent = File(desc="apply transformation from 3dWarpDrive", - argstr="-matparent %s", - exists=True) - - deoblique = traits.Bool(desc='transform dataset from oblique to cardinal', - argstr='-deoblique') - - interp = traits.Enum(('linear', 'cubic', 'NN', 'quintic'), - desc='spatial interpolation methods [default = linear]', - argstr='-%s') - - gridset = File(desc="copy grid of specified dataset", - argstr="-gridset %s", - exists=True) - - newgrid = traits.Float(desc="specify grid of this size (mm)", - argstr="-newgrid %f") - - zpad = traits.Int(desc="pad input dataset with N planes" + - " of zero on all sides.", - argstr="-zpad %d") + in_file = File( + desc='input file to 3dWarp', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_warp', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + tta2mni = traits.Bool( + desc='transform dataset from Talairach to MNI152', + argstr='-tta2mni') + mni2tta = traits.Bool( + desc='transform dataset from MNI152 to Talaraich', + argstr='-mni2tta') + matparent = File( + desc='apply transformation from 3dWarpDrive', + argstr='-matparent %s', + exists=True) + deoblique = traits.Bool( + desc='transform dataset from oblique to cardinal', + argstr='-deoblique') + interp = traits.Enum( + ('linear', 'cubic', 'NN', 'quintic'), + desc='spatial interpolation methods [default = linear]', + argstr='-%s') + gridset = File( + desc='copy grid of specified dataset', + argstr='-gridset %s', + exists=True) + newgrid = traits.Float( + desc='specify grid of this size (mm)', + argstr='-newgrid %f') + zpad = traits.Int( + desc='pad input dataset with N planes of zero on all sides.', + argstr='-zpad %d') class Warp(AFNICommand): @@ -3018,14 +2290,14 @@ class Warp(AFNICommand): >>> warp = afni.Warp() >>> warp.inputs.in_file = 'structural.nii' >>> warp.inputs.deoblique = True - >>> warp.inputs.out_file = "trans.nii.gz" + >>> warp.inputs.out_file = 'trans.nii.gz' >>> warp.cmdline # doctest: +IGNORE_UNICODE '3dWarp -deoblique -prefix trans.nii.gz structural.nii' >>> warp_2 = afni.Warp() >>> warp_2.inputs.in_file = 'structural.nii' >>> warp_2.inputs.newgrid = 1.0 - >>> warp_2.inputs.out_file = "trans.nii.gz" + >>> warp_2.inputs.out_file = 'trans.nii.gz' >>> warp_2.cmdline # doctest: +IGNORE_UNICODE '3dWarp -newgrid 1.000000 -prefix trans.nii.gz structural.nii' @@ -3033,39 +2305,3 @@ class Warp(AFNICommand): _cmd = '3dWarp' input_spec = WarpInputSpec output_spec = AFNICommandOutputSpec - - -class ZCutUpInputSpec(AFNICommandInputSpec): - in_file = File(desc='input file to 3dZcutup', - argstr='%s', - position=-1, - mandatory=True, - exists=True, - copyfile=False) - out_file = File(name_template="%s_zcupup", desc='output image file name', - argstr='-prefix %s', name_source="in_file") - keep = Str(desc='slice range to keep in output', - argstr='-keep %s') - - -class ZCutUp(AFNICommand): - """Cut z-slices from a volume using AFNI 3dZcutup command - - For complete details, see the `3dZcutup Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni as afni - >>> zcutup = afni.ZCutUp() - >>> zcutup.inputs.in_file = 'functional.nii' - >>> zcutup.inputs.out_file = 'functional_zcutup.nii' - >>> zcutup.inputs.keep= '0 10' - >>> res = zcutup.run() # doctest: +SKIP - - """ - - _cmd = '3dZcutup' - input_spec = ZCutUpInputSpec - output_spec = AFNICommandOutputSpec diff --git a/nipype/interfaces/afni/tests/test_auto_AFNItoNIFTI.py b/nipype/interfaces/afni/tests/test_auto_AFNItoNIFTI.py index 1e46cccd56..7bb382cb5e 100644 --- a/nipype/interfaces/afni/tests/test_auto_AFNItoNIFTI.py +++ b/nipype/interfaces/afni/tests/test_auto_AFNItoNIFTI.py @@ -1,11 +1,13 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import AFNItoNIFTI +from ..utils import AFNItoNIFTI def test_AFNItoNIFTI_inputs(): input_map = dict(args=dict(argstr='%s', ), + denote=dict(argstr='-denote', + ), environ=dict(nohash=True, usedefault=True, ), @@ -17,11 +19,20 @@ def test_AFNItoNIFTI_inputs(): mandatory=True, position=-1, ), + newid=dict(argstr='-newid', + xor=[u'oldid'], + ), + oldid=dict(argstr='-oldid', + xor=[u'newid'], + ), out_file=dict(argstr='-prefix %s', + hash_files=False, name_source='in_file', name_template='%s.nii', ), outputtype=dict(), + pure=dict(argstr='-pure', + ), terminal_output=dict(nohash=True, ), ) diff --git a/nipype/interfaces/afni/tests/test_auto_Autobox.py b/nipype/interfaces/afni/tests/test_auto_Autobox.py index 3a23e751a3..a994c9a293 100644 --- a/nipype/interfaces/afni/tests/test_auto_Autobox.py +++ b/nipype/interfaces/afni/tests/test_auto_Autobox.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import Autobox +from ..utils import Autobox def test_Autobox_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_BrickStat.py b/nipype/interfaces/afni/tests/test_auto_BrickStat.py index af318cb3ad..6c91fcf69f 100644 --- a/nipype/interfaces/afni/tests/test_auto_BrickStat.py +++ b/nipype/interfaces/afni/tests/test_auto_BrickStat.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import BrickStat +from ..utils import BrickStat def test_BrickStat_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_Calc.py b/nipype/interfaces/afni/tests/test_auto_Calc.py index 98d99d3a73..80f0442c1c 100644 --- a/nipype/interfaces/afni/tests/test_auto_Calc.py +++ b/nipype/interfaces/afni/tests/test_auto_Calc.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import Calc +from ..utils import Calc def test_Calc_inputs(): @@ -20,10 +20,10 @@ def test_Calc_inputs(): mandatory=True, position=0, ), - in_file_b=dict(argstr=' -b %s', + in_file_b=dict(argstr='-b %s', position=1, ), - in_file_c=dict(argstr=' -c %s', + in_file_c=dict(argstr='-c %s', position=2, ), other=dict(argstr='', diff --git a/nipype/interfaces/afni/tests/test_auto_Copy.py b/nipype/interfaces/afni/tests/test_auto_Copy.py index fffc9267d1..bc83efde94 100644 --- a/nipype/interfaces/afni/tests/test_auto_Copy.py +++ b/nipype/interfaces/afni/tests/test_auto_Copy.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import Copy +from ..utils import Copy def test_Copy_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_Eval.py b/nipype/interfaces/afni/tests/test_auto_Eval.py index 5f872e795a..7bbbaa78a5 100644 --- a/nipype/interfaces/afni/tests/test_auto_Eval.py +++ b/nipype/interfaces/afni/tests/test_auto_Eval.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import Eval +from ..utils import Eval def test_Eval_inputs(): @@ -20,10 +20,10 @@ def test_Eval_inputs(): mandatory=True, position=0, ), - in_file_b=dict(argstr=' -b %s', + in_file_b=dict(argstr='-b %s', position=1, ), - in_file_c=dict(argstr=' -c %s', + in_file_c=dict(argstr='-c %s', position=2, ), other=dict(argstr='', diff --git a/nipype/interfaces/afni/tests/test_auto_FWHMx.py b/nipype/interfaces/afni/tests/test_auto_FWHMx.py index 145476b22c..267f88db4e 100644 --- a/nipype/interfaces/afni/tests/test_auto_FWHMx.py +++ b/nipype/interfaces/afni/tests/test_auto_FWHMx.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import FWHMx +from ..utils import FWHMx def test_FWHMx_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_MaskTool.py b/nipype/interfaces/afni/tests/test_auto_MaskTool.py index 5e6e809767..14a35c9492 100644 --- a/nipype/interfaces/afni/tests/test_auto_MaskTool.py +++ b/nipype/interfaces/afni/tests/test_auto_MaskTool.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import MaskTool +from ..utils import MaskTool def test_MaskTool_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_Merge.py b/nipype/interfaces/afni/tests/test_auto_Merge.py index 9851b90b9c..100a397862 100644 --- a/nipype/interfaces/afni/tests/test_auto_Merge.py +++ b/nipype/interfaces/afni/tests/test_auto_Merge.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import Merge +from ..utils import Merge def test_Merge_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_Notes.py b/nipype/interfaces/afni/tests/test_auto_Notes.py index 3dc8d4fcc7..8f783fdae9 100644 --- a/nipype/interfaces/afni/tests/test_auto_Notes.py +++ b/nipype/interfaces/afni/tests/test_auto_Notes.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import Notes +from ..utils import Notes def test_Notes_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_Refit.py b/nipype/interfaces/afni/tests/test_auto_Refit.py index 124655276a..16a97fb139 100644 --- a/nipype/interfaces/afni/tests/test_auto_Refit.py +++ b/nipype/interfaces/afni/tests/test_auto_Refit.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import Refit +from ..utils import Refit def test_Refit_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_Resample.py b/nipype/interfaces/afni/tests/test_auto_Resample.py index 8aa40f92ee..b41f33a7ae 100644 --- a/nipype/interfaces/afni/tests/test_auto_Resample.py +++ b/nipype/interfaces/afni/tests/test_auto_Resample.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import Resample +from ..utils import Resample def test_Resample_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_TCat.py b/nipype/interfaces/afni/tests/test_auto_TCat.py index ce1e8fbaac..756cc83ed9 100644 --- a/nipype/interfaces/afni/tests/test_auto_TCat.py +++ b/nipype/interfaces/afni/tests/test_auto_TCat.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import TCat +from ..utils import TCat def test_TCat_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_TCorrelate.py b/nipype/interfaces/afni/tests/test_auto_TCorrelate.py index 4a5d68f9e9..729aa54a54 100644 --- a/nipype/interfaces/afni/tests/test_auto_TCorrelate.py +++ b/nipype/interfaces/afni/tests/test_auto_TCorrelate.py @@ -25,12 +25,12 @@ def test_TCorrelate_inputs(): ), terminal_output=dict(nohash=True, ), - xset=dict(argstr=' %s', + xset=dict(argstr='%s', copyfile=False, mandatory=True, position=-2, ), - yset=dict(argstr=' %s', + yset=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, diff --git a/nipype/interfaces/afni/tests/test_auto_TStat.py b/nipype/interfaces/afni/tests/test_auto_TStat.py index f7a60ca78c..ce179f5e29 100644 --- a/nipype/interfaces/afni/tests/test_auto_TStat.py +++ b/nipype/interfaces/afni/tests/test_auto_TStat.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import TStat +from ..utils import TStat def test_TStat_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_To3D.py b/nipype/interfaces/afni/tests/test_auto_To3D.py index a18cf7bf68..27eba788a9 100644 --- a/nipype/interfaces/afni/tests/test_auto_To3D.py +++ b/nipype/interfaces/afni/tests/test_auto_To3D.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import To3D +from ..utils import To3D def test_To3D_inputs(): diff --git a/nipype/interfaces/afni/tests/test_auto_ZCutUp.py b/nipype/interfaces/afni/tests/test_auto_ZCutUp.py index f3ede54b3e..95b3cc4dc6 100644 --- a/nipype/interfaces/afni/tests/test_auto_ZCutUp.py +++ b/nipype/interfaces/afni/tests/test_auto_ZCutUp.py @@ -1,6 +1,6 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ....testing import assert_equal -from ..preprocess import ZCutUp +from ..utils import ZCutUp def test_ZCutUp_inputs(): @@ -21,7 +21,7 @@ def test_ZCutUp_inputs(): ), out_file=dict(argstr='-prefix %s', name_source='in_file', - name_template='%s_zcupup', + name_template='%s_zcutup', ), outputtype=dict(), terminal_output=dict(nohash=True, diff --git a/nipype/interfaces/afni/utils.py b/nipype/interfaces/afni/utils.py new file mode 100644 index 0000000000..06ff530a04 --- /dev/null +++ b/nipype/interfaces/afni/utils.py @@ -0,0 +1,1244 @@ +# -*- coding: utf-8 -*- +# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- +# vi: set ft = python sts = 4 ts = 4 sw = 4 et: +"""AFNI utility interfaces + +Examples +-------- +See the docstrings of the individual classes for examples. + .. testsetup:: + # Change directory to provide relative paths for doctests + >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) + >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) + >>> os.chdir(datadir) +""" +from __future__ import print_function, division, unicode_literals, absolute_import +from builtins import open, str, bytes + +import os +import os.path as op +import re +import numpy as np + +from ...utils.filemanip import (load_json, save_json, split_filename) +from ..base import ( + CommandLineInputSpec, CommandLine, Directory, TraitedSpec, + traits, isdefined, File, InputMultiPath, Undefined, Str) + +from .base import ( + AFNICommandBase, AFNICommand, AFNICommandInputSpec, AFNICommandOutputSpec, + Info, no_afni) + + +class AFNItoNIFTIInputSpec(AFNICommandInputSpec): + in_file = File( + desc='input file to 3dAFNItoNIFTI', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s.nii', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file', + hash_files=False) + float_ = traits.Bool( + desc='Force the output dataset to be 32-bit floats. This option ' + 'should be used when the input AFNI dataset has different float ' + 'scale factors for different sub-bricks, an option that ' + 'NIfTI-1.1 does not support.', + argstr='-float') + pure = traits.Bool( + desc='Do NOT write an AFNI extension field into the output file. Only ' + 'use this option if needed. You can also use the \'nifti_tool\' ' + 'program to strip extensions from a file.', + argstr='-pure') + denote = traits.Bool( + desc='When writing the AFNI extension field, remove text notes that ' + 'might contain subject identifying information.', + argstr='-denote') + oldid = traits.Bool( + desc='Give the new dataset the input dataset''s AFNI ID code.', + argstr='-oldid', + xor=['newid']) + newid = traits.Bool( + desc='Give the new dataset a new AFNI ID code, to distinguish it from ' + 'the input dataset.', + argstr='-newid', + xor=['oldid']) + + +class AFNItoNIFTI(AFNICommand): + """Changes AFNI format files to NIFTI format using 3dAFNItoNIFTI + + see AFNI Documentation: + + this can also convert 2D or 1D data, which you can numpy.squeeze() to + remove extra dimensions + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> a2n = afni.AFNItoNIFTI() + >>> a2n.inputs.in_file = 'afni_output.3D' + >>> a2n.inputs.out_file = 'afni_output.nii' + >>> a2n.cmdline # doctest: +IGNORE_UNICODE + '3dAFNItoNIFTI -prefix afni_output.nii afni_output.3D' + + """ + + _cmd = '3dAFNItoNIFTI' + input_spec = AFNItoNIFTIInputSpec + output_spec = AFNICommandOutputSpec + + def _overload_extension(self, value): + path, base, ext = split_filename(value) + if ext.lower() not in ['.nii', '.nii.gz', '.1d', '.1D']: + ext += '.nii' + return os.path.join(path, base + ext) + + def _gen_filename(self, name): + return os.path.abspath(super(AFNItoNIFTI, self)._gen_filename(name)) + + +class AutoboxInputSpec(AFNICommandInputSpec): + in_file = File( + exists=True, + mandatory=True, + argstr='-input %s', + desc='input file', + copyfile=False) + padding = traits.Int( + argstr='-npad %d', + desc='Number of extra voxels to pad on each side of box') + out_file = File( + argstr='-prefix %s', + name_source='in_file') + no_clustering = traits.Bool( + argstr='-noclust', + desc='Don\'t do any clustering to find box. Any non-zero voxel will ' + 'be preserved in the cropped volume. The default method uses ' + 'some clustering to find the cropping box, and will clip off ' + 'small isolated blobs.') + + +class AutoboxOutputSpec(TraitedSpec): # out_file not mandatory + x_min = traits.Int() + x_max = traits.Int() + y_min = traits.Int() + y_max = traits.Int() + z_min = traits.Int() + z_max = traits.Int() + + out_file = File( + desc='output file') + + +class Autobox(AFNICommand): + """ Computes size of a box that fits around the volume. + Also can be used to crop the volume to that box. + + For complete details, see the `3dAutobox Documentation. + + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> abox = afni.Autobox() + >>> abox.inputs.in_file = 'structural.nii' + >>> abox.inputs.padding = 5 + >>> res = abox.run() # doctest: +SKIP + + """ + + _cmd = '3dAutobox' + input_spec = AutoboxInputSpec + output_spec = AutoboxOutputSpec + + def aggregate_outputs(self, runtime=None, needed_outputs=None): + outputs = self._outputs() + pattern = 'x=(?P-?\d+)\.\.(?P-?\d+) '\ + 'y=(?P-?\d+)\.\.(?P-?\d+) '\ + 'z=(?P-?\d+)\.\.(?P-?\d+)' + for line in runtime.stderr.split('\n'): + m = re.search(pattern, line) + if m: + d = m.groupdict() + for k in list(d.keys()): + d[k] = int(d[k]) + outputs.set(**d) + outputs.set(out_file=self._gen_filename('out_file')) + return outputs + + def _gen_filename(self, name): + if name == 'out_file' and (not isdefined(self.inputs.out_file)): + return Undefined + return super(Autobox, self)._gen_filename(name) + + +class BrickStatInputSpec(AFNICommandInputSpec): + in_file = File( + desc='input file to 3dmaskave', + argstr='%s', + position=-1, + mandatory=True, + exists=True) + mask = File( + desc='-mask dset = use dset as mask to include/exclude voxels', + argstr='-mask %s', + position=2, + exists=True) + min = traits.Bool( + desc='print the minimum value in dataset', + argstr='-min', + position=1) + + +class BrickStatOutputSpec(TraitedSpec): + min_val = traits.Float( + desc='output') + + +class BrickStat(AFNICommand): + """Compute maximum and/or minimum voxel values of an input dataset + + For complete details, see the `3dBrickStat Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> brickstat = afni.BrickStat() + >>> brickstat.inputs.in_file = 'functional.nii' + >>> brickstat.inputs.mask = 'skeleton_mask.nii.gz' + >>> brickstat.inputs.min = True + >>> res = brickstat.run() # doctest: +SKIP + + """ + _cmd = '3dBrickStat' + input_spec = BrickStatInputSpec + output_spec = BrickStatOutputSpec + + def aggregate_outputs(self, runtime=None, needed_outputs=None): + + outputs = self._outputs() + + outfile = os.path.join(os.getcwd(), 'stat_result.json') + + if runtime is None: + try: + min_val = load_json(outfile)['stat'] + except IOError: + return self.run().outputs + else: + min_val = [] + for line in runtime.stdout.split('\n'): + if line: + values = line.split() + if len(values) > 1: + min_val.append([float(val) for val in values]) + else: + min_val.extend([float(val) for val in values]) + + if len(min_val) == 1: + min_val = min_val[0] + save_json(outfile, dict(stat=min_val)) + outputs.min_val = min_val + + return outputs + + +class CalcInputSpec(AFNICommandInputSpec): + in_file_a = File( + desc='input file to 3dcalc', + argstr='-a %s', + position=0, + mandatory=True, + exists=True) + in_file_b = File( + desc='operand file to 3dcalc', + argstr='-b %s', + position=1, + exists=True) + in_file_c = File( + desc='operand file to 3dcalc', + argstr='-c %s', + position=2, + exists=True) + out_file = File( + name_template='%s_calc', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file_a') + expr = Str( + desc='expr', + argstr='-expr "%s"', + position=3, + mandatory=True) + start_idx = traits.Int( + desc='start index for in_file_a', + requires=['stop_idx']) + stop_idx = traits.Int( + desc='stop index for in_file_a', + requires=['start_idx']) + single_idx = traits.Int( + desc='volume index for in_file_a') + other = File( + desc='other options', + argstr='') + + +class Calc(AFNICommand): + """This program does voxel-by-voxel arithmetic on 3D datasets + + For complete details, see the `3dcalc Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> calc = afni.Calc() + >>> calc.inputs.in_file_a = 'functional.nii' + >>> calc.inputs.in_file_b = 'functional2.nii' + >>> calc.inputs.expr='a*b' + >>> calc.inputs.out_file = 'functional_calc.nii.gz' + >>> calc.inputs.outputtype = 'NIFTI' + >>> calc.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dcalc -a functional.nii -b functional2.nii -expr "a*b" -prefix functional_calc.nii.gz' + + """ + + _cmd = '3dcalc' + input_spec = CalcInputSpec + output_spec = AFNICommandOutputSpec + + def _format_arg(self, name, trait_spec, value): + if name == 'in_file_a': + arg = trait_spec.argstr % value + if isdefined(self.inputs.start_idx): + arg += '[%d..%d]' % (self.inputs.start_idx, + self.inputs.stop_idx) + if isdefined(self.inputs.single_idx): + arg += '[%d]' % (self.inputs.single_idx) + return arg + return super(Calc, self)._format_arg(name, trait_spec, value) + + def _parse_inputs(self, skip=None): + """Skip the arguments without argstr metadata + """ + return super(Calc, self)._parse_inputs( + skip=('start_idx', 'stop_idx', 'other')) + + +class CopyInputSpec(AFNICommandInputSpec): + in_file = File( + desc='input file to 3dcopy', + argstr='%s', + position=-2, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_copy', + desc='output image file name', + argstr='%s', + position=-1, + name_source='in_file') + + +class Copy(AFNICommand): + """Copies an image of one type to an image of the same + or different type using 3dcopy command + + For complete details, see the `3dcopy Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> copy3d = afni.Copy() + >>> copy3d.inputs.in_file = 'functional.nii' + >>> copy3d.cmdline # doctest: +IGNORE_UNICODE + '3dcopy functional.nii functional_copy' + + >>> from copy import deepcopy + >>> copy3d_2 = deepcopy(copy3d) + >>> copy3d_2.inputs.outputtype = 'NIFTI' + >>> copy3d_2.cmdline # doctest: +IGNORE_UNICODE + '3dcopy functional.nii functional_copy.nii' + + >>> copy3d_3 = deepcopy(copy3d) + >>> copy3d_3.inputs.outputtype = 'NIFTI_GZ' + >>> copy3d_3.cmdline # doctest: +IGNORE_UNICODE + '3dcopy functional.nii functional_copy.nii.gz' + + >>> copy3d_4 = deepcopy(copy3d) + >>> copy3d_4.inputs.out_file = 'new_func.nii' + >>> copy3d_4.cmdline # doctest: +IGNORE_UNICODE + '3dcopy functional.nii new_func.nii' + """ + + _cmd = '3dcopy' + input_spec = CopyInputSpec + output_spec = AFNICommandOutputSpec + + +class EvalInputSpec(AFNICommandInputSpec): + in_file_a = File( + desc='input file to 1deval', + argstr='-a %s', + position=0, + mandatory=True, + exists=True) + in_file_b = File( + desc='operand file to 1deval', + argstr='-b %s', + position=1, + exists=True) + in_file_c = File( + desc='operand file to 1deval', + argstr='-c %s', + position=2, + exists=True) + out_file = File( + name_template='%s_calc', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file_a') + out1D = traits.Bool( + desc='output in 1D', + argstr='-1D') + expr = Str( + desc='expr', + argstr='-expr "%s"', + position=3, + mandatory=True) + start_idx = traits.Int( + desc='start index for in_file_a', + requires=['stop_idx']) + stop_idx = traits.Int( + desc='stop index for in_file_a', + requires=['start_idx']) + single_idx = traits.Int( + desc='volume index for in_file_a') + other = File( + desc='other options', + argstr='') + + +class Eval(AFNICommand): + """Evaluates an expression that may include columns of data from one or more text files + + see AFNI Documentation: + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> eval = afni.Eval() + >>> eval.inputs.in_file_a = 'seed.1D' + >>> eval.inputs.in_file_b = 'resp.1D' + >>> eval.inputs.expr='a*b' + >>> eval.inputs.out1D = True + >>> eval.inputs.out_file = 'data_calc.1D' + >>> calc.cmdline #doctest: +SKIP +IGNORE_UNICODE + '3deval -a timeseries1.1D -b timeseries2.1D -expr "a*b" -1D -prefix data_calc.1D' + + """ + + _cmd = '1deval' + input_spec = EvalInputSpec + output_spec = AFNICommandOutputSpec + + def _format_arg(self, name, trait_spec, value): + if name == 'in_file_a': + arg = trait_spec.argstr % value + if isdefined(self.inputs.start_idx): + arg += '[%d..%d]' % (self.inputs.start_idx, + self.inputs.stop_idx) + if isdefined(self.inputs.single_idx): + arg += '[%d]' % (self.inputs.single_idx) + return arg + return super(Eval, self)._format_arg(name, trait_spec, value) + + def _parse_inputs(self, skip=None): + """Skip the arguments without argstr metadata + """ + return super(Eval, self)._parse_inputs( + skip=('start_idx', 'stop_idx', 'out1D', 'other')) + + +class FWHMxInputSpec(CommandLineInputSpec): + in_file = File( + desc='input dataset', + argstr='-input %s', + mandatory=True, + exists=True) + out_file = File( + argstr='> %s', + name_source='in_file', + name_template='%s_fwhmx.out', + position=-1, + keep_extension=False, + desc='output file') + out_subbricks = File( + argstr='-out %s', + name_source='in_file', + name_template='%s_subbricks.out', + keep_extension=False, + desc='output file listing the subbricks FWHM') + mask = File( + desc='use only voxels that are nonzero in mask', + argstr='-mask %s', + exists=True) + automask = traits.Bool( + False, + usedefault=True, + argstr='-automask', + desc='compute a mask from THIS dataset, a la 3dAutomask') + detrend = traits.Either( + traits.Bool(), traits.Int(), + default=False, + argstr='-detrend', + xor=['demed'], + usedefault=True, + desc='instead of demed (0th order detrending), detrend to the ' + 'specified order. If order is not given, the program picks ' + 'q=NT/30. -detrend disables -demed, and includes -unif.') + demed = traits.Bool( + False, + argstr='-demed', + xor=['detrend'], + desc='If the input dataset has more than one sub-brick (e.g., has a ' + 'time axis), then subtract the median of each voxel\'s time ' + 'series before processing FWHM. This will tend to remove ' + 'intrinsic spatial structure and leave behind the noise.') + unif = traits.Bool( + False, + argstr='-unif', + desc='If the input dataset has more than one sub-brick, then ' + 'normalize each voxel\'s time series to have the same MAD before ' + 'processing FWHM.') + out_detrend = File( + argstr='-detprefix %s', + name_source='in_file', + name_template='%s_detrend', + keep_extension=False, + desc='Save the detrended file into a dataset') + geom = traits.Bool( + argstr='-geom', + xor=['arith'], + desc='if in_file has more than one sub-brick, compute the final ' + 'estimate as the geometric mean of the individual sub-brick FWHM ' + 'estimates') + arith = traits.Bool( + argstr='-arith', + xor=['geom'], + desc='if in_file has more than one sub-brick, compute the final ' + 'estimate as the arithmetic mean of the individual sub-brick ' + 'FWHM estimates') + combine = traits.Bool( + argstr='-combine', + desc='combine the final measurements along each axis') + compat = traits.Bool( + argstr='-compat', + desc='be compatible with the older 3dFWHM') + acf = traits.Either( + traits.Bool(), File(), traits.Tuple(File(exists=True), traits.Float()), + default=False, + usedefault=True, + argstr='-acf', + desc='computes the spatial autocorrelation') + + +class FWHMxOutputSpec(TraitedSpec): + out_file = File( + exists=True, + desc='output file') + out_subbricks = File( + exists=True, + desc='output file (subbricks)') + out_detrend = File( + desc='output file, detrended') + fwhm = traits.Either( + traits.Tuple(traits.Float(), traits.Float(), traits.Float()), + traits.Tuple(traits.Float(), traits.Float(), traits.Float(), traits.Float()), + desc='FWHM along each axis') + acf_param = traits.Either( + traits.Tuple(traits.Float(), traits.Float(), traits.Float()), + traits.Tuple(traits.Float(), traits.Float(), traits.Float(), traits.Float()), + desc='fitted ACF model parameters') + out_acf = File( + exists=True, + desc='output acf file') + + +class FWHMx(AFNICommandBase): + """ + Unlike the older 3dFWHM, this program computes FWHMs for all sub-bricks + in the input dataset, each one separately. The output for each one is + written to the file specified by '-out'. The mean (arithmetic or geometric) + of all the FWHMs along each axis is written to stdout. (A non-positive + output value indicates something bad happened; e.g., FWHM in z is meaningless + for a 2D dataset; the estimation method computed incoherent intermediate results.) + + Examples + -------- + + >>> from nipype.interfaces import afni as afp + >>> fwhm = afp.FWHMx() + >>> fwhm.inputs.in_file = 'functional.nii' + >>> fwhm.cmdline # doctest: +IGNORE_UNICODE + '3dFWHMx -input functional.nii -out functional_subbricks.out > functional_fwhmx.out' + + + (Classic) METHOD: + + * Calculate ratio of variance of first differences to data variance. + * Should be the same as 3dFWHM for a 1-brick dataset. + (But the output format is simpler to use in a script.) + + + .. note:: IMPORTANT NOTE [AFNI > 16] + + A completely new method for estimating and using noise smoothness values is + now available in 3dFWHMx and 3dClustSim. This method is implemented in the + '-acf' options to both programs. 'ACF' stands for (spatial) AutoCorrelation + Function, and it is estimated by calculating moments of differences out to + a larger radius than before. + + Notably, real FMRI data does not actually have a Gaussian-shaped ACF, so the + estimated ACF is then fit (in 3dFWHMx) to a mixed model (Gaussian plus + mono-exponential) of the form + + .. math:: + + ACF(r) = a * exp(-r*r/(2*b*b)) + (1-a)*exp(-r/c) + + + where :math:`r` is the radius, and :math:`a, b, c` are the fitted parameters. + The apparent FWHM from this model is usually somewhat larger in real data + than the FWHM estimated from just the nearest-neighbor differences used + in the 'classic' analysis. + + The longer tails provided by the mono-exponential are also significant. + 3dClustSim has also been modified to use the ACF model given above to generate + noise random fields. + + + .. note:: TL;DR or summary + + The take-awaymessage is that the 'classic' 3dFWHMx and + 3dClustSim analysis, using a pure Gaussian ACF, is not very correct for + FMRI data -- I cannot speak for PET or MEG data. + + + .. warning:: + + Do NOT use 3dFWHMx on the statistical results (e.g., '-bucket') from + 3dDeconvolve or 3dREMLfit!!! The function of 3dFWHMx is to estimate + the smoothness of the time series NOISE, not of the statistics. This + proscription is especially true if you plan to use 3dClustSim next!! + + + .. note:: Recommendations + + * For FMRI statistical purposes, you DO NOT want the FWHM to reflect + the spatial structure of the underlying anatomy. Rather, you want + the FWHM to reflect the spatial structure of the noise. This means + that the input dataset should not have anatomical (spatial) structure. + * One good form of input is the output of '3dDeconvolve -errts', which is + the dataset of residuals left over after the GLM fitted signal model is + subtracted out from each voxel's time series. + * If you don't want to go to that much trouble, use '-detrend' to approximately + subtract out the anatomical spatial structure, OR use the output of 3dDetrend + for the same purpose. + * If you do not use '-detrend', the program attempts to find non-zero spatial + structure in the input, and will print a warning message if it is detected. + + + .. note:: Notes on -demend + + * I recommend this option, and it is not the default only for historical + compatibility reasons. It may become the default someday. + * It is already the default in program 3dBlurToFWHM. This is the same detrending + as done in 3dDespike; using 2*q+3 basis functions for q > 0. + * If you don't use '-detrend', the program now [Aug 2010] checks if a large number + of voxels are have significant nonzero means. If so, the program will print a + warning message suggesting the use of '-detrend', since inherent spatial + structure in the image will bias the estimation of the FWHM of the image time + series NOISE (which is usually the point of using 3dFWHMx). + + + """ + _cmd = '3dFWHMx' + input_spec = FWHMxInputSpec + output_spec = FWHMxOutputSpec + _acf = True + + def _parse_inputs(self, skip=None): + if not self.inputs.detrend: + if skip is None: + skip = [] + skip += ['out_detrend'] + return super(FWHMx, self)._parse_inputs(skip=skip) + + def _format_arg(self, name, trait_spec, value): + if name == 'detrend': + if isinstance(value, bool): + if value: + return trait_spec.argstr + else: + return None + elif isinstance(value, int): + return trait_spec.argstr + ' %d' % value + + if name == 'acf': + if isinstance(value, bool): + if value: + return trait_spec.argstr + else: + self._acf = False + return None + elif isinstance(value, tuple): + return trait_spec.argstr + ' %s %f' % value + elif isinstance(value, (str, bytes)): + return trait_spec.argstr + ' ' + value + return super(FWHMx, self)._format_arg(name, trait_spec, value) + + def _list_outputs(self): + outputs = super(FWHMx, self)._list_outputs() + + if self.inputs.detrend: + fname, ext = op.splitext(self.inputs.in_file) + if '.gz' in ext: + _, ext2 = op.splitext(fname) + ext = ext2 + ext + outputs['out_detrend'] += ext + else: + outputs['out_detrend'] = Undefined + + sout = np.loadtxt(outputs['out_file']) #pylint: disable=E1101 + if self._acf: + outputs['acf_param'] = tuple(sout[1]) + sout = tuple(sout[0]) + + outputs['out_acf'] = op.abspath('3dFWHMx.1D') + if isinstance(self.inputs.acf, (str, bytes)): + outputs['out_acf'] = op.abspath(self.inputs.acf) + + outputs['fwhm'] = tuple(sout) + return outputs + + +class MaskToolInputSpec(AFNICommandInputSpec): + in_file = File( + desc='input file or files to 3dmask_tool', + argstr='-input %s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_mask', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + count = traits.Bool( + desc='Instead of created a binary 0/1 mask dataset, create one with ' + 'counts of voxel overlap, i.e., each voxel will contain the ' + 'number of masks that it is set in.', + argstr='-count', + position=2) + datum = traits.Enum( + 'byte','short','float', + argstr='-datum %s', + desc='specify data type for output. Valid types are \'byte\', ' + '\'short\' and \'float\'.') + dilate_inputs = Str( + desc='Use this option to dilate and/or erode datasets as they are ' + 'read. ex. \'5 -5\' to dilate and erode 5 times', + argstr='-dilate_inputs %s') + dilate_results = Str( + desc='dilate and/or erode combined mask at the given levels.', + argstr='-dilate_results %s') + frac = traits.Float( + desc='When combining masks (across datasets and sub-bricks), use ' + 'this option to restrict the result to a certain fraction of the ' + 'set of volumes', + argstr='-frac %s') + inter = traits.Bool( + desc='intersection, this means -frac 1.0', + argstr='-inter') + union = traits.Bool( + desc='union, this means -frac 0', + argstr='-union') + fill_holes = traits.Bool( + desc='This option can be used to fill holes in the resulting mask, ' + 'i.e. after all other processing has been done.', + argstr='-fill_holes') + fill_dirs = Str( + desc='fill holes only in the given directions. This option is for use ' + 'with -fill holes. should be a single string that specifies ' + '1-3 of the axes using {x,y,z} labels (i.e. dataset axis order), ' + 'or using the labels in {R,L,A,P,I,S}.', + argstr='-fill_dirs %s', + requires=['fill_holes']) + + +class MaskToolOutputSpec(TraitedSpec): + out_file = File(desc='mask file', + exists=True) + + +class MaskTool(AFNICommand): + """3dmask_tool - for combining/dilating/eroding/filling masks + + For complete details, see the `3dmask_tool Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> automask = afni.Automask() + >>> automask.inputs.in_file = 'functional.nii' + >>> automask.inputs.dilate = 1 + >>> automask.inputs.outputtype = 'NIFTI' + >>> automask.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + '3dAutomask -apply_prefix functional_masked.nii -dilate 1 -prefix functional_mask.nii functional.nii' + >>> res = automask.run() # doctest: +SKIP + + """ + + _cmd = '3dmask_tool' + input_spec = MaskToolInputSpec + output_spec = MaskToolOutputSpec + + +class MergeInputSpec(AFNICommandInputSpec): + in_files = InputMultiPath( + File( + desc='input file to 3dmerge', + exists=True), + argstr='%s', + position=-1, + mandatory=True, + copyfile=False) + out_file = File( + name_template='%s_merge', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + doall = traits.Bool( + desc='apply options to all sub-bricks in dataset', + argstr='-doall') + blurfwhm = traits.Int( + desc='FWHM blur value (mm)', + argstr='-1blur_fwhm %d', + units='mm') + + +class Merge(AFNICommand): + """Merge or edit volumes using AFNI 3dmerge command + + For complete details, see the `3dmerge Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> merge = afni.Merge() + >>> merge.inputs.in_files = ['functional.nii', 'functional2.nii'] + >>> merge.inputs.blurfwhm = 4 + >>> merge.inputs.doall = True + >>> merge.inputs.out_file = 'e7.nii' + >>> res = merge.run() # doctest: +SKIP + + """ + + _cmd = '3dmerge' + input_spec = MergeInputSpec + output_spec = AFNICommandOutputSpec + + +class NotesInputSpec(AFNICommandInputSpec): + in_file = File( + desc='input file to 3dNotes', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + add = Str( + desc='note to add', + argstr='-a "%s"') + add_history = Str( + desc='note to add to history', + argstr='-h "%s"', + xor=['rep_history']) + rep_history = Str( + desc='note with which to replace history', + argstr='-HH "%s"', + xor=['add_history']) + delete = traits.Int( + desc='delete note number num', + argstr='-d %d') + ses = traits.Bool( + desc='print to stdout the expanded notes', + argstr='-ses') + out_file = File( + desc='output image file name', + argstr='%s') + + +class Notes(CommandLine): + """ + A program to add, delete, and show notes for AFNI datasets. + + For complete details, see the `3dNotes Documentation. + + + Examples + ======== + + >>> from nipype.interfaces import afni + >>> notes = afni.Notes() + >>> notes.inputs.in_file = 'functional.HEAD' + >>> notes.inputs.add = 'This note is added.' + >>> notes.inputs.add_history = 'This note is added to history.' + >>> notes.cmdline #doctest: +IGNORE_UNICODE + '3dNotes -a "This note is added." -h "This note is added to history." functional.HEAD' + >>> res = notes.run() # doctest: +SKIP + """ + + _cmd = '3dNotes' + input_spec = NotesInputSpec + output_spec = AFNICommandOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs['out_file'] = os.path.abspath(self.inputs.in_file) + return outputs + + +class RefitInputSpec(CommandLineInputSpec): + in_file = File( + desc='input file to 3drefit', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=True) + deoblique = traits.Bool( + desc='replace current transformation matrix with cardinal matrix', + argstr='-deoblique') + xorigin = Str( + desc='x distance for edge voxel offset', + argstr='-xorigin %s') + yorigin = Str( + desc='y distance for edge voxel offset', + argstr='-yorigin %s') + zorigin = Str( + desc='z distance for edge voxel offset', + argstr='-zorigin %s') + xdel = traits.Float( + desc='new x voxel dimension in mm', + argstr='-xdel %f') + ydel = traits.Float( + desc='new y voxel dimension in mm', + argstr='-ydel %f') + zdel = traits.Float( + desc='new z voxel dimension in mm', + argstr='-zdel %f') + space = traits.Enum( + 'TLRC', 'MNI', 'ORIG', + argstr='-space %s', + desc='Associates the dataset with a specific template type, e.g. ' + 'TLRC, MNI, ORIG') + + +class Refit(AFNICommandBase): + """Changes some of the information inside a 3D dataset's header + + For complete details, see the `3drefit Documentation. + + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> refit = afni.Refit() + >>> refit.inputs.in_file = 'structural.nii' + >>> refit.inputs.deoblique = True + >>> refit.cmdline # doctest: +IGNORE_UNICODE + '3drefit -deoblique structural.nii' + >>> res = refit.run() # doctest: +SKIP + + """ + _cmd = '3drefit' + input_spec = RefitInputSpec + output_spec = AFNICommandOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs['out_file'] = os.path.abspath(self.inputs.in_file) + return outputs + + +class ResampleInputSpec(AFNICommandInputSpec): + + in_file = File( + desc='input file to 3dresample', + argstr='-inset %s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_resample', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + orientation = Str( + desc='new orientation code', + argstr='-orient %s') + resample_mode = traits.Enum( + 'NN', 'Li', 'Cu', 'Bk', + argstr='-rmode %s', + desc='resampling method from set {"NN", "Li", "Cu", "Bk"}. These are ' + 'for "Nearest Neighbor", "Linear", "Cubic" and "Blocky"' + 'interpolation, respectively. Default is NN.') + voxel_size = traits.Tuple( + *[traits.Float()] * 3, + argstr='-dxyz %f %f %f', + desc='resample to new dx, dy and dz') + master = traits.File( + argstr='-master %s', + desc='align dataset grid to a reference file') + + +class Resample(AFNICommand): + """Resample or reorient an image using AFNI 3dresample command + + For complete details, see the `3dresample Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> resample = afni.Resample() + >>> resample.inputs.in_file = 'functional.nii' + >>> resample.inputs.orientation= 'RPI' + >>> resample.inputs.outputtype = 'NIFTI' + >>> resample.cmdline # doctest: +IGNORE_UNICODE + '3dresample -orient RPI -prefix functional_resample.nii -inset functional.nii' + >>> res = resample.run() # doctest: +SKIP + + """ + + _cmd = '3dresample' + input_spec = ResampleInputSpec + output_spec = AFNICommandOutputSpec + + +class TCatInputSpec(AFNICommandInputSpec): + in_files = InputMultiPath( + File( + exists=True), + desc='input file to 3dTcat', + argstr=' %s', + position=-1, + mandatory=True, + copyfile=False) + out_file = File( + name_template='%s_tcat', + desc='output image file name', + argstr='-prefix %s', + name_source='in_files') + rlt = Str( + desc='options', + argstr='-rlt%s', + position=1) + + +class TCat(AFNICommand): + """Concatenate sub-bricks from input datasets into + one big 3D+time dataset + + For complete details, see the `3dTcat Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> tcat = afni.TCat() + >>> tcat.inputs.in_files = ['functional.nii', 'functional2.nii'] + >>> tcat.inputs.out_file= 'functional_tcat.nii' + >>> tcat.inputs.rlt = '+' + >>> res = tcat.run() # doctest: +SKIP + + """ + + _cmd = '3dTcat' + input_spec = TCatInputSpec + output_spec = AFNICommandOutputSpec + + +class TStatInputSpec(AFNICommandInputSpec): + in_file = File( + desc='input file to 3dTstat', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_tstat', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + mask = File( + desc='mask file', + argstr='-mask %s', + exists=True) + options = Str( + desc='selected statistical output', + argstr='%s') + + +class TStat(AFNICommand): + """Compute voxel-wise statistics using AFNI 3dTstat command + + For complete details, see the `3dTstat Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> tstat = afni.TStat() + >>> tstat.inputs.in_file = 'functional.nii' + >>> tstat.inputs.args= '-mean' + >>> tstat.inputs.out_file = 'stats' + >>> tstat.cmdline # doctest: +IGNORE_UNICODE + '3dTstat -mean -prefix stats functional.nii' + >>> res = tstat.run() # doctest: +SKIP + + """ + + _cmd = '3dTstat' + input_spec = TStatInputSpec + output_spec = AFNICommandOutputSpec + + +class To3DInputSpec(AFNICommandInputSpec): + out_file = File( + name_template='%s', + desc='output image file name', + argstr='-prefix %s', + name_source=['in_folder']) + in_folder = Directory( + desc='folder with DICOM images to convert', + argstr='%s/*.dcm', + position=-1, + mandatory=True, + exists=True) + filetype = traits.Enum( + 'spgr', 'fse', 'epan', 'anat', 'ct', 'spct', + 'pet', 'mra', 'bmap', 'diff', + 'omri', 'abuc', 'fim', 'fith', 'fico', 'fitt', + 'fift', 'fizt', 'fict', 'fibt', + 'fibn', 'figt', 'fipt', + 'fbuc', + argstr='-%s', + desc='type of datafile being converted') + skipoutliers = traits.Bool( + desc='skip the outliers check', + argstr='-skip_outliers') + assumemosaic = traits.Bool( + desc='assume that Siemens image is mosaic', + argstr='-assume_dicom_mosaic') + datatype = traits.Enum( + 'short', 'float', 'byte', 'complex', + desc='set output file datatype', + argstr='-datum %s') + funcparams = Str( + desc='parameters for functional data', + argstr='-time:zt %s alt+z2') + + +class To3D(AFNICommand): + """Create a 3D dataset from 2D image files using AFNI to3d command + + For complete details, see the `to3d Documentation + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni + >>> To3D = afni.To3D() + >>> To3D.inputs.datatype = 'float' + >>> To3D.inputs.in_folder = '.' + >>> To3D.inputs.out_file = 'dicomdir.nii' + >>> To3D.inputs.filetype = 'anat' + >>> To3D.cmdline #doctest: +ELLIPSIS +IGNORE_UNICODE + 'to3d -datum float -anat -prefix dicomdir.nii ./*.dcm' + >>> res = To3D.run() #doctest: +SKIP + + """ + _cmd = 'to3d' + input_spec = To3DInputSpec + output_spec = AFNICommandOutputSpec + + +class ZCutUpInputSpec(AFNICommandInputSpec): + in_file = File( + desc='input file to 3dZcutup', + argstr='%s', + position=-1, + mandatory=True, + exists=True, + copyfile=False) + out_file = File( + name_template='%s_zcutup', + desc='output image file name', + argstr='-prefix %s', + name_source='in_file') + keep = Str( + desc='slice range to keep in output', + argstr='-keep %s') + + +class ZCutUp(AFNICommand): + """Cut z-slices from a volume using AFNI 3dZcutup command + + For complete details, see the `3dZcutup Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> zcutup = afni.ZCutUp() + >>> zcutup.inputs.in_file = 'functional.nii' + >>> zcutup.inputs.out_file = 'functional_zcutup.nii' + >>> zcutup.inputs.keep= '0 10' + >>> res = zcutup.run() # doctest: +SKIP + + """ + + _cmd = '3dZcutup' + input_spec = ZCutUpInputSpec + output_spec = AFNICommandOutputSpec diff --git a/von-ray_errmap.nii.gz b/von-ray_errmap.nii.gz new file mode 100644 index 0000000000000000000000000000000000000000..3ddefec4bc6c43bb3812adbfbe7dcd8a2da9dcd6 GIT binary patch literal 107 zcmV-x0F?h9iwFoCX8BhF|8{R~EplObUuAM~ZDDXOZfR)%i(zD7Ff?Nz2$&g|z>tvv z0#P*xFercp8tfSu@Zk;45P4MH1IJ^+V>QSh=zv%;28KLsL$K!0EL*Xd!@vL%-*&j& N0RaEE!jOOg004L)DwY5M literal 0 HcmV?d00001 diff --git a/von_errmap.nii.gz b/von_errmap.nii.gz new file mode 100644 index 0000000000000000000000000000000000000000..0912fd5dd8f8781152ebe5d13f0d27b99e6938ac GIT binary patch literal 96 zcmV-m0H6OKiwFoCX8BhF|8{R~UuAM~ZDDXOZfR)%i(zD7Ff?Nz2$&g|z>tvv0#P*x zFercp8tfSu@Zk;45P4MH1IJ^+V>QSh=zv%;28KLsLzrd<7z34tgcAUGrDr&R0RRA$ CH6iW* literal 0 HcmV?d00001 From 677807c66c788345e30fe07c0051ddd798bfb6b2 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Sat, 8 Oct 2016 18:19:43 -0400 Subject: [PATCH 3/7] Run check. Edit possum to pass test. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FSLOUTTYPE defaults to “nit”, not “nii.gz”. --- nipype/algorithms/tests/test_auto_CompCor.py | 38 --------------- nipype/algorithms/tests/test_auto_ErrorMap.py | 35 -------------- nipype/algorithms/tests/test_auto_Overlap.py | 47 ------------------- nipype/interfaces/fsl/possum.py | 2 +- .../tests/test_auto_SignalExtraction.py} | 28 +++++------ nipype/testing/data/ev_test_condition_0_1.txt | 2 + 6 files changed, 17 insertions(+), 135 deletions(-) delete mode 100644 nipype/algorithms/tests/test_auto_CompCor.py delete mode 100644 nipype/algorithms/tests/test_auto_ErrorMap.py delete mode 100644 nipype/algorithms/tests/test_auto_Overlap.py rename nipype/{algorithms/tests/test_auto_TSNR.py => interfaces/tests/test_auto_SignalExtraction.py} (57%) create mode 100644 nipype/testing/data/ev_test_condition_0_1.txt diff --git a/nipype/algorithms/tests/test_auto_CompCor.py b/nipype/algorithms/tests/test_auto_CompCor.py deleted file mode 100644 index 61bc2195a2..0000000000 --- a/nipype/algorithms/tests/test_auto_CompCor.py +++ /dev/null @@ -1,38 +0,0 @@ -# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT -from ...testing import assert_equal -from ..confounds import CompCor - - -def test_CompCor_inputs(): - input_map = dict(components_file=dict(mandatory=False, - usedefault=True, - ), - ignore_exception=dict(nohash=True, - usedefault=True, - ), - mask_file=dict(mandatory=False, - ), - num_components=dict(usedefault=True, - ), - realigned_file=dict(mandatory=True, - ), - regress_poly_degree=dict(usedefault=True, - ), - use_regress_poly=dict(usedefault=True, - ), - ) - inputs = CompCor.input_spec() - - for key, metadata in list(input_map.items()): - for metakey, value in list(metadata.items()): - yield assert_equal, getattr(inputs.traits()[key], metakey), value - - -def test_CompCor_outputs(): - output_map = dict(components_file=dict(), - ) - outputs = CompCor.output_spec() - - for key, metadata in list(output_map.items()): - for metakey, value in list(metadata.items()): - yield assert_equal, getattr(outputs.traits()[key], metakey), value diff --git a/nipype/algorithms/tests/test_auto_ErrorMap.py b/nipype/algorithms/tests/test_auto_ErrorMap.py deleted file mode 100644 index 69484529dd..0000000000 --- a/nipype/algorithms/tests/test_auto_ErrorMap.py +++ /dev/null @@ -1,35 +0,0 @@ -# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT -from ...testing import assert_equal -from ..metrics import ErrorMap - - -def test_ErrorMap_inputs(): - input_map = dict(ignore_exception=dict(nohash=True, - usedefault=True, - ), - in_ref=dict(mandatory=True, - ), - in_tst=dict(mandatory=True, - ), - mask=dict(), - metric=dict(mandatory=True, - usedefault=True, - ), - out_map=dict(), - ) - inputs = ErrorMap.input_spec() - - for key, metadata in list(input_map.items()): - for metakey, value in list(metadata.items()): - yield assert_equal, getattr(inputs.traits()[key], metakey), value - - -def test_ErrorMap_outputs(): - output_map = dict(distance=dict(), - out_map=dict(), - ) - outputs = ErrorMap.output_spec() - - for key, metadata in list(output_map.items()): - for metakey, value in list(metadata.items()): - yield assert_equal, getattr(outputs.traits()[key], metakey), value diff --git a/nipype/algorithms/tests/test_auto_Overlap.py b/nipype/algorithms/tests/test_auto_Overlap.py deleted file mode 100644 index a5a3874bd1..0000000000 --- a/nipype/algorithms/tests/test_auto_Overlap.py +++ /dev/null @@ -1,47 +0,0 @@ -# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT -from ...testing import assert_equal -from ..misc import Overlap - - -def test_Overlap_inputs(): - input_map = dict(bg_overlap=dict(mandatory=True, - usedefault=True, - ), - ignore_exception=dict(nohash=True, - usedefault=True, - ), - mask_volume=dict(), - out_file=dict(usedefault=True, - ), - vol_units=dict(mandatory=True, - usedefault=True, - ), - volume1=dict(mandatory=True, - ), - volume2=dict(mandatory=True, - ), - weighting=dict(usedefault=True, - ), - ) - inputs = Overlap.input_spec() - - for key, metadata in list(input_map.items()): - for metakey, value in list(metadata.items()): - yield assert_equal, getattr(inputs.traits()[key], metakey), value - - -def test_Overlap_outputs(): - output_map = dict(dice=dict(), - diff_file=dict(), - jaccard=dict(), - labels=dict(), - roi_di=dict(), - roi_ji=dict(), - roi_voldiff=dict(), - volume_difference=dict(), - ) - outputs = Overlap.output_spec() - - for key, metadata in list(output_map.items()): - for metakey, value in list(metadata.items()): - yield assert_equal, getattr(outputs.traits()[key], metakey), value diff --git a/nipype/interfaces/fsl/possum.py b/nipype/interfaces/fsl/possum.py index 14b0f24b96..6c6bfad4c6 100644 --- a/nipype/interfaces/fsl/possum.py +++ b/nipype/interfaces/fsl/possum.py @@ -80,7 +80,7 @@ class B0Calc(FSLCommand): >>> b0calc.inputs.in_file = 'tissue+air_map.nii' >>> b0calc.inputs.z_b0 = 3.0 >>> b0calc.cmdline # doctest: +IGNORE_UNICODE - 'b0calc -i tissue+air_map.nii -o tissue+air_map_b0field.nii.gz --b0=3.00' + 'b0calc -i tissue+air_map.nii -o tissue+air_map_b0field.nii --b0=3.00' """ diff --git a/nipype/algorithms/tests/test_auto_TSNR.py b/nipype/interfaces/tests/test_auto_SignalExtraction.py similarity index 57% rename from nipype/algorithms/tests/test_auto_TSNR.py rename to nipype/interfaces/tests/test_auto_SignalExtraction.py index 92d39721ae..d35260c969 100644 --- a/nipype/algorithms/tests/test_auto_TSNR.py +++ b/nipype/interfaces/tests/test_auto_SignalExtraction.py @@ -1,10 +1,12 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from ...testing import assert_equal -from ..confounds import TSNR +from ..nilearn import SignalExtraction -def test_TSNR_inputs(): - input_map = dict(detrended_file=dict(hash_files=False, +def test_SignalExtraction_inputs(): + input_map = dict(class_labels=dict(mandatory=True, + ), + detrend=dict(mandatory=False, usedefault=True, ), ignore_exception=dict(nohash=True, @@ -12,31 +14,29 @@ def test_TSNR_inputs(): ), in_file=dict(mandatory=True, ), - mean_file=dict(hash_files=False, + incl_shared_variance=dict(mandatory=False, usedefault=True, ), - regress_poly=dict(), - stddev_file=dict(hash_files=False, + include_global=dict(mandatory=False, usedefault=True, ), - tsnr_file=dict(hash_files=False, + label_files=dict(mandatory=True, + ), + out_file=dict(mandatory=False, usedefault=True, ), ) - inputs = TSNR.input_spec() + inputs = SignalExtraction.input_spec() for key, metadata in list(input_map.items()): for metakey, value in list(metadata.items()): yield assert_equal, getattr(inputs.traits()[key], metakey), value -def test_TSNR_outputs(): - output_map = dict(detrended_file=dict(), - mean_file=dict(), - stddev_file=dict(), - tsnr_file=dict(), +def test_SignalExtraction_outputs(): + output_map = dict(out_file=dict(), ) - outputs = TSNR.output_spec() + outputs = SignalExtraction.output_spec() for key, metadata in list(output_map.items()): for metakey, value in list(metadata.items()): diff --git a/nipype/testing/data/ev_test_condition_0_1.txt b/nipype/testing/data/ev_test_condition_0_1.txt new file mode 100644 index 0000000000..a1399761f5 --- /dev/null +++ b/nipype/testing/data/ev_test_condition_0_1.txt @@ -0,0 +1,2 @@ +0.000000 10.000000 1.000000 +10.000000 10.000000 1.000000 From 42c3c1fe9c260fdeb73752ec00d9c6010cbb034c Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Sat, 8 Oct 2016 19:29:29 -0400 Subject: [PATCH 4/7] Add cmdline test. --- nipype/interfaces/afni/preprocess.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index 26690df338..59f80dd6cb 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -1655,6 +1655,8 @@ class Retroicor(AFNICommand): >>> ret.inputs.card = 'mask.1D' >>> ret.inputs.resp = 'resp.1D' >>> ret.inputs.outputtype = 'NIFTI' + >>> ret.cmdline # doctest: +IGNORE_UNICODE + '3dretroicor -prefix functional_retroicor.nii -resp resp.1D -card mask.1D functional.nii' >>> res = ret.run() # doctest: +SKIP """ From b64a63ad19d2ed4922207b71c31870dac3784870 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Sat, 8 Oct 2016 21:38:00 -0400 Subject: [PATCH 5/7] Fix possum test. FSLOUTTYPE must only default to .nii for me. --- nipype/interfaces/fsl/possum.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/fsl/possum.py b/nipype/interfaces/fsl/possum.py index 6c6bfad4c6..14b0f24b96 100644 --- a/nipype/interfaces/fsl/possum.py +++ b/nipype/interfaces/fsl/possum.py @@ -80,7 +80,7 @@ class B0Calc(FSLCommand): >>> b0calc.inputs.in_file = 'tissue+air_map.nii' >>> b0calc.inputs.z_b0 = 3.0 >>> b0calc.cmdline # doctest: +IGNORE_UNICODE - 'b0calc -i tissue+air_map.nii -o tissue+air_map_b0field.nii --b0=3.00' + 'b0calc -i tissue+air_map.nii -o tissue+air_map_b0field.nii.gz --b0=3.00' """ From 3ae518485268fc26defc930f7859bf4a166e9126 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Sat, 8 Oct 2016 23:04:00 -0400 Subject: [PATCH 6/7] Remove extra files. --- .cache/v/cache/lastfailed | 4 ---- nipype/testing/data/ev_test_condition_0_1.txt | 2 -- 2 files changed, 6 deletions(-) delete mode 100644 .cache/v/cache/lastfailed delete mode 100644 nipype/testing/data/ev_test_condition_0_1.txt diff --git a/.cache/v/cache/lastfailed b/.cache/v/cache/lastfailed deleted file mode 100644 index f27711958e..0000000000 --- a/.cache/v/cache/lastfailed +++ /dev/null @@ -1,4 +0,0 @@ -{ - "nipype/algorithms/tests/test_mesh_ops.py::test_ident_distances": true, - "nipype/algorithms/tests/test_mesh_ops.py::test_trans_distances": true -} \ No newline at end of file diff --git a/nipype/testing/data/ev_test_condition_0_1.txt b/nipype/testing/data/ev_test_condition_0_1.txt deleted file mode 100644 index a1399761f5..0000000000 --- a/nipype/testing/data/ev_test_condition_0_1.txt +++ /dev/null @@ -1,2 +0,0 @@ -0.000000 10.000000 1.000000 -10.000000 10.000000 1.000000 From 74f4b7460372e5247e92ba5cb1c2990c9a4b0ea8 Mon Sep 17 00:00:00 2001 From: Taylor Salo Date: Sat, 8 Oct 2016 23:06:09 -0400 Subject: [PATCH 7/7] Remove other extra files. --- von-ray_errmap.nii.gz | Bin 107 -> 0 bytes von_errmap.nii.gz | Bin 96 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 von-ray_errmap.nii.gz delete mode 100644 von_errmap.nii.gz diff --git a/von-ray_errmap.nii.gz b/von-ray_errmap.nii.gz deleted file mode 100644 index 3ddefec4bc6c43bb3812adbfbe7dcd8a2da9dcd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107 zcmV-x0F?h9iwFoCX8BhF|8{R~EplObUuAM~ZDDXOZfR)%i(zD7Ff?Nz2$&g|z>tvv z0#P*xFercp8tfSu@Zk;45P4MH1IJ^+V>QSh=zv%;28KLsL$K!0EL*Xd!@vL%-*&j& N0RaEE!jOOg004L)DwY5M diff --git a/von_errmap.nii.gz b/von_errmap.nii.gz deleted file mode 100644 index 0912fd5dd8f8781152ebe5d13f0d27b99e6938ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 zcmV-m0H6OKiwFoCX8BhF|8{R~UuAM~ZDDXOZfR)%i(zD7Ff?Nz2$&g|z>tvv0#P*x zFercp8tfSu@Zk;45P4MH1IJ^+V>QSh=zv%;28KLsLzrd<7z34tgcAUGrDr&R0RRA$ CH6iW*