Skip to content

Commit 5d11fbd

Browse files
committed
Merge pull request #472 from chrisfilo/enh/c3c
added C3dAffineTool for converting FSL to ITK affines
2 parents d9908ea + 7154fab commit 5d11fbd

32 files changed

+326
-165
lines changed

CHANGES

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Next release
22
============
33

44
* ENH: Add basic support for LSF plugin.
5-
* ENH: New interfaces: ICC, Meshfix, ants.Register
5+
* ENH: New interfaces: ICC, Meshfix, ants.Register, C3dAffineTool
66
* ENH: New workflows: ants template building (both using 'ANTS' and the new 'antsRegistration')
77
* ENH: New examples: how to use ANTS template building workflows (smri_ants_build_tmeplate),
88
how to set SGE specific options (smri_ants_build_template_new)

nipype/interfaces/base.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,39 @@ def _gen_filename(self, name):
12561256
def _gen_outfilename(self):
12571257
raise NotImplementedError
12581258

1259+
class SEMLikeCommandLine(CommandLine):
1260+
"""By default in SEM derived interface all outputs have corresponding inputs.
1261+
However, some SEM commands create outputs that are not defined in the XML.
1262+
In those cases one has to create a subclass of the autogenerated one and
1263+
overload the _list_outputs method. _outputs_from_inputs should still be
1264+
used but only for the reduced (by excluding those that do not have
1265+
corresponding inputs list of outputs.
1266+
"""
1267+
def _list_outputs(self):
1268+
outputs = self.output_spec().get()
1269+
return self._outputs_from_inputs(outputs)
1270+
1271+
def _outputs_from_inputs(self, outputs):
1272+
for name in outputs.keys():
1273+
coresponding_input = getattr(self.inputs, name)
1274+
if isdefined(coresponding_input):
1275+
if isinstance(coresponding_input, bool) and coresponding_input == True:
1276+
outputs[name] = os.path.abspath(self._outputs_filenames[name])
1277+
else:
1278+
if isinstance(coresponding_input, list):
1279+
outputs[name] = [os.path.abspath(inp) for inp in coresponding_input]
1280+
else:
1281+
outputs[name] = os.path.abspath(coresponding_input)
1282+
return outputs
1283+
1284+
def _format_arg(self, name, spec, value):
1285+
if name in self._outputs_filenames.keys():
1286+
if isinstance(value, bool):
1287+
if value == True:
1288+
value = os.path.abspath(self._outputs_filenames[name])
1289+
else:
1290+
return ""
1291+
return super(SEMLikeCommandLine, self)._format_arg(name, spec, value)
12591292

12601293
class MultiPath(traits.List):
12611294
""" Abstract class - shared functionality of input and output MultiPath

nipype/interfaces/c3.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""The ants module provides basic functions for interfacing with ants functions.
2+
3+
Change directory to provide relative paths for doctests
4+
>>> import os
5+
>>> filepath = os.path.dirname( os.path.realpath( __file__ ) )
6+
>>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data'))
7+
>>> os.chdir(datadir)
8+
"""
9+
from nipype.interfaces.base import (CommandLineInputSpec, traits, TraitedSpec,
10+
File, SEMLikeCommandLine)
11+
12+
13+
class C3dAffineToolInputSpec(CommandLineInputSpec):
14+
reference_file = File(exists=True, argstr="-ref %s", position=1)
15+
source_file = File(exists=True, argstr='-src %s', position=2)
16+
transform_file = File(exists=True, argstr='%s', position=3)
17+
itk_transform = traits.Either(traits.Bool, File(), hash_files=False,
18+
desc="Export ITK transform.",
19+
argstr="-oitk %s", position=5)
20+
fsl2ras = traits.Bool(argstr='-fsl2ras', position=4)
21+
22+
23+
class C3dAffineToolOutputSpec(TraitedSpec):
24+
itk_transform = File(exists=True)
25+
26+
27+
class C3dAffineTool(SEMLikeCommandLine):
28+
"""Converts fsl-style Affine registration into ANTS compatible itk format
29+
30+
Example
31+
>>> from nipype.interfaces.c3 import C3dAffineTool
32+
>>> c3 = C3dAffineTool()
33+
>>> c3.inputs.source_file = 'cmatrix.mat'
34+
>>> c3.inputs.itk_transform = 'affine.txt'
35+
>>> c3.inputs.fsl2ras = True
36+
>>> c3.cmdline
37+
'c3d_affine_tool -src cmatrix.mat -fsl2ras -oitk affine.txt'
38+
"""
39+
input_spec = C3dAffineToolInputSpec
40+
output_spec = C3dAffineToolOutputSpec
41+
42+
_cmd = 'c3d_affine_tool'
43+
_outputs_filenames = {'itk_transform': 'affine.txt'}

nipype/interfaces/slicer/base.py

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,4 @@
1-
from nipype.interfaces.base import CommandLine, isdefined
2-
import os
1+
from ..base import SEMLikeCommandLine
32

4-
5-
class SlicerCommandLine(CommandLine):
6-
"""By default in SEM derived interface all outputs have corresponding inputs.
7-
However, some SEM commands create outputs that are not defined in the XML.
8-
In those cases one has to create a subclass of the autogenerated one and
9-
overload the _list_outputs method. _outputs_from_inputs should still be
10-
used but only for the reduced (by excluding those that do not have
11-
corresponding inputs list of outputs.
12-
"""
13-
def _list_outputs(self):
14-
outputs = self.output_spec().get()
15-
return self._outputs_from_inputs(outputs)
16-
17-
def _outputs_from_inputs(self, outputs):
18-
for name in outputs.keys():
19-
coresponding_input = getattr(self.inputs, name)
20-
if isdefined(coresponding_input):
21-
if isinstance(coresponding_input, bool) and coresponding_input == True:
22-
outputs[name] = os.path.abspath(self._outputs_filenames[name])
23-
else:
24-
if isinstance(coresponding_input, list):
25-
outputs[name] = [os.path.abspath(inp) for inp in coresponding_input]
26-
else:
27-
outputs[name] = os.path.abspath(coresponding_input)
28-
return outputs
29-
30-
def _format_arg(self, name, spec, value):
31-
if name in self._outputs_filenames.keys():
32-
if isinstance(value, bool):
33-
if value == True:
34-
value = os.path.abspath(self._outputs_filenames[name])
35-
else:
36-
return ""
37-
return super(SlicerCommandLine, self)._format_arg(name, spec, value)
3+
class SlicerCommandLine(SEMLikeCommandLine):
4+
pass

nipype/interfaces/slicer/converters.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1+
# -*- coding: utf8 -*-
12
"""Autogenerated file - DO NOT EDIT
23
If you spot a bug, please report it on the mailing list and/or change the generator."""
34

4-
from nipype.interfaces.base import CommandLine, CommandLineInputSpec, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath
5+
from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath
56
import os
6-
from nipype.interfaces.slicer.base import SlicerCommandLine
77

88

99
class DicomToNrrdConverterInputSpec(CommandLineInputSpec):
10+
inputDicomDirectory = Directory(desc="Directory holding Dicom series", exists=True, argstr="--inputDicomDirectory %s")
1011
outputDirectory = traits.Either(traits.Bool, Directory(), hash_files=False, desc="Directory holding the output NRRD format", argstr="--outputDirectory %s")
1112
outputVolume = traits.Str(desc="Output filename (.nhdr or .nrrd)", argstr="--outputVolume %s")
1213
smallGradientThreshold = traits.Float(desc="If a gradient magnitude is greater than 0 and less than smallGradientThreshold, then DicomToNrrdConverter will display an error message and quit, unless the useBMatrixGradientDirections option is set.", argstr="--smallGradientThreshold %f")
13-
writeProtocolGradientsFile = traits.Bool(desc="Write the protocol gradients to a file suffixed by \".txt\" as they were specified in the procol by multiplying each diffusion gradient direction by the measurement frame. This file is for debugging purposes only, the format is not fixed, and will likely change as debugging of new dicom formats is necessary.", argstr="--writeProtocolGradientsFile ")
14+
writeProtocolGradientsFile = traits.Bool(desc="Write the protocol gradients to a file suffixed by \'.txt\' as they were specified in the procol by multiplying each diffusion gradient direction by the measurement frame. This file is for debugging purposes only, the format is not fixed, and will likely change as debugging of new dicom formats is necessary.", argstr="--writeProtocolGradientsFile ")
1415
useIdentityMeaseurementFrame = traits.Bool(desc="Adjust all the gradients so that the measurement frame is an identity matrix.", argstr="--useIdentityMeaseurementFrame ")
1516
useBMatrixGradientDirections = traits.Bool(desc="Fill the nhdr header with the gradient directions and bvalues computed out of the BMatrix. Only changes behavior for Siemens data.", argstr="--useBMatrixGradientDirections ")
1617

@@ -19,7 +20,7 @@ class DicomToNrrdConverterOutputSpec(TraitedSpec):
1920
outputDirectory = Directory(desc="Directory holding the output NRRD format", exists=True)
2021

2122

22-
class DicomToNrrdConverter(SlicerCommandLine):
23+
class DicomToNrrdConverter(SEMLikeCommandLine):
2324
"""title: DICOM to NRRD Converter
2425
2526
category: Converters
@@ -45,6 +46,7 @@ class DicomToNrrdConverter(SlicerCommandLine):
4546

4647

4748
class OrientScalarVolumeInputSpec(CommandLineInputSpec):
49+
inputVolume1 = File(position=-2, desc="Input volume 1", exists=True, argstr="%s")
4850
outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="The oriented volume", argstr="%s")
4951
orientation = traits.Enum("Axial", "Coronal", "Sagittal", "RIP", "LIP", "RSP", "LSP", "RIA", "LIA", "RSA", "LSA", "IRP", "ILP", "SRP", "SLP", "IRA", "ILA", "SRA", "SLA", "RPI", "LPI", "RAI", "LAI", "RPS", "LPS", "RAS", "LAS", "PRI", "PLI", "ARI", "ALI", "PRS", "PLS", "ARS", "ALS", "IPR", "SPR", "IAR", "SAR", "IPL", "SPL", "IAL", "SAL", "PIR", "PSR", "AIR", "ASR", "PIL", "PSL", "AIL", "ASL", desc="Orientation choices", argstr="--orientation %s")
5052

@@ -53,7 +55,7 @@ class OrientScalarVolumeOutputSpec(TraitedSpec):
5355
outputVolume = File(position=-1, desc="The oriented volume", exists=True)
5456

5557

56-
class OrientScalarVolume(SlicerCommandLine):
58+
class OrientScalarVolume(SEMLikeCommandLine):
5759
"""title: Orient Scalar Volume
5860
5961
category: Converters

0 commit comments

Comments
 (0)