Skip to content

Commit 29bb49c

Browse files
committed
base implementation, now the mapper
1 parent cfc0987 commit 29bb49c

File tree

2 files changed

+94
-19
lines changed

2 files changed

+94
-19
lines changed

nipype/interfaces/dipy/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
from .tracks import TrackDensityMap
22
from .tensors import TensorMode
33
from .preprocess import Resample, Denoise
4+
from .simulate import SimulateMultiTensor

nipype/interfaces/dipy/simulate.py

Lines changed: 93 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"""
88

99
from nipype.interfaces.base import (
10-
TraitedSpec, BaseInterface, BaseInterfaceInputSpec, File)
10+
TraitedSpec, BaseInterface, BaseInterfaceInputSpec, File,
11+
InputMultiPath, isdefined)
1112
from nipype.utils.filemanip import split_filename
1213
import os.path as op
1314
import nibabel as nb
@@ -27,23 +28,31 @@
2728
import numpy as np
2829
from dipy.sims.voxel import (multi_tensor,
2930
all_tensor_evecs)
31+
from dipy.core.gradients import GradientTable
3032

3133

3234
class SimulateMultiTensorInputSpec(BaseInterfaceInputSpec):
33-
fibers = InputMultiPath(File(exists=True), mandatory=True,
34-
desc='list of fibers principal directions')
35-
vfractions = File(exists=True, mandatory=True,
36-
desc='volume fractions')
35+
in_dirs = InputMultiPath(File(exists=True), mandatory=True,
36+
desc='list of fibers (principal directions)')
37+
in_frac = InputMultiPath(File(exists=True), mandatory=True,
38+
desc=('volume fraction of each fiber'))
39+
in_vfms = InputMultiPath(File(exists=True), mandatory=True,
40+
desc='volume fraction map')
41+
in_mask = File(exists=True, desc='mask to simulate data')
42+
3743
baseline = File(exists=True, mandatory=True, desc='baseline T2 signal')
3844
gradients = File(exists=True, desc='gradients file')
39-
bvec = File(exists=True, desc='bvecs file')
40-
bval = File(exists=True, desc='bvals file')
45+
bvec = File(exists=True, mandatory=True, desc='bvecs file')
46+
bval = File(exists=True, mandatory=True, desc='bvals file')
4147
out_file = File('sim_dwi.nii.gz', usedefault=True,
4248
desc='output file with fractions to be simluated')
49+
out_mask = File('sim_msk.nii.gz', usedefault=True,
50+
desc='file with the mask simulated')
4351

4452

4553
class SimulateMultiTensorOutputSpec(TraitedSpec):
46-
out_file = File(exists=True)
54+
out_file = File(exists=True, desc='simulated DWIs')
55+
out_mask = File(exists=True, desc='mask file')
4756

4857

4958
class SimulateMultiTensor(BaseInterface):
@@ -57,8 +66,8 @@ class SimulateMultiTensor(BaseInterface):
5766
5867
>>> import nipype.interfaces.dipy as dipy
5968
>>> sim = dipy.SimulateMultiTensor()
60-
>>> sim.inputs.fibers = 'fibers.nii'
61-
>>> sim.inputs.vfractions = 'fractions.nii'
69+
>>> sim.inputs.in_dirs = 'fibers.nii'
70+
>>> sim.inputs.in_frac = 'fractions.nii'
6271
>>> sim.inputs.baseline = 'S0.nii'
6372
>>> sim.inputs.bvecs = 'bvecs'
6473
>>> sim.inputs.bvals = 'bvals'
@@ -68,19 +77,84 @@ class SimulateMultiTensor(BaseInterface):
6877
output_spec = SimulateMultiTensorOutputSpec
6978

7079
def _run_interface(self, runtime):
71-
# Load the 4D image files
72-
img = nb.load(self.inputs.fibers)
73-
fibers = img.get_data()
74-
fractions = nb.load(self.inputs.vfractions).get_data()
75-
affine = img.get_affine()
76-
7780
# Load the baseline b0 signal
78-
b0 = nb.load(self.inputs.baseline).get_data()
81+
b0_im = nb.load(self.inputs.baseline)
82+
hdr = b0_im.get_header()
83+
shape = b0_im.get_shape()
84+
aff = b0_im.get_affine()
85+
b0 = b0_im.get_data().reshape(-1)
86+
87+
ffsim = nb.concat_images([nb.load(f) for f in self.inputs.in_frac])
88+
ffs = np.squeeze(ffsim.get_data()) # fiber fractions
89+
90+
vfsim = nb.concat_images([nb.load(f) for f in self.inputs.in_vfms])
91+
vfs = np.squeeze(vfsim.get_data()) # volume fractions
92+
93+
# Load structural files
94+
thetas = []
95+
phis = []
96+
97+
total_ff = np.sum(ffs, axis=3)
98+
total_vf = np.sum(vfs, axis=3)
99+
100+
msk = np.zeros(shape, dtype=np.uint8)
101+
msk[(total_vf > 0.0) & (total_ff > 0.0)] = 1
102+
103+
if isdefined(self.inputs.in_mask):
104+
msk = nb.load(self.inputs.in_mask).get_data()
105+
msk[msk > 0.0] = 1.0
106+
msk[msk < 1.0] = 0.0
107+
108+
mhdr = hdr.copy()
109+
mhdr.set_data_dtype(np.uint8)
110+
mhdr.set_xyzt_units('mm', 'sec')
111+
nb.Nifti1Image(msk, aff, mhdr).to_filename(
112+
op.abspath(self.inputs.out_mask))
113+
114+
for f in self.inputs.in_dirs:
115+
fd = nb.load(f).get_data()
116+
x = fd[msk > 0][..., 0]
117+
y = fd[msk > 0][..., 1]
118+
z = fd[msk > 0][..., 2]
119+
th = np.arccos(z / np.sqrt(x ** 2 + y ** 2 + z ** 2))
120+
ph = np.arctan2(y, x)
121+
thetas.append(th)
122+
phis.append(ph)
79123

80124
# Load the gradient strengths and directions
81-
bvals = np.loadtxt(self.inputs.bvals)
82-
gradients = np.loadtxt(self.inputs.bvecs).T
125+
bvals = np.loadtxt(self.inputs.bval)
126+
gradients = np.loadtxt(self.inputs.bvec).T
83127

84128
# Place in Dipy's preferred format
85129
gtab = GradientTable(gradients)
86130
gtab.bvals = bvals
131+
132+
return runtime
133+
134+
def _list_outputs(self):
135+
outputs = self._outputs().get()
136+
outputs['out_file'] = op.abspath(self.inputs.out_file)
137+
outputs['out_mask'] = op.abspath(self.inputs.out_mask)
138+
return outputs
139+
140+
141+
def _compute_voxel(vfs, ffs, ths, phs, S0, gtab, snr=None,
142+
csf_evals=[0.0015, 0.0015, 0.0015],
143+
gm_evals=[0.0007, 0.0007, 0.0007],
144+
wm_evals=[0.0015, 0.0003, 0.0003]):
145+
146+
nf = len(ffs)
147+
total_ff = np.sum(ffs)
148+
149+
gm_vf = vfs[1] * (1 - total_ff) / (vfs[0] + vfs[1])
150+
ffs.insert(0, gm_vf)
151+
csf_vf = vfs[0] * (1 - total_ff) / (vfs[0] + vfs[1])
152+
ffs.insert(0, csf_vf)
153+
angles = [(0, 0), (0, 0)] # angles of gm and csf
154+
angles += [(th, ph) for ph, th in zip(ths, phs)]
155+
156+
mevals = np.array([csf_evals, gm_evals] + [wm_evals] * nf)
157+
ffs = np.array(ffs) * 100
158+
signal, sticks = multi_tensor(gtab, mevals, S0=S0, angles=angles,
159+
fractions=ffs, snr=snr)
160+
return signal, sticks

0 commit comments

Comments
 (0)