@@ -103,6 +103,19 @@ class SimulateMultiTensor(BaseInterface):
103
103
output_spec = SimulateMultiTensorOutputSpec
104
104
105
105
def _run_interface (self , runtime ):
106
+ # Gradient table
107
+ if isdefined (self .inputs .in_bval ) and isdefined (self .inputs .in_bvec ):
108
+ # Load the gradient strengths and directions
109
+ bvals = np .loadtxt (self .inputs .in_bval )
110
+ bvecs = np .loadtxt (self .inputs .in_bvec ).T
111
+ gtab = gradient_table (bvals , bvecs )
112
+ else :
113
+ gtab = _generate_gradients (self .inputs .num_dirs ,
114
+ self .inputs .bvalues )
115
+ ndirs = len (gtab .bvals )
116
+ np .savetxt (op .abspath (self .inputs .out_bvec ), gtab .bvecs .T )
117
+ np .savetxt (op .abspath (self .inputs .out_bval ), gtab .bvals )
118
+
106
119
# Load the baseline b0 signal
107
120
b0_im = nb .load (self .inputs .baseline )
108
121
hdr = b0_im .get_header ()
@@ -135,17 +148,20 @@ def _run_interface(self, runtime):
135
148
total_ff = np .sum (ffs , axis = 3 )
136
149
137
150
# Volume fractions of isotropic compartiments
138
- vfsim = nb .concat_images ([nb .load (f ) for f in self .inputs .in_vfms ])
139
- vfs = np .squeeze (vfsim .get_data ()) # volume fractions
140
- total_vf = np .sum (vfs , axis = 3 )
151
+ nballs = len (self .inputs .in_vfms )
152
+ vfs = np .squeeze (nb .concat_images ([nb .load (f ) for f in self .inputs .in_vfms ]).get_data ())
153
+ if nsticks == 1 :
154
+ vfs = vfs [..., np .newaxis ]
155
+
141
156
142
157
for i in range (vfs .shape [- 1 ]):
143
158
vfs [..., i ] -= total_ff
144
-
145
159
vfs [vfs < 0.0 ] = 0
146
160
147
- newhdr = hdr .copy ()
148
- newhdr .set_data_dtype (np .float32 )
161
+ fractions = np .concatenate ((ffs , vfs ), axis = 3 )
162
+ total_vf = np .sum (fractions , axis = 3 )
163
+ nb .Nifti1Image (fractions , aff , None ).to_filename ('fractions.nii.gz' )
164
+ nb .Nifti1Image (total_vf , aff , None ).to_filename ('total_vf.nii.gz' )
149
165
150
166
# Generate a mask
151
167
if isdefined (self .inputs .in_mask ):
@@ -156,37 +172,40 @@ def _run_interface(self, runtime):
156
172
msk = np .zeros (shape , dtype = np .uint8 )
157
173
msk [total_vf > 0.0 ] = 1
158
174
175
+ nvox = len (mask [mask > 0 ])
176
+
159
177
mhdr = hdr .copy ()
160
178
mhdr .set_data_dtype (np .uint8 )
161
179
mhdr .set_xyzt_units ('mm' , 'sec' )
162
180
nb .Nifti1Image (msk , aff , mhdr ).to_filename (
163
181
op .abspath (self .inputs .out_mask ))
164
182
165
183
# Initialize stack of args
166
- args = ffs [msk > 0 ]. copy ()
184
+ fracs = fractions [msk > 0 ]
167
185
168
186
# Stack directions
187
+ dirs = None
169
188
for f in self .inputs .in_dirs :
170
189
fd = nb .load (f ).get_data ()
171
- args = np .hstack ((args , fd [msk > 0 ]))
190
+ if dirs is None :
191
+ dirs = fd [msk > 0 ].copy ()
192
+ else :
193
+ dirs = np .hstack ((dirs , fd [msk > 0 ]))
172
194
173
- if isdefined (self .inputs .in_bval ) and isdefined (self .inputs .in_bvec ):
174
- # Load the gradient strengths and directions
175
- bvals = np .loadtxt (self .inputs .in_bval )
176
- bvecs = np .loadtxt (self .inputs .in_bvec ).T
177
195
178
- # Place in Dipy's preferred format
179
- gtab = gradient_table (bvals , bvecs )
180
- else :
181
- gtab = _generate_gradients (self .inputs .num_dirs ,
182
- self .inputs .bvalues )
196
+ sf_evals = list (self .inputs .diff_sf )
197
+ ba_evals = self .inputs .diff_iso
183
198
184
- np .savetxt (op .abspath (self .inputs .out_bvec ), gtab .bvecs .T )
185
- np .savetxt (op .abspath (self .inputs .out_bval ), gtab .bvals )
199
+ args = []
200
+ for i in range (nvox ):
201
+ args .append (
202
+ {'fractions' : fracs [i , ...].tolist (),
203
+ 'sticks' : [(1.0 , 0.0 , 0.0 )] * nballs + dirs [i , ...].tolist (),
204
+ 'gradients' : gtab ,
205
+ 'mevals' : [[ba_evals [d ]* 3 ] for d in range (nballs )] + [sf_evals ] * nsticks
206
+ })
186
207
187
- snr = self .inputs .snr
188
- sf_evals = list (self .inputs .diff_sf )
189
- args = [tuple ([nsticks , gtab ] + sf_evals + r .tolist ()) for r in args ]
208
+ print args [:5 ]
190
209
191
210
n_proc = self .inputs .n_proc
192
211
if n_proc == 0 :
@@ -197,30 +216,20 @@ def _run_interface(self, runtime):
197
216
except TypeError :
198
217
pool = Pool (processes = n_proc )
199
218
200
- ndirs = len (gtab .bvals )
201
- iflogger .info (('Starting simulation of %d voxels, %d diffusion'
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 )
211
-
212
219
# Simulate sticks using dipy
220
+ iflogger .info (('Starting simulation of %d voxels, %d diffusion'
221
+ ' directions.' ) % (len (args ), ndirs ))
213
222
result = np .array (pool .map (_compute_voxel , args ))
214
223
if np .shape (result )[1 ] != ndirs :
215
224
raise RuntimeError (('Computed directions do not match number'
216
225
'of b-values.' ))
217
- fibers = np .zeros ((shape [0 ], shape [1 ], shape [2 ], ndirs ))
218
- fibers [msk > 0 ] += result
219
226
220
- signal += total_ff [..., np .newaxis ] * fibers
227
+ signal = np .zeros ((shape [0 ], shape [1 ], shape [2 ], ndirs ))
228
+ signal [msk > 0 ] += result
221
229
222
- if snr > 0 :
223
- signal [msk > 0 ] = add_noise (signal [msk > 0 ], snr , 1 )
230
+ # Add noise
231
+ if self .inputs .snr > 0 :
232
+ signal [msk > 0 ] = add_noise (signal [msk > 0 ], self .inputs .snr , 1 )
224
233
225
234
# S0
226
235
b0 = b0_im .get_data ()
@@ -260,24 +269,19 @@ def _compute_voxel(args):
260
269
.. [Pierpaoli1996] Pierpaoli et al., Diffusion tensor MR imaging
261
270
of the human brain, Radiology 201:637-648. 1996.
262
271
"""
263
- nf = args [0 ] # number of fibers
264
- gtab = args [1 ] # gradient table
265
- sf_evals = args [2 :5 ] # single fiber eigenvalues
266
-
267
- sst = 5 + nf
268
- ffs = args [5 :sst ] # single fiber fractions
269
272
270
- sticks = [ tuple ( args [sst + i * 3 : sst + 3 + i * 3 ])
271
- for i in range ( 0 , nf ) ]
273
+ ffs = args ['fractions' ]
274
+ gtab = args [ 'gradients' ]
272
275
273
- mevals = [sf_evals ] * nf
274
276
sf_vf = np .sum (ffs )
275
277
276
278
# Simulate sticks
277
279
if sf_vf > 1.0e-3 :
278
280
ffs = ((np .array (ffs ) / sf_vf ) * 100 )
279
- signal , _ = multi_tensor (gtab , np .array (mevals ), S0 = 1.0 ,
280
- angles = sticks , fractions = ffs , snr = None )
281
+ signal , _ = multi_tensor (gtab , args ['mevals' ], S0 = 1.0 ,
282
+ angles = args ['sticks' ],
283
+ fractions = ffs ,
284
+ snr = None )
281
285
else :
282
286
signal = np .zeros_like (gtab .bvals , dtype = np .float32 )
283
287
0 commit comments