Skip to content

Commit 67a5c89

Browse files
authored
Merge pull request #2219 from salma1601/afni_nwarpcat
interface for AFNI's 3dNwarpCat
2 parents a40e056 + 741dd1c commit 67a5c89

File tree

3 files changed

+174
-1
lines changed

3 files changed

+174
-1
lines changed

nipype/interfaces/afni/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from .utils import (ABoverlap, AFNItoNIFTI, Autobox, Axialize, BrickStat,
2323
Bucket, Calc, Cat, CatMatvec, CenterMass, Copy, Dot,
2424
Edge3, Eval, FWHMx, MaskTool, Merge, Notes, NwarpApply,
25-
OneDToolPy,
25+
NwarpCat, OneDToolPy,
2626
Refit, Resample, TCat, TCatSubBrick, TStat, To3D, Unifize,
2727
Undump, ZCutUp, GCOR,
2828
Zcat, Zeropad)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from __future__ import unicode_literals
3+
from ..utils import NwarpCat
4+
5+
6+
def test_NwarpCat_inputs():
7+
input_map = dict(args=dict(argstr='%s',
8+
),
9+
environ=dict(nohash=True,
10+
usedefault=True,
11+
),
12+
expad=dict(argstr='-expad %d',
13+
),
14+
ignore_exception=dict(nohash=True,
15+
usedefault=True,
16+
),
17+
in_files=dict(argstr='%s',
18+
descr='list of tuples of 3D warps and associated functions',
19+
mandatory=True,
20+
position=-1,
21+
),
22+
interp=dict(argstr='-interp %s',
23+
),
24+
inv_warp=dict(argstr='-iwarp',
25+
),
26+
num_threads=dict(nohash=True,
27+
usedefault=True,
28+
),
29+
out_file=dict(argstr='-prefix %s',
30+
name_source='in_files',
31+
name_template='%s_NwarpCat',
32+
),
33+
outputtype=dict(),
34+
space=dict(argstr='-space %s',
35+
),
36+
terminal_output=dict(deprecated='1.0.0',
37+
nohash=True,
38+
),
39+
verb=dict(argstr='-verb',
40+
),
41+
)
42+
inputs = NwarpCat.input_spec()
43+
44+
for key, metadata in list(input_map.items()):
45+
for metakey, value in list(metadata.items()):
46+
assert getattr(inputs.traits()[key], metakey) == value
47+
48+
49+
def test_NwarpCat_outputs():
50+
output_map = dict(out_file=dict(),
51+
)
52+
outputs = NwarpCat.output_spec()
53+
54+
for key, metadata in list(output_map.items()):
55+
for metakey, value in list(metadata.items()):
56+
assert getattr(outputs.traits()[key], metakey) == value

nipype/interfaces/afni/utils.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,123 @@ class NwarpApply(AFNICommandBase):
15881588
input_spec = NwarpApplyInputSpec
15891589
output_spec = AFNICommandOutputSpec
15901590

1591+
1592+
class NwarpCatInputSpec(AFNICommandInputSpec):
1593+
in_files = traits.List(
1594+
traits.Either(
1595+
traits.File(),
1596+
traits.Tuple(traits.Enum('IDENT', 'INV', 'SQRT', 'SQRTINV'),
1597+
traits.File())),
1598+
descr="list of tuples of 3D warps and associated functions",
1599+
mandatory=True,
1600+
argstr="%s",
1601+
position=-1)
1602+
space = traits.String(
1603+
desc='string to attach to the output dataset as its atlas space '
1604+
'marker.',
1605+
argstr='-space %s')
1606+
inv_warp = traits.Bool(
1607+
desc='invert the final warp before output',
1608+
argstr='-iwarp')
1609+
interp = traits.Enum(
1610+
'linear', 'quintic', 'wsinc5',
1611+
desc='specify a different interpolation method than might '
1612+
'be used for the warp',
1613+
argstr='-interp %s',
1614+
default='wsinc5')
1615+
expad = traits.Int(
1616+
desc='Pad the nonlinear warps by the given number of voxels voxels in '
1617+
'all directions. The warp displacements are extended by linear '
1618+
'extrapolation from the faces of the input grid..',
1619+
argstr='-expad %d')
1620+
out_file = File(
1621+
name_template='%s_NwarpCat',
1622+
desc='output image file name',
1623+
argstr='-prefix %s',
1624+
name_source='in_files')
1625+
verb = traits.Bool(
1626+
desc='be verbose',
1627+
argstr='-verb')
1628+
1629+
1630+
class NwarpCat(AFNICommand):
1631+
"""Catenates (composes) 3D warps defined on a grid, OR via a matrix.
1632+
1633+
.. note::
1634+
1635+
* All transformations are from DICOM xyz (in mm) to DICOM xyz.
1636+
1637+
* Matrix warps are in files that end in '.1D' or in '.txt'. A matrix
1638+
warp file should have 12 numbers in it, as output (for example), by
1639+
'3dAllineate -1Dmatrix_save'.
1640+
1641+
* Nonlinear warps are in dataset files (AFNI .HEAD/.BRIK or NIfTI .nii)
1642+
with 3 sub-bricks giving the DICOM order xyz grid displacements in mm.
1643+
1644+
* If all the input warps are matrices, then the output is a matrix
1645+
and will be written to the file 'prefix.aff12.1D'.
1646+
Unless the prefix already contains the string '.1D', in which case
1647+
the filename is just the prefix.
1648+
1649+
* If 'prefix' is just 'stdout', then the output matrix is written
1650+
to standard output.
1651+
In any of these cases, the output format is 12 numbers in one row.
1652+
1653+
* If any of the input warps are datasets, they must all be defined on
1654+
the same 3D grid!
1655+
And of course, then the output will be a dataset on the same grid.
1656+
However, you can expand the grid using the '-expad' option.
1657+
1658+
* The order of operations in the final (output) warp is, for the
1659+
case of 3 input warps:
1660+
1661+
OUTPUT(x) = warp3( warp2( warp1(x) ) )
1662+
1663+
That is, warp1 is applied first, then warp2, et cetera.
1664+
The 3D x coordinates are taken from each grid location in the
1665+
first dataset defined on a grid.
1666+
1667+
For complete details, see the `3dNwarpCat Documentation.
1668+
<https://afni.nimh.nih.gov/pub/dist/doc/program_help/3dNwarpCat.html>`_
1669+
1670+
Examples
1671+
========
1672+
1673+
>>> from nipype.interfaces import afni
1674+
>>> nwarpcat = afni.NwarpCat()
1675+
>>> nwarpcat.inputs.in_files = ['Q25_warp+tlrc.HEAD', ('IDENT', 'structural.nii')]
1676+
>>> nwarpcat.inputs.out_file = 'Fred_total_WARP'
1677+
>>> nwarpcat.cmdline # doctest: +ALLOW_UNICODE
1678+
"3dNwarpCat -prefix Fred_total_WARP Q25_warp+tlrc.HEAD 'IDENT(structural.nii)'"
1679+
>>> res = nwarpcat.run() # doctest: +SKIP
1680+
1681+
"""
1682+
_cmd = '3dNwarpCat'
1683+
input_spec = NwarpCatInputSpec
1684+
output_spec = AFNICommandOutputSpec
1685+
1686+
def _format_arg(self, name, spec, value):
1687+
if name == 'in_files':
1688+
return spec.argstr % (' '.join(["'" + v[0] + "(" + v[1] + ")'"
1689+
if isinstance(v, tuple) else v
1690+
for v in value]))
1691+
return super(NwarpCat, self)._format_arg(name, spec, value)
1692+
1693+
def _gen_filename(self, name):
1694+
if name == 'out_file':
1695+
return self._gen_fname(self.inputs.in_files[0][0],
1696+
suffix='_NwarpCat')
1697+
1698+
def _list_outputs(self):
1699+
outputs = self.output_spec().get()
1700+
if isdefined(self.inputs.out_file):
1701+
outputs['out_file'] = os.path.abspath(self.inputs.out_file)
1702+
else:
1703+
outputs['out_file'] = os.path.abspath(self._gen_fname(
1704+
self.inputs.in_files[0], suffix='_NwarpCat+tlrc', ext='.HEAD'))
1705+
return outputs
1706+
1707+
15911708
class OneDToolPyInputSpec(AFNIPythonCommandInputSpec):
15921709
in_file = File(
15931710
desc='input file to OneDTool',

0 commit comments

Comments
 (0)