def test_predict(): """ Test model prediction API """ psphere = get_sphere('symmetric362') bvecs = np.concatenate(([[1, 0, 0]], psphere.vertices)) bvals = np.zeros(len(bvecs)) + 1000 bvals[0] = 0 gtab = grad.gradient_table(bvals, bvecs) mevals = np.array(([0.0015, 0.0003, 0.0001], [0.0015, 0.0003, 0.0003])) mevecs = [ np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]), np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]]) ] S = single_tensor(gtab, 100, mevals[0], mevecs[0], snr=None) dm = dti.TensorModel(gtab, 'LS') dmfit = dm.fit(S) assert_array_almost_equal(dmfit.predict(gtab, S0=100), S) assert_array_almost_equal(dm.predict(dmfit.model_params, S0=100), S) data, gtab = dsi_voxels() dtim = dti.TensorModel(gtab) dtif = dtim.fit(data) S0 = np.mean(data[..., gtab.b0s_mask], -1) p = dtif.predict(gtab, S0)
def test_adc(): """ Test the implementation of the calculation of apparent diffusion coefficient """ data, gtab = dsi_voxels() dm = dti.TensorModel(gtab, 'LS') mask = np.zeros(data.shape[:-1], dtype=bool) mask[0, 0, 0] = True dtifit = dm.fit(data) sphere = create_unit_sphere(4) # The ADC in the principal diffusion direction should be equal to the AD in # each voxel: pdd0 = dtifit.evecs[0,0,0,0] sphere_pdd0 = dps.Sphere(x=pdd0[0], y=pdd0[1], z=pdd0[2]) assert_array_almost_equal(dtifit.adc(sphere_pdd0)[0,0,0], dtifit.ad[0,0,0], decimal=5) # Test that it works for cases in which the data is 1D dtifit = dm.fit(data[0,0,0]) sphere_pdd0 = dps.Sphere(x=pdd0[0], y=pdd0[1], z=pdd0[2]) assert_array_almost_equal(dtifit.adc(sphere_pdd0), dtifit.ad, decimal=5)
def test_adc(): """ Test the implementation of the calculation of apparent diffusion coefficient """ data, gtab = dsi_voxels() dm = dti.TensorModel(gtab, 'LS') mask = np.zeros(data.shape[:-1], dtype=bool) mask[0, 0, 0] = True dtifit = dm.fit(data) # The ADC in the principal diffusion direction should be equal to the AD in # each voxel: pdd0 = dtifit.evecs[0, 0, 0, 0] sphere_pdd0 = dps.Sphere(x=pdd0[0], y=pdd0[1], z=pdd0[2]) npt.assert_array_almost_equal(dtifit.adc(sphere_pdd0)[0, 0, 0], dtifit.ad[0, 0, 0], decimal=5) # Test that it works for cases in which the data is 1D dtifit = dm.fit(data[0, 0, 0]) sphere_pdd0 = dps.Sphere(x=pdd0[0], y=pdd0[1], z=pdd0[2]) npt.assert_array_almost_equal(dtifit.adc(sphere_pdd0), dtifit.ad, decimal=5)
def test_multib0_dsi(): data, gtab = dsi_voxels() # Create a new data-set with a b0 measurement: new_data = np.concatenate([data, data[..., 0, None]], -1) new_bvecs = np.concatenate([gtab.bvecs, np.zeros((1, 3))]) new_bvals = np.concatenate([gtab.bvals, [0]]) new_gtab = gradient_table(new_bvals, new_bvecs) ds = DiffusionSpectrumModel(new_gtab) dsfit = ds.fit(new_data) pdf = dsfit.pdf() dsfit.odf(default_sphere) assert_equal(new_data.shape[:-1] + (17, 17, 17), pdf.shape) assert_equal(np.alltrue(np.isreal(pdf)), True) # And again, with one more b0 measurement (two in total): new_data = np.concatenate([data, data[..., 0, None]], -1) new_bvecs = np.concatenate([gtab.bvecs, np.zeros((1, 3))]) new_bvals = np.concatenate([gtab.bvals, [0]]) new_gtab = gradient_table(new_bvals, new_bvecs) ds = DiffusionSpectrumModel(new_gtab) dsfit = ds.fit(new_data) pdf = dsfit.pdf() dsfit.odf(default_sphere) assert_equal(new_data.shape[:-1] + (17, 17, 17), pdf.shape) assert_equal(np.alltrue(np.isreal(pdf)), True)
def test_mask(): data, gtab = dsi_voxels() dm = dti.TensorModel(gtab, 'LS') mask = np.zeros(data.shape[:-1], dtype=bool) mask[0, 0, 0] = True dtifit = dm.fit(data) dtifit_w_mask = dm.fit(data, mask=mask) # Without a mask it has some value assert_(not np.isnan(dtifit.fa[0, 0, 0])) # Where mask is False, evals, evecs and fa should all be 0 assert_array_equal(dtifit_w_mask.evals[~mask], 0) assert_array_equal(dtifit_w_mask.evecs[~mask], 0) assert_array_equal(dtifit_w_mask.fa[~mask], 0) # Except for the one voxel that was selected by the mask: assert_almost_equal(dtifit_w_mask.fa[0, 0, 0], dtifit.fa[0, 0, 0]) # Test with returning S0_hat dm = dti.TensorModel(gtab, 'LS', return_S0_hat=True) mask = np.zeros(data.shape[:-1], dtype=bool) mask[0, 0, 0] = True dtifit = dm.fit(data) dtifit_w_mask = dm.fit(data, mask=mask) # Without a mask it has some value assert_(not np.isnan(dtifit.fa[0, 0, 0])) # Where mask is False, evals, evecs and fa should all be 0 assert_array_equal(dtifit_w_mask.evals[~mask], 0) assert_array_equal(dtifit_w_mask.evecs[~mask], 0) assert_array_equal(dtifit_w_mask.fa[~mask], 0) assert_array_equal(dtifit_w_mask.S0_hat[~mask], 0) # Except for the one voxel that was selected by the mask: assert_almost_equal(dtifit_w_mask.fa[0, 0, 0], dtifit.fa[0, 0, 0]) assert_almost_equal(dtifit_w_mask.S0_hat[0, 0, 0], dtifit.S0_hat[0, 0, 0])
def test_multib0_dsi(): data, gtab = dsi_voxels() # Create a new data-set with a b0 measurement: new_data = np.concatenate([data, data[..., 0, None]], -1) new_bvecs = np.concatenate([gtab.bvecs, np.zeros((1, 3))]) new_bvals = np.concatenate([gtab.bvals, [0]]) new_gtab = gradient_table(new_bvals, new_bvecs) ds = DiffusionSpectrumModel(new_gtab) sphere = get_sphere('repulsion724') dsfit = ds.fit(new_data) pdf = dsfit.pdf() dsfit.odf(sphere) assert_equal(new_data.shape[:-1] + (17, 17, 17), pdf.shape) assert_equal(np.alltrue(np.isreal(pdf)), True) # And again, with one more b0 measurement (two in total): new_data = np.concatenate([data, data[..., 0, None]], -1) new_bvecs = np.concatenate([gtab.bvecs, np.zeros((1, 3))]) new_bvals = np.concatenate([gtab.bvals, [0]]) new_gtab = gradient_table(new_bvals, new_bvecs) ds = DiffusionSpectrumModel(new_gtab) dsfit = ds.fit(new_data) pdf = dsfit.pdf() dsfit.odf(sphere) assert_equal(new_data.shape[:-1] + (17, 17, 17), pdf.shape) assert_equal(np.alltrue(np.isreal(pdf)), True)
def test_design_matrix(): data, gtab = dpd.dsi_voxels() sphere = dpd.get_sphere() # Make it with NNLS, so that it gets tested regardless of sklearn sparse_fascicle_model = sfm.SparseFascicleModel(gtab, sphere, solver='NNLS') npt.assert_equal(sparse_fascicle_model.design_matrix.shape, (np.sum(~gtab.b0s_mask), sphere.vertices.shape[0]))
def test_multivox_dsi(): data, gtab = dsi_voxels() DS = DiffusionSpectrumModel(gtab) DSfit = DS.fit(data) PDF = DSfit.pdf() assert_equal(data.shape[:-1] + (17, 17, 17), PDF.shape) assert_equal(np.alltrue(np.isreal(PDF)), True)
def test_TensorModel(): data, gtab = dsi_voxels() dm = dti.TensorModel(gtab, 'LS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.5, True) dm = dti.TensorModel(gtab, 'WLS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.5, True) sphere = create_unit_sphere(4) assert_equal(len(dtifit.odf(sphere)), len(sphere.vertices)) assert_almost_equal(dtifit.fa, gfa(dtifit.odf(sphere)), 1) # Check that the multivoxel case works: dtifit = dm.fit(data) assert_equal(dtifit.fa.shape, data.shape[:3]) # Make some synthetic data b0 = 1000. bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec')) gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T) # The first b value is 0., so we take the second one: B = bvals[1] #Scale the eigenvalues and tensor by the B value so the units match D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B evals = np.array([2., 1., 0.]) / B md = evals.mean() tensor = from_lower_triangular(D) evecs = np.linalg.eigh(tensor)[1] #Design Matrix X = dti.design_matrix(bvecs, bvals) #Signals Y = np.exp(np.dot(X,D)) assert_almost_equal(Y[0], b0) Y.shape = (-1,) + Y.shape # Test fitting with different methods: #XXX Add NNLS methods! for fit_method in ['OLS', 'WLS']: tensor_model = dti.TensorModel(gtab, fit_method=fit_method) tensor_fit = tensor_model.fit(Y) assert_true(tensor_fit.model is tensor_model) assert_equal(tensor_fit.shape, Y.shape[:-1]) assert_array_almost_equal(tensor_fit.evals[0], evals) assert_array_almost_equal(tensor_fit.quadratic_form[0], tensor, err_msg =\ "Calculation of tensor from Y does not compare to analytical solution") assert_almost_equal(tensor_fit.md[0], md) assert_equal(tensor_fit.directions.shape[-2], 1) assert_equal(tensor_fit.directions.shape[-1], 3) # Test error-handling: assert_raises(ValueError, dti.TensorModel, gtab, fit_method='crazy_method')
def test_multivox_dsi(): data, gtab = dsi_voxels() DS = DiffusionSpectrumModel(gtab) get_sphere('symmetric724') DSfit = DS.fit(data) PDF = DSfit.pdf() assert_equal(data.shape[:-1] + (17, 17, 17), PDF.shape) assert_equal(np.alltrue(np.isreal(PDF)), True)
def test_multivox_dsi(): data, gtab = dsi_voxels() DS = DiffusionSpectrumModel(gtab, "standard") sphere = get_sphere("symmetric724") DS.direction_finder.config(sphere=sphere, min_separation_angle=25, relative_peak_threshold=0.35) DSfit = DS.fit(data) PDF = DSfit.pdf() assert_equal(data.shape[:-1] + (16, 16, 16), PDF.shape) assert_equal(np.alltrue(np.isreal(PDF)), True)
def test_mvoxel_gqi(): data, gtab = dsi_voxels() gq = GeneralizedQSamplingModel(gtab, 'standard') sphere = get_sphere('symmetric724') gq.direction_finder.config(sphere=sphere, min_separation_angle=25, relative_peak_threshold=.35) gqfit = gq.fit(data) directions = gqfit.directions assert_equal(directions[0, 0, 0].shape[0], 2) assert_equal(directions[-1, -1, -1].shape[0], 2)
def test_mask(): data, gtab = dsi_voxels() dm = dti.TensorModel(gtab, 'LS') mask = np.zeros(data.shape[:-1], dtype=bool) mask[0, 0, 0] = True dtifit = dm.fit(data) dtifit_w_mask = dm.fit(data, mask=mask) # Without a mask it has some value assert_(not np.isnan(dtifit.fa[0, 0, 0])) # But with the mask, it's a nan: assert_(np.isnan(dtifit_w_mask.fa[0, 0, 1])) # Except for the one voxel that was selected by the mask: assert_almost_equal(dtifit_w_mask.fa[0, 0, 0], dtifit.fa[0, 0, 0])
def test_mvoxel_gqi(): data, gtab = dsi_voxels() sphere = get_sphere('symmetric724') gq = GeneralizedQSamplingModel(gtab, 'standard') gqfit = gq.fit(data) all_odfs = gqfit.odf(sphere) # Check that the first and last voxels each have 2 peaks odf = all_odfs[0, 0, 0] directions, values, indices = peak_directions(odf, sphere, .35, 25) assert_equal(directions.shape[0], 2) odf = all_odfs[-1, -1, -1] directions, values, indices = peak_directions(odf, sphere, .35, 25) assert_equal(directions.shape[0], 2)
def test_color_fa(): data, gtab = dsi_voxels() dm = dti.TensorModel(gtab, 'LS') dmfit = dm.fit(data) fa = fractional_anisotropy(dmfit.evals) cfa = color_fa(fa, dmfit.evecs) fa = np.ones((3, 3, 3)) # evecs should be of shape (fa, 3, 3) evecs = np.zeros(fa.shape + (3, 2)) npt.assert_raises(ValueError, color_fa, fa, evecs) evecs = np.zeros(fa.shape + (3, 3)) evecs[..., :, :] = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) assert_equal(fa.shape, evecs[..., 0, 0].shape) assert_equal((3, 3), evecs.shape[-2:]) # 3D test case fa = np.ones((3, 3, 3)) evecs = np.zeros(fa.shape + (3, 3)) evecs[..., :, :] = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) cfa = color_fa(fa, evecs) cfa_truth = np.array([1, 0, 0]) true_cfa = np.reshape(np.tile(cfa_truth, 27), [3, 3, 3, 3]) assert_array_equal(cfa, true_cfa) # 2D test case fa = np.ones((3, 3)) evecs = np.zeros(fa.shape + (3, 3)) evecs[..., :, :] = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) cfa = color_fa(fa, evecs) cfa_truth = np.array([1, 0, 0]) true_cfa = np.reshape(np.tile(cfa_truth, 9), [3, 3, 3]) assert_array_equal(cfa, true_cfa) # 1D test case fa = np.ones((3)) evecs = np.zeros(fa.shape + (3, 3)) evecs[..., :, :] = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) cfa = color_fa(fa, evecs) cfa_truth = np.array([1, 0, 0]) true_cfa = np.reshape(np.tile(cfa_truth, 3), [3, 3]) assert_array_equal(cfa, true_cfa)
def test_predict(): """ Test model prediction API """ psphere = get_sphere('symmetric362') bvecs = np.concatenate(([[1, 0, 0]], psphere.vertices)) bvals = np.zeros(len(bvecs)) + 1000 bvals[0] = 0 gtab = grad.gradient_table(bvals, bvecs) mevals = np.array(([0.0015, 0.0003, 0.0001], [0.0015, 0.0003, 0.0003])) mevecs = [ np.array( [ [1, 0, 0], [0, 1, 0], [0, 0, 1] ] ), np.array( [ [0, 0, 1], [0, 1, 0], [1, 0, 0] ] ) ] S = single_tensor( gtab, 100, mevals[0], mevecs[0], snr=None ) dm = dti.TensorModel(gtab, 'LS') dmfit = dm.fit(S) assert_array_almost_equal(dmfit.predict(gtab, S0=100), S) assert_array_almost_equal(dm.predict(dmfit.model_params, S0=100), S) data, gtab = dsi_voxels() dtim = dti.TensorModel(gtab) dtif = dtim.fit(data) S0 = np.mean(data[...,gtab.b0s_mask], -1) p = dtif.predict(gtab, S0)
def test_tensor_model(): fdata, fbval, fbvec = get_data('small_25') data1 = nib.load(fdata).get_data() gtab1 = grad.gradient_table(fbval, fbvec) data2, gtab2 = dsi_voxels() for data, gtab in zip([data1, data2], [gtab1, gtab2]): dm = dti.TensorModel(gtab, 'LS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.9, True) dm = dti.TensorModel(gtab, 'WLS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.9, True) assert_equal(dtifit.fa > 0, True) sphere = create_unit_sphere(4) assert_equal(len(dtifit.odf(sphere)), len(sphere.vertices)) # Check that the multivoxel case works: dtifit = dm.fit(data) # Check that it works on signal that has already been normalized to S0: dm_to_relative = dti.TensorModel(gtab) if np.any(gtab.b0s_mask): relative_data = (data[0, 0, 0]/np.mean(data[0, 0, 0, gtab.b0s_mask])) dtifit_to_relative = dm_to_relative.fit(relative_data) npt.assert_almost_equal(dtifit.fa[0, 0, 0], dtifit_to_relative.fa, decimal=3) # And smoke-test that all these operations return sensibly-shaped arrays: assert_equal(dtifit.fa.shape, data.shape[:3]) assert_equal(dtifit.ad.shape, data.shape[:3]) assert_equal(dtifit.md.shape, data.shape[:3]) assert_equal(dtifit.rd.shape, data.shape[:3]) assert_equal(dtifit.trace.shape, data.shape[:3]) assert_equal(dtifit.mode.shape, data.shape[:3]) assert_equal(dtifit.linearity.shape, data.shape[:3]) assert_equal(dtifit.planarity.shape, data.shape[:3]) assert_equal(dtifit.sphericity.shape, data.shape[:3]) # Test for the shape of the mask assert_raises(ValueError, dm.fit, np.ones((10, 10, 3)), np.ones((3, 3))) # Make some synthetic data b0 = 1000. bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec')) gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T) # The first b value is 0., so we take the second one: B = bvals[1] # Scale the eigenvalues and tensor by the B value so the units match D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B evals = np.array([2., 1., 0.]) / B md = evals.mean() tensor = from_lower_triangular(D) A_squiggle = tensor - (1 / 3.0) * np.trace(tensor) * np.eye(3) mode = (3 * np.sqrt(6) * np.linalg.det(A_squiggle / np.linalg.norm(A_squiggle))) evals_eigh, evecs_eigh = np.linalg.eigh(tensor) # Sort according to eigen-value from large to small: evecs = evecs_eigh[:, np.argsort(evals_eigh)[::-1]] # Check that eigenvalues and eigenvectors are properly sorted through # that previous operation: for i in range(3): assert_array_almost_equal(np.dot(tensor, evecs[:, i]), evals[i] * evecs[:, i]) # Design Matrix X = dti.design_matrix(gtab) # Signals Y = np.exp(np.dot(X, D)) assert_almost_equal(Y[0], b0) Y.shape = (-1,) + Y.shape # Test fitting with different methods: for fit_method in ['OLS', 'WLS', 'NLLS']: tensor_model = dti.TensorModel(gtab, fit_method=fit_method, return_S0_hat=True) tensor_fit = tensor_model.fit(Y) assert_true(tensor_fit.model is tensor_model) assert_equal(tensor_fit.shape, Y.shape[:-1]) assert_array_almost_equal(tensor_fit.evals[0], evals) assert_array_almost_equal(tensor_fit.S0_hat, b0, decimal=3) # Test that the eigenvectors are correct, one-by-one: for i in range(3): # Eigenvectors have intrinsic sign ambiguity # (see # http://prod.sandia.gov/techlib/access-control.cgi/2007/076422.pdf) # so we need to allow for sign flips. One of the following should # always be true: assert_( np.all(np.abs(tensor_fit.evecs[0][:, i] - evecs[:, i]) < 10e-6) or np.all(np.abs(-tensor_fit.evecs[0][:, i] - evecs[:, i]) < 10e-6)) # We set a fixed tolerance of 10e-6, similar to array_almost_equal err_msg = "Calculation of tensor from Y does not compare to " err_msg += "analytical solution" assert_array_almost_equal(tensor_fit.quadratic_form[0], tensor, err_msg=err_msg) assert_almost_equal(tensor_fit.md[0], md) assert_array_almost_equal(tensor_fit.mode, mode, decimal=5) assert_equal(tensor_fit.directions.shape[-2], 1) assert_equal(tensor_fit.directions.shape[-1], 3) # Test error-handling: assert_raises(ValueError, dti.TensorModel, gtab, fit_method='crazy_method') # Test custom fit tensor method try: model = dti.TensorModel(gtab, fit_method=lambda *args, **kwargs: 42) fit = model.fit_method() except Exception as exc: assert False, "TensorModel should accept custom fit methods: %s" % exc assert fit == 42, "Custom fit method for TensorModel returned %s." % fit # Test multi-voxel data data = np.zeros((3, Y.shape[1])) # Normal voxel data[0] = Y # High diffusion voxel, all diffusing weighted signal equal to zero data[1, gtab.b0s_mask] = b0 data[1, ~gtab.b0s_mask] = 0 # Masked voxel, all data set to zero data[2] = 0. tensor_model = dti.TensorModel(gtab) fit = tensor_model.fit(data) assert_array_almost_equal(fit[0].evals, evals) # Return S0_test tensor_model = dti.TensorModel(gtab, return_S0_hat=True) fit = tensor_model.fit(data) assert_array_almost_equal(fit[0].evals, evals) assert_array_almost_equal(fit[0].S0_hat, b0) # Evals should be high for high diffusion voxel assert_(all(fit[1].evals > evals[0] * .9)) # Evals should be zero where data is masked assert_array_almost_equal(fit[2].evals, 0.)
def test_tensor_model(): fdata, fbval, fbvec = get_data('small_25') data1 = nib.load(fdata).get_data() gtab1 = grad.gradient_table(fbval, fbvec) data2, gtab2 = dsi_voxels() for data, gtab in zip([data1, data2], [gtab1, gtab2]): dm = dti.TensorModel(gtab, 'LS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.9, True) dm = dti.TensorModel(gtab, 'WLS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.9, True) assert_equal(dtifit.fa > 0, True) sphere = create_unit_sphere(4) assert_equal(len(dtifit.odf(sphere)), len(sphere.vertices)) # Check that the multivoxel case works: dtifit = dm.fit(data) # Check that it works on signal that has already been normalized to S0: dm_to_relative = dti.TensorModel(gtab) if np.any(gtab.b0s_mask): relative_data = (data[0, 0, 0] / np.mean(data[0, 0, 0, gtab.b0s_mask])) dtifit_to_relative = dm_to_relative.fit(relative_data) npt.assert_almost_equal(dtifit.fa[0, 0, 0], dtifit_to_relative.fa, decimal=3) # And smoke-test that all these operations return sensibly-shaped arrays: assert_equal(dtifit.fa.shape, data.shape[:3]) assert_equal(dtifit.ad.shape, data.shape[:3]) assert_equal(dtifit.md.shape, data.shape[:3]) assert_equal(dtifit.rd.shape, data.shape[:3]) assert_equal(dtifit.trace.shape, data.shape[:3]) assert_equal(dtifit.mode.shape, data.shape[:3]) assert_equal(dtifit.linearity.shape, data.shape[:3]) assert_equal(dtifit.planarity.shape, data.shape[:3]) assert_equal(dtifit.sphericity.shape, data.shape[:3]) # Test for the shape of the mask assert_raises(ValueError, dm.fit, np.ones((10, 10, 3)), np.ones((3, 3))) # Make some synthetic data b0 = 1000. bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec')) gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T) # The first b value is 0., so we take the second one: B = bvals[1] # Scale the eigenvalues and tensor by the B value so the units match D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B evals = np.array([2., 1., 0.]) / B md = evals.mean() tensor = from_lower_triangular(D) A_squiggle = tensor - (1 / 3.0) * np.trace(tensor) * np.eye(3) mode = 3 * np.sqrt(6) * np.linalg.det( A_squiggle / np.linalg.norm(A_squiggle)) evecs = np.linalg.eigh(tensor)[1] # Design Matrix X = dti.design_matrix(gtab) # Signals Y = np.exp(np.dot(X, D)) assert_almost_equal(Y[0], b0) Y.shape = (-1, ) + Y.shape # Test fitting with different methods: for fit_method in ['OLS', 'WLS', 'NLLS']: tensor_model = dti.TensorModel(gtab, fit_method=fit_method) tensor_fit = tensor_model.fit(Y) assert_true(tensor_fit.model is tensor_model) assert_equal(tensor_fit.shape, Y.shape[:-1]) assert_array_almost_equal(tensor_fit.evals[0], evals) assert_array_almost_equal(tensor_fit.quadratic_form[0], tensor, err_msg=\ "Calculation of tensor from Y does not compare to analytical solution") assert_almost_equal(tensor_fit.md[0], md) assert_array_almost_equal(tensor_fit.mode, mode, decimal=5) assert_equal(tensor_fit.directions.shape[-2], 1) assert_equal(tensor_fit.directions.shape[-1], 3) # Test error-handling: assert_raises(ValueError, dti.TensorModel, gtab, fit_method='crazy_method') # Test multi-voxel data data = np.zeros((3, Y.shape[1])) # Normal voxel data[0] = Y # High diffusion voxel, all diffusing weighted signal equal to zero data[1, gtab.b0s_mask] = b0 data[1, ~gtab.b0s_mask] = 0 # Masked voxel, all data set to zero data[2] = 0. tensor_model = dti.TensorModel(gtab) fit = tensor_model.fit(data) assert_array_almost_equal(fit[0].evals, evals) # Evals should be high for high diffusion voxel assert_(all(fit[1].evals > evals[0] * .9)) # Evals should be zero where data is masked assert_array_almost_equal(fit[2].evals, 0.)
def test_TensorModel(): data, gtab = dsi_voxels() dm = dti.TensorModel(gtab, 'LS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.5, True) dm = dti.TensorModel(gtab, 'WLS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.5, True) sphere = create_unit_sphere(4) assert_equal(len(dtifit.odf(sphere)), len(sphere.vertices)) assert_almost_equal(dtifit.fa, gfa(dtifit.odf(sphere)), 1) # Check that the multivoxel case works: dtifit = dm.fit(data) # And smoke-test that all these operations return sensibly-shaped arrays: assert_equal(dtifit.fa.shape, data.shape[:3]) assert_equal(dtifit.ad.shape, data.shape[:3]) assert_equal(dtifit.md.shape, data.shape[:3]) assert_equal(dtifit.rd.shape, data.shape[:3]) assert_equal(dtifit.trace.shape, data.shape[:3]) assert_equal(dtifit.mode.shape, data.shape[:3]) assert_equal(dtifit.linearity.shape, data.shape[:3]) assert_equal(dtifit.planarity.shape, data.shape[:3]) assert_equal(dtifit.sphericity.shape, data.shape[:3]) # Test for the shape of the mask assert_raises(ValueError, dm.fit, np.ones((10, 10, 3)), np.ones((3, 3))) # Make some synthetic data b0 = 1000. bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec')) gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T) # The first b value is 0., so we take the second one: B = bvals[1] # Scale the eigenvalues and tensor by the B value so the units match D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B evals = np.array([2., 1., 0.]) / B md = evals.mean() tensor = from_lower_triangular(D) A_squiggle = tensor - (1 / 3.0) * np.trace(tensor) * np.eye(3) mode = 3 * np.sqrt(6) * np.linalg.det( A_squiggle / np.linalg.norm(A_squiggle)) evecs = np.linalg.eigh(tensor)[1] # Design Matrix X = dti.design_matrix(gtab) # Signals Y = np.exp(np.dot(X, D)) assert_almost_equal(Y[0], b0) Y.shape = (-1, ) + Y.shape # Test fitting with different methods: for fit_method in ['OLS', 'WLS', 'NLLS']: tensor_model = dti.TensorModel(gtab, fit_method=fit_method) tensor_fit = tensor_model.fit(Y) assert_true(tensor_fit.model is tensor_model) assert_equal(tensor_fit.shape, Y.shape[:-1]) assert_array_almost_equal(tensor_fit.evals[0], evals) assert_array_almost_equal(tensor_fit.quadratic_form[0], tensor, err_msg=\ "Calculation of tensor from Y does not compare to analytical solution") assert_almost_equal(tensor_fit.md[0], md) assert_array_almost_equal(tensor_fit.mode, mode, decimal=5) assert_equal(tensor_fit.directions.shape[-2], 1) assert_equal(tensor_fit.directions.shape[-1], 3) # Test error-handling: assert_raises(ValueError, dti.TensorModel, gtab, fit_method='crazy_method')
def test_TensorModel(): data, gtab = dsi_voxels() dm = dti.TensorModel(gtab, 'LS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.5, True) dm = dti.TensorModel(gtab, 'WLS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.5, True) sphere = create_unit_sphere(4) assert_equal(len(dtifit.odf(sphere)), len(sphere.vertices)) assert_almost_equal(dtifit.fa, gfa(dtifit.odf(sphere)), 1) # Check that the multivoxel case works: dtifit = dm.fit(data) # And smoke-test that all these operations return sensibly-shaped arrays: assert_equal(dtifit.fa.shape, data.shape[:3]) assert_equal(dtifit.ad.shape, data.shape[:3]) assert_equal(dtifit.md.shape, data.shape[:3]) assert_equal(dtifit.rd.shape, data.shape[:3]) assert_equal(dtifit.trace.shape, data.shape[:3]) assert_equal(dtifit.mode.shape, data.shape[:3]) assert_equal(dtifit.linearity.shape, data.shape[:3]) assert_equal(dtifit.planarity.shape, data.shape[:3]) assert_equal(dtifit.sphericity.shape, data.shape[:3]) # Test for the shape of the mask assert_raises(ValueError, dm.fit, np.ones((10, 10, 3)), np.ones((3,3))) # Make some synthetic data b0 = 1000. bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec')) gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T) # The first b value is 0., so we take the second one: B = bvals[1] # Scale the eigenvalues and tensor by the B value so the units match D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B evals = np.array([2., 1., 0.]) / B md = evals.mean() tensor = from_lower_triangular(D) A_squiggle = tensor - (1 / 3.0) * np.trace(tensor) * np.eye(3) mode = 3 * np.sqrt(6) * np.linalg.det(A_squiggle / np.linalg.norm(A_squiggle)) evecs = np.linalg.eigh(tensor)[1] # Design Matrix X = dti.design_matrix(gtab) # Signals Y = np.exp(np.dot(X, D)) assert_almost_equal(Y[0], b0) Y.shape = (-1,) + Y.shape # Test fitting with different methods: for fit_method in ['OLS', 'WLS', 'NLLS']: tensor_model = dti.TensorModel(gtab, fit_method=fit_method) tensor_fit = tensor_model.fit(Y) assert_true(tensor_fit.model is tensor_model) assert_equal(tensor_fit.shape, Y.shape[:-1]) assert_array_almost_equal(tensor_fit.evals[0], evals) assert_array_almost_equal(tensor_fit.quadratic_form[0], tensor, err_msg=\ "Calculation of tensor from Y does not compare to analytical solution") assert_almost_equal(tensor_fit.md[0], md) assert_array_almost_equal(tensor_fit.mode, mode, decimal=5) assert_equal(tensor_fit.directions.shape[-2], 1) assert_equal(tensor_fit.directions.shape[-1], 3) # Test error-handling: assert_raises(ValueError, dti.TensorModel, gtab, fit_method='crazy_method')
def test_tensor_model(): fdata, fbval, fbvec = get_data('small_25') data1 = nib.load(fdata).get_data() gtab1 = grad.gradient_table(fbval, fbvec) data2, gtab2 = dsi_voxels() for data, gtab in zip([data1, data2], [gtab1, gtab2]): dm = dti.TensorModel(gtab, 'LS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.9, True) dm = dti.TensorModel(gtab, 'WLS') dtifit = dm.fit(data[0, 0, 0]) assert_equal(dtifit.fa < 0.9, True) assert_equal(dtifit.fa > 0, True) sphere = create_unit_sphere(4) assert_equal(len(dtifit.odf(sphere)), len(sphere.vertices)) # Check that the multivoxel case works: dtifit = dm.fit(data) # Check that it works on signal that has already been normalized to S0: dm_to_relative = dti.TensorModel(gtab) if np.any(gtab.b0s_mask): relative_data = (data[0, 0, 0]/np.mean(data[0, 0, 0, gtab.b0s_mask])) dtifit_to_relative = dm_to_relative.fit(relative_data) npt.assert_almost_equal(dtifit.fa[0,0,0], dtifit_to_relative.fa, decimal=3) # And smoke-test that all these operations return sensibly-shaped arrays: assert_equal(dtifit.fa.shape, data.shape[:3]) assert_equal(dtifit.ad.shape, data.shape[:3]) assert_equal(dtifit.md.shape, data.shape[:3]) assert_equal(dtifit.rd.shape, data.shape[:3]) assert_equal(dtifit.trace.shape, data.shape[:3]) assert_equal(dtifit.mode.shape, data.shape[:3]) assert_equal(dtifit.linearity.shape, data.shape[:3]) assert_equal(dtifit.planarity.shape, data.shape[:3]) assert_equal(dtifit.sphericity.shape, data.shape[:3]) # Test for the shape of the mask assert_raises(ValueError, dm.fit, np.ones((10, 10, 3)), np.ones((3,3))) # Make some synthetic data b0 = 1000. bvecs, bvals = read_bvec_file(get_data('55dir_grad.bvec')) gtab = grad.gradient_table_from_bvals_bvecs(bvals, bvecs.T) # The first b value is 0., so we take the second one: B = bvals[1] # Scale the eigenvalues and tensor by the B value so the units match D = np.array([1., 1., 1., 0., 0., 1., -np.log(b0) * B]) / B evals = np.array([2., 1., 0.]) / B md = evals.mean() tensor = from_lower_triangular(D) A_squiggle = tensor - (1 / 3.0) * np.trace(tensor) * np.eye(3) mode = 3 * np.sqrt(6) * np.linalg.det(A_squiggle / np.linalg.norm(A_squiggle)) evecs = np.linalg.eigh(tensor)[1] # Design Matrix X = dti.design_matrix(gtab) # Signals Y = np.exp(np.dot(X, D)) assert_almost_equal(Y[0], b0) Y.shape = (-1,) + Y.shape # Test fitting with different methods: for fit_method in ['OLS', 'WLS', 'NLLS']: tensor_model = dti.TensorModel(gtab, fit_method=fit_method) tensor_fit = tensor_model.fit(Y) assert_true(tensor_fit.model is tensor_model) assert_equal(tensor_fit.shape, Y.shape[:-1]) assert_array_almost_equal(tensor_fit.evals[0], evals) assert_array_almost_equal(tensor_fit.quadratic_form[0], tensor, err_msg=\ "Calculation of tensor from Y does not compare to analytical solution") assert_almost_equal(tensor_fit.md[0], md) assert_array_almost_equal(tensor_fit.mode, mode, decimal=5) assert_equal(tensor_fit.directions.shape[-2], 1) assert_equal(tensor_fit.directions.shape[-1], 3) # Test error-handling: assert_raises(ValueError, dti.TensorModel, gtab, fit_method='crazy_method') # Test multi-voxel data data = np.zeros((3, Y.shape[1])) # Normal voxel data[0] = Y # High diffusion voxel, all diffusing weighted signal equal to zero data[1, gtab.b0s_mask] = b0 data[1, ~gtab.b0s_mask] = 0 # Masked voxel, all data set to zero data[2] = 0. tensor_model = dti.TensorModel(gtab) fit = tensor_model.fit(data) assert_array_almost_equal(fit[0].evals, evals) # Evals should be high for high diffusion voxel assert_(all(fit[1].evals > evals[0] * .9)) # Evals should be zero where data is masked assert_array_almost_equal(fit[2].evals, 0.)