From 8dfc981816dd2a0a78ad1bd4a6179c5d12baf5df Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Wed, 10 Feb 2016 09:02:48 -0800 Subject: [PATCH 1/6] [ENH] Addition of 3dHist from AFNI --- nipype/interfaces/afni/__init__.py | 2 +- nipype/interfaces/afni/preprocess.py | 64 +++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/nipype/interfaces/afni/__init__.py b/nipype/interfaces/afni/__init__.py index 4437a3ccd2..959a420635 100644 --- a/nipype/interfaces/afni/__init__.py +++ b/nipype/interfaces/afni/__init__.py @@ -12,5 +12,5 @@ Fourier, Allineate, Maskave, SkullStrip, TCat, Fim, BlurInMask, Autobox, TCorrMap, Bandpass, Retroicor, TCorrelate, TCorr1D, BrickStat, ROIStats, AutoTcorrelate, - AFNItoNIFTI, Eval, Means) + AFNItoNIFTI, Eval, Means, Histogram) from .svm import (SVMTest, SVMTrain) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index 85f2a4eaf9..f1c6a0e885 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -10,10 +10,11 @@ """ import os +import os.path as op import re from warnings import warn -from .base import AFNICommand, AFNICommandInputSpec, AFNICommandOutputSpec +from .base import AFNICommand, AFNICommandInputSpec, AFNICommandOutputSpec, Info from ..base import CommandLineInputSpec, CommandLine, OutputMultiPath from ..base import (Directory, TraitedSpec, traits, isdefined, File, InputMultiPath, Undefined) @@ -2090,3 +2091,64 @@ class Means(AFNICommand): _cmd = '3dMean' input_spec = MeansInputSpec output_spec = AFNICommandOutputSpec + + +class HistogramInputSpec(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 HistogramOutputSpec(TraitedSpec): + out_file = File(desc='output file', exists=True) + out_show = File(desc='output visual histogram') + + +class Histogram(CommandLine): + """Computes average of all voxels in the input dataset + which satisfy the criterion in the options list + + For complete details, see the `3dHist Documentation. + `_ + + Examples + ======== + + >>> from nipype.interfaces import afni as afni + >>> maskave = afni.Histogram() + >>> maskave.inputs.in_file = 'functional.nii' + '3dHist -input functional.nii -prefix functional_hist' + >>> res = maskave.run() # doctest: +SKIP + + """ + + _cmd = '3dHist' + input_spec = HistogramInputSpec + output_spec = HistogramOutputSpec + + def _parse_inputs(self, skip=None): + if not self.inputs.showhist: + if skip is None: + skip = [] + skip += ['out_show'] + return super(Histogram, self)._parse_inputs(skip=skip) + + + def _list_outputs(self): + outputs = super(Histogram, self)._list_outputs() + outputs['out_file'] += '.niml.hist' + if not self.inputs.showhist: + outputs['out_show'] = Undefined + return outputs From 4d0ab579ffea0f5e30c2badf7d0dda6c1574cf1e Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Wed, 10 Feb 2016 09:19:05 -0800 Subject: [PATCH 2/6] updated CHANGES, fixed doctest, add auto tests --- CHANGES | 1 + nipype/interfaces/afni/preprocess.py | 7 ++- .../afni/tests/test_auto_Histogram.py | 62 +++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 nipype/interfaces/afni/tests/test_auto_Histogram.py diff --git a/CHANGES b/CHANGES index 3bf1ee167e..34e3f7bbd7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ Next release ============ +* ENH: Added interfaces of AFNI (https://github.com/nipy/nipype/pull/1360) * ENH: Added support for PETPVC (https://github.com/nipy/nipype/pull/1335) * ENH: Merge S3DataSink into DataSink, added AWS documentation (https://github.com/nipy/nipype/pull/1316) * TST: Cache APT in CircleCI (https://github.com/nipy/nipype/pull/1333) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index f1c6a0e885..8b04334150 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -2127,10 +2127,11 @@ class Histogram(CommandLine): ======== >>> from nipype.interfaces import afni as afni - >>> maskave = afni.Histogram() - >>> maskave.inputs.in_file = 'functional.nii' + >>> hist = afni.Histogram() + >>> hist.inputs.in_file = 'functional.nii' + >>> hist.cmdline '3dHist -input functional.nii -prefix functional_hist' - >>> res = maskave.run() # doctest: +SKIP + >>> res = hist.run() # doctest: +SKIP """ diff --git a/nipype/interfaces/afni/tests/test_auto_Histogram.py b/nipype/interfaces/afni/tests/test_auto_Histogram.py new file mode 100644 index 0000000000..67b9b2f20c --- /dev/null +++ b/nipype/interfaces/afni/tests/test_auto_Histogram.py @@ -0,0 +1,62 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from ....testing import assert_equal +from ..preprocess import Histogram + + +def test_Histogram_inputs(): + input_map = dict(args=dict(argstr='%s', + ), + bin_width=dict(argstr='-binwidth %f', + ), + environ=dict(nohash=True, + usedefault=True, + ), + ignore_exception=dict(nohash=True, + usedefault=True, + ), + in_file=dict(argstr='-input %s', + copyfile=False, + mandatory=True, + position=1, + ), + mask=dict(argstr='-mask %s', + ), + max_value=dict(argstr='-max %f', + ), + min_value=dict(argstr='-min %f', + ), + nbin=dict(argstr='-nbin %d', + ), + out_file=dict(argstr='-prefix %s', + keep_extension=False, + name_source=['in_file'], + name_template='%s_hist', + ), + out_show=dict(argstr='> %s', + keep_extension=False, + name_source='in_file', + name_template='%s_hist.out', + position=-1, + ), + showhist=dict(argstr='-showhist', + usedefault=True, + ), + terminal_output=dict(nohash=True, + ), + ) + inputs = Histogram.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_Histogram_outputs(): + output_map = dict(out_file=dict(), + out_show=dict(), + ) + outputs = Histogram.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 From 2e2f4879f80245545171aa9d6ba0033d630691a7 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Wed, 10 Feb 2016 12:16:58 -0800 Subject: [PATCH 3/6] renamed afni.Histogram to afni.Hist --- nipype/interfaces/afni/preprocess.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index 8b04334150..aaca71c336 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -2093,7 +2093,7 @@ class Means(AFNICommand): output_spec = AFNICommandOutputSpec -class HistogramInputSpec(CommandLineInputSpec): +class HistInputSpec(CommandLineInputSpec): in_file = File( desc='input file to 3dHist', argstr='-input %s', position=1, mandatory=True, exists=True, copyfile=False) @@ -2111,12 +2111,12 @@ class HistogramInputSpec(CommandLineInputSpec): min_value = traits.Float(argstr='-min %f', desc='minimum intensity value') bin_width = traits.Float(argstr='-binwidth %f', desc='bin width') -class HistogramOutputSpec(TraitedSpec): +class HistOutputSpec(TraitedSpec): out_file = File(desc='output file', exists=True) out_show = File(desc='output visual histogram') -class Histogram(CommandLine): +class Hist(CommandLine): """Computes average of all voxels in the input dataset which satisfy the criterion in the options list @@ -2127,7 +2127,7 @@ class Histogram(CommandLine): ======== >>> from nipype.interfaces import afni as afni - >>> hist = afni.Histogram() + >>> hist = afni.Hist() >>> hist.inputs.in_file = 'functional.nii' >>> hist.cmdline '3dHist -input functional.nii -prefix functional_hist' @@ -2136,19 +2136,19 @@ class Histogram(CommandLine): """ _cmd = '3dHist' - input_spec = HistogramInputSpec - output_spec = HistogramOutputSpec + input_spec = HistInputSpec + output_spec = HistOutputSpec def _parse_inputs(self, skip=None): if not self.inputs.showhist: if skip is None: skip = [] skip += ['out_show'] - return super(Histogram, self)._parse_inputs(skip=skip) + return super(Hist, self)._parse_inputs(skip=skip) def _list_outputs(self): - outputs = super(Histogram, self)._list_outputs() + outputs = super(Hist, self)._list_outputs() outputs['out_file'] += '.niml.hist' if not self.inputs.showhist: outputs['out_show'] = Undefined From 8f8b5888ae86b46e457d21d156aced9f1e5bb674 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Wed, 10 Feb 2016 13:17:33 -0800 Subject: [PATCH 4/6] fix problem when changing name --- nipype/interfaces/afni/__init__.py | 2 +- .../interfaces/afni/tests/test_auto_Hist.py | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 nipype/interfaces/afni/tests/test_auto_Hist.py diff --git a/nipype/interfaces/afni/__init__.py b/nipype/interfaces/afni/__init__.py index 959a420635..c579d5b89d 100644 --- a/nipype/interfaces/afni/__init__.py +++ b/nipype/interfaces/afni/__init__.py @@ -12,5 +12,5 @@ Fourier, Allineate, Maskave, SkullStrip, TCat, Fim, BlurInMask, Autobox, TCorrMap, Bandpass, Retroicor, TCorrelate, TCorr1D, BrickStat, ROIStats, AutoTcorrelate, - AFNItoNIFTI, Eval, Means, Histogram) + AFNItoNIFTI, Eval, Means, Hist) from .svm import (SVMTest, SVMTrain) diff --git a/nipype/interfaces/afni/tests/test_auto_Hist.py b/nipype/interfaces/afni/tests/test_auto_Hist.py new file mode 100644 index 0000000000..0024e5f186 --- /dev/null +++ b/nipype/interfaces/afni/tests/test_auto_Hist.py @@ -0,0 +1,62 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from ....testing import assert_equal +from ..preprocess import Hist + + +def test_Hist_inputs(): + input_map = dict(args=dict(argstr='%s', + ), + bin_width=dict(argstr='-binwidth %f', + ), + environ=dict(nohash=True, + usedefault=True, + ), + ignore_exception=dict(nohash=True, + usedefault=True, + ), + in_file=dict(argstr='-input %s', + copyfile=False, + mandatory=True, + position=1, + ), + mask=dict(argstr='-mask %s', + ), + max_value=dict(argstr='-max %f', + ), + min_value=dict(argstr='-min %f', + ), + nbin=dict(argstr='-nbin %d', + ), + out_file=dict(argstr='-prefix %s', + keep_extension=False, + name_source=['in_file'], + name_template='%s_hist', + ), + out_show=dict(argstr='> %s', + keep_extension=False, + name_source='in_file', + name_template='%s_hist.out', + position=-1, + ), + showhist=dict(argstr='-showhist', + usedefault=True, + ), + terminal_output=dict(nohash=True, + ), + ) + inputs = Hist.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_Hist_outputs(): + output_map = dict(out_file=dict(), + out_show=dict(), + ) + outputs = Hist.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 From f60ffc25d7cd4489dbb622670461b3ebd7ae6205 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Wed, 10 Feb 2016 13:56:29 -0800 Subject: [PATCH 5/6] remove outdated auto test --- .../afni/tests/test_auto_Histogram.py | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 nipype/interfaces/afni/tests/test_auto_Histogram.py diff --git a/nipype/interfaces/afni/tests/test_auto_Histogram.py b/nipype/interfaces/afni/tests/test_auto_Histogram.py deleted file mode 100644 index 67b9b2f20c..0000000000 --- a/nipype/interfaces/afni/tests/test_auto_Histogram.py +++ /dev/null @@ -1,62 +0,0 @@ -# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT -from ....testing import assert_equal -from ..preprocess import Histogram - - -def test_Histogram_inputs(): - input_map = dict(args=dict(argstr='%s', - ), - bin_width=dict(argstr='-binwidth %f', - ), - environ=dict(nohash=True, - usedefault=True, - ), - ignore_exception=dict(nohash=True, - usedefault=True, - ), - in_file=dict(argstr='-input %s', - copyfile=False, - mandatory=True, - position=1, - ), - mask=dict(argstr='-mask %s', - ), - max_value=dict(argstr='-max %f', - ), - min_value=dict(argstr='-min %f', - ), - nbin=dict(argstr='-nbin %d', - ), - out_file=dict(argstr='-prefix %s', - keep_extension=False, - name_source=['in_file'], - name_template='%s_hist', - ), - out_show=dict(argstr='> %s', - keep_extension=False, - name_source='in_file', - name_template='%s_hist.out', - position=-1, - ), - showhist=dict(argstr='-showhist', - usedefault=True, - ), - terminal_output=dict(nohash=True, - ), - ) - inputs = Histogram.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_Histogram_outputs(): - output_map = dict(out_file=dict(), - out_show=dict(), - ) - outputs = Histogram.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 From 286fd7cae0610a6e290953c8b39d9e0c984d9c3f Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Wed, 10 Feb 2016 14:53:08 -0800 Subject: [PATCH 6/6] 3dHist in afni < 16 uses virtual display --- nipype/interfaces/afni/preprocess.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/nipype/interfaces/afni/preprocess.py b/nipype/interfaces/afni/preprocess.py index aaca71c336..34367b81e0 100644 --- a/nipype/interfaces/afni/preprocess.py +++ b/nipype/interfaces/afni/preprocess.py @@ -14,14 +14,13 @@ import re from warnings import warn -from .base import AFNICommand, AFNICommandInputSpec, AFNICommandOutputSpec, Info +from .base import AFNICommand, AFNICommandInputSpec, AFNICommandOutputSpec, Info, no_afni from ..base import CommandLineInputSpec, CommandLine, OutputMultiPath from ..base import (Directory, TraitedSpec, traits, isdefined, File, InputMultiPath, Undefined) from ...utils.filemanip import (load_json, save_json, split_filename) from ...utils.filemanip import fname_presuffix - class To3DInputSpec(AFNICommandInputSpec): out_file = File(name_template="%s", desc='output image file name', argstr='-prefix %s', name_source=["in_folder"]) @@ -1235,9 +1234,7 @@ class SkullStrip(AFNICommand): output_spec = AFNICommandOutputSpec def __init__(self, **inputs): - from .base import Info, no_afni super(SkullStrip, self).__init__(**inputs) - if not no_afni(): v = Info.version() @@ -2138,6 +2135,16 @@ class Hist(CommandLine): _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() + + # As of AFNI 16.0.00, redirect_x is not needed + if isinstance(version[0], int) and version[0] > 15: + self._redirect_x = False def _parse_inputs(self, skip=None): if not self.inputs.showhist: