def _run_interface(self, runtime): ## Load the 4D image files img = nb.load(self.inputs.in_file) data = img.get_data() affine = img.get_affine() ## Load the gradient strengths and directions bvals = np.loadtxt(self.inputs.bvals) gradients = np.loadtxt(self.inputs.bvecs).T ## Place in Dipy's preferred format gtab = GradientTable(gradients) gtab.bvals = bvals ## Mask the data so that tensors are not fit for ## unnecessary voxels mask = data[..., 0] > 50 ## Fit the tensors to the data tenmodel = dti.TensorModel(gtab) tenfit = tenmodel.fit(data, mask) ## Calculate the mode of each voxel's tensor mode_data = tenfit.mode ## Write as a 3D Nifti image with the original affine img = nb.Nifti1Image(mode_data, affine) out_file = op.abspath(self._gen_outfilename()) nb.save(img, out_file) iflogger.info('Tensor mode image saved as {i}'.format(i=out_file)) return runtime
return A * B directions, values = peak_directions_nl(discrete_eval, 0.) assert_equal(directions.shape, (3, 3)) directions, values = peak_directions_nl(discrete_eval, .6) assert_equal(directions.shape, (2, 3)) directions, values = peak_directions_nl(discrete_eval, .8) assert_equal(directions.shape, (1, 3)) assert_almost_equal(values, 3 * 3 / np.sqrt(3)) _sphere = create_unit_hemisphere(4) _odf = (_sphere.vertices * [1, 2, 3]).sum(-1) _gtab = GradientTable(np.ones((64, 3))) class SimpleOdfModel(OdfModel): sphere = _sphere def fit(self, data): fit = SimpleOdfFit(self, data) fit.model = self return fit class SimpleOdfFit(OdfFit): def odf(self, sphere=None): if sphere is None: sphere = self.model.sphere
def test_GradientTable_btensor_calculation(): # Generate a gradient table without specifying b-tensors gradients = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1], [3, 4, 0], [5, 0, 12]], 'float') # Check that no btens are created unless specified gt = GradientTable(gradients) npt.assert_equal(hasattr(gt, 'btens'), False) # Check that btens are correctly created if specified gt = GradientTable(gradients, btens='LTE') # Check that the number of b tensors is correct npt.assert_equal(gt.btens.shape[0], gt.bvals.shape[0]) for i, (bval, bten) in enumerate(zip(gt.bvals, gt.btens)): # Check that the b tensor magnitude is correct npt.assert_almost_equal(np.trace(bten), bval) # Check that the b tensor orientation is correct if bval != 0: evals, evecs = np.linalg.eig(bten) dot_prod = np.dot(np.real(evecs[:, np.argmax(evals)]), gt.bvecs[i]) npt.assert_almost_equal(np.abs(dot_prod), 1) # Check btens input option 1 for btens in ['LTE', 'PTE', 'STE', 'CTE']: gt = GradientTable(gradients, btens=btens) # Check that the number of b tensors is correct npt.assert_equal(gt.bvals.shape[0], gt.btens.shape[0]) for i, (bval, bvec, bten) in enumerate(zip(gt.bvals, gt.bvecs, gt.btens)): # Check that the b tensor magnitude is correct npt.assert_almost_equal(np.trace(bten), bval) # Check that the b tensor orientation is correct if btens == ('LTE' or 'CTE'): if bval != 0: evals, evecs = np.linalg.eig(bten) dot_prod = np.dot(np.real(evecs[:, np.argmax(evals)]), bvec) npt.assert_almost_equal(np.abs(dot_prod), 1) elif btens == 'PTE': if bval != 0: evals, evecs = np.linalg.eig(bten) dot_prod = np.dot(np.real(evecs[:, np.argmin(evals)]), bvec) npt.assert_almost_equal(np.abs(dot_prod), 1) # Check btens input option 2 btens = np.array(['LTE', 'PTE', 'STE', 'CTE', 'LTE', 'PTE']) gt = GradientTable(gradients, btens=btens) # Check that the number of b tensors is correct npt.assert_equal(gt.bvals.shape[0], gt.btens.shape[0]) for i, (bval, bvec, bten) in enumerate(zip(gt.bvals, gt.bvecs, gt.btens)): # Check that the b tensor magnitude is correct npt.assert_almost_equal(np.trace(bten), bval) # Check that the b tensor orientation is correct if btens[i] == ('LTE' or 'CTE'): if bval != 0: evals, evecs = np.linalg.eig(bten) dot_prod = np.dot(np.real(evecs[:, np.argmax(evals)]), bvec) npt.assert_almost_equal(np.abs(dot_prod), 1) elif btens[i] == 'PTE': if bval != 0: evals, evecs = np.linalg.eig(bten) dot_prod = np.dot(np.real(evecs[:, np.argmin(evals)]), bvec) npt.assert_almost_equal(np.abs(dot_prod), 1) # Check btens input option 3 btens = np.array([np.eye(3, 3) for i in range(6)]) gt = GradientTable(gradients, btens=btens) npt.assert_equal(btens, gt.btens) npt.assert_equal(gt.bvals.shape[0], gt.btens.shape[0]) # Check invalid input npt.assert_raises(ValueError, GradientTable, gradients=gradients, btens='PPP') npt.assert_raises(ValueError, GradientTable, gradients=gradients, btens=np.array([np.eye(3, 3) for i in range(10)])) npt.assert_raises(ValueError, GradientTable, gradients=gradients, btens=np.zeros((10, 10)))
def gtab_getter(): gradfile = pjoin(THIS_DIR, filename) grad = np.loadtxt(gradfile, delimiter=',') gtab = GradientTable(grad) return gtab
#!/usr/bin/env python # -*- coding: utf-8 -*- """Tests for `bonndit.gradients` module.""" from bonndit.utils.gradients import gtab_reorient, gtab_rotate from dipy.core.gradients import GradientTable import numpy as np GRADIENTS = np.array([[2500, 0, 0], [0, 2500, 0], [0, 0, 2500], [0, 0, 0]]) gtab = GradientTable(GRADIENTS) def test_gtab_rotate(): rot_matrix = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) assert (gtab_rotate(gtab, rot_matrix).gradients == GRADIENTS).all() def test_gtab_rotate2(): rot_matrix = np.array([[1, 0, 1], [0, 1, 0], [0, 0, 0]]) assert (gtab_rotate(gtab, rot_matrix).gradients == np.array([[2500, 0, 0], [0, 2500, 0], [2500, 0, 0], [0, 0, 0]])).all() def test_gtab_reorient(): old_vec = np.array((0, 0, 1)) new_vec = np.array((0, 0, 1)) assert (gtab_reorient(gtab, old_vec, new_vec).gradients == GRADIENTS).all()
def multi_shell_fiber_response(sh_order, bvals, wm_rf, gm_rf, csf_rf, sphere=None, tol=20): """Fiber response function estimation for multi-shell data. Parameters ---------- sh_order : int Maximum spherical harmonics order. bvals : ndarray Array containing the b-values. Must be unique b-values, like outputed by `dipy.core.gradients.unique_bvals_tolerance`. wm_rf : (4, len(bvals)) ndarray Response function of the WM tissue, for each bvals. gm_rf : (4, len(bvals)) ndarray Response function of the GM tissue, for each bvals. csf_rf : (4, len(bvals)) ndarray Response function of the CSF tissue, for each bvals. sphere : `dipy.core.Sphere` instance, optional Sphere where the signal will be evaluated. Returns ------- MultiShellResponse MultiShellResponse object. """ NUMPY_1_14_PLUS = LooseVersion(np.__version__) >= LooseVersion('1.14.0') rcond_value = None if NUMPY_1_14_PLUS else -1 bvals = np.array(bvals, copy=True) evecs = np.zeros((3, 3)) z = np.array([0, 0, 1.]) evecs[:, 0] = z evecs[:2, 1:] = np.eye(2) n = np.arange(0, sh_order + 1, 2) m = np.zeros_like(n) if sphere is None: sphere = default_sphere big_sphere = sphere.subdivide() theta, phi = big_sphere.theta, big_sphere.phi B = shm.real_sph_harm(m, n, theta[:, None], phi[:, None]) A = shm.real_sph_harm(0, 0, 0, 0) response = np.empty([len(bvals), len(n) + 2]) if bvals[0] < tol: gtab = GradientTable(big_sphere.vertices * 0) wm_response = single_tensor(gtab, wm_rf[0, 3], wm_rf[0, :3], evecs, snr=None) response[0, 2:] = np.linalg.lstsq(B, wm_response, rcond=rcond_value)[0] response[0, 1] = gm_rf[0, 3] / A response[0, 0] = csf_rf[0, 3] / A for i, bvalue in enumerate(bvals[1:]): gtab = GradientTable(big_sphere.vertices * bvalue) wm_response = single_tensor(gtab, wm_rf[i, 3], wm_rf[i, :3], evecs, snr=None) response[i + 1, 2:] = np.linalg.lstsq(B, wm_response, rcond=rcond_value)[0] response[i + 1, 1] = gm_rf[i, 3] * np.exp(-bvalue * gm_rf[i, 0]) / A response[i + 1, 0] = csf_rf[i, 3] * np.exp(-bvalue * csf_rf[i, 0]) / A S0 = [csf_rf[0, 3], gm_rf[0, 3], wm_rf[0, 3]] else: warnings.warn("""No b0 given. Proceeding either way.""", UserWarning) for i, bvalue in enumerate(bvals): gtab = GradientTable(big_sphere.vertices * bvalue) wm_response = single_tensor(gtab, wm_rf[i, 3], wm_rf[i, :3], evecs, snr=None) response[i, 2:] = np.linalg.lstsq(B, wm_response, rcond=rcond_value)[0] response[i, 1] = gm_rf[i, 3] * np.exp(-bvalue * gm_rf[i, 0]) / A response[i, 0] = csf_rf[i, 3] * np.exp(-bvalue * csf_rf[i, 0]) / A S0 = [csf_rf[0, 3], gm_rf[0, 3], wm_rf[0, 3]] return MultiShellResponse(response, sh_order, bvals, S0=S0)
def gtable_from_qvecs(qvecs, b0_threshold=10): """ qvecs: Nx3 """ return GradientTable(qvecs, b0_threshold)
def nonlinfit_fn(dwi, bvecs, bvals, base_name): import nibabel as nb import numpy as np import os.path as op import dipy.reconst.dti as dti from dipy.core.gradients import GradientTable dwi_img = nb.load(dwi) dwi_data = dwi_img.get_data() dwi_affine = dwi_img.get_affine() from dipy.segment.mask import median_otsu b0_mask, mask = median_otsu(dwi_data, 2, 4) # Mask the data so that tensors are not fit for # unnecessary voxels mask_img = nb.Nifti1Image(mask.astype(np.float32), dwi_affine) b0_imgs = nb.Nifti1Image(b0_mask.astype(np.float32), dwi_affine) b0_img = nb.four_to_three(b0_imgs)[0] out_mask_name = op.abspath(base_name + '_binary_mask.nii.gz') out_b0_name = op.abspath(base_name + '_b0_mask.nii.gz') nb.save(mask_img, out_mask_name) nb.save(b0_img, out_b0_name) # Load the gradient strengths and directions bvals = np.loadtxt(bvals) gradients = np.loadtxt(bvecs) # Dipy wants Nx3 arrays if gradients.shape[0] == 3: gradients = gradients.T assert(gradients.shape[1] == 3) # Place in Dipy's preferred format gtab = GradientTable(gradients) gtab.bvals = bvals # Fit the tensors to the data tenmodel = dti.TensorModel(gtab, fit_method="NLLS") tenfit = tenmodel.fit(dwi_data, mask) # Calculate the fit, fa, and md of each voxel's tensor tensor_data = tenfit.lower_triangular() print('Computing anisotropy measures (FA, MD, RGB)') from dipy.reconst.dti import fractional_anisotropy, color_fa evals = tenfit.evals.astype(np.float32) FA = fractional_anisotropy(np.abs(evals)) FA = np.clip(FA, 0, 1) MD = dti.mean_diffusivity(np.abs(evals)) norm = dti.norm(tenfit.quadratic_form) RGB = color_fa(FA, tenfit.evecs) evecs = tenfit.evecs.astype(np.float32) mode = tenfit.mode.astype(np.float32) mode = np.nan_to_num(mode) # Write tensor as a 4D Nifti image with the original affine tensor_fit_img = nb.Nifti1Image(tensor_data.astype(np.float32), dwi_affine) mode_img = nb.Nifti1Image(mode.astype(np.float32), dwi_affine) norm_img = nb.Nifti1Image(norm.astype(np.float32), dwi_affine) FA_img = nb.Nifti1Image(FA.astype(np.float32), dwi_affine) evecs_img = nb.Nifti1Image(evecs, dwi_affine) evals_img = nb.Nifti1Image(evals, dwi_affine) rgb_img = nb.Nifti1Image(np.array(255 * RGB, 'uint8'), dwi_affine) MD_img = nb.Nifti1Image(MD.astype(np.float32), dwi_affine) out_tensor_file = op.abspath(base_name + "_tensor.nii.gz") out_mode_file = op.abspath(base_name + "_mode.nii.gz") out_fa_file = op.abspath(base_name + "_fa.nii.gz") out_norm_file = op.abspath(base_name + "_norm.nii.gz") out_evals_file = op.abspath(base_name + "_evals.nii.gz") out_evecs_file = op.abspath(base_name + "_evecs.nii.gz") out_rgb_fa_file = op.abspath(base_name + "_rgb_fa.nii.gz") out_md_file = op.abspath(base_name + "_md.nii.gz") nb.save(rgb_img, out_rgb_fa_file) nb.save(norm_img, out_norm_file) nb.save(mode_img, out_mode_file) nb.save(tensor_fit_img, out_tensor_file) nb.save(evecs_img, out_evecs_file) nb.save(evals_img, out_evals_file) nb.save(FA_img, out_fa_file) nb.save(MD_img, out_md_file) print('Tensor fit image saved as {i}'.format(i=out_tensor_file)) print('FA image saved as {i}'.format(i=out_fa_file)) print('MD image saved as {i}'.format(i=out_md_file)) return out_tensor_file, out_fa_file, out_md_file, \ out_evecs_file, out_evals_file, out_rgb_fa_file, out_norm_file, \ out_mode_file, out_mask_name, out_b0_name
def nonlinfit_fn(dwi, bvecs, bvals, base_name): import nibabel as nb import numpy as np import os.path as op import dipy.reconst.dti as dti from dipy.core.gradients import GradientTable dwi_img = nb.load(dwi) dwi_data = dwi_img.get_data() dwi_affine = dwi_img.get_affine() from dipy.segment.mask import median_otsu b0_mask, mask = median_otsu(dwi_data, 2, 4) # Mask the data so that tensors are not fit for # unnecessary voxels mask_img = nb.Nifti1Image(mask.astype(np.float32), dwi_affine) b0_imgs = nb.Nifti1Image(b0_mask.astype(np.float32), dwi_affine) b0_img = nb.four_to_three(b0_imgs)[0] out_mask_name = op.abspath(base_name + '_binary_mask.nii.gz') out_b0_name = op.abspath(base_name + '_b0_mask.nii.gz') nb.save(mask_img, out_mask_name) nb.save(b0_img, out_b0_name) # Load the gradient strengths and directions bvals = np.loadtxt(bvals) gradients = np.loadtxt(bvecs).T # Place in Dipy's preferred format gtab = GradientTable(gradients) gtab.bvals = bvals # Fit the tensors to the data tenmodel = dti.TensorModel(gtab, fit_method="NLLS") tenfit = tenmodel.fit(dwi_data, mask) # Calculate the fit, fa, and md of each voxel's tensor tensor_data = tenfit.lower_triangular() print('Computing anisotropy measures (FA, MD, RGB)') from dipy.reconst.dti import fractional_anisotropy, color_fa evals = tenfit.evals.astype(np.float32) FA = fractional_anisotropy(np.abs(evals)) FA = np.clip(FA, 0, 1) MD = dti.mean_diffusivity(np.abs(evals)) norm = dti.norm(tenfit.quadratic_form) RGB = color_fa(FA, tenfit.evecs) evecs = tenfit.evecs.astype(np.float32) mode = tenfit.mode.astype(np.float32) # Write tensor as a 4D Nifti image with the original affine tensor_fit_img = nb.Nifti1Image(tensor_data.astype(np.float32), dwi_affine) mode_img = nb.Nifti1Image(mode.astype(np.float32), dwi_affine) norm_img = nb.Nifti1Image(norm.astype(np.float32), dwi_affine) FA_img = nb.Nifti1Image(FA.astype(np.float32), dwi_affine) evecs_img = nb.Nifti1Image(evecs, dwi_affine) evals_img = nb.Nifti1Image(evals, dwi_affine) rgb_img = nb.Nifti1Image(np.array(255 * RGB, 'uint8'), dwi_affine) MD_img = nb.Nifti1Image(MD.astype(np.float32), dwi_affine) out_tensor_file = op.abspath(base_name + "_tensor.nii.gz") out_mode_file = op.abspath(base_name + "_mode.nii.gz") out_fa_file = op.abspath(base_name + "_fa.nii.gz") out_norm_file = op.abspath(base_name + "_norm.nii.gz") out_evals_file = op.abspath(base_name + "_evals.nii.gz") out_evecs_file = op.abspath(base_name + "_evecs.nii.gz") out_rgb_fa_file = op.abspath(base_name + "_rgb_fa.nii.gz") out_md_file = op.abspath(base_name + "_md.nii.gz") nb.save(rgb_img, out_rgb_fa_file) nb.save(norm_img, out_norm_file) nb.save(mode_img, out_mode_file) nb.save(tensor_fit_img, out_tensor_file) nb.save(evecs_img, out_evecs_file) nb.save(evals_img, out_evals_file) nb.save(FA_img, out_fa_file) nb.save(MD_img, out_md_file) print('Tensor fit image saved as {i}'.format(i=out_tensor_file)) print('FA image saved as {i}'.format(i=out_fa_file)) print('MD image saved as {i}'.format(i=out_md_file)) return out_tensor_file, out_fa_file, out_md_file, \ out_evecs_file, out_evals_file, out_rgb_fa_file, out_norm_file, \ out_mode_file, out_mask_name, out_b0_name