@@ -44,6 +44,14 @@ class SimulateMultiTensorInputSpec(BaseInterfaceInputSpec):
44
44
'compartiments' ))
45
45
in_mask = File (exists = True , desc = 'mask to simulate data' )
46
46
47
+ diff_iso = traits .List (
48
+ traits .Float , default = [3000e-6 , 960e-6 , 680e-6 ], usedefault = True ,
49
+ desc = 'Diffusivity of isotropic compartments' )
50
+ diff_sf = traits .Tuple (
51
+ traits .Float , traits .Float , traits .Float ,
52
+ default = (1700e-6 , 200e-6 , 200e-6 ), usedefault = True ,
53
+ desc = 'Single fiber tensor' )
54
+
47
55
n_proc = traits .Int (0 , usedefault = True , desc = 'number of processes' )
48
56
baseline = File (exists = True , mandatory = True , desc = 'baseline T2 signal' )
49
57
gradients = File (exists = True , desc = 'gradients file' )
@@ -129,21 +137,15 @@ def _run_interface(self, runtime):
129
137
# Volume fractions of isotropic compartiments
130
138
vfsim = nb .concat_images ([nb .load (f ) for f in self .inputs .in_vfms ])
131
139
vfs = np .squeeze (vfsim .get_data ()) # volume fractions
140
+ total_vf = np .sum (vfs , axis = 3 )
132
141
133
142
for i in range (vfs .shape [- 1 ]):
134
143
vfs [..., i ] -= total_ff
144
+
135
145
vfs [vfs < 0.0 ] = 0
136
- total_vf = np .sum (vfs , axis = 3 )
137
146
138
147
newhdr = hdr .copy ()
139
148
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
149
148
150
# Generate a mask
149
151
if isdefined (self .inputs .in_mask ):
@@ -183,7 +185,8 @@ def _run_interface(self, runtime):
183
185
np .savetxt (op .abspath (self .inputs .out_bval ), gtab .bvals )
184
186
185
187
snr = self .inputs .snr
186
- args = [tuple ([nsticks , gtab ] + r .tolist ()) for r in args ]
188
+ sf_evals = list (self .inputs .diff_sf )
189
+ args = [tuple ([nsticks , gtab ] + sf_evals + r .tolist ()) for r in args ]
187
190
188
191
n_proc = self .inputs .n_proc
189
192
if n_proc == 0 :
@@ -194,26 +197,27 @@ def _run_interface(self, runtime):
194
197
except TypeError :
195
198
pool = Pool (processes = n_proc )
196
199
200
+ ndirs = len (gtab .bvals )
197
201
iflogger .info (('Starting simulation of %d voxels, %d diffusion'
198
- ' directions.' ) % (len (args ), len (gtab .bvals )))
202
+ ' directions.' ) % (len (args ), ndirs ))
203
+
204
+ signal = np .zeros ((shape [0 ], shape [1 ], shape [2 ], ndirs ))
205
+
206
+ # Simulate balls
207
+ for i , d in enumerate (self .inputs .diff_iso ):
208
+ f0 = vfs [..., i ]
209
+ comp = f0 [..., np .newaxis ] * np .exp (- gtab .bvals * d )
210
+ signal += f0 [..., np .newaxis ] * np .exp (- gtab .bvals * d )
199
211
200
212
# Simulate sticks using dipy
201
213
result = np .array (pool .map (_compute_voxel , args ))
202
-
203
- ndirs = len (gtab .bvals )
204
214
if np .shape (result )[1 ] != ndirs :
205
215
raise RuntimeError (('Computed directions do not match number'
206
216
'of b-values.' ))
217
+ fibers = np .zeros ((shape [0 ], shape [1 ], shape [2 ], ndirs ))
218
+ fibers [msk > 0 ] += result
207
219
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 )
220
+ signal += total_ff [..., np .newaxis ] * fibers
217
221
218
222
if snr > 0 :
219
223
signal [msk > 0 ] = add_noise (signal [msk > 0 ], snr , 1 )
@@ -256,13 +260,12 @@ def _compute_voxel(args):
256
260
.. [Pierpaoli1996] Pierpaoli et al., Diffusion tensor MR imaging
257
261
of the human brain, Radiology 201:637-648. 1996.
258
262
"""
259
- sf_evals = [1700e-6 , 200e-6 , 200e-6 ]
260
-
261
263
nf = args [0 ] # number of fibers
262
264
gtab = args [1 ] # gradient table
265
+ sf_evals = args [2 :5 ] # single fiber eigenvalues
263
266
264
- sst = 2 + nf
265
- ffs = args [2 :sst ] # single fiber fractions
267
+ sst = 5 + nf
268
+ ffs = args [5 :sst ] # single fiber fractions
266
269
267
270
sticks = [tuple (args [sst + i * 3 :sst + 3 + i * 3 ])
268
271
for i in range (0 , nf )]
0 commit comments