Skip to content

Commit f450b72

Browse files
committed
Merge pull request #704 from mick-d/camino
New interface for Camino dtshape.
2 parents c9c34c1 + ae52aa8 commit f450b72

File tree

7 files changed

+178
-18
lines changed

7 files changed

+178
-18
lines changed

nipype/interfaces/camino/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
from .dti import (DTIFit, ModelFit, DTLUTGen, PicoPDFs, Track, TrackPICo,
1010
TrackBayesDirac, TrackDT, TrackBallStick, TrackBootstrap,
1111
ComputeFractionalAnisotropy, ComputeMeanDiffusivity,
12-
ComputeTensorTrace, ComputeEigensystem)
12+
ComputeTensorTrace, ComputeEigensystem, DTMetric)
1313
from .calib import (SFPICOCalibData, SFLUTGen)
1414
from .odf import (QBallMX, LinRecon, SFPeaks)

nipype/interfaces/camino/convert.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ class AnalyzeHeader(StdOutCommandLine):
563563
564564
>>> import nipype.interfaces.camino as cmon
565565
>>> hdr = cmon.AnalyzeHeader()
566-
>>> hdr.inputs.in_file = 'tensor_fitted_data.Bfloat'
566+
>>> hdr.inputs.in_file = 'tensor_fitted_data.Bdouble'
567567
>>> hdr.inputs.scheme_file = 'A.scheme'
568568
>>> hdr.inputs.data_dims = [256,256,256]
569569
>>> hdr.inputs.voxel_dims = [1,1,1]

nipype/interfaces/camino/dti.py

Lines changed: 125 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"""
99
from nipype.interfaces.base import (CommandLineInputSpec, CommandLine, traits,
1010
TraitedSpec, File, StdOutCommandLine,
11-
StdOutCommandLineInputSpec)
11+
StdOutCommandLineInputSpec, isdefined)
1212
from nipype.utils.filemanip import split_filename
1313
import os
1414

@@ -49,7 +49,7 @@ class DTIFit(StdOutCommandLine):
4949
>>> import nipype.interfaces.camino as cmon
5050
>>> fit = cmon.DTIFit()
5151
>>> fit.inputs.scheme_file = 'A.scheme'
52-
>>> fit.inputs.in_file = 'tensor_fitted_data.Bfloat'
52+
>>> fit.inputs.in_file = 'tensor_fitted_data.Bdouble'
5353
>>> fit.run() # doctest: +SKIP
5454
"""
5555
_cmd = 'dtfit'
@@ -65,6 +65,107 @@ def _gen_outfilename(self):
6565
_, name , _ = split_filename(self.inputs.in_file)
6666
return name + '_DT.Bdouble'
6767

68+
class DTMetricInputSpec(CommandLineInputSpec):
69+
eigen_data = File(exists=True, argstr='-inputfile %s', mandatory=True,
70+
desc='voxel-order data filename')
71+
72+
metric = traits.Enum('fa','md','rd','l1', 'l2', 'l3', 'tr', 'ra', '2dfa','cl','cp','cs',
73+
argstr='-stat %s', mandatory=True,
74+
desc=('Specifies the metric to compute. Possible choices are: '
75+
'"fa", "md", "rd", "l1", "l2", "l3", "tr", "ra", "2dfa", "cl", "cp" or "cs".'))
76+
77+
inputdatatype = traits.Enum('double', 'float', 'long', 'int', 'short', 'char',
78+
argstr='-inputdatatype %s', usedefault=True,
79+
desc=('Specifies the data type of the input data. '
80+
'The data type can be any of the following strings: '
81+
'"char", "short", "int", "long", "float" or "double".'
82+
'Default is double data type'))
83+
84+
outputdatatype = traits.Enum('double', 'float', 'long', 'int', 'short', 'char',
85+
argstr='-outputdatatype %s', usedefault=True,
86+
desc=('Specifies the data type of the output data. '
87+
'The data type can be any of the following strings: '
88+
'"char", "short", "int", "long", "float" or "double".'
89+
'Default is double data type'))
90+
91+
data_header = File(argstr='-header %s', exists=True,
92+
desc=('A Nifti .nii or .nii.gz file containing the header information. '
93+
'Usually this will be the header of the raw data file from which '
94+
'the diffusion tensors were reconstructed.'))
95+
96+
outputfile = File(argstr='-outputfile %s', genfile=True,
97+
desc=('Output name. Output will be a .nii.gz file if data_header is provided and'
98+
'in voxel order with outputdatatype datatype (default: double) otherwise.'))
99+
100+
class DTMetricOutputSpec(TraitedSpec):
101+
metric_stats = File(exists=True, desc='Diffusion Tensor statistics of the chosen metric')
102+
103+
class DTMetric(CommandLine):
104+
"""
105+
Computes tensor metric statistics based on the eigenvalues l1 >= l2 >= l3
106+
typically obtained from ComputeEigensystem.
107+
108+
The full list of statistics is:
109+
110+
<cl> = (l1 - l2) / l1 , a measure of linearity
111+
<cp> = (l2 - l3) / l1 , a measure of planarity
112+
<cs> = l3 / l1 , a measure of isotropy
113+
with: cl + cp + cs = 1
114+
115+
<l1> = first eigenvalue
116+
<l2> = second eigenvalue
117+
<l3> = third eigenvalue
118+
119+
<tr> = l1 + l2 + l3
120+
<md> = tr / 3
121+
<rd> = (l2 + l3) / 2
122+
<fa> = fractional anisotropy. (Basser et al, J Magn Reson B 1996)
123+
<ra> = relative anisotropy (Basser et al, J Magn Reson B 1996)
124+
125+
<2dfa> = 2D FA of the two minor eigenvalues l2 and l3
126+
i.e. sqrt( 2 * [(l2 - <l>)^2 + (l3 - <l>)^2] / (l2^2 + l3^2) )
127+
with: <l> = (l2 + l3) / 2
128+
129+
Example
130+
-------
131+
Compute the CP planar metric as float data type.
132+
133+
>>> import nipype.interfaces.camino as cam
134+
>>> dtmetric = cam.DTMetric()
135+
>>> dtmetric.inputs.eigen_data = 'dteig.Bdouble'
136+
>>> dtmetric.inputs.metric = 'cp'
137+
>>> dtmetric.inputs.outputdatatype = 'float'
138+
>>> dtmetric.run() # doctest: +SKIP
139+
"""
140+
_cmd = 'dtshape'
141+
input_spec=DTMetricInputSpec
142+
output_spec=DTMetricOutputSpec
143+
144+
def _list_outputs(self):
145+
outputs = self.output_spec().get()
146+
outputs['metric_stats'] = os.path.abspath(self._gen_outfilename())
147+
return outputs
148+
149+
def _gen_outfilename(self):
150+
return self._gen_outputfile()
151+
152+
def _gen_outputfile(self):
153+
outputfile = self.inputs.outputfile
154+
if not isdefined(outputfile):
155+
outputfile = self._gen_filename('outputfile')
156+
return outputfile
157+
158+
def _gen_filename(self, name):
159+
if name == 'outputfile':
160+
_, name , _ = split_filename(self.inputs.eigen_data)
161+
metric = self.inputs.metric
162+
datatype= self.inputs.outputdatatype
163+
if isdefined(self.inputs.data_header):
164+
filename = name + '_' + metric + '.nii.gz'
165+
else:
166+
filename = name + '_' + metric + '.B' + datatype
167+
return filename
168+
68169
class ModelFitInputSpec(StdOutCommandLineInputSpec):
69170
def _gen_model_options(): #@NoSelf
70171
"""
@@ -134,7 +235,7 @@ class ModelFit(StdOutCommandLine):
134235
>>> fit = cmon.ModelFit()
135236
>>> fit.model = 'dt'
136237
>>> fit.inputs.scheme_file = 'A.scheme'
137-
>>> fit.inputs.in_file = 'tensor_fitted_data.Bfloat'
238+
>>> fit.inputs.in_file = 'tensor_fitted_data.Bdouble'
138239
>>> fit.run() # doctest: +SKIP
139240
"""
140241
_cmd = 'modelfit'
@@ -381,7 +482,7 @@ class TrackDT(Track):
381482
382483
>>> import nipype.interfaces.camino as cmon
383484
>>> track = cmon.TrackDT()
384-
>>> track.inputs.in_file = 'tensor_fitted_data.Bfloat'
485+
>>> track.inputs.in_file = 'tensor_fitted_data.Bdouble'
385486
>>> track.inputs.seed_file = 'seed_mask.nii'
386487
>>> track.run() # doctest: +SKIP
387488
"""
@@ -447,7 +548,7 @@ class TrackBayesDirac(Track):
447548
448549
>>> import nipype.interfaces.camino as cmon
449550
>>> track = cmon.TrackBayesDirac()
450-
>>> track.inputs.in_file = 'tensor_fitted_data.Bfloat'
551+
>>> track.inputs.in_file = 'tensor_fitted_data.Bdouble'
451552
>>> track.inputs.seed_file = 'seed_mask.nii'
452553
>>> track.inputs.scheme_file = 'bvecs.scheme'
453554
>>> track.run() # doctest: +SKIP
@@ -547,7 +648,7 @@ class ComputeMeanDiffusivity(StdOutCommandLine):
547648
548649
>>> import nipype.interfaces.camino as cmon
549650
>>> md = cmon.ComputeMeanDiffusivity()
550-
>>> md.inputs.in_file = 'tensor_fitted_data.Bfloat'
651+
>>> md.inputs.in_file = 'tensor_fitted_data.Bdouble'
551652
>>> md.inputs.scheme_file = 'A.scheme'
552653
>>> md.run() # doctest: +SKIP
553654
"""
@@ -606,7 +707,7 @@ class ComputeFractionalAnisotropy(StdOutCommandLine):
606707
607708
>>> import nipype.interfaces.camino as cmon
608709
>>> fa = cmon.ComputeFractionalAnisotropy()
609-
>>> fa.inputs.in_file = 'tensor_fitted_data.Bfloat'
710+
>>> fa.inputs.in_file = 'tensor_fitted_data.Bdouble'
610711
>>> fa.inputs.scheme_file = 'A.scheme'
611712
>>> fa.run() # doctest: +SKIP
612713
"""
@@ -667,7 +768,7 @@ class ComputeTensorTrace(StdOutCommandLine):
667768
668769
>>> import nipype.interfaces.camino as cmon
669770
>>> trace = cmon.ComputeTensorTrace()
670-
>>> trace.inputs.in_file = 'tensor_fitted_data.Bfloat'
771+
>>> trace.inputs.in_file = 'tensor_fitted_data.Bdouble'
671772
>>> trace.inputs.scheme_file = 'A.scheme'
672773
>>> trace.run() # doctest: +SKIP
673774
"""
@@ -690,11 +791,21 @@ class ComputeEigensystemInputSpec(StdOutCommandLineInputSpec):
690791

691792
inputmodel = traits.Enum('dt', 'multitensor', argstr='-inputmodel %s', desc='Specifies the model that the input data contains parameters for. Possible model types are: "dt" (diffusion-tensor data) and "multitensor"')
692793

693-
maxcomponents = traits.Int(argstr='-maxcomponents %s', desc='The maximum number of tensor components in a voxel of the input data.')
794+
maxcomponents = traits.Int(argstr='-maxcomponents %d', desc='The maximum number of tensor components in a voxel of the input data.')
694795

695-
inputdatatype = traits.Enum("double", "char", "short", "int", "long", "float", argstr='-inputdatatype %s', desc='Specifies the data type of the input file. The data type can be any of the following strings: "char", "short", "int", "long", "float" or "double".')
796+
inputdatatype = traits.Enum('double', 'float', 'long', 'int', 'short', 'char',
797+
argstr='-inputdatatype %s', usedefault=True,
798+
desc=('Specifies the data type of the input data. '
799+
'The data type can be any of the following strings: '
800+
'"char", "short", "int", "long", "float" or "double".'
801+
'Default is double data type'))
696802

697-
outputdatatype = traits.Enum("double", "char", "short", "int", "long", "float", argstr='-outputdatatype %s', desc='Specifies the data type of the output data. The data type can be any of the following strings: "char", "short", "int", "long", "float" or "double".')
803+
outputdatatype = traits.Enum('double', 'float', 'long', 'int', 'short', 'char',
804+
argstr='-outputdatatype %s', usedefault=True,
805+
desc=('Specifies the data type of the output data. '
806+
'The data type can be any of the following strings: '
807+
'"char", "short", "int", "long", "float" or "double".'
808+
'Default is double data type'))
698809

699810
class ComputeEigensystemOutputSpec(TraitedSpec):
700811
eigen = File(exists=True, desc='Trace of the diffusion tensor')
@@ -716,7 +827,7 @@ class ComputeEigensystem(StdOutCommandLine):
716827
717828
>>> import nipype.interfaces.camino as cmon
718829
>>> dteig = cmon.ComputeEigensystem()
719-
>>> dteig.inputs.in_file = 'tensor_fitted_data.Bfloat'
830+
>>> dteig.inputs.in_file = 'tensor_fitted_data.Bdouble'
720831
>>> dteig.run() # doctest: +SKIP
721832
"""
722833
_cmd = 'dteig'
@@ -730,4 +841,5 @@ def _list_outputs(self):
730841

731842
def _gen_outfilename(self):
732843
_, name , _ = split_filename(self.inputs.in_file)
733-
return name + "_Eigen.img" #Need to change to self.inputs.outputdatatype
844+
datatype= self.inputs.outputdatatype
845+
return name + '_eig.B' + datatype

nipype/interfaces/camino/tests/test_auto_ComputeEigensystem.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ def test_ComputeEigensystem_inputs():
1111
),
1212
inputmodel=dict(argstr='-inputmodel %s',
1313
),
14-
outputdatatype=dict(argstr='-outputdatatype %s',
14+
outputdatatype=dict(usedefault=True,
15+
argstr='-outputdatatype %s',
1516
),
1617
args=dict(argstr='%s',
1718
),
18-
inputdatatype=dict(argstr='-inputdatatype %s',
19+
inputdatatype=dict(usedefault=True,
20+
argstr='-inputdatatype %s',
1921
),
20-
maxcomponents=dict(argstr='-maxcomponents %s',
22+
maxcomponents=dict(argstr='-maxcomponents %d',
2123
),
2224
environ=dict(nohash=True,
2325
usedefault=True,
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from nipype.testing import assert_equal
3+
from nipype.interfaces.camino.dti import DTMetric
4+
def test_DTMetric_inputs():
5+
input_map = dict(ignore_exception=dict(nohash=True,
6+
usedefault=True,
7+
),
8+
outputfile=dict(argstr='-outputfile %s',
9+
genfile=True,
10+
),
11+
outputdatatype=dict(usedefault=True,
12+
argstr='-outputdatatype %s',
13+
),
14+
metric=dict(mandatory=True,
15+
argstr='-stat %s',
16+
),
17+
args=dict(argstr='%s',
18+
),
19+
inputdatatype=dict(usedefault=True,
20+
argstr='-inputdatatype %s',
21+
),
22+
terminal_output=dict(mandatory=True,
23+
nohash=True,
24+
),
25+
environ=dict(nohash=True,
26+
usedefault=True,
27+
),
28+
eigen_data=dict(mandatory=True,
29+
argstr='-inputfile %s',
30+
),
31+
data_header=dict(argstr='-header %s',
32+
),
33+
)
34+
inputs = DTMetric.input_spec()
35+
36+
for key, metadata in input_map.items():
37+
for metakey, value in metadata.items():
38+
yield assert_equal, getattr(inputs.traits()[key], metakey), value
39+
def test_DTMetric_outputs():
40+
output_map = dict(metric_stats=dict(),
41+
)
42+
outputs = DTMetric.output_spec()
43+
44+
for key, metadata in output_map.items():
45+
for metakey, value in metadata.items():
46+
yield assert_equal, getattr(outputs.traits()[key], metakey), value

nipype/testing/data/tensor_fitted_data.Bdouble

Whitespace-only changes.

0 commit comments

Comments
 (0)