def predicted_signal(self, bvecs, bvals, axial_diffusivity, radial_diffusivity): """ Compute the fiber contribution to the *relative signal* along its coords. Notes ----- The calculation is based on a simplified Stejskal/Tanner equation: .. math:: \frac{S/S_0} = exp^{-bval (\vec{b}*Q*\vec{b}^T)} Where $S0$ is the unweighted signal and $\vec{b} * Q * \vec{b}^t$ is the ADC for each tensor. To get the diffusion signal measured, you will have to multiply back by the $S_0$ in each voxel. Parameters ---------- """ # Gotta have those tensors: tens = self.tensors(axial_diffusivity, radial_diffusivity) # Preallocate: sig = np.empty((tens.shape[0], len(bvals))) for t_idx, ten in enumerate(tens): ADC = ozt.apparent_diffusion_coef(bvecs, ten.reshape((3, 3))) # Call S/T with the ADC as input: sig[t_idx] = ozt.stejskal_tanner(1, bvals, ADC) return sig
def predict(self, sphere, bvals=None): """ Predict the values of the signal on a novel sphere (not neccesarily measured points) in every voxel Parameters ---------- sphere : 3 x n array """ if self.verbose: print("Predicting signal from TensorModel") if bvals is None: # Assume there's only one b value and you know where to find it: bvals = self.bvals[self.b_idx][0] * np.ones(sphere.shape[-1]) else: # If you gave them as input, you need to scale them: bvals = bvals / float(self.scaling_factor) pred_adc_flat = self.predict_adc(sphere)[self.mask] predict_flat = np.empty(pred_adc_flat.shape) out = ozu.nans(self.signal.shape[:3] + (sphere.shape[-1], )) for ii in xrange(len(predict_flat)): predict_flat[ii] = ozt.stejskal_tanner(self._flat_S0[ii], bvals, pred_adc_flat[ii]) out[self.mask] = predict_flat return out
def predict(self, sphere, bvals=None): """ Predict the values of the signal on a novel sphere (not neccesarily measured points) in every voxel Parameters ---------- sphere : 3 x n array """ if self.verbose: print("Predicting signal from TensorModel") if bvals is None: # Assume there's only one b value and you know where to find it: bvals = self.bvals[self.b_idx][0] * np.ones(sphere.shape[-1]) else: # If you gave them as input, you need to scale them: bvals = bvals/float(self.scaling_factor) pred_adc_flat = self.predict_adc(sphere)[self.mask] predict_flat = np.empty(pred_adc_flat.shape) out = ozu.nans(self.signal.shape[:3] + (sphere.shape[-1], )) for ii in xrange(len(predict_flat)): predict_flat[ii] = ozt.stejskal_tanner(self._flat_S0[ii], bvals, pred_adc_flat[ii]) out[self.mask] = predict_flat return out
def fit(self): if self.verbose: print("Predicting signal from TensorModel") adc_flat = self.model_adc[self.mask] fit_flat = np.empty(adc_flat.shape) out = ozu.nans(self.signal.shape) for ii in xrange(len(fit_flat)): fit_flat[ii] = ozt.stejskal_tanner(self._flat_S0[ii], self.bvals[self.b_idx], adc_flat[ii]) out[self.mask] = fit_flat return out
def fit(self): if self.verbose: print("Predicting signal from TensorModel") adc_flat = self.model_adc[self.mask] fit_flat = np.empty(adc_flat.shape) out = ozu.nans(self.signal.shape) for ii in xrange(len(fit_flat)): fit_flat[ii] = ozt.stejskal_tanner(self._flat_S0[ii], self.bvals[self.b_idx], adc_flat[ii]) out[self.mask] = fit_flat return out
def test_stejskal_tanner(): """ Test the implementation of the S/T equation. """ bvecs = [[1,0,0],[0,1,0],[0,0,1]] bvals = [1,1,1] S0 = 1 ADC = np.random.rand(3) Q = np.diag(ADC) # Calculate explicitely: st = S0 * np.exp(-1 * np.asarray(bvecs).T * Q * np.asarray(bvecs)) # These should give the same answer: npt.assert_equal(mtt.stejskal_tanner(S0, bvals, ADC), np.diag(st))
def test_stejskal_tanner(): """ Test the implementation of the S/T equation. """ bvecs = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] bvals = [1, 1, 1] S0 = 1 ADC = np.random.rand(3) Q = np.diag(ADC) # Calculate explicitely: st = S0 * np.exp(-1 * np.asarray(bvecs).T * Q * np.asarray(bvecs)) # These should give the same answer: npt.assert_equal(mtt.stejskal_tanner(S0, bvals, ADC), np.diag(st))
def predicted_signal(self, bvecs, bvals, axial_diffusivity, radial_diffusivity): """ Compute the fiber contribution to the *relative signal* along its coords. Notes ----- The calculation is based on a simplified Stejskal/Tanner equation: .. math:: \frac{S/S_0} = exp^{-bval (\vec{b}*Q*\vec{b}^T)} Where $S0$ is the unweighted signal and $\vec{b} * Q * \vec{b}^t$ is the ADC for each tensor. To get the diffusion signal measured, you will have to multiply back by the $S_0$ in each voxel. Parameters ---------- """ # Gotta have those tensors: tens = self.tensors(axial_diffusivity, radial_diffusivity) # Preallocate: sig = np.empty((tens.shape[0], len(bvals))) for t_idx, ten in enumerate(tens): ADC = ozt.apparent_diffusion_coef(bvecs, ten.reshape((3,3))) # Call S/T with the ADC as input: sig[t_idx] = ozt.stejskal_tanner(1, bvals, ADC) return sig