diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index 4e56f7578b..e5528ec102 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -2953,107 +2953,6 @@ def _list_outputs(self): return outputs -class QwarpPlusMinusInputSpec(CommandLineInputSpec): - source_file = File( - desc= - 'Source image (opposite phase encoding direction than base image).', - argstr='-source %s', - mandatory=True, - exists=True, - copyfile=False) - base_file = File( - desc= - 'Base image (opposite phase encoding direction than source image).', - argstr='-base %s', - mandatory=True, - exists=True, - copyfile=False) - pblur = traits.List( - traits.Float(), - desc='The fraction of the patch size that' - 'is used for the progressive blur by providing a ' - 'value between 0 and 0.25. If you provide TWO ' - 'values, the first fraction is used for ' - 'progressively blurring the base image and the ' - 'second for the source image.', - argstr='-pblur %s', - minlen=1, - maxlen=2) - blur = traits.List( - traits.Float(), - desc="Gaussian blur the input images by (FWHM) voxels " - "before doing the alignment (the output dataset " - "will not be blurred). The default is 2.345 (for " - "no good reason). Optionally, you can provide 2 " - "values, and then the first one is applied to the " - "base volume, the second to the source volume. A " - "negative blur radius means to use 3D median " - "filtering, rather than Gaussian blurring. This " - "type of filtering will better preserve edges, " - "which can be important in alignment.", - argstr='-blur %s', - minlen=1, - maxlen=2) - noweight = traits.Bool( - desc='If you want a binary weight (the old default), use this option.' - 'That is, each voxel in the base volume automask will be' - 'weighted the same in the computation of the cost functional.', - argstr='-noweight') - minpatch = traits.Int( - desc="Set the minimum patch size for warp searching to 'mm' voxels.", - argstr='-minpatch %d') - nopadWARP = traits.Bool( - desc='If for some reason you require the warp volume to' - 'match the base volume, then use this option to have the output' - 'WARP dataset(s) truncated.', - argstr='-nopadWARP') - - -class QwarpPlusMinusOutputSpec(TraitedSpec): - warped_source = File(desc='Undistorted source file.', exists=True) - warped_base = File(desc='Undistorted base file.', exists=True) - source_warp = File( - desc="Field suceptibility correction warp (in 'mm') for source image.", - exists=True) - base_warp = File( - desc="Field suceptibility correction warp (in 'mm') for base image.", - exists=True) - - -class QwarpPlusMinus(CommandLine): - """A version of 3dQwarp for performing field susceptibility correction - using two images with opposing phase encoding directions. - - For complete details, see the `3dQwarp Documentation. - `_ - - Examples - ======== - - >>> from nipype.interfaces import afni - >>> qwarp = afni.QwarpPlusMinus() - >>> qwarp.inputs.source_file = 'sub-01_dir-LR_epi.nii.gz' - >>> qwarp.inputs.nopadWARP = True - >>> qwarp.inputs.base_file = 'sub-01_dir-RL_epi.nii.gz' - >>> qwarp.cmdline - '3dQwarp -prefix Qwarp.nii.gz -plusminus -base sub-01_dir-RL_epi.nii.gz -nopadWARP -source sub-01_dir-LR_epi.nii.gz' - >>> res = warp.run() # doctest: +SKIP - - """ - _cmd = '3dQwarp -prefix Qwarp.nii.gz -plusminus' - input_spec = QwarpPlusMinusInputSpec - output_spec = QwarpPlusMinusOutputSpec - - def _list_outputs(self): - outputs = self.output_spec().get() - outputs['warped_source'] = os.path.abspath("Qwarp_PLUS.nii.gz") - outputs['warped_base'] = os.path.abspath("Qwarp_MINUS.nii.gz") - outputs['source_warp'] = os.path.abspath("Qwarp_PLUS_WARP.nii.gz") - outputs['base_warp'] = os.path.abspath("Qwarp_MINUS_WARP.nii.gz") - - return outputs - - class QwarpInputSpec(AFNICommandInputSpec): in_file = File( desc= @@ -3722,3 +3621,54 @@ def _list_outputs(self): def _gen_filename(self, name): if name == 'out_file': return self._gen_fname(self.inputs.source_file, suffix='_QW') + + +class QwarpPlusMinusInputSpec(QwarpInputSpec): + source_file = File( + desc='Source image (opposite phase encoding direction than base image)', + argstr='-source %s', + exists=True, + deprecated='1.1.2', + new_name='in_file', + copyfile=False) + out_file = File( + argstr='-prefix %s', + value='Qwarp.nii.gz', + position=0, + usedefault=True, + desc="Output file") + plusminus = traits.Bool( + True, + usedefault=True, + position=1, + desc='Normally, the warp displacements dis(x) are defined to match' + 'base(x) to source(x+dis(x)). With this option, the match' + 'is between base(x-dis(x)) and source(x+dis(x)) -- the two' + 'images \'meet in the middle\'. For more info, view Qwarp` interface', + argstr='-plusminus', + xor=['duplo', 'allsave', 'iwarp']) + + +class QwarpPlusMinus(Qwarp): + """A version of 3dQwarp for performing field susceptibility correction + using two images with opposing phase encoding directions. + + For complete details, see the `3dQwarp Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni + >>> qwarp = afni.QwarpPlusMinus() + >>> qwarp.inputs.in_file = 'sub-01_dir-LR_epi.nii.gz' + >>> qwarp.inputs.nopadWARP = True + >>> qwarp.inputs.base_file = 'sub-01_dir-RL_epi.nii.gz' + >>> qwarp.cmdline + '3dQwarp -prefix Qwarp.nii.gz -plusminus -base sub-01_dir-RL_epi.nii.gz \ + -source sub-01_dir-LR_epi.nii.gz -nopadWARP' + >>> res = warp.run() # doctest: +SKIP + + """ + + input_spec = QwarpPlusMinusInputSpec diff --git a/nipype/interfaces/afni/tests/test_auto_QwarpPlusMinus.py b/nipype/interfaces/afni/tests/test_auto_QwarpPlusMinus.py index 2b823cf8af..340f3a0e4a 100644 --- a/nipype/interfaces/afni/tests/test_auto_QwarpPlusMinus.py +++ b/nipype/interfaces/afni/tests/test_auto_QwarpPlusMinus.py @@ -5,25 +5,154 @@ def test_QwarpPlusMinus_inputs(): input_map = dict( + Qfinal=dict(argstr='-Qfinal', ), + Qonly=dict(argstr='-Qonly', ), + allineate=dict(argstr='-allineate', ), + allineate_opts=dict( + argstr='-allineate_opts %s', + requires=['allineate'], + ), + allsave=dict( + argstr='-allsave', + xor=['nopadWARP', 'duplo', 'plusminus'], + ), args=dict(argstr='%s', ), + ballopt=dict( + argstr='-ballopt', + xor=['workhard', 'boxopt'], + ), base_file=dict( argstr='-base %s', copyfile=False, mandatory=True, ), + baxopt=dict( + argstr='-boxopt', + xor=['workhard', 'ballopt'], + ), blur=dict(argstr='-blur %s', ), + duplo=dict( + argstr='-duplo', + xor=[ + 'gridlist', 'maxlev', 'inilev', 'iniwarp', 'plusminus', + 'allsave' + ], + ), + emask=dict( + argstr='-emask %s', + copyfile=False, + ), environ=dict( nohash=True, usedefault=True, ), + expad=dict( + argstr='-expad %d', + xor=['nopadWARP'], + ), + gridlist=dict( + argstr='-gridlist %s', + copyfile=False, + xor=['duplo', 'plusminus'], + ), + hel=dict( + argstr='-hel', + xor=['nmi', 'mi', 'lpc', 'lpa', 'pear'], + ), + in_file=dict( + argstr='-source %s', + copyfile=False, + mandatory=True, + ), + inilev=dict( + argstr='-inilev %d', + xor=['duplo'], + ), + iniwarp=dict( + argstr='-iniwarp %s', + xor=['duplo'], + ), + iwarp=dict( + argstr='-iwarp', + xor=['plusminus'], + ), + lpa=dict( + argstr='-lpa', + xor=['nmi', 'mi', 'lpc', 'hel', 'pear'], + ), + lpc=dict( + argstr='-lpc', + position=-2, + xor=['nmi', 'mi', 'hel', 'lpa', 'pear'], + ), + maxlev=dict( + argstr='-maxlev %d', + position=-1, + xor=['duplo'], + ), + mi=dict( + argstr='-mi', + xor=['mi', 'hel', 'lpc', 'lpa', 'pear'], + ), minpatch=dict(argstr='-minpatch %d', ), - nopadWARP=dict(argstr='-nopadWARP', ), + nmi=dict( + argstr='-nmi', + xor=['nmi', 'hel', 'lpc', 'lpa', 'pear'], + ), + noXdis=dict(argstr='-noXdis', ), + noYdis=dict(argstr='-noYdis', ), + noZdis=dict(argstr='-noZdis', ), + noneg=dict(argstr='-noneg', ), + nopad=dict(argstr='-nopad', ), + nopadWARP=dict( + argstr='-nopadWARP', + xor=['allsave', 'expad'], + ), + nopenalty=dict(argstr='-nopenalty', ), + nowarp=dict(argstr='-nowarp', ), noweight=dict(argstr='-noweight', ), + num_threads=dict( + nohash=True, + usedefault=True, + ), + out_file=dict( + argstr='-prefix %s', + position=0, + usedefault=True, + ), + out_weight_file=dict(argstr='-wtprefix %s', ), + outputtype=dict(), + overwrite=dict(argstr='-overwrite', ), pblur=dict(argstr='-pblur %s', ), + pear=dict(argstr='-pear', ), + penfac=dict(argstr='-penfac %f', ), + plusminus=dict( + argstr='-plusminus', + position=1, + usedefault=True, + xor=['duplo', 'allsave', 'iwarp'], + ), + quiet=dict( + argstr='-quiet', + xor=['verb'], + ), + resample=dict(argstr='-resample', ), source_file=dict( argstr='-source %s', copyfile=False, - mandatory=True, + deprecated='1.1.2', + new_name='in_file', + ), + verb=dict( + argstr='-verb', + xor=['quiet'], + ), + wball=dict(argstr='-wball %s', ), + weight=dict(argstr='-weight %s', ), + wmask=dict(argstr='-wpass %s %f', ), + workhard=dict( + argstr='-workhard', + xor=['boxopt', 'ballopt'], ), ) inputs = QwarpPlusMinus.input_spec() @@ -37,6 +166,7 @@ def test_QwarpPlusMinus_outputs(): source_warp=dict(), warped_base=dict(), warped_source=dict(), + weights=dict(), ) outputs = QwarpPlusMinus.output_spec() diff --git a/nipype/interfaces/elastix/registration.py b/nipype/interfaces/elastix/registration.py index 7f2565d58c..3a815963a2 100644 --- a/nipype/interfaces/elastix/registration.py +++ b/nipype/interfaces/elastix/registration.py @@ -178,13 +178,28 @@ def _list_outputs(self): return outputs -class AnalyzeWarpInputSpec(ElastixBaseInputSpec): - transform_file = File( +class AnalyzeWarpInputSpec(ApplyWarpInputSpec): + points = traits.Enum( + 'all', + usedefault=True, + position=0, + argstr='-def %s', + desc='transform all points from the input-image, which effectively' + ' generates a deformation field.') + jac = traits.Enum( + 'all', + usedefault=True, + argstr='-jac %s', + desc='generate an image with the determinant of the spatial Jacobian') + jacmat = traits.Enum( + 'all', + usedefault=True, + argstr='-jacmat %s', + desc='generate an image with the spatial Jacobian matrix at each voxel') + moving_image = File( exists=True, - mandatory=True, - argstr='-tp %s', - desc='transform-parameter file, only 1') - + argstr='-in %s', + desc='input image to deform (not used)') class AnalyzeWarpOutputSpec(TraitedSpec): disp_field = File(desc='displacements field') @@ -192,7 +207,7 @@ class AnalyzeWarpOutputSpec(TraitedSpec): jacmat_map = File(desc='Jacobian matrix map') -class AnalyzeWarp(CommandLine): +class AnalyzeWarp(ApplyWarp): """ Use transformix to get details from the input transform (generate the corresponding deformation field, generate the determinant of the @@ -210,7 +225,6 @@ class AnalyzeWarp(CommandLine): """ - _cmd = 'transformix -def all -jac all -jacmat all' input_spec = AnalyzeWarpInputSpec output_spec = AnalyzeWarpOutputSpec diff --git a/nipype/interfaces/elastix/tests/test_auto_AnalyzeWarp.py b/nipype/interfaces/elastix/tests/test_auto_AnalyzeWarp.py index cb486b8487..f05821d9c1 100644 --- a/nipype/interfaces/elastix/tests/test_auto_AnalyzeWarp.py +++ b/nipype/interfaces/elastix/tests/test_auto_AnalyzeWarp.py @@ -10,6 +10,15 @@ def test_AnalyzeWarp_inputs(): nohash=True, usedefault=True, ), + jac=dict( + argstr='-jac %s', + usedefault=True, + ), + jacmat=dict( + argstr='-jacmat %s', + usedefault=True, + ), + moving_image=dict(argstr='-in %s', ), num_threads=dict( argstr='-threads %01d', nohash=True, @@ -20,6 +29,11 @@ def test_AnalyzeWarp_inputs(): mandatory=True, usedefault=True, ), + points=dict( + argstr='-def %s', + position=0, + usedefault=True, + ), transform_file=dict( argstr='-tp %s', mandatory=True,