-
Notifications
You must be signed in to change notification settings - Fork 533
[ENH] Add afni.LocalStat and afni.ReHo, update afni.ROIStats inputs #2740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 12 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
62d1155
add 3dLocalstat functionality to support ANATICOR
rciric 494e224
add regional homogeneity interface
rciric 05c056c
substantially expand functionality of 3dROIstats interface
rciric cca5eb2
fix Localstat interface
rciric b0c95e0
remove unnecessary dependency; formatting
rciric a8fa089
new/updated autotests
rciric 1aee771
remove unused dependency
rciric f66e414
update documentation
rciric c2e507f
remove escaped line breaks from example cmdline
rciric 5149267
desc format cleanup
rciric b7d6871
update convention; use object after all
rciric 426def1
examples fix
rciric 13d7229
conform to PEP8, add deprecated field for ROIStats interface
rciric 8c65b81
update deprecation
rciric File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1802,28 +1802,107 @@ class QualityIndex(CommandLine): | |
|
||
class ROIStatsInputSpec(CommandLineInputSpec): | ||
in_file = File( | ||
desc='input file to 3dROIstats', | ||
desc='input dataset', | ||
argstr='%s', | ||
position=-1, | ||
position=-2, | ||
mandatory=True, | ||
exists=True) | ||
mask = File(desc='input mask', argstr='-mask %s', position=3, exists=True) | ||
mask_file = File(desc='input mask', argstr='-mask %s', 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) | ||
argstr='-mask_f2short') | ||
num_roi = traits.Int( | ||
desc='Forces the assumption that the mask dataset\'s ROIs are ' | ||
'denoted by 1 to n inclusive. Normally, the program ' | ||
'figures out the ROIs on its own. This option is ' | ||
'useful if a) you are certain that the mask dataset ' | ||
'has no values outside the range [0 n], b) there may ' | ||
'be some ROIs missing between [1 n] in the mask data-' | ||
'set and c) you want those columns in the output any-' | ||
'way so the output lines up with the output from other ' | ||
'invocations of 3dROIstats.', | ||
argstr='-numroi %s') | ||
zerofill = traits.Str( | ||
requires=['num_roi'], | ||
desc='For ROI labels not found, use the provided string instead of ' | ||
'a \'0\' in the output file. Only active if `num_roi` is ' | ||
'enabled.', | ||
argstr='-zerofill %s') | ||
roisel = traits.File( | ||
exists=True, | ||
desc='Only considers ROIs denoted by values found in the specified ' | ||
'file. Note that the order of the ROIs as specified in the file ' | ||
'is not preserved. So an SEL.1D of \'2 8 20\' produces the same ' | ||
'output as \'8 20 2\'', | ||
argstr='-roisel %s') | ||
debug = traits.Bool( | ||
desc='print debug information', | ||
argstr='-debug') | ||
quiet = traits.Bool( | ||
desc='execute quietly', | ||
argstr='-quiet') | ||
nomeanout = traits.Bool( | ||
desc='Do not include the (zero-inclusive) mean among computed stats', | ||
argstr='-nomeanout') | ||
nobriklab = traits.Bool( | ||
desc='Do not print the sub-brick label next to its index', | ||
argstr='-nobriklab') | ||
format1D = traits.Bool( | ||
xor=['format1DR'], | ||
desc='Output results in a 1D format that includes commented labels', | ||
argstr='-1Dformat') | ||
format1DR = traits.Bool( | ||
xor=['format1D'], | ||
desc='Output results in a 1D format that includes uncommented ' | ||
'labels. May not work optimally with typical 1D functions, ' | ||
'but is useful for R functions.', | ||
argstr='-1DRformat') | ||
_stat_names = ['mean', 'sum', 'voxels', 'minmax', 'sigma', 'median', | ||
'mode', 'summary', 'zerominmax', 'zerosigma', 'zeromedian', | ||
'zeromode'] | ||
stat = InputMultiObject( | ||
traits.Enum(_stat_names), | ||
desc='statistics to compute. Options include: ' | ||
' * mean = Compute the mean using only non_zero voxels.' | ||
' Implies the opposite for the mean computed ' | ||
' by default.\n' | ||
' * median = Compute the median of nonzero voxels\n' | ||
' * mode = Compute the mode of nonzero voxels.' | ||
' (integral valued sets only)\n' | ||
' * minmax = Compute the min/max of nonzero voxels\n' | ||
' * sum = Compute the sum using only nonzero voxels.\n' | ||
' * voxels = Compute the number of nonzero voxels\n' | ||
' * sigma = Compute the standard deviation of nonzero' | ||
' voxels\n' | ||
'Statistics that include zero-valued voxels:\n' | ||
' * zerominmax = Compute the min/max of all voxels.\n' | ||
' * zerosigma = Compute the standard deviation of all' | ||
' voxels.\n' | ||
' * zeromedian = Compute the median of all voxels.\n' | ||
' * zeromode = Compute the mode of all voxels.\n' | ||
' * summary = Only output a summary line with the grand ' | ||
' mean across all briks in the input dataset.' | ||
' This option cannot be used with nomeanout.\n' | ||
'More that one option can be specified.', | ||
argstr='%s...') | ||
out_file = File( | ||
name_template='%s_roistat.1D', | ||
desc='output file', | ||
keep_extension=False, | ||
argstr='> %s', | ||
name_source='in_file', | ||
position=-1) | ||
|
||
|
||
class ROIStatsOutputSpec(TraitedSpec): | ||
stats = File(desc='output tab separated values file', exists=True) | ||
out_file = File(desc='output tab-separated values file', exists=True) | ||
|
||
|
||
class ROIStats(AFNICommandBase): | ||
"""Display statistics over masked regions | ||
|
||
For complete details, see the `3dROIstats Documentation. | ||
For complete details, see the `3dROIstats Documentation | ||
<https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dROIstats.html>`_ | ||
|
||
Examples | ||
|
@@ -1832,10 +1911,11 @@ class ROIStats(AFNICommandBase): | |
>>> from nipype.interfaces import afni | ||
>>> roistats = afni.ROIStats() | ||
>>> roistats.inputs.in_file = 'functional.nii' | ||
>>> roistats.inputs.mask = 'skeleton_mask.nii.gz' | ||
>>> roistats.inputs.quiet = True | ||
>>> roistats.inputs.mask_file = 'skeleton_mask.nii.gz' | ||
>>> roistats.inputs.stat = ['mean', 'median', 'voxels'] | ||
>>> roistats.inputs.nomeanout = True | ||
>>> roistats.cmdline | ||
'3dROIstats -quiet -mask skeleton_mask.nii.gz functional.nii' | ||
'3dROIstats -mask skeleton_mask.nii.gz -nomeanout -nzmean -nzmedian -nzvoxels functional.nii > functional_roistat.1D' | ||
>>> res = roistats.run() # doctest: +SKIP | ||
|
||
""" | ||
|
@@ -1844,14 +1924,26 @@ class ROIStats(AFNICommandBase): | |
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) | ||
def _format_arg(self, name, spec, value): | ||
|
||
outputs.stats = os.path.abspath(output_filename) | ||
return outputs | ||
_stat_dict = { | ||
'mean': '-nzmean', | ||
'median': '-nzmedian', | ||
'mode': '-nzmode', | ||
'minmax': '-nzminmax', | ||
'sigma': '-nzsigma', | ||
'voxels': '-nzvoxels', | ||
'sum': '-nzsum', | ||
'summary': '-summary', | ||
'zerominmax': '-minmax', | ||
'zeromedian': '-median', | ||
'zerosigma': '-sigma', | ||
'zeromode': '-mode' | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We (try to) conform to PEP8. Can you restyle this as follows (4 space indentation, no double spaces, closing brace matching entries)? _stat_dict = {
'mean': '-nzmean',
...
} |
||
if name == 'stat': | ||
value = [_stat_dict[v] for v in value] | ||
|
||
return super(ROIStats, self)._format_arg(name, spec, value) | ||
|
||
|
||
class RetroicorInputSpec(AFNICommandInputSpec): | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT | ||
from __future__ import unicode_literals | ||
from ..utils import Localstat | ||
|
||
|
||
def test_Localstat_inputs(): | ||
input_map = dict( | ||
args=dict(argstr='%s', ), | ||
automask=dict(argstr='-automask', ), | ||
environ=dict( | ||
nohash=True, | ||
usedefault=True, | ||
), | ||
grid_rmode=dict( | ||
argstr='-grid_rmode %s', | ||
requires=['reduce_restore_grid'], | ||
), | ||
in_file=dict( | ||
argstr='%s', | ||
mandatory=True, | ||
position=-1, | ||
), | ||
mask_file=dict(argstr='-mask %s', ), | ||
neighborhood=dict( | ||
argstr="-nbhd '%s(%s)'", | ||
mandatory=True, | ||
), | ||
nonmask=dict(argstr='-use_nonmask', ), | ||
num_threads=dict( | ||
nohash=True, | ||
usedefault=True, | ||
), | ||
out_file=dict( | ||
argstr='-prefix %s', | ||
keep_extension=True, | ||
name_source='in_file', | ||
name_template='%s_localstat', | ||
position=0, | ||
), | ||
outputtype=dict(), | ||
overwrite=dict(argstr='-overwrite', ), | ||
quiet=dict(argstr='-quiet', ), | ||
reduce_grid=dict( | ||
argstr='-reduce_grid %s', | ||
xor=['reduce_restore_grid', 'reduce_max_vox'], | ||
), | ||
reduce_max_vox=dict( | ||
argstr='-reduce_max_vox %s', | ||
xor=['reduce_restore_grid', 'reduce_grid'], | ||
), | ||
reduce_restore_grid=dict( | ||
argstr='-reduce_restore_grid %s', | ||
xor=['reduce_max_vox', 'reduce_grid'], | ||
), | ||
stat=dict( | ||
argstr='-stat %s...', | ||
mandatory=True, | ||
), | ||
) | ||
inputs = Localstat.input_spec() | ||
|
||
for key, metadata in list(input_map.items()): | ||
for metakey, value in list(metadata.items()): | ||
assert getattr(inputs.traits()[key], metakey) == value | ||
def test_Localstat_outputs(): | ||
output_map = dict(out_file=dict(), ) | ||
outputs = Localstat.output_spec() | ||
|
||
for key, metadata in list(output_map.items()): | ||
for metakey, value in list(metadata.items()): | ||
assert getattr(outputs.traits()[key], metakey) == value |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT | ||
from __future__ import unicode_literals | ||
from ..utils import ReHo | ||
|
||
|
||
def test_ReHo_inputs(): | ||
input_map = dict( | ||
args=dict(argstr='%s', ), | ||
chi_sq=dict(argstr='-chi_sq', ), | ||
ellipsoid=dict( | ||
argstr='-neigh_X %s -neigh_Y %s -neigh_Z %s', | ||
xor=['sphere', 'neighborhood'], | ||
), | ||
environ=dict( | ||
nohash=True, | ||
usedefault=True, | ||
), | ||
in_file=dict( | ||
argstr='-inset %s', | ||
mandatory=True, | ||
position=1, | ||
), | ||
label_set=dict(argstr='-in_rois %s', ), | ||
mask=dict(argstr='-mask %s', ), | ||
neighborhood=dict( | ||
argstr='-nneigh %s', | ||
xor=['sphere', 'ellipsoid'], | ||
), | ||
out_file=dict( | ||
argstr='-prefix %s', | ||
keep_extension=True, | ||
name_source='in_file', | ||
name_template='%s_reho', | ||
position=0, | ||
), | ||
overwrite=dict(argstr='-overwrite', ), | ||
sphere=dict( | ||
argstr='-neigh_RAD %s', | ||
xor=['neighborhood', 'ellipsoid'], | ||
), | ||
) | ||
inputs = ReHo.input_spec() | ||
|
||
for key, metadata in list(input_map.items()): | ||
for metakey, value in list(metadata.items()): | ||
assert getattr(inputs.traits()[key], metakey) == value | ||
def test_ReHo_outputs(): | ||
output_map = dict( | ||
out_file=dict(), | ||
out_vals=dict(), | ||
) | ||
outputs = ReHo.output_spec() | ||
|
||
for key, metadata in list(output_map.items()): | ||
for metakey, value in list(metadata.items()): | ||
assert getattr(outputs.traits()[key], metakey) == value |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When renaming a field, you should use
deprecated
andnew_name
(see the developer guide) fields (in addition to the new trait).