Skip to content

interface for AFNI's 3dNwarpCat #2219

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 5 commits into from
Oct 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from .utils import (ABoverlap, AFNItoNIFTI, Autobox, Axialize, BrickStat,
Bucket, Calc, Cat, CatMatvec, CenterMass, Copy, Dot,
Edge3, Eval, FWHMx, MaskTool, Merge, Notes, NwarpApply,
OneDToolPy,
NwarpCat, OneDToolPy,
Refit, Resample, TCat, TCatSubBrick, TStat, To3D, Unifize,
Undump, ZCutUp, GCOR,
Zcat, Zeropad)
Expand Down
56 changes: 56 additions & 0 deletions nipype/interfaces/afni/tests/test_auto_NwarpCat.py
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 NwarpCat


def test_NwarpCat_inputs():
input_map = dict(args=dict(argstr='%s',
),
environ=dict(nohash=True,
usedefault=True,
),
expad=dict(argstr='-expad %d',
),
ignore_exception=dict(nohash=True,
usedefault=True,
),
in_files=dict(argstr='%s',
descr='list of tuples of 3D warps and associated functions',
mandatory=True,
position=-1,
),
interp=dict(argstr='-interp %s',
),
inv_warp=dict(argstr='-iwarp',
),
num_threads=dict(nohash=True,
usedefault=True,
),
out_file=dict(argstr='-prefix %s',
name_source='in_files',
name_template='%s_NwarpCat',
),
outputtype=dict(),
space=dict(argstr='-space %s',
),
terminal_output=dict(deprecated='1.0.0',
nohash=True,
),
verb=dict(argstr='-verb',
),
)
inputs = NwarpCat.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_NwarpCat_outputs():
output_map = dict(out_file=dict(),
)
outputs = NwarpCat.output_spec()

for key, metadata in list(output_map.items()):
for metakey, value in list(metadata.items()):
assert getattr(outputs.traits()[key], metakey) == value
117 changes: 117 additions & 0 deletions nipype/interfaces/afni/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1588,6 +1588,123 @@ class NwarpApply(AFNICommandBase):
input_spec = NwarpApplyInputSpec
output_spec = AFNICommandOutputSpec


class NwarpCatInputSpec(AFNICommandInputSpec):
in_files = traits.List(
traits.Either(
traits.File(),
traits.Tuple(traits.Enum('IDENT', 'INV', 'SQRT', 'SQRTINV'),
traits.File())),
descr="list of tuples of 3D warps and associated functions",
mandatory=True,
argstr="%s",
position=-1)
space = traits.String(
desc='string to attach to the output dataset as its atlas space '
'marker.',
argstr='-space %s')
inv_warp = traits.Bool(
desc='invert the final warp before output',
argstr='-iwarp')
interp = traits.Enum(
'linear', 'quintic', 'wsinc5',
desc='specify a different interpolation method than might '
'be used for the warp',
argstr='-interp %s',
default='wsinc5')
expad = traits.Int(
desc='Pad the nonlinear warps by the given number of voxels voxels in '
'all directions. The warp displacements are extended by linear '
'extrapolation from the faces of the input grid..',
argstr='-expad %d')
out_file = File(
name_template='%s_NwarpCat',
desc='output image file name',
argstr='-prefix %s',
name_source='in_files')
verb = traits.Bool(
desc='be verbose',
argstr='-verb')


class NwarpCat(AFNICommand):
"""Catenates (composes) 3D warps defined on a grid, OR via a matrix.

.. note::

* All transformations are from DICOM xyz (in mm) to DICOM xyz.

* Matrix warps are in files that end in '.1D' or in '.txt'. A matrix
warp file should have 12 numbers in it, as output (for example), by
'3dAllineate -1Dmatrix_save'.

* Nonlinear warps are in dataset files (AFNI .HEAD/.BRIK or NIfTI .nii)
with 3 sub-bricks giving the DICOM order xyz grid displacements in mm.

* If all the input warps are matrices, then the output is a matrix
and will be written to the file 'prefix.aff12.1D'.
Unless the prefix already contains the string '.1D', in which case
the filename is just the prefix.

* If 'prefix' is just 'stdout', then the output matrix is written
to standard output.
In any of these cases, the output format is 12 numbers in one row.

* If any of the input warps are datasets, they must all be defined on
the same 3D grid!
And of course, then the output will be a dataset on the same grid.
However, you can expand the grid using the '-expad' option.

* The order of operations in the final (output) warp is, for the
case of 3 input warps:

OUTPUT(x) = warp3( warp2( warp1(x) ) )

That is, warp1 is applied first, then warp2, et cetera.
The 3D x coordinates are taken from each grid location in the
first dataset defined on a grid.

For complete details, see the `3dNwarpCat Documentation.
<https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dNwarpCat.html>`_

Examples
========

>>> from nipype.interfaces import afni
>>> nwarpcat = afni.NwarpCat()
>>> nwarpcat.inputs.in_files = ['Q25_warp+tlrc.HEAD', ('IDENT', 'structural.nii')]
>>> nwarpcat.inputs.out_file = 'Fred_total_WARP'
>>> nwarpcat.cmdline # doctest: +ALLOW_UNICODE
"3dNwarpCat -prefix Fred_total_WARP Q25_warp+tlrc.HEAD 'IDENT(structural.nii)'"
>>> res = nwarpcat.run() # doctest: +SKIP

"""
_cmd = '3dNwarpCat'
input_spec = NwarpCatInputSpec
output_spec = AFNICommandOutputSpec

def _format_arg(self, name, spec, value):
if name == 'in_files':
return spec.argstr % (' '.join(["'" + v[0] + "(" + v[1] + ")'"
if isinstance(v, tuple) else v
for v in value]))
return super(NwarpCat, self)._format_arg(name, spec, value)

def _gen_filename(self, name):
if name == 'out_file':
return self._gen_fname(self.inputs.in_files[0][0],
suffix='_NwarpCat')

def _list_outputs(self):
outputs = self.output_spec().get()
if isdefined(self.inputs.out_file):
outputs['out_file'] = os.path.abspath(self.inputs.out_file)
else:
outputs['out_file'] = os.path.abspath(self._gen_fname(
self.inputs.in_files[0], suffix='_NwarpCat+tlrc', ext='.HEAD'))
return outputs


class OneDToolPyInputSpec(AFNIPythonCommandInputSpec):
in_file = File(
desc='input file to OneDTool',
Expand Down