def test_check_directions(): # Testing spherical angles for two principal coordinate axis angles = [(0, 0)] # axis z sticks = _check_directions(angles) assert_array_almost_equal(sticks, [[0, 0, 1]]) angles = [(0, 90)] # axis z again (phi can be anything it theta is zero) sticks = _check_directions(angles) assert_array_almost_equal(sticks, [[0, 0, 1]]) angles = [(90, 0)] # axis x sticks = _check_directions(angles) assert_array_almost_equal(sticks, [[1, 0, 0]]) # Testing if directions are already given in cartesian coordinates angles = [(0, 0, 1)] sticks = _check_directions(angles) assert_array_almost_equal(sticks, [[0, 0, 1]]) # Testing more than one direction simultaneously angles = np.array([[90, 0], [30, 0]]) sticks = _check_directions(angles) ref_vec = [np.sin(np.pi * 30 / 180), 0, np.cos(np.pi * 30 / 180)] assert_array_almost_equal(sticks, [[1, 0, 0], ref_vec]) # Testing directions not aligned to planes x = 0, y = 0, or z = 0 the1 = 0 phi1 = 90 the2 = 30 phi2 = 45 angles = np.array([(the1, phi1), (the2, phi2)]) sticks = _check_directions(angles) ref_vec1 = (np.sin(np.pi * the1 / 180) * np.cos(np.pi * phi1 / 180), np.sin(np.pi * the1 / 180) * np.sin(np.pi * phi1 / 180), np.cos(np.pi * the1 / 180)) ref_vec2 = (np.sin(np.pi * the2 / 180) * np.cos(np.pi * phi2 / 180), np.sin(np.pi * the2 / 180) * np.sin(np.pi * phi2 / 180), np.cos(np.pi * the2 / 180)) assert_array_almost_equal(sticks, [ref_vec1, ref_vec2])
def test_check_directions(): # Testing spherical angles for two principal coordinate axis angles = [(0, 0)] # axis z sticks = _check_directions(angles) assert_array_almost_equal(sticks, [[0, 0, 1]]) angles = [(0, 90)] # axis z again (phi can be anything it theta is zero) sticks = _check_directions(angles) assert_array_almost_equal(sticks, [[0, 0, 1]]) angles = [(90, 0)] # axis x sticks = _check_directions(angles) assert_array_almost_equal(sticks, [[1, 0, 0]]) # Testing if directions are already given in cartesian coordinates angles = [(0, 0, 1)] sticks = _check_directions(angles) assert_array_almost_equal(sticks, [[0, 0, 1]]) # Testing more than one direction simultaneously angles = np.array([[90, 0], [30, 0]]) sticks = _check_directions(angles) ref_vec = [np.sin(np.pi*30/180), 0, np.cos(np.pi*30/180)] assert_array_almost_equal(sticks, [[1, 0, 0], ref_vec]) # Testing directions not aligned to planes x = 0, y = 0, or z = 0 the1 = 0 phi1 = 90 the2 = 30 phi2 = 45 angles = np.array([(the1, phi1), (the2, phi2)]) sticks = _check_directions(angles) ref_vec1 = (np.sin(np.pi*the1/180) * np.cos(np.pi*phi1/180), np.sin(np.pi*the1/180) * np.sin(np.pi*phi1/180), np.cos(np.pi*the1/180)) ref_vec2 = (np.sin(np.pi*the2/180) * np.cos(np.pi*phi2/180), np.sin(np.pi*the2/180) * np.sin(np.pi*phi2/180), np.cos(np.pi*the2/180)) assert_array_almost_equal(sticks, [ref_vec1, ref_vec2])
def test_kurtosis_elements(): """ Testing symmetry of the elements of the KT As an 4th order tensor, KT has 81 elements. However, due to diffusion symmetry the KT is fully characterized by 15 independent elements. This test checks for this property. """ # two fiber not aligned to planes x = 0, y = 0, or z = 0 mevals = np.array([[0.00099, 0, 0], [0.00226, 0.00087, 0.00087], [0.00099, 0, 0], [0.00226, 0.00087, 0.00087]]) angles = [(80, 10), (80, 10), (20, 30), (20, 30)] fie = 0.49 # intra axonal water fraction frac = [fie * 50, (1 - fie) * 50, fie * 50, (1 - fie) * 50] sticks = _check_directions(angles) mD = np.zeros((len(frac), 3, 3)) for i in range(len(frac)): R = all_tensor_evecs(sticks[i]) mD[i] = np.dot(np.dot(R, np.diag(mevals[i])), R.T) # compute global DT D = np.zeros((3, 3)) for i in range(len(frac)): D = D + frac[i] * mD[i] # compute voxel's MD MD = (D[0][0] + D[1][1] + D[2][2]) / 3 # Reference dictionary with the 15 independent elements. # Note: The multiplication of the indexes (i+1) * (j+1) * (k+1) * (l+1) # for of an elements is only equal to this multiplication for another # element if an only if the element corresponds to an symmetry element. # Thus indexes multiplication is used as key of the reference dictionary kt_ref = { 1: kurtosis_element(mD, frac, 0, 0, 0, 0), 16: kurtosis_element(mD, frac, 1, 1, 1, 1), 81: kurtosis_element(mD, frac, 2, 2, 2, 2), 2: kurtosis_element(mD, frac, 0, 0, 0, 1), 3: kurtosis_element(mD, frac, 0, 0, 0, 2), 8: kurtosis_element(mD, frac, 0, 1, 1, 1), 24: kurtosis_element(mD, frac, 1, 1, 1, 2), 27: kurtosis_element(mD, frac, 0, 2, 2, 2), 54: kurtosis_element(mD, frac, 1, 2, 2, 2), 4: kurtosis_element(mD, frac, 0, 0, 1, 1), 9: kurtosis_element(mD, frac, 0, 0, 2, 2), 36: kurtosis_element(mD, frac, 1, 1, 2, 2), 6: kurtosis_element(mD, frac, 0, 0, 1, 2), 12: kurtosis_element(mD, frac, 0, 1, 1, 2), 18: kurtosis_element(mD, frac, 0, 1, 2, 2) } # Testing all 81 possible elements xyz = [0, 1, 2] for i in xyz: for j in xyz: for k in xyz: for l in xyz: key = (i + 1) * (j + 1) * (k + 1) * (l + 1) assert_almost_equal(kurtosis_element(mD, frac, i, k, j, l), kt_ref[key]) # Testing optional function inputs assert_almost_equal( kurtosis_element(mD, frac, i, k, j, l), kurtosis_element(mD, frac, i, k, j, l, D, MD))
def test_single_fiber_model(): # single fiber simulate (which is the assumption of our model) fie = 0.49 ADi = 0.00099 ADe = 0.00226 RDi = 0 RDe = 0.00087 # prepare simulation: theta = random.uniform(0, 180) phi = random.uniform(0, 320) angles = [(theta, phi), (theta, phi)] mevals = np.array([[ADi, RDi, RDi], [ADe, RDe, RDe]]) frac = [fie * 100, (1 - fie) * 100] signal, dt, kt = multi_tensor_dki(gtab_2s, mevals, angles=angles, fractions=frac, snr=None) # DKI fit dkiM = dki_micro.DiffusionKurtosisModel(gtab_2s, fit_method="WLS") dkiF = dkiM.fit(signal) # Axonal Water Fraction sphere = get_sphere('symmetric724') AWF = dki_micro.axonal_water_fraction(dkiF.model_params, sphere, mask=None, gtol=1e-5) assert_almost_equal(AWF, fie) # Extra-cellular and intra-cellular components edt, idt = dki_micro.diffusion_components(dkiF.model_params, sphere) EDT = eig_from_lo_tri(edt) IDT = eig_from_lo_tri(idt) # check eigenvalues assert_array_almost_equal(EDT[0:3], np.array([ADe, RDe, RDe])) assert_array_almost_equal(IDT[0:3], np.array([ADi, RDi, RDi])) # first eigenvalue should be the direction of the fibers fiber_direction = _check_directions([(theta, phi)]) f_norm = abs(np.dot(fiber_direction, np.array((EDT[3], EDT[6], EDT[9])))) assert_almost_equal(f_norm, 1.) f_norm = abs(np.dot(fiber_direction, np.array((IDT[3], IDT[6], IDT[9])))) assert_almost_equal(f_norm, 1.) # Test model and fit objects wmtiM = dki_micro.KurtosisMicrostructureModel(gtab_2s, fit_method="WLS") wmtiF = wmtiM.fit(signal) assert_almost_equal(wmtiF.awf, AWF) assert_array_almost_equal(wmtiF.hindered_evals, np.array([ADe, RDe, RDe])) assert_array_almost_equal(wmtiF.restricted_evals, np.array([ADi, RDi, RDi])) assert_almost_equal(wmtiF.hindered_ad, ADe) assert_almost_equal(wmtiF.hindered_rd, RDe) assert_almost_equal(wmtiF.axonal_diffusivity, ADi) assert_almost_equal(wmtiF.tortuosity, ADe / RDe, decimal=4) # Test diffusion_components when a kurtosis tensors is associated with # negative kurtosis values. E.g of this cases is given below: dkiparams = np.array([ 1.67135726e-03, 5.03651205e-04, 9.35365328e-05, -7.11167583e-01, 6.23186820e-01, -3.25390313e-01, -1.75247376e-02, -4.78415563e-01, -8.77958674e-01, 7.02804064e-01, 6.18673368e-01, -3.51154825e-01, 2.18384153, -2.76378153e-02, 2.22893297, -2.68306546e-01, -1.28411610, -1.56557645e-01, -1.80850619e-01, -8.33152110e-01, -3.62410766e-01, 1.57775442e-01, 8.73775381e-01, 2.77188975e-01, -3.67415502e-02, -1.56330984e-01, -1.62295407e-02 ]) edt, idt = dki_micro.diffusion_components(dkiparams) assert_(np.all(np.isfinite(edt)))
def test_kurtosis_elements(): """ Testing symmetry of the elements of the KT As an 4th order tensor, KT has 81 elements. However, due to diffusion symmetry the KT is fully characterized by 15 independent elements. This test checks for this property. """ # two fiber not aligned to planes x = 0, y = 0, or z = 0 mevals = np.array([[0.00099, 0, 0], [0.00226, 0.00087, 0.00087], [0.00099, 0, 0], [0.00226, 0.00087, 0.00087]]) angles = [(80, 10), (80, 10), (20, 30), (20, 30)] fie = 0.49 # intra axonal water fraction frac = [fie * 50, (1-fie) * 50, fie * 50, (1-fie) * 50] sticks = _check_directions(angles) mD = np.zeros((len(frac), 3, 3)) for i in range(len(frac)): R = all_tensor_evecs(sticks[i]) mD[i] = np.dot(np.dot(R, np.diag(mevals[i])), R.T) # compute global DT D = np.zeros((3, 3)) for i in range(len(frac)): D = D + frac[i]*mD[i] # compute voxel's MD MD = (D[0][0] + D[1][1] + D[2][2]) / 3 # Reference dictionary with the 15 independent elements. # Note: The multiplication of the indexes (i+1) * (j+1) * (k+1) * (l+1) # for of an elements is only equal to this multiplication for another # element if an only if the element corresponds to an symmetry element. # Thus indexes multiplication is used as key of the reference dictionary kt_ref = {1: kurtosis_element(mD, frac, 0, 0, 0, 0), 16: kurtosis_element(mD, frac, 1, 1, 1, 1), 81: kurtosis_element(mD, frac, 2, 2, 2, 2), 2: kurtosis_element(mD, frac, 0, 0, 0, 1), 3: kurtosis_element(mD, frac, 0, 0, 0, 2), 8: kurtosis_element(mD, frac, 0, 1, 1, 1), 24: kurtosis_element(mD, frac, 1, 1, 1, 2), 27: kurtosis_element(mD, frac, 0, 2, 2, 2), 54: kurtosis_element(mD, frac, 1, 2, 2, 2), 4: kurtosis_element(mD, frac, 0, 0, 1, 1), 9: kurtosis_element(mD, frac, 0, 0, 2, 2), 36: kurtosis_element(mD, frac, 1, 1, 2, 2), 6: kurtosis_element(mD, frac, 0, 0, 1, 2), 12: kurtosis_element(mD, frac, 0, 1, 1, 2), 18: kurtosis_element(mD, frac, 0, 1, 2, 2)} # Testing all 81 possible elements xyz = [0, 1, 2] for i in xyz: for j in xyz: for k in xyz: for l in xyz: key = (i+1) * (j+1) * (k+1) * (l+1) assert_almost_equal(kurtosis_element(mD, frac, i, k, j, l), kt_ref[key]) # Testing optional funtion inputs assert_almost_equal(kurtosis_element(mD, frac, i, k, j, l), kurtosis_element(mD, frac, i, k, j, l, D, MD))
def test_single_fiber_model(): # single fiber simulate (which is the assumption of our model) fie = 0.49 ADi = 0.00099 ADe = 0.00226 RDi = 0 RDe = 0.00087 # prepare simulation: theta = random.uniform(0, 180) phi = random.uniform(0, 320) angles = [(theta, phi), (theta, phi)] mevals = np.array([[ADi, RDi, RDi], [ADe, RDe, RDe]]) frac = [fie*100, (1 - fie)*100] signal, dt, kt = multi_tensor_dki(gtab_2s, mevals, angles=angles, fractions=frac, snr=None) # DKI fit dkiM = dki_micro.DiffusionKurtosisModel(gtab_2s, fit_method="WLS") dkiF = dkiM.fit(signal) # Axonal Water Fraction sphere = get_sphere('symmetric724') AWF = dki_micro.axonal_water_fraction(dkiF.model_params, sphere, mask=None, gtol=1e-5) assert_almost_equal(AWF, fie) # Extra-cellular and intra-cellular components edt, idt = dki_micro.diffusion_components(dkiF.model_params, sphere) EDT = eig_from_lo_tri(edt) IDT = eig_from_lo_tri(idt) # check eigenvalues assert_array_almost_equal(EDT[0:3], np.array([ADe, RDe, RDe])) assert_array_almost_equal(IDT[0:3], np.array([ADi, RDi, RDi])) # first eigenvalue should be the direction of the fibers fiber_direction = _check_directions([(theta, phi)]) f_norm = abs(np.dot(fiber_direction, np.array((EDT[3], EDT[6], EDT[9])))) assert_almost_equal(f_norm, 1.) f_norm = abs(np.dot(fiber_direction, np.array((IDT[3], IDT[6], IDT[9])))) assert_almost_equal(f_norm, 1.) # Test model and fit objects wmtiM = dki_micro.KurtosisMicrostructureModel(gtab_2s, fit_method="WLS") wmtiF = wmtiM.fit(signal) assert_almost_equal(wmtiF.awf, AWF) assert_array_almost_equal(wmtiF.hindered_evals, np.array([ADe, RDe, RDe])) assert_array_almost_equal(wmtiF.restricted_evals, np.array([ADi, RDi, RDi])) assert_almost_equal(wmtiF.hindered_ad, ADe) assert_almost_equal(wmtiF.hindered_rd, RDe) assert_almost_equal(wmtiF.axonal_diffusivity, ADi) assert_almost_equal(wmtiF.tortuosity, ADe/RDe, decimal=4) # Test diffusion_components when a kurtosis tensors is associated with # negative kurtosis values. E.g of this cases is given below: dkiparams = np.array([1.67135726e-03, 5.03651205e-04, 9.35365328e-05, -7.11167583e-01, 6.23186820e-01, -3.25390313e-01, -1.75247376e-02, -4.78415563e-01, -8.77958674e-01, 7.02804064e-01, 6.18673368e-01, -3.51154825e-01, 2.18384153, -2.76378153e-02, 2.22893297, -2.68306546e-01, -1.28411610, -1.56557645e-01, -1.80850619e-01, -8.33152110e-01, -3.62410766e-01, 1.57775442e-01, 8.73775381e-01, 2.77188975e-01, -3.67415502e-02, -1.56330984e-01, -1.62295407e-02]) edt, idt = dki_micro.diffusion_components(dkiparams) assert_(np.all(np.isfinite(edt)))