Skip to content

Commit 53b602e

Browse files
committed
remove isotropic compartiments from parallelization
1 parent 0ef93e8 commit 53b602e

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

nipype/interfaces/dipy/simulate.py

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,42 @@ def _run_interface(self, runtime):
109109

110110
ffsim = nb.concat_images([nb.load(f) for f in self.inputs.in_frac])
111111
ffs = np.squeeze(ffsim.get_data()) # fiber fractions
112+
ffs[ffs > 1.0] = 1.0
113+
ffs[ffs < 0.0] = 0.0
114+
112115
if nsticks == 1:
113116
ffs = ffs[..., np.newaxis]
114117

118+
total_ff = np.sum(ffs, axis=3)
119+
120+
# Fix incongruencies in fiber fractions
121+
for i in range(1, nsticks):
122+
if np.any(total_ff > 1.0):
123+
errors = np.zeros_like(total_ff)
124+
errors[total_ff > 1.0] = total_ff[total_ff > 1.0] - 1.0
125+
ffs[..., i] -= errors
126+
ffs[ffs < 0.0] = 0.0
127+
total_ff = np.sum(ffs, axis=3)
128+
115129
# Volume fractions of isotropic compartiments
116130
vfsim = nb.concat_images([nb.load(f) for f in self.inputs.in_vfms])
117131
vfs = np.squeeze(vfsim.get_data()) # volume fractions
118132

119-
total_ff = np.sum(ffs, axis=3)
133+
for i in range(vfs.shape[-1]):
134+
vfs[..., i] -= total_ff
135+
vfs[vfs < 0.0] = 0
120136
total_vf = np.sum(vfs, axis=3)
121137

138+
newhdr = hdr.copy()
139+
newhdr.set_data_dtype(np.float32)
140+
for i in range(vfs.shape[-1]):
141+
nb.Nifti1Image(vfs[..., i].astype(np.float32), aff,
142+
newhdr).to_filename('vf_iso%02d.nii.gz' % i)
143+
144+
for i in range(ffs.shape[-1]):
145+
nb.Nifti1Image(ffs[..., i].astype(np.float32), aff,
146+
newhdr).to_filename('vf_ani%02d.nii.gz' % i)
147+
122148
# Generate a mask
123149
if isdefined(self.inputs.in_mask):
124150
msk = nb.load(self.inputs.in_mask).get_data()
@@ -135,7 +161,7 @@ def _run_interface(self, runtime):
135161
op.abspath(self.inputs.out_mask))
136162

137163
# Initialize stack of args
138-
args = np.hstack((vfs[msk > 0], ffs[msk > 0]))
164+
args = ffs[msk > 0].copy()
139165

140166
# Stack directions
141167
for f in self.inputs.in_dirs:
@@ -157,7 +183,7 @@ def _run_interface(self, runtime):
157183
np.savetxt(op.abspath(self.inputs.out_bval), gtab.bvals)
158184

159185
snr = self.inputs.snr
160-
args = [tuple([nsticks, gtab, snr] + r.tolist()) for r in args]
186+
args = [tuple([nsticks, gtab] + r.tolist()) for r in args]
161187

162188
n_proc = self.inputs.n_proc
163189
if n_proc == 0:
@@ -171,25 +197,36 @@ def _run_interface(self, runtime):
171197
iflogger.info(('Starting simulation of %d voxels, %d diffusion'
172198
' directions.') % (len(args), len(gtab.bvals)))
173199

200+
# Simulate sticks using dipy
174201
result = np.array(pool.map(_compute_voxel, args))
175202

176203
ndirs = len(gtab.bvals)
177204
if np.shape(result)[1] != ndirs:
178205
raise RuntimeError(('Computed directions do not match number'
179206
'of b-values.'))
180207

181-
simulated = np.zeros((shape[0], shape[1], shape[2], ndirs))
182-
simulated[msk > 0] = result
208+
signal = np.zeros((shape[0], shape[1], shape[2], ndirs))
209+
signal[msk > 0] = result
210+
211+
# Simulate balls
212+
D_ball = [3000e-6, 960e-6, 680e-6]
213+
214+
for i in range(ndirs):
215+
for f0, d in zip(vfs, D_ball):
216+
signal += f0 * np.exp(-gtab.bvals * d)
217+
218+
if snr > 0:
219+
signal[msk > 0] = add_noise(signal[msk > 0], snr, 1)
183220

184221
# S0
185222
b0 = b0_im.get_data()
186223
for i in xrange(ndirs):
187-
simulated[..., i] *= b0
224+
signal[..., i] *= b0
188225

189226
simhdr = hdr.copy()
190227
simhdr.set_data_dtype(np.float32)
191228
simhdr.set_xyzt_units('mm', 'sec')
192-
nb.Nifti1Image(simulated.astype(np.float32), aff,
229+
nb.Nifti1Image(signal.astype(np.float32), aff,
193230
simhdr).to_filename(op.abspath(self.inputs.out_file))
194231

195232
return runtime
@@ -219,18 +256,13 @@ def _compute_voxel(args):
219256
.. [Pierpaoli1996] Pierpaoli et al., Diffusion tensor MR imaging
220257
of the human brain, Radiology 201:637-648. 1996.
221258
"""
222-
D_ball = [3000e-6, 960e-6, 680e-6]
223259
sf_evals = [1700e-6, 200e-6, 200e-6]
224260

225261
nf = args[0] # number of fibers
226262
gtab = args[1] # gradient table
227-
snr = args[2]
228-
vfs = args[3:6]
229-
230-
vfs = (np.array(vfs) / np.sum(vfs))
231263

232-
sst = 6 + nf
233-
ffs = args[6:sst] # single fiber fractions
264+
sst = 2 + nf
265+
ffs = args[2:sst] # single fiber fractions
234266

235267
sticks = [tuple(args[sst + i * 3:sst + 3 + i * 3])
236268
for i in range(0, nf)]
@@ -246,16 +278,6 @@ def _compute_voxel(args):
246278
else:
247279
signal = np.zeros_like(gtab.bvals, dtype=np.float32)
248280

249-
signal *= vfs[2] * sf_vf
250-
251-
# Simulate balls
252-
vfs[2] *= (1 - sf_vf)
253-
for f0, d in zip(vfs, D_ball):
254-
signal += f0 * np.exp(-gtab.bvals * d)
255-
256-
if snr > 0:
257-
signal = add_noise(signal, snr, 1)
258-
259281
return signal.tolist()
260282

261283

0 commit comments

Comments
 (0)