Skip to content

Commit 84c360f

Browse files
committed
NF: First pass at a dipy DTI interface.
1 parent 73f3a73 commit 84c360f

File tree

3 files changed

+114
-12
lines changed

3 files changed

+114
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
.pydevproject
1515
.idea/
1616
/documentation.zip
17+
.DS_Store

nipype/interfaces/dipy/tensors.py

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,93 @@
2525
have_dipy = False
2626
else:
2727
import dipy.reconst.dti as dti
28-
from dipy.core.gradients import GradientTable
28+
from dipy.core.gradients import gradient_table
29+
from dipy.io.utils import nifti1_symmat
2930

3031

32+
class DTIInputSpec(TraitedSpec):
33+
in_file = File(exists=True, mandatory=True,
34+
desc='The input 4D diffusion-weighted image file')
35+
bvecs = File(exists=True, mandatory=True,
36+
desc='The input b-vector text file')
37+
bvals = File(exists=True, mandatory=True,
38+
desc='The input b-value text file')
39+
mask_file = File(exists=True, mandatory=False,
40+
desc='An optional white matter mask')
41+
out_filename = File(
42+
genfile=True, desc='The output filename for the DTI parameters image')
43+
44+
45+
class DTIOutputSpec(TraitedSpec):
46+
out_file = File(exists=True)
47+
48+
49+
class DTI(BaseInterface):
50+
"""
51+
Calculates the diffusion tensor model parameters
52+
53+
Example
54+
-------
55+
56+
>>> import nipype.interfaces.dipy as dipy
57+
>>> mode = dipy.DTI()
58+
>>> mode.inputs.in_file = 'diffusion.nii'
59+
>>> mode.inputs.bvecs = 'bvecs'
60+
>>> mode.inputs.bvals = 'bvals'
61+
>>> mode.inputs.mask_file = 'wm_mask.nii'
62+
>>> mode.run() # doctest: +SKIP
63+
"""
64+
input_spec = DTIInputSpec
65+
output_spec = DTIOutputSpec
66+
67+
def _run_interface(self, runtime):
68+
## Load the 4D image files
69+
img = nb.load(self.inputs.in_file)
70+
data = img.get_data()
71+
affine = img.get_affine()
72+
mask = nb.load(self.inputs.mask_file).get_data()
73+
74+
# Load information about the gradients:
75+
gtab = grad.gradient_table(self.inputs.bvals, self.inputs.bvecs)
76+
gtab.bvals = bvals
77+
78+
# Fit it
79+
tenmodel = dti.TensorModel(gtab)
80+
tenfit = tenmodel.fit(data, mask)
81+
82+
lower_triangular = tenfit.lower_triangular()
83+
lower_triangular *= opts.scale
84+
img = nifti1_symmat(lower_triangular, affine)
85+
out_file = op.abspath(self._gen_outfilename())
86+
nb.save(img, out_file)
87+
iflogger.info('DTI parameters image saved as {i}'.format(i=out_file))
88+
return runtime
89+
90+
def _list_outputs(self):
91+
outputs = self._outputs().get()
92+
outputs['out_file'] = op.abspath(self._gen_outfilename())
93+
return outputs
94+
95+
def _gen_filename(self, name):
96+
if name is 'out_filename':
97+
return self._gen_outfilename()
98+
else:
99+
return None
100+
101+
def _gen_outfilename(self):
102+
_, name, _ = split_filename(self.inputs.in_file)
103+
return name + '_dti.nii'
104+
105+
31106
class TensorModeInputSpec(TraitedSpec):
32107
in_file = File(exists=True, mandatory=True,
33108
desc='The input 4D diffusion-weighted image file')
34109
bvecs = File(exists=True, mandatory=True,
35110
desc='The input b-vector text file')
36111
bvals = File(exists=True, mandatory=True,
37112
desc='The input b-value text file')
113+
mask_file = File(exists=True, mandatory=False,
114+
desc='An optional white matter mask')
38115
out_filename = File(
39116
genfile=True, desc='The output filename for the Tensor mode image')
40117

@@ -63,6 +140,7 @@ class TensorMode(BaseInterface):
63140
>>> mode.inputs.in_file = 'diffusion.nii'
64141
>>> mode.inputs.bvecs = 'bvecs'
65142
>>> mode.inputs.bvals = 'bvals'
143+
>>> mode.inputs.mask = 'wm_mask.nii'
66144
>>> mode.run() # doctest: +SKIP
67145
"""
68146
input_spec = TensorModeInputSpec
@@ -73,18 +151,10 @@ def _run_interface(self, runtime):
73151
img = nb.load(self.inputs.in_file)
74152
data = img.get_data()
75153
affine = img.get_affine()
154+
mask = nb.load(self.inputs.mask_file).get_data()
76155

77-
## Load the gradient strengths and directions
78-
bvals = np.loadtxt(self.inputs.bvals)
79-
gradients = np.loadtxt(self.inputs.bvecs).T
80-
81-
## Place in Dipy's preferred format
82-
gtab = GradientTable(gradients)
83-
gtab.bvals = bvals
84-
85-
## Mask the data so that tensors are not fit for
86-
## unnecessary voxels
87-
mask = data[..., 0] > 50
156+
## Load the gradients
157+
bvals = grad.gradient_table(self.inputs.bvals, self.inputs.bvecs)
88158

89159
## Fit the tensors to the data
90160
tenmodel = dti.TensorModel(gtab)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from nipype.testing import assert_equal
3+
from nipype.interfaces.dipy.tensors import DTI
4+
5+
def test_DTI_inputs():
6+
input_map = dict(bvals=dict(mandatory=True,
7+
),
8+
bvecs=dict(mandatory=True,
9+
),
10+
in_file=dict(mandatory=True,
11+
),
12+
mask_file=dict(mandatory=False,
13+
),
14+
out_filename=dict(genfile=True,
15+
),
16+
)
17+
inputs = DTI.input_spec()
18+
19+
for key, metadata in input_map.items():
20+
for metakey, value in metadata.items():
21+
yield assert_equal, getattr(inputs.traits()[key], metakey), value
22+
23+
def test_DTI_outputs():
24+
output_map = dict(out_file=dict(),
25+
)
26+
outputs = DTI.output_spec()
27+
28+
for key, metadata in output_map.items():
29+
for metakey, value in metadata.items():
30+
yield assert_equal, getattr(outputs.traits()[key], metakey), value
31+

0 commit comments

Comments
 (0)