From 4032ee1821a8470a0ffa3d38db8e5a181099184b Mon Sep 17 00:00:00 2001 From: Chris Gorgolewski Date: Wed, 26 Apr 2017 18:28:45 -0700 Subject: [PATCH 1/6] add qwarp --- nipype/interfaces/afni/__init__.py | 2 +- nipype/interfaces/afni/preprocess.py | 66 ++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/nipype/interfaces/afni/__init__.py b/nipype/interfaces/afni/__init__.py index dfc0d794f5..75a42df11e 100644 --- a/nipype/interfaces/afni/__init__.py +++ b/nipype/interfaces/afni/__init__.py @@ -15,7 +15,7 @@ Maskave, Means, OutlierCount, QualityIndex, ROIStats, Retroicor, Seg, SkullStrip, TCorr1D, TCorrMap, TCorrelate, - TShift, Volreg, Warp) + TShift, Volreg, Warp, Qwarp) from .svm import (SVMTest, SVMTrain) from .utils import (AFNItoNIFTI, Autobox, BrickStat, Calc, Copy, Eval, FWHMx, diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index 19fe073ac5..c2b86dae9e 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -2347,3 +2347,69 @@ class Warp(AFNICommand): _cmd = '3dWarp' input_spec = WarpInputSpec output_spec = AFNICommandOutputSpec + + +class QwarpInputSpec(CommandLineInputSpec): + source_file = File( + desc='', + argstr='-source %s', + mandatory=True, + exists=True, + copyfile=False) + base_file = File( + desc='', + argstr='-base %s', + mandatory=True, + exists=True, + copyfile=False) + plusminus = traits.Bool( + desc='', + argstr='-plusminus') + pmNAMES = traits.List(traits.Str(), + desc='', + argstr='-pmNAMES %') + pblur = traits.List(traits.Float(), + desc='', + argstr='-pblur %s') + blur = traits.List(traits.Float(), + desc='', + argstr='-blur %s') + noweight = traits.Bool( + desc='', + argstr='-noweight') + minpatch = traits.Int( + desc='', + argstr='-minpatch %d') + nopadWARP = traits.Bool( + desc='', + argstr='-nopadWARP') + + +class QwarpOutputSpec(TraitedSpec): + warped_source = File( + desc='', + exists=True) + warped_base = File( + desc='', + exists=True) + source_warp = File( + desc='', + exists=True) + base_warp = File( + desc='', + exists=True) + + +class Qwarp(CommandLine): + _cmd = '3dQwarp -prefix Qwarp.nii.gz' + input_spec = QwarpInputSpec + output_spec = QwarpOutputSpec + + 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 From 9b9c3dbefb876d9cd8f2df7f3b74817c2ad17080 Mon Sep 17 00:00:00 2001 From: Chris Gorgolewski Date: Thu, 27 Apr 2017 15:27:54 -0700 Subject: [PATCH 2/6] Added documentation and doctests. --- nipype/interfaces/afni/preprocess.py | 82 ++++++++++++++------ nipype/testing/data/sub-01_dir-LR_epi.nii.gz | 0 nipype/testing/data/sub-01_dir-RL_epi.nii.gz | 0 3 files changed, 59 insertions(+), 23 deletions(-) create mode 100644 nipype/testing/data/sub-01_dir-LR_epi.nii.gz create mode 100644 nipype/testing/data/sub-01_dir-RL_epi.nii.gz diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index c2b86dae9e..b2e65e40ea 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -2349,59 +2349,95 @@ class Warp(AFNICommand): output_spec = AFNICommandOutputSpec -class QwarpInputSpec(CommandLineInputSpec): +class QwarpPlusMinusInputSpec(CommandLineInputSpec): source_file = File( - desc='', + desc='Source image (opposite phase encoding direction than base image).', argstr='-source %s', mandatory=True, exists=True, copyfile=False) base_file = File( - desc='', + desc='Base image (opposite phase encoding direction than source image).', argstr='-base %s', mandatory=True, exists=True, copyfile=False) - plusminus = traits.Bool( - desc='', - argstr='-plusminus') - pmNAMES = traits.List(traits.Str(), - desc='', - argstr='-pmNAMES %') pblur = traits.List(traits.Float(), - desc='', - argstr='-pblur %s') + 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 %g', + minlen=1, + maxlen=2) blur = traits.List(traits.Float(), - desc='', - argstr='-blur %s') + 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 %g', + minlen=1, + maxlen=2) noweight = traits.Bool( - desc='', + 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='', + desc="Set the minimum patch size for warp searching to 'mm' voxels.", argstr='-minpatch %d') nopadWARP = traits.Bool( - desc='', + 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 QwarpOutputSpec(TraitedSpec): +class QwarpPlusMinusOutputSpec(TraitedSpec): warped_source = File( - desc='', + desc='Undistorted source file.', exists=True) warped_base = File( - desc='', + desc='Undistorted source file.', exists=True) source_warp = File( - desc='', + desc="Field suceptibility correction warp (in 'mm') for source image.", exists=True) base_warp = File( - desc='', + desc="Field suceptibility correction warp (in 'mm') for base image.", exists=True) -class Qwarp(CommandLine): - _cmd = '3dQwarp -prefix Qwarp.nii.gz' +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 # doctest: +ALLOW_UNICODE + '3dQwarp -prefix Qwarp.nii.gz -plusminus -source sub-01_dir-LR_epi.nii.gz + -base sub-01_dir-RL_epi.nii.gz' + >>> res = warp.run() # doctest: +SKIP + + """ + _cmd = '3dQwarp -prefix Qwarp.nii.gz -plusminus' input_spec = QwarpInputSpec output_spec = QwarpOutputSpec diff --git a/nipype/testing/data/sub-01_dir-LR_epi.nii.gz b/nipype/testing/data/sub-01_dir-LR_epi.nii.gz new file mode 100644 index 0000000000..e69de29bb2 diff --git a/nipype/testing/data/sub-01_dir-RL_epi.nii.gz b/nipype/testing/data/sub-01_dir-RL_epi.nii.gz new file mode 100644 index 0000000000..e69de29bb2 From f95ce0d7da442afa932920f2063a9e7fb64f6f43 Mon Sep 17 00:00:00 2001 From: Chris Gorgolewski Date: Thu, 27 Apr 2017 15:39:05 -0700 Subject: [PATCH 3/6] naming fixes --- nipype/interfaces/afni/__init__.py | 2 +- nipype/interfaces/afni/preprocess.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/afni/__init__.py b/nipype/interfaces/afni/__init__.py index 75a42df11e..abfeda39f6 100644 --- a/nipype/interfaces/afni/__init__.py +++ b/nipype/interfaces/afni/__init__.py @@ -15,7 +15,7 @@ Maskave, Means, OutlierCount, QualityIndex, ROIStats, Retroicor, Seg, SkullStrip, TCorr1D, TCorrMap, TCorrelate, - TShift, Volreg, Warp, Qwarp) + TShift, Volreg, Warp, QwarpPlusMinus) from .svm import (SVMTest, SVMTrain) from .utils import (AFNItoNIFTI, Autobox, BrickStat, Calc, Copy, Eval, FWHMx, diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index b2e65e40ea..0373cf3ff6 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -2438,8 +2438,8 @@ class QwarpPlusMinus(CommandLine): """ _cmd = '3dQwarp -prefix Qwarp.nii.gz -plusminus' - input_spec = QwarpInputSpec - output_spec = QwarpOutputSpec + input_spec = QwarpPlusMinusInputSpec + output_spec = QwarpPlusMinusOutputSpec def _list_outputs(self): outputs = self.output_spec().get() From 01747aa68c250d30062b04647b3028d972bfbcaa Mon Sep 17 00:00:00 2001 From: Chris Gorgolewski Date: Thu, 27 Apr 2017 15:53:13 -0700 Subject: [PATCH 4/6] fixing expected output string --- nipype/interfaces/afni/preprocess.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index 0373cf3ff6..e159b2f825 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -2432,8 +2432,7 @@ class QwarpPlusMinus(CommandLine): >>> qwarp.inputs.nopadWARP = True >>> qwarp.inputs.base_file = 'sub-01_dir-RL_epi.nii.gz' >>> qwarp.cmdline # doctest: +ALLOW_UNICODE - '3dQwarp -prefix Qwarp.nii.gz -plusminus -source sub-01_dir-LR_epi.nii.gz - -base sub-01_dir-RL_epi.nii.gz' + '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 """ From 3f47b2e410d313a48bba117eb7d5e9fd1c263f2c Mon Sep 17 00:00:00 2001 From: Chris Gorgolewski Date: Thu, 27 Apr 2017 16:15:49 -0700 Subject: [PATCH 5/6] fixing arg strings --- nipype/interfaces/afni/preprocess.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index e159b2f825..e9d32e6a17 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -2369,7 +2369,7 @@ class QwarpPlusMinusInputSpec(CommandLineInputSpec): 'values, the first fraction is used for ' 'progressively blurring the base image and the ' 'second for the source image.', - argstr='-pblur %g', + argstr='-pblur %s', minlen=1, maxlen=2) blur = traits.List(traits.Float(), @@ -2383,7 +2383,7 @@ class QwarpPlusMinusInputSpec(CommandLineInputSpec): "filtering, rather than Gaussian blurring. This " "type of filtering will better preserve edges, " "which can be important in alignment.", - argstr='-blur %g', + argstr='-blur %s', minlen=1, maxlen=2) noweight = traits.Bool( From 5dee2f0fa0a15d9be2b7c2c74a996f94a4889776 Mon Sep 17 00:00:00 2001 From: Chris Gorgolewski Date: Fri, 28 Apr 2017 17:32:13 -0700 Subject: [PATCH 6/6] Fixed description. --- nipype/interfaces/afni/preprocess.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index e9d32e6a17..3556e7e589 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -2406,7 +2406,7 @@ class QwarpPlusMinusOutputSpec(TraitedSpec): desc='Undistorted source file.', exists=True) warped_base = File( - desc='Undistorted source file.', + desc='Undistorted base file.', exists=True) source_warp = File( desc="Field suceptibility correction warp (in 'mm') for source image.",