Skip to content

Commit 5191e8c

Browse files
committed
Merge branch 'enh/tensor_mode'
2 parents 9e23f15 + 97f460e commit 5191e8c

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

CHANGES

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

4-
* ENH: New interfaces: nipy.Trim, fsl.GLM, fsl.SigLoss, spm.VBMSegment, fsl.InvWarp
4+
* ENH: New interfaces: nipy.Trim, fsl.GLM, fsl.SigLoss, spm.VBMSegment, fsl.InvWarp,
5+
dipy.TensorMode
56
* ENH: Allow control over terminal output for commandline interfaces
67
* ENH: Added preliminary support for generating Python code from Workflows.
78
* ENH: New workflows for dMRI and fMRI pre-processing: added motion artifact correction

nipype/interfaces/dipy/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from .tracks import TrackDensityMap
2+
from .tensors import TensorMode

nipype/interfaces/dipy/tensors.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# -*- coding: utf-8 -*-
2+
"""Change directory to provide relative paths for doctests
3+
>>> import os
4+
>>> filepath = os.path.dirname( os.path.realpath( __file__ ) )
5+
>>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data'))
6+
>>> os.chdir(datadir)
7+
"""
8+
9+
from nipype.interfaces.base import (
10+
TraitedSpec, BaseInterface, File)
11+
from nipype.utils.filemanip import split_filename
12+
import os.path as op
13+
import nibabel as nb
14+
import numpy as np
15+
from nipype.utils.misc import package_check
16+
import warnings
17+
18+
from ... import logging
19+
iflogger = logging.getLogger('interface')
20+
21+
try:
22+
package_check('dipy', version='0.7.0')
23+
import dipy.reconst.dti as dti
24+
from dipy.core.gradients import GradientTable
25+
except Exception, e:
26+
warnings.warn('dipy not installed')
27+
28+
29+
class TensorModeInputSpec(TraitedSpec):
30+
in_file = File(exists=True, mandatory=True,
31+
desc='The input 4D diffusion-weighted image file')
32+
bvecs = File(exists=True, mandatory=True,
33+
desc='The input b-vector text file')
34+
bvals = File(exists=True, mandatory=True,
35+
desc='The input b-value text file')
36+
out_filename = File(
37+
genfile=True, desc='The output filename for the Tensor mode image')
38+
39+
40+
class TensorModeOutputSpec(TraitedSpec):
41+
out_file = File(exists=True)
42+
43+
44+
class TensorMode(BaseInterface):
45+
"""
46+
Creates a map of the mode of the diffusion tensors given a set of
47+
diffusion-weighted images, as well as their associated b-values and
48+
b-vectors. Fits the diffusion tensors and calculates tensor mode
49+
with Dipy.
50+
51+
.. [1] Daniel B. Ennis and G. Kindlmann, "Orthogonal Tensor
52+
Invariants and the Analysis of Diffusion Tensor Magnetic Resonance
53+
Images", Magnetic Resonance in Medicine, vol. 55, no. 1, pp. 136-146,
54+
2006.
55+
56+
Example
57+
-------
58+
59+
>>> import nipype.interfaces.dipy as dipy
60+
>>> mode = dipy.TensorMode()
61+
>>> mode.inputs.in_file = 'diffusion.nii'
62+
>>> mode.inputs.bvecs = 'bvecs'
63+
>>> mode.inputs.bvals = 'bvals'
64+
>>> mode.run() # doctest: +SKIP
65+
"""
66+
input_spec = TensorModeInputSpec
67+
output_spec = TensorModeOutputSpec
68+
69+
def _run_interface(self, runtime):
70+
## Load the 4D image files
71+
img = nb.load(self.inputs.in_file)
72+
data = img.get_data()
73+
affine = img.get_affine()
74+
75+
## Load the gradient strengths and directions
76+
bvals = np.loadtxt(self.inputs.bvals)
77+
gradients = np.loadtxt(self.inputs.bvecs).T
78+
79+
## Place in Dipy's preferred format
80+
gtab = GradientTable(gradients)
81+
gtab.bvals = bvals
82+
83+
## Mask the data so that tensors are not fit for
84+
## unnecessary voxels
85+
mask = data[..., 0] > 50
86+
87+
## Fit the tensors to the data
88+
tenmodel = dti.TensorModel(gtab)
89+
tenfit = tenmodel.fit(data, mask)
90+
91+
## Calculate the mode of each voxel's tensor
92+
mode_data = tenfit.mode
93+
94+
## Write as a 3D Nifti image with the original affine
95+
img = nb.Nifti1Image(mode_data, affine)
96+
out_file = op.abspath(self._gen_outfilename())
97+
nb.save(img, out_file)
98+
iflogger.info('Tensor mode image saved as {i}'.format(i=out_file))
99+
return runtime
100+
101+
def _list_outputs(self):
102+
outputs = self._outputs().get()
103+
outputs['out_file'] = op.abspath(self._gen_outfilename())
104+
return outputs
105+
106+
def _gen_filename(self, name):
107+
if name is 'out_filename':
108+
return self._gen_outfilename()
109+
else:
110+
return None
111+
112+
def _gen_outfilename(self):
113+
_, name, _ = split_filename(self.inputs.in_file)
114+
return name + '_mode.nii'

0 commit comments

Comments
 (0)