def test_mapmri_metrics_isotropic(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0003, 0.0003, 0.0003] # isotropic diffusivities S = single_tensor(gtab, evals=np.r_[l1, l2, l3]) # test MAPMRI q-space indices mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, anisotropic_scaling=False) mapfit = mapm.fit(S) tau = 1 / (4 * np.pi ** 2) # ground truth indices estimated from the DTI tensor rtpp_gt = 1. / (2 * np.sqrt(np.pi * l1 * tau)) rtap_gt = ( 1. / (2 * np.sqrt(np.pi * l2 * tau)) * 1. / (2 * np.sqrt(np.pi * l3 * tau)) ) rtop_gt = rtpp_gt * rtap_gt msd_gt = 2 * (l1 + l2 + l3) * tau qiv_gt = ( (64 * np.pi ** (7 / 2.) * (l1 * l2 * l3 * tau ** 3) ** (3 / 2.)) / ((l2 * l3 + l1 * (l2 + l3)) * tau ** 2) ) assert_almost_equal(mapfit.rtap(), rtap_gt, 5) assert_almost_equal(mapfit.rtpp(), rtpp_gt, 5) assert_almost_equal(mapfit.rtop(), rtop_gt, 4) assert_almost_equal(mapfit.msd(), msd_gt, 5) assert_almost_equal(mapfit.qiv(), qiv_gt, 5)
def test_mapmri_laplacian_isotropic(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0003, 0.0003, 0.0003] # isotropic diffusivities S = single_tensor(gtab, evals=np.r_[l1, l2, l3]) mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, anisotropic_scaling=False) mapfit = mapm.fit(S) tau = 1 / (4 * np.pi ** 2) # ground truth norm of laplacian of tensor norm_of_laplacian_gt = ( (3 * (l1 ** 2 + l2 ** 2 + l3 ** 2) + 2 * l2 * l3 + 2 * l1 * (l2 + l3)) * (np.pi ** (5 / 2.) * tau) / (np.sqrt(2 * l1 * l2 * l3 * tau)) ) # check if estimated laplacian corresponds with ground truth laplacian_matrix = mapmri.mapmri_isotropic_laplacian_reg_matrix( radial_order, mapfit.mu[0]) coef = mapfit._mapmri_coef norm_of_laplacian = np.dot(np.dot(coef, laplacian_matrix), coef) assert_almost_equal(norm_of_laplacian, norm_of_laplacian_gt)
def test_mapmri_compare_fitted_pdf_with_multi_tensor(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3) radius_max = 0.02 # 40 microns gridsize = 10 r_points = mapmri.create_rspace(gridsize, radius_max) # test MAPMRI fitting mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001) mapfit = mapm.fit(S) # compare the mapmri pdf with the ground truth multi_tensor pdf mevals = np.array(([l1, l2, l3], [l1, l2, l3])) angl = [(0, 0), (60, 0)] pdf_mt = multi_tensor_pdf(r_points, mevals=mevals, angles=angl, fractions=[50, 50]) pdf_map = mapfit.pdf(r_points) nmse_pdf = np.sqrt(np.sum((pdf_mt - pdf_map) ** 2)) / (pdf_mt.sum()) assert_almost_equal(nmse_pdf, 0.0, 2)
def test_mapmri_metrics_anisotropic(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=0) # test MAPMRI q-space indices mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False) mapfit = mapm.fit(S) tau = 1 / (4 * np.pi ** 2) # ground truth indices estimated from the DTI tensor rtpp_gt = 1. / (2 * np.sqrt(np.pi * l1 * tau)) rtap_gt = ( 1. / (2 * np.sqrt(np.pi * l2 * tau)) * 1. / (2 * np.sqrt(np.pi * l3 * tau)) ) rtop_gt = rtpp_gt * rtap_gt msd_gt = 2 * (l1 + l2 + l3) * tau qiv_gt = ( (64 * np.pi ** (7 / 2.) * (l1 * l2 * l3 * tau ** 3) ** (3 / 2.)) / ((l2 * l3 + l1 * (l2 + l3)) * tau ** 2) ) assert_almost_equal(mapfit.rtap(), rtap_gt, 5) assert_almost_equal(mapfit.rtpp(), rtpp_gt, 5) assert_almost_equal(mapfit.rtop(), rtop_gt, 5) assert_almost_equal(mapfit.ng(), 0., 5) assert_almost_equal(mapfit.ng_parallel(), 0., 5) assert_almost_equal(mapfit.ng_perpendicular(), 0., 5) assert_almost_equal(mapfit.msd(), msd_gt, 5) assert_almost_equal(mapfit.qiv(), qiv_gt, 5)
def test_mapmri_compare_fitted_pdf_with_multi_tensor(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3) radius_max = 0.02 # 40 microns gridsize = 10 r_points = mapmri.create_rspace(gridsize, radius_max) # test MAPMRI fitting mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001) mapfit = mapm.fit(S) # compare the mapmri pdf with the ground truth multi_tensor pdf mevals = np.array(([l1, l2, l3], [l1, l2, l3])) angl = [(0, 0), (60, 0)] pdf_mt = multi_tensor_pdf(r_points, mevals=mevals, angles=angl, fractions=[50, 50]) pdf_map = mapfit.pdf(r_points) nmse_pdf = np.sqrt(np.sum((pdf_mt - pdf_map)**2)) / (pdf_mt.sum()) assert_almost_equal(nmse_pdf, 0.0, 2)
def test_mapmri_metrics_anisotropic(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=0) # test MAPMRI q-space indices mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False) mapfit = mapm.fit(S) tau = 1 / (4 * np.pi**2) # ground truth indices estimated from the DTI tensor rtpp_gt = 1. / (2 * np.sqrt(np.pi * l1 * tau)) rtap_gt = (1. / (2 * np.sqrt(np.pi * l2 * tau)) * 1. / (2 * np.sqrt(np.pi * l3 * tau))) rtop_gt = rtpp_gt * rtap_gt msd_gt = 2 * (l1 + l2 + l3) * tau qiv_gt = ((64 * np.pi**(7 / 2.) * (l1 * l2 * l3 * tau**3)**(3 / 2.)) / ((l2 * l3 + l1 * (l2 + l3)) * tau**2)) assert_almost_equal(mapfit.rtap(), rtap_gt, 5) assert_almost_equal(mapfit.rtpp(), rtpp_gt, 5) assert_almost_equal(mapfit.rtop(), rtop_gt, 5) assert_almost_equal(mapfit.ng(), 0., 5) assert_almost_equal(mapfit.ng_parallel(), 0., 5) assert_almost_equal(mapfit.ng_perpendicular(), 0., 5) assert_almost_equal(mapfit.msd(), msd_gt, 5) assert_almost_equal(mapfit.qiv(), qiv_gt, 5)
def test_mapmri_metrics_isotropic(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0003, 0.0003, 0.0003] # isotropic diffusivities S = single_tensor(gtab, evals=np.r_[l1, l2, l3]) # test MAPMRI q-space indices mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, anisotropic_scaling=False) mapfit = mapm.fit(S) tau = 1 / (4 * np.pi**2) # ground truth indices estimated from the DTI tensor rtpp_gt = 1. / (2 * np.sqrt(np.pi * l1 * tau)) rtap_gt = (1. / (2 * np.sqrt(np.pi * l2 * tau)) * 1. / (2 * np.sqrt(np.pi * l3 * tau))) rtop_gt = rtpp_gt * rtap_gt msd_gt = 2 * (l1 + l2 + l3) * tau qiv_gt = ((64 * np.pi**(7 / 2.) * (l1 * l2 * l3 * tau**3)**(3 / 2.)) / ((l2 * l3 + l1 * (l2 + l3)) * tau**2)) assert_almost_equal(mapfit.rtap(), rtap_gt, 5) assert_almost_equal(mapfit.rtpp(), rtpp_gt, 5) assert_almost_equal(mapfit.rtop(), rtop_gt, 4) assert_almost_equal(mapfit.msd(), msd_gt, 5) assert_almost_equal(mapfit.qiv(), qiv_gt, 5)
def test_mapmri_laplacian_isotropic(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0003, 0.0003, 0.0003] # isotropic diffusivities S = single_tensor(gtab, evals=np.r_[l1, l2, l3]) mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, anisotropic_scaling=False) mapfit = mapm.fit(S) tau = 1 / (4 * np.pi**2) # ground truth norm of laplacian of tensor norm_of_laplacian_gt = ((3 * (l1**2 + l2**2 + l3**2) + 2 * l2 * l3 + 2 * l1 * (l2 + l3)) * (np.pi**(5 / 2.) * tau) / (np.sqrt(2 * l1 * l2 * l3 * tau))) # check if estimated laplacian corresponds with ground truth laplacian_matrix = mapmri.mapmri_isotropic_laplacian_reg_matrix( radial_order, mapfit.mu[0]) coef = mapfit._mapmri_coef norm_of_laplacian = np.dot(np.dot(coef, laplacian_matrix), coef) assert_almost_equal(norm_of_laplacian, norm_of_laplacian_gt)
def test_shore_metrics(): gtab = get_gtab_taiwan_dsi() mevals = np.array(([0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003])) angl = [(0, 0), (60, 0)] S, sticks = MultiTensor(gtab, mevals, S0=100.0, angles=angl, fractions=[50, 50], snr=None) # since we are testing without noise we can use higher order and lower lambdas, with respect to the default. radial_order = 6 lambd = 1e-8 # test mapmri_indices indices = mapmri_index_matrix(radial_order) n_c = indices.shape[0] F = radial_order / 2 n_gt = np.round(1 / 6.0 * (F + 1) * (F + 2) * (4 * F + 3)) assert_equal(n_c, n_gt) # test MAPMRI fitting mapm= MapmriModel(gtab, radial_order=radial_order, lambd=lambd) mapfit = mapm.fit(S) c_map=mapfit.mapmri_coeff R = mapfit.mapmri_R mu = mapfit.mapmri_mu S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # test if the analytical integral of the pdf is equal to one integral = 0 for i in range(indices.shape[0]): n1,n2,n3 = indices[i] integral += c_map[i] * int_func(n1) * int_func(n2) * int_func(n3) assert_almost_equal(integral, 1.0, 3) # compare the shore pdf with the ground truth multi_tensor pdf sphere = get_sphere('symmetric724') v = sphere.vertices radius = 10e-3 r_points = v * radius pdf_mt = multi_tensor_pdf(r_points, mevals=mevals, angles=angl, fractions= [50, 50]) pdf_map = mapmri_EAP(r_points, radial_order, c_map, mu, R) nmse_pdf = np.sqrt(np.sum((pdf_mt - pdf_map) ** 2)) / (pdf_mt.sum()) assert_almost_equal(nmse_pdf, 0.0, 2)
def test_multivox_mapmri(): gtab = get_3shell_gtab() data = np.random.random([20, 30, 1, gtab.gradients.shape[0]]) radial_order = 4 map_model = MapmriModel(gtab, radial_order=radial_order) mapfit = map_model.fit(data) c_map = mapfit.mapmri_coeff assert_equal(c_map.shape[0:3], data.shape[0:3]) assert_equal(np.alltrue(np.isreal(c_map)), True)
def test_mapmri_odf(radial_order=6): gtab = get_gtab_taiwan_dsi() # load symmetric 724 sphere sphere = get_sphere('symmetric724') # load icosahedron sphere l1, l2, l3 = [0.0015, 0.0003, 0.0003] data, golden_directions = generate_signal_crossing(gtab, l1, l2, l3, angle2=90) mapmod = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting=0.01) # symmetric724 sphere2 = create_unit_sphere(5) mapfit = mapmod.fit(data) odf = mapfit.odf(sphere) directions, _, _ = peak_directions(odf, sphere, .35, 25) assert_equal(len(directions), 2) assert_almost_equal( angular_similarity(directions, golden_directions), 2, 1) # 5 subdivisions odf = mapfit.odf(sphere2) directions, _, _ = peak_directions(odf, sphere2, .35, 25) assert_equal(len(directions), 2) assert_almost_equal( angular_similarity(directions, golden_directions), 2, 1) sb_dummies = sticks_and_ball_dummies(gtab) for sbd in sb_dummies: data, golden_directions = sb_dummies[sbd] asmfit = mapmod.fit(data) odf = asmfit.odf(sphere2) directions, _, _ = peak_directions(odf, sphere2, .35, 25) if len(directions) <= 3: assert_equal(len(directions), len(golden_directions)) if len(directions) > 3: assert_equal(gfa(odf) < 0.1, True) # for the isotropic implementation check if the odf spherical harmonics # actually represent the discrete sphere function. mapmod = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting=0.01, anisotropic_scaling=False) mapfit = mapmod.fit(data) odf = mapfit.odf(sphere) odf_sh = mapfit.odf_sh() odf_from_sh = sh_to_sf(odf_sh, sphere, radial_order, basis_type=None) assert_almost_equal(odf, odf_from_sh, 10)
def test_mapmri_signal_fitting_over_radial_order(order_max=8): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0012, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=60) # take radial order 0, 4 and 8 orders = [0, 4, 8] error_array = np.zeros(len(orders)) for i, order in enumerate(orders): mapm = MapmriModel(gtab, radial_order=order, laplacian_regularization=False) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 100.0) error_array[i] = np.mean((S - S_reconst) ** 2) # check if the fitting error decreases as radial order increases assert_equal(np.diff(error_array) < 0., True)
def test_mapmri_isotropic_static_scale_factor(radial_order=6): gtab = get_gtab_taiwan_dsi() D = 0.7e-3 tau = 1 / (4 * np.pi ** 2) mu = np.sqrt(D * 2 * tau) l1, l2, l3 = [D, D, D] S = single_tensor(gtab, evals=np.r_[l1, l2, l3]) S_array = np.tile(S, (5, 1)) stat_weight = 0.1 mapm_scale_stat_reg_stat = MapmriModel(gtab, radial_order=radial_order, anisotropic_scaling=False, dti_scale_estimation=False, static_diffusivity=D, laplacian_regularization=True, laplacian_weighting=stat_weight) mapm_scale_adapt_reg_stat = MapmriModel(gtab, radial_order=radial_order, anisotropic_scaling=False, dti_scale_estimation=True, laplacian_regularization=True, laplacian_weighting=stat_weight) start = time.time() mapf_scale_stat_reg_stat = mapm_scale_stat_reg_stat.fit(S_array) time_scale_stat_reg_stat = time.time() - start start = time.time() mapf_scale_adapt_reg_stat = mapm_scale_adapt_reg_stat.fit(S_array) time_scale_adapt_reg_stat = time.time() - start # test if indeed the scale factor is fixed now assert_equal(np.all(mapf_scale_stat_reg_stat.mu == mu), True) # test if computation time is shorter (except on Windows): if not platform.system() == "Windows": assert_equal(time_scale_stat_reg_stat < time_scale_adapt_reg_stat, True) # check if the fitted signal is the same assert_almost_equal(mapf_scale_stat_reg_stat.fitted_signal(), mapf_scale_adapt_reg_stat.fitted_signal())
def test_mapmri_pdf_integral_unity(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3) sphere = get_sphere('symmetric724') # test MAPMRI fitting mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.02) mapfit = mapm.fit(S) c_map = mapfit.mapmri_coeff # test if the analytical integral of the pdf is equal to one indices = mapmri_index_matrix(radial_order) integral = 0 for i in range(indices.shape[0]): n1, n2, n3 = indices[i] integral += c_map[i] * int_func(n1) * int_func(n2) * int_func(n3) assert_almost_equal(integral, 1.0, 3) # test if numerical integral of odf is equal to one odf = mapfit.odf(sphere, s=0) odf_sum = odf.sum() / sphere.vertices.shape[0] * (4 * np.pi) assert_almost_equal(odf_sum, 1.0, 2) # do the same for isotropic implementation radius_max = 0.04 # 40 microns gridsize = 17 r_points = mapmri.create_rspace(gridsize, radius_max) mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.02, anisotropic_scaling=False) mapfit = mapm.fit(S) pdf = mapfit.pdf(r_points) pdf[r_points[:, 2] == 0.] /= 2 # for antipodal symmetry on z-plane point_volume = (radius_max / (gridsize // 2)) ** 3 integral = pdf.sum() * point_volume * 2 assert_almost_equal(integral, 1.0, 3) odf = mapfit.odf(sphere, s=0) odf_sum = odf.sum() / sphere.vertices.shape[0] * (4 * np.pi) assert_almost_equal(odf_sum, 1.0, 2)
def test_positivity_constraint(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=60) S_noise = add_noise(S, snr=20, S0=100.) gridsize = 20 max_radius = 15e-3 # 20 microns maximum radius r_grad = mapmri.create_rspace(gridsize, max_radius) # the posivitivity constraint does not make the pdf completely positive # but greatly decreases the amount of negativity in the constrained points. # we test if the amount of negative pdf has decreased more than 90% mapmod_no_constraint = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, positivity_constraint=False) mapfit_no_constraint = mapmod_no_constraint.fit(S_noise) pdf = mapfit_no_constraint.pdf(r_grad) pdf_negative_no_constraint = pdf[pdf < 0].sum() mapmod_constraint = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, positivity_constraint=True, pos_grid=gridsize, pos_radius='adaptive') mapfit_constraint = mapmod_constraint.fit(S_noise) pdf = mapfit_constraint.pdf(r_grad) pdf_negative_constraint = pdf[pdf < 0].sum() assert_equal((pdf_negative_constraint / pdf_negative_no_constraint) < 0.1, True) # the same for isotropic scaling mapmod_no_constraint = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, positivity_constraint=False, anisotropic_scaling=False) mapfit_no_constraint = mapmod_no_constraint.fit(S_noise) pdf = mapfit_no_constraint.pdf(r_grad) pdf_negative_no_constraint = pdf[pdf < 0].sum() mapmod_constraint = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, positivity_constraint=True, anisotropic_scaling=False, pos_grid=gridsize, pos_radius='adaptive') mapfit_constraint = mapmod_constraint.fit(S_noise) pdf = mapfit_constraint.pdf(r_grad) pdf_negative_constraint = pdf[pdf < 0].sum() assert_equal((pdf_negative_constraint / pdf_negative_no_constraint) < 0.1, True)
def test_mapmri_odf(radial_order=6): gtab = get_gtab_taiwan_dsi() # load repulsion 724 sphere sphere = default_sphere # load icosahedron sphere l1, l2, l3 = [0.0015, 0.0003, 0.0003] data, golden_directions = generate_signal_crossing(gtab, l1, l2, l3, angle2=90) mapmod = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting=0.01) # repulsion724 sphere2 = create_unit_sphere(5) mapfit = mapmod.fit(data) odf = mapfit.odf(sphere) directions, _, _ = peak_directions(odf, sphere, .35, 25) assert_equal(len(directions), 2) assert_almost_equal(angular_similarity(directions, golden_directions), 2, 1) # 5 subdivisions odf = mapfit.odf(sphere2) directions, _, _ = peak_directions(odf, sphere2, .35, 25) assert_equal(len(directions), 2) assert_almost_equal(angular_similarity(directions, golden_directions), 2, 1) sb_dummies = sticks_and_ball_dummies(gtab) for sbd in sb_dummies: data, golden_directions = sb_dummies[sbd] asmfit = mapmod.fit(data) odf = asmfit.odf(sphere2) directions, _, _ = peak_directions(odf, sphere2, .35, 25) if len(directions) <= 3: assert_equal(len(directions), len(golden_directions)) if len(directions) > 3: assert_equal(gfa(odf) < 0.1, True) # for the isotropic implementation check if the odf spherical harmonics # actually represent the discrete sphere function. mapmod = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting=0.01, anisotropic_scaling=False) mapfit = mapmod.fit(data) odf = mapfit.odf(sphere) odf_sh = mapfit.odf_sh() odf_from_sh = sh_to_sf(odf_sh, sphere, radial_order, basis_type=None) assert_almost_equal(odf, odf_from_sh, 10)
def test_mapmri_odf(): gtab = get_3shell_gtab() # load symmetric 724 sphere sphere = get_sphere('symmetric724') # load icosahedron sphere sphere2 = create_unit_sphere(5) evals = np.array(([0.0017, 0.0003, 0.0003], [0.0017, 0.0003, 0.0003])) data, golden_directions = MultiTensor(gtab, evals, S0=1.0, angles=[(0, 0), (90, 0)], fractions=[50, 50], snr=None) map_model = MapmriModel(gtab, radial_order=4) # symmetric724 mapfit = map_model.fit(data) odf = mapfit.odf(sphere) directions, _, _ = peak_directions(odf, sphere, .35, 25) assert_equal(len(directions), 2) assert_almost_equal(angular_similarity(directions, golden_directions), 2, 1) # 5 subdivisions odf = mapfit.odf(sphere2) directions, _, _ = peak_directions(odf, sphere2, .35, 25) assert_equal(len(directions), 2) assert_almost_equal(angular_similarity(directions, golden_directions), 2, 1) sb_dummies = sticks_and_ball_dummies(gtab) for sbd in sb_dummies: data, golden_directions = sb_dummies[sbd] mapfit = map_model.fit(data) odf = mapfit.odf(sphere2) directions, _, _ = peak_directions(odf, sphere2, .35, 25) if len(directions) <= 3: assert_equal(len(directions), len(golden_directions)) if len(directions) > 3: assert_equal(gfa(odf) < 0.1, True)
def test_mapmri_metrics_anisotropic(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=0) # test MAPMRI q-space indices mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False) mapfit = mapm.fit(S) tau = 1 / (4 * np.pi**2) # ground truth indices estimated from the DTI tensor rtpp_gt = 1. / (2 * np.sqrt(np.pi * l1 * tau)) rtap_gt = (1. / (2 * np.sqrt(np.pi * l2 * tau)) * 1. / (2 * np.sqrt(np.pi * l3 * tau))) rtop_gt = rtpp_gt * rtap_gt msd_gt = 2 * (l1 + l2 + l3) * tau qiv_gt = ((64 * np.pi**(7 / 2.) * (l1 * l2 * l3 * tau**3)**(3 / 2.)) / ((l2 * l3 + l1 * (l2 + l3)) * tau**2)) assert_almost_equal(mapfit.rtap(), rtap_gt, 5) assert_almost_equal(mapfit.rtpp(), rtpp_gt, 5) assert_almost_equal(mapfit.rtop(), rtop_gt, 5) with warnings.catch_warnings(record=True) as w: ng = mapfit.ng() ng_parallel = mapfit.ng_parallel() ng_perpendicular = mapfit.ng_perpendicular() assert_equal(len(w), 3) for l_w in w: assert_(issubclass(l_w.category, UserWarning)) assert_("model bval_threshold must be lower than 2000".lower() in str(l_w.message).lower()) assert_almost_equal(ng, 0., 5) assert_almost_equal(ng_parallel, 0., 5) assert_almost_equal(ng_perpendicular, 0., 5) assert_almost_equal(mapfit.msd(), msd_gt, 5) assert_almost_equal(mapfit.qiv(), qiv_gt, 5)
def test_mapmri_odf(): gtab = get_3shell_gtab() # load symmetric 724 sphere sphere = get_sphere('symmetric724') # load icosahedron sphere sphere2 = create_unit_sphere(5) evals = np.array(([0.0017, 0.0003, 0.0003], [0.0017, 0.0003, 0.0003])) data, golden_directions = MultiTensor( gtab, evals, S0=1.0, angles=[(0, 0), (90, 0)], fractions=[50, 50], snr=None) map_model = MapmriModel(gtab, radial_order=4) # symmetric724 mapfit = map_model.fit(data) odf = mapfit.odf(sphere) directions, _, _ = peak_directions(odf, sphere, .35, 25) assert_equal(len(directions), 2) assert_almost_equal( angular_similarity(directions, golden_directions), 2, 1) # 5 subdivisions odf = mapfit.odf(sphere2) directions, _, _ = peak_directions(odf, sphere2, .35, 25) assert_equal(len(directions), 2) assert_almost_equal( angular_similarity(directions, golden_directions), 2, 1) sb_dummies = sticks_and_ball_dummies(gtab) for sbd in sb_dummies: data, golden_directions = sb_dummies[sbd] mapfit = map_model.fit(data) odf = mapfit.odf(sphere2) directions, _, _ = peak_directions(odf, sphere2, .35, 25) if len(directions) <= 3: assert_equal(len(directions), len(golden_directions)) if len(directions) > 3: assert_equal(gfa(odf) < 0.1, True)
def test_mapmri_pdf_integral_unity(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3) sphere = default_sphere # test MAPMRI fitting mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.02) mapfit = mapm.fit(S) c_map = mapfit.mapmri_coeff # test if the analytical integral of the pdf is equal to one indices = mapmri_index_matrix(radial_order) integral = 0 for i in range(indices.shape[0]): n1, n2, n3 = indices[i] integral += c_map[i] * int_func(n1) * int_func(n2) * int_func(n3) assert_almost_equal(integral, 1.0, 3) # test if numerical integral of odf is equal to one odf = mapfit.odf(sphere, s=0) odf_sum = odf.sum() / sphere.vertices.shape[0] * (4 * np.pi) assert_almost_equal(odf_sum, 1.0, 2) # do the same for isotropic implementation radius_max = 0.04 # 40 microns gridsize = 17 r_points = mapmri.create_rspace(gridsize, radius_max) with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=descoteaux07_legacy_msg, category=PendingDeprecationWarning) mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.02, anisotropic_scaling=False) mapfit = mapm.fit(S) with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=descoteaux07_legacy_msg, category=PendingDeprecationWarning) pdf = mapfit.pdf(r_points) pdf[r_points[:, 2] == 0.] /= 2 # for antipodal symmetry on z-plane point_volume = (radius_max / (gridsize // 2))**3 integral = pdf.sum() * point_volume * 2 assert_almost_equal(integral, 1.0, 3) with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=descoteaux07_legacy_msg, category=PendingDeprecationWarning) odf = mapfit.odf(sphere, s=0) odf_sum = odf.sum() / sphere.vertices.shape[0] * (4 * np.pi) assert_almost_equal(odf_sum, 1.0, 2)
def test_mapmri_isotropic_static_scale_factor(radial_order=6): gtab = get_gtab_taiwan_dsi() D = 0.7e-3 tau = 1 / (4 * np.pi**2) mu = np.sqrt(D * 2 * tau) l1, l2, l3 = [D, D, D] S = single_tensor(gtab, evals=np.r_[l1, l2, l3]) S_array = np.tile(S, (5, 1)) stat_weight = 0.1 with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=descoteaux07_legacy_msg, category=PendingDeprecationWarning) mapm_scale_stat_reg_stat = MapmriModel(gtab, radial_order=radial_order, anisotropic_scaling=False, dti_scale_estimation=False, static_diffusivity=D, laplacian_regularization=True, laplacian_weighting=stat_weight) mapm_scale_adapt_reg_stat = MapmriModel( gtab, radial_order=radial_order, anisotropic_scaling=False, dti_scale_estimation=True, laplacian_regularization=True, laplacian_weighting=stat_weight) start = time.time() mapf_scale_stat_reg_stat = mapm_scale_stat_reg_stat.fit(S_array) time_scale_stat_reg_stat = time.time() - start start = time.time() mapf_scale_adapt_reg_stat = mapm_scale_adapt_reg_stat.fit(S_array) time_scale_adapt_reg_stat = time.time() - start # test if indeed the scale factor is fixed now assert_equal(np.all(mapf_scale_stat_reg_stat.mu == mu), True) # test if computation time is shorter (except on Windows): if not platform.system() == "Windows": assert_equal( time_scale_stat_reg_stat < time_scale_adapt_reg_stat, True, "mapf_scale_stat_reg_stat ({0}s) slower than " "mapf_scale_adapt_reg_stat ({1}s). It should be the" " opposite.".format(time_scale_stat_reg_stat, time_scale_adapt_reg_stat)) # check if the fitted signal is the same with warnings.catch_warnings(): warnings.filterwarnings("ignore", message=descoteaux07_legacy_msg, category=PendingDeprecationWarning) assert_almost_equal(mapf_scale_stat_reg_stat.fitted_signal(), mapf_scale_adapt_reg_stat.fitted_signal())
def test_mapmri_isotropic_static_scale_factor(radial_order=6): gtab = get_gtab_taiwan_dsi() D = 0.7e-3 tau = 1 / (4 * np.pi**2) mu = np.sqrt(D * 2 * tau) l1, l2, l3 = [D, D, D] S = single_tensor(gtab, evals=np.r_[l1, l2, l3]) S_array = np.tile(S, (5, 1)) stat_weight = 0.1 mapm_scale_stat_reg_stat = MapmriModel(gtab, radial_order=radial_order, anisotropic_scaling=False, dti_scale_estimation=False, static_diffusivity=D, laplacian_regularization=True, laplacian_weighting=stat_weight) mapm_scale_adapt_reg_stat = MapmriModel(gtab, radial_order=radial_order, anisotropic_scaling=False, dti_scale_estimation=True, laplacian_regularization=True, laplacian_weighting=stat_weight) start = time.time() mapf_scale_stat_reg_stat = mapm_scale_stat_reg_stat.fit(S_array) time_scale_stat_reg_stat = time.time() - start start = time.time() mapf_scale_adapt_reg_stat = mapm_scale_adapt_reg_stat.fit(S_array) time_scale_adapt_reg_stat = time.time() - start # test if indeed the scale factor is fixed now assert_equal(np.all(mapf_scale_stat_reg_stat.mu == mu), True) # test if computation time is shorter (except on Windows): if not platform.system() == "Windows": assert_equal(time_scale_stat_reg_stat < time_scale_adapt_reg_stat, True) # check if the fitted signal is the same assert_almost_equal(mapf_scale_stat_reg_stat.fitted_signal(), mapf_scale_adapt_reg_stat.fitted_signal())
def test_positivity_constraint(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=60) S_noise = add_noise(S, snr=20, S0=100.) gridsize = 20 max_radius = 15e-3 # 20 microns maximum radius r_grad = mapmri.create_rspace(gridsize, max_radius) # The positivity constraint does not make the pdf completely positive # but greatly decreases the amount of negativity in the constrained points. # We test if the amount of negative pdf has decreased more than 90% mapmod_no_constraint = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, positivity_constraint=False) mapfit_no_constraint = mapmod_no_constraint.fit(S_noise) pdf = mapfit_no_constraint.pdf(r_grad) pdf_negative_no_constraint = pdf[pdf < 0].sum() mapmod_constraint = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, positivity_constraint=True, pos_grid=gridsize, pos_radius='adaptive') mapfit_constraint = mapmod_constraint.fit(S_noise) pdf = mapfit_constraint.pdf(r_grad) pdf_negative_constraint = pdf[pdf < 0].sum() assert_equal((pdf_negative_constraint / pdf_negative_no_constraint) < 0.1, True) # the same for isotropic scaling mapmod_no_constraint = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, positivity_constraint=False, anisotropic_scaling=False) mapfit_no_constraint = mapmod_no_constraint.fit(S_noise) pdf = mapfit_no_constraint.pdf(r_grad) pdf_negative_no_constraint = pdf[pdf < 0].sum() mapmod_constraint = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, positivity_constraint=True, anisotropic_scaling=False, pos_grid=gridsize, pos_radius='adaptive') mapfit_constraint = mapmod_constraint.fit(S_noise) pdf = mapfit_constraint.pdf(r_grad) pdf_negative_constraint = pdf[pdf < 0].sum() assert_equal((pdf_negative_constraint / pdf_negative_no_constraint) < 0.1, True)
def test_signal_fitting_equality_anisotropic_isotropic(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=60) gridsize = 17 radius_max = 0.02 r_points = mapmri.create_rspace(gridsize, radius_max) tenmodel = dti.TensorModel(gtab) evals = tenmodel.fit(S).evals tau = 1 / (4 * np.pi**2) # estimate isotropic scale factor u0 = mapmri.isotropic_scale_factor(evals * 2 * tau) mu = np.array([u0, u0, u0]) qvals = np.sqrt(gtab.bvals / tau) / (2 * np.pi) q = gtab.bvecs * qvals[:, None] M_aniso = mapmri.mapmri_phi_matrix(radial_order, mu, q) K_aniso = mapmri.mapmri_psi_matrix(radial_order, mu, r_points) M_iso = mapmri.mapmri_isotropic_phi_matrix(radial_order, u0, q) K_iso = mapmri.mapmri_isotropic_psi_matrix(radial_order, u0, r_points) coef_aniso = np.dot(np.linalg.pinv(M_aniso), S) coef_iso = np.dot(np.linalg.pinv(M_iso), S) # test if anisotropic and isotropic implementation produce equal results # if the same isotropic scale factors are used s_fitted_aniso = np.dot(M_aniso, coef_aniso) s_fitted_iso = np.dot(M_iso, coef_iso) assert_array_almost_equal(s_fitted_aniso, s_fitted_iso) # the same test for the PDF pdf_fitted_aniso = np.dot(K_aniso, coef_aniso) pdf_fitted_iso = np.dot(K_iso, coef_iso) assert_array_almost_equal(pdf_fitted_aniso / pdf_fitted_iso, np.ones_like(pdf_fitted_aniso), 3) # test if the implemented version also produces the same result mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, anisotropic_scaling=False) s_fitted_implemented_isotropic = mapm.fit(S).fitted_signal() # normalize non-implemented fitted signal with b0 value s_fitted_aniso_norm = s_fitted_aniso / s_fitted_aniso.max() assert_array_almost_equal(s_fitted_aniso_norm, s_fitted_implemented_isotropic) # test if norm of signal laplacians are the same laplacian_matrix_iso = mapmri.mapmri_isotropic_laplacian_reg_matrix( radial_order, mu[0]) ind_mat = mapmri.mapmri_index_matrix(radial_order) S_mat, T_mat, U_mat = mapmri.mapmri_STU_reg_matrices(radial_order) laplacian_matrix_aniso = mapmri.mapmri_laplacian_reg_matrix( ind_mat, mu, S_mat, T_mat, U_mat) norm_aniso = np.dot(coef_aniso, np.dot(coef_aniso, laplacian_matrix_aniso)) norm_iso = np.dot(coef_iso, np.dot(coef_iso, laplacian_matrix_iso)) assert_almost_equal(norm_iso, norm_aniso)
def test_mapmri_metrics(): gtab = get_gtab_taiwan_dsi() mevals = np.array(([0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003])) angl = [(0, 0), (60, 0)] S, sticks = MultiTensor(gtab, mevals, S0=100.0, angles=angl, fractions=[50, 50], snr=None) # since we are testing without noise we can use higher order and lower # lambdas, with respect to the default. radial_order = 6 lambd = 1e-8 # test mapmri_indices indices = mapmri_index_matrix(radial_order) n_c = indices.shape[0] F = radial_order / 2 n_gt = np.round(1 / 6.0 * (F + 1) * (F + 2) * (4 * F + 3)) assert_equal(n_c, n_gt) # test MAPMRI fitting mapm = MapmriModel(gtab, radial_order=radial_order, lambd=lambd) mapfit = mapm.fit(S) c_map = mapfit.mapmri_coeff R = mapfit.mapmri_R mu = mapfit.mapmri_mu S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst)**2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # test if the analytical integral of the pdf is equal to one integral = 0 for i in range(indices.shape[0]): n1, n2, n3 = indices[i] integral += c_map[i] * int_func(n1) * int_func(n2) * int_func(n3) assert_almost_equal(integral, 1.0, 3) # compare the shore pdf with the ground truth multi_tensor pdf sphere = get_sphere('symmetric724') v = sphere.vertices radius = 10e-3 r_points = v * radius pdf_mt = multi_tensor_pdf(r_points, mevals=mevals, angles=angl, fractions=[50, 50]) pdf_map = mapmri_EAP(r_points, radial_order, c_map, mu, R) nmse_pdf = np.sqrt(np.sum((pdf_mt - pdf_map)**2)) / (pdf_mt.sum()) assert_almost_equal(nmse_pdf, 0.0, 2) # test MAPMRI metrics tau = 1 / (4 * np.pi**2) angl = [(0, 0), (0, 0)] S, sticks = MultiTensor(gtab, mevals, S0=100.0, angles=angl, fractions=[50, 50], snr=None) mapm = MapmriModel(gtab, radial_order=radial_order, lambd=lambd) mapfit = mapm.fit(S) # RTOP gt_rtop = 1.0 / np.sqrt( (4 * np.pi * tau)**3 * mevals[0, 0] * mevals[0, 1] * mevals[0, 2]) rtop = mapfit.rtop() assert_almost_equal(rtop, gt_rtop, 4) # RTAP gt_rtap = 1.0 / np.sqrt((4 * np.pi * tau)**2 * mevals[0, 1] * mevals[0, 2]) rtap = mapfit.rtap() assert_almost_equal(rtap, gt_rtap, 4) # RTPP gt_rtpp = 1.0 / np.sqrt((4 * np.pi * tau) * mevals[0, 0]) rtpp = mapfit.rtpp() assert_almost_equal(rtpp, gt_rtpp, 4)
def test_mapmri_signal_fitting(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3) mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.02) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # Test with multidimensional signals: mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.02) # Each voxel is identical: mapfit = mapm.fit(S[:, None, None].T * np.ones((3, 3, 3, S.shape[0]))) # Predict back with an array of ones or a single value: for S0 in [S[0], np.ones((3, 3, 3, 203))]: S_reconst = mapfit.predict(gtab, S0=S0) # test the signal reconstruction for one voxel: nmse_signal = (np.sqrt(np.sum((S - S_reconst[0, 0, 0]) ** 2)) / (S.sum())) assert_almost_equal(nmse_signal, 0.0, 3) # do the same for isotropic implementation mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001, anisotropic_scaling=False) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # do the same without the positivity constraint: mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001, positivity_constraint=False, anisotropic_scaling=False) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # Repeat with a gtab with big_delta and small_delta: gtab.big_delta = 5 gtab.small_delta = 3 mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001, positivity_constraint=False, anisotropic_scaling=False) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) if mapmri.have_cvxopt: # Positivity constraint and anisotropic scaling: mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001, positivity_constraint=True, anisotropic_scaling=False, pos_radius=2) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # Positivity constraint and anisotropic scaling: mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=None, positivity_constraint=True, anisotropic_scaling=False, pos_radius=2) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 2)
def test_signal_fitting_equality_anisotropic_isotropic(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=60) gridsize = 17 radius_max = 0.02 r_points = mapmri.create_rspace(gridsize, radius_max) tenmodel = dti.TensorModel(gtab) evals = tenmodel.fit(S).evals tau = 1 / (4 * np.pi ** 2) # estimate isotropic scale factor u0 = mapmri.isotropic_scale_factor(evals * 2 * tau) mu = np.array([u0, u0, u0]) qvals = np.sqrt(gtab.bvals / tau) / (2 * np.pi) q = gtab.bvecs * qvals[:, None] M_aniso = mapmri.mapmri_phi_matrix(radial_order, mu, q) K_aniso = mapmri.mapmri_psi_matrix(radial_order, mu, r_points) M_iso = mapmri.mapmri_isotropic_phi_matrix(radial_order, u0, q) K_iso = mapmri.mapmri_isotropic_psi_matrix(radial_order, u0, r_points) coef_aniso = np.dot(np.linalg.pinv(M_aniso), S) coef_iso = np.dot(np.linalg.pinv(M_iso), S) # test if anisotropic and isotropic implementation produce equal results # if the same isotropic scale factors are used s_fitted_aniso = np.dot(M_aniso, coef_aniso) s_fitted_iso = np.dot(M_iso, coef_iso) assert_array_almost_equal(s_fitted_aniso, s_fitted_iso) # the same test for the PDF pdf_fitted_aniso = np.dot(K_aniso, coef_aniso) pdf_fitted_iso = np.dot(K_iso, coef_iso) assert_array_almost_equal(pdf_fitted_aniso / pdf_fitted_iso, np.ones_like(pdf_fitted_aniso), 3) # test if the implemented version also produces the same result mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, anisotropic_scaling=False) s_fitted_implemented_isotropic = mapm.fit(S).fitted_signal() # normalize non-implemented fitted signal with b0 value s_fitted_aniso_norm = s_fitted_aniso / s_fitted_aniso.max() assert_array_almost_equal(s_fitted_aniso_norm, s_fitted_implemented_isotropic) # test if norm of signal laplacians are the same laplacian_matrix_iso = mapmri.mapmri_isotropic_laplacian_reg_matrix( radial_order, mu[0]) ind_mat = mapmri.mapmri_index_matrix(radial_order) S_mat, T_mat, U_mat = mapmri.mapmri_STU_reg_matrices(radial_order) laplacian_matrix_aniso = mapmri.mapmri_laplacian_reg_matrix( ind_mat, mu, S_mat, T_mat, U_mat) norm_aniso = np.dot(coef_aniso, np.dot(coef_aniso, laplacian_matrix_aniso)) norm_iso = np.dot(coef_iso, np.dot(coef_iso, laplacian_matrix_iso)) assert_almost_equal(norm_iso, norm_aniso)
print('data.shape (%d, %d, %d, %d)' % data.shape) """ data contains the voxel data and gtab contains a GradientTable object (gradient information e.g. b-values). For example, to show the b-values it is possible to write print(gtab.bvals). Instantiate the MAPMRI Model. radial_order is the radial order of the MAPMRI basis. For details regarding the parameters see [Ozarslan2013]_. """ radial_order = 4 map_model = MapmriModel(gtab, radial_order=radial_order, lambd=2e-1, eap_cons=False) """ Fit the MAPMRI model to the data """ mapfit = map_model.fit(data_small) """ Load an odf reconstruction sphere """ sphere = get_sphere('symmetric724') """ Compute the ODFs """
def test_laplacian_regularization(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=60) S_noise = add_noise(S, snr=20, S0=100.) weight_array = np.linspace(0, .3, 301) mapmod_unreg = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, laplacian_weighting=weight_array) mapmod_laplacian_array = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting=weight_array) mapmod_laplacian_gcv = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting="GCV") # test the Generalized Cross Validation # test if GCV gives very low if there is no noise mapfit_laplacian_array = mapmod_laplacian_array.fit(S) assert_equal(mapfit_laplacian_array.lopt < 0.01, True) # test if GCV gives higher values if there is noise mapfit_laplacian_array = mapmod_laplacian_array.fit(S_noise) lopt_array = mapfit_laplacian_array.lopt assert_equal(lopt_array > 0.01, True) # test if continuous GCV gives the same the one based on an array mapfit_laplacian_gcv = mapmod_laplacian_gcv.fit(S_noise) lopt_gcv = mapfit_laplacian_gcv.lopt assert_almost_equal(lopt_array, lopt_gcv, 2) # test if laplacian reduced the norm of the laplacian in the reconstruction mu = mapfit_laplacian_gcv.mu laplacian_matrix = mapmri.mapmri_laplacian_reg_matrix( mapmod_laplacian_gcv.ind_mat, mu, mapmod_laplacian_gcv.S_mat, mapmod_laplacian_gcv.T_mat, mapmod_laplacian_gcv.U_mat) coef_unreg = mapmod_unreg.fit(S_noise)._mapmri_coef coef_laplacian = mapfit_laplacian_gcv._mapmri_coef laplacian_norm_unreg = np.dot( coef_unreg, np.dot(coef_unreg, laplacian_matrix)) laplacian_norm_laplacian = np.dot( coef_laplacian, np.dot(coef_laplacian, laplacian_matrix)) assert_equal(laplacian_norm_laplacian < laplacian_norm_unreg, True) # the same for isotropic scaling mapmod_unreg = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, laplacian_weighting=weight_array, anisotropic_scaling=False) mapmod_laplacian_array = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting=weight_array, anisotropic_scaling=False) mapmod_laplacian_gcv = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting="GCV", anisotropic_scaling=False) # test the Generalized Cross Validation # test if GCV gives zero if there is no noise mapfit_laplacian_array = mapmod_laplacian_array.fit(S) assert_equal(mapfit_laplacian_array.lopt < 0.01, True) # test if GCV gives higher values if there is noise mapfit_laplacian_array = mapmod_laplacian_array.fit(S_noise) lopt_array = mapfit_laplacian_array.lopt assert_equal(lopt_array > 0.01, True) # test if continuous GCV gives the same the one based on an array mapfit_laplacian_gcv = mapmod_laplacian_gcv.fit(S_noise) lopt_gcv = mapfit_laplacian_gcv.lopt assert_almost_equal(lopt_array, lopt_gcv, 2) # test if laplacian reduced the norm of the laplacian in the reconstruction mu = mapfit_laplacian_gcv.mu laplacian_matrix = mapmri.mapmri_isotropic_laplacian_reg_matrix( radial_order, mu[0]) coef_unreg = mapmod_unreg.fit(S_noise)._mapmri_coef coef_laplacian = mapfit_laplacian_gcv._mapmri_coef laplacian_norm_unreg = np.dot( coef_unreg, np.dot(coef_unreg, laplacian_matrix)) laplacian_norm_laplacian = np.dot( coef_laplacian, np.dot(coef_laplacian, laplacian_matrix)) assert_equal(laplacian_norm_laplacian < laplacian_norm_unreg, True)
def test_laplacian_regularization(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3, angle2=60) S_noise = add_noise(S, snr=20, S0=100.) weight_array = np.linspace(0, .3, 301) mapmod_unreg = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, laplacian_weighting=weight_array) mapmod_laplacian_array = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting=weight_array) mapmod_laplacian_gcv = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting="GCV") # test the Generalized Cross Validation # test if GCV gives very low if there is no noise mapfit_laplacian_array = mapmod_laplacian_array.fit(S) assert_equal(mapfit_laplacian_array.lopt < 0.01, True) # test if GCV gives higher values if there is noise mapfit_laplacian_array = mapmod_laplacian_array.fit(S_noise) lopt_array = mapfit_laplacian_array.lopt assert_equal(lopt_array > 0.01, True) # test if continuous GCV gives the same the one based on an array mapfit_laplacian_gcv = mapmod_laplacian_gcv.fit(S_noise) lopt_gcv = mapfit_laplacian_gcv.lopt assert_almost_equal(lopt_array, lopt_gcv, 2) # test if laplacian reduced the norm of the laplacian in the reconstruction mu = mapfit_laplacian_gcv.mu laplacian_matrix = mapmri.mapmri_laplacian_reg_matrix( mapmod_laplacian_gcv.ind_mat, mu, mapmod_laplacian_gcv.S_mat, mapmod_laplacian_gcv.T_mat, mapmod_laplacian_gcv.U_mat) coef_unreg = mapmod_unreg.fit(S_noise)._mapmri_coef coef_laplacian = mapfit_laplacian_gcv._mapmri_coef laplacian_norm_unreg = np.dot(coef_unreg, np.dot(coef_unreg, laplacian_matrix)) laplacian_norm_laplacian = np.dot(coef_laplacian, np.dot(coef_laplacian, laplacian_matrix)) assert_equal(laplacian_norm_laplacian < laplacian_norm_unreg, True) # the same for isotropic scaling mapmod_unreg = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=False, laplacian_weighting=weight_array, anisotropic_scaling=False) mapmod_laplacian_array = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting=weight_array, anisotropic_scaling=False) mapmod_laplacian_gcv = MapmriModel(gtab, radial_order=radial_order, laplacian_regularization=True, laplacian_weighting="GCV", anisotropic_scaling=False) # test the Generalized Cross Validation # test if GCV gives zero if there is no noise mapfit_laplacian_array = mapmod_laplacian_array.fit(S) assert_equal(mapfit_laplacian_array.lopt < 0.01, True) # test if GCV gives higher values if there is noise mapfit_laplacian_array = mapmod_laplacian_array.fit(S_noise) lopt_array = mapfit_laplacian_array.lopt assert_equal(lopt_array > 0.01, True) # test if continuous GCV gives the same the one based on an array mapfit_laplacian_gcv = mapmod_laplacian_gcv.fit(S_noise) lopt_gcv = mapfit_laplacian_gcv.lopt assert_almost_equal(lopt_array, lopt_gcv, 2) # test if laplacian reduced the norm of the laplacian in the reconstruction mu = mapfit_laplacian_gcv.mu laplacian_matrix = mapmri.mapmri_isotropic_laplacian_reg_matrix( radial_order, mu[0]) coef_unreg = mapmod_unreg.fit(S_noise)._mapmri_coef coef_laplacian = mapfit_laplacian_gcv._mapmri_coef laplacian_norm_unreg = np.dot(coef_unreg, np.dot(coef_unreg, laplacian_matrix)) laplacian_norm_laplacian = np.dot(coef_laplacian, np.dot(coef_laplacian, laplacian_matrix)) assert_equal(laplacian_norm_laplacian < laplacian_norm_unreg, True)
def test_mapmri_signal_fitting(radial_order=6): gtab = get_gtab_taiwan_dsi() l1, l2, l3 = [0.0015, 0.0003, 0.0003] S, _ = generate_signal_crossing(gtab, l1, l2, l3) mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.02) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst)**2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # Test with multidimensional signals: mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.02) # Each voxel is identical: mapfit = mapm.fit(S[:, None, None].T * np.ones((3, 3, 3, S.shape[0]))) # Predict back with an array of ones or a single value: for S0 in [S[0], np.ones((3, 3, 3, 203))]: S_reconst = mapfit.predict(gtab, S0=S0) # test the signal reconstruction for one voxel: nmse_signal = (np.sqrt(np.sum( (S - S_reconst[0, 0, 0])**2)) / (S.sum())) assert_almost_equal(nmse_signal, 0.0, 3) # do the same for isotropic implementation mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001, anisotropic_scaling=False) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst)**2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # do the same without the positivity constraint: mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001, positivity_constraint=False, anisotropic_scaling=False) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst)**2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # Repeat with a gtab with big_delta and small_delta: gtab.big_delta = 5 gtab.small_delta = 3 mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001, positivity_constraint=False, anisotropic_scaling=False) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst)**2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) if mapmri.have_cvxpy: # Positivity constraint and anisotropic scaling: mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=0.0001, positivity_constraint=True, anisotropic_scaling=False, pos_radius=2) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst)**2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 3) # Positivity constraint and anisotropic scaling: mapm = MapmriModel(gtab, radial_order=radial_order, laplacian_weighting=None, positivity_constraint=True, anisotropic_scaling=False, pos_radius=2) mapfit = mapm.fit(S) S_reconst = mapfit.predict(gtab, 1.0) # test the signal reconstruction S = S / S[0] nmse_signal = np.sqrt(np.sum((S - S_reconst)**2)) / (S.sum()) assert_almost_equal(nmse_signal, 0.0, 2)
def main(): parser = buildArgsParser() args = parser.parse_args() if args.isVerbose: logging.basicConfig(level=logging.DEBUG) if os.path.isfile(args.output): if args.overwrite: logging.debug('Overwriting "{0}".'.format(args.output)) else: parser.error( '"{0}" already exists! Use -f to overwrite it.'.format( args.output)) bvals_source, bvecs_source = read_bvals_bvecs(args.bvals_source, args.bvecs_source) if not is_normalized_bvecs(bvecs_source): logging.warning('Your source b-vectors do not seem normalized...') bvecs_source = normalize_bvecs(bvecs_source) if bvals_source.min() > 0: if bvals_source.min() > 20: raise ValueError('The minimal source b-value is greater than 20.' + ' This is highly suspicious. Please check ' + 'your data to ensure everything is correct.\n' + 'Value found: {0}'.format(bvals_source.min())) else: logging.warning('Warning: no b=0 image. Setting b0_threshold to ' + 'bvals.min() = {0}'.format(bvals_source.min())) gtab_source = gradient_table(bvals_source, bvecs_source, b0_threshold=bvals_source.min()) bvals_target, bvecs_target = read_bvals_bvecs(args.bvals_target, args.bvecs_target) if not is_normalized_bvecs(bvecs_target): logging.warning('Your output b-vectors do not seem normalized...') bvecs_target = normalize_bvecs(bvecs_target) if bvals_target.min() != 0: if bvals_target.min() > 20: raise ValueError('The minimal target b-value is greater than 20.' + ' This is highly suspicious. Please check ' + 'your data to ensure everything is correct.\n' + 'Value found: {0}'.format(bvals_target.min())) else: logging.warning('Warning: no b=0 image. Setting b0_threshold to ' + 'bvals.min() = {0}'.format(bvals_target.min())) gtab_target = gradient_table(bvals_target, bvecs_target, b0_threshold=bvals_target.min()) dwi_img_source = nib.load(args.input) data_source = dwi_img_source.get_data() data_target = np.zeros(list(data_source.shape)[:-1] + [len(bvals_target)]) if args.mask is not None: mask = nib.load(args.mask).get_data().astype('bool') else: mask = np.ones_like(data_source[..., 0], dtype=np.bool) mapmri = MapmriModel(gtab_source, radial_order=args.radial_order, lambd=args.lambd, anisotropic_scaling=args.anisotropic_scaling, eap_cons=args.eap_cons, bmax_threshold=args.bmax_threshold) nbr_voxels_total = mask.sum() nbr_voxels_done = 0 for idx in np.ndindex(mask.shape): if mask[idx] > 0: if nbr_voxels_done % 100 == 0: logging.warning("{}/{} voxels dones".format( nbr_voxels_done, nbr_voxels_total)) fit = mapmri.fit(data_source[idx], mask=mask) data_target[idx] = fit.predict(gtab_target) nbr_voxels_done += 1 # header information is updated accordingly by nibabel out_img = nib.Nifti1Image(data_target, dwi_img_source.get_affine(), dwi_img_source.get_header()) out_img.to_filename(args.output)
print('data.shape (%d, %d, %d, %d)' % data.shape) """ data contains the voxel data and gtab contains a GradientTable object (gradient information e.g. b-values). For example, to show the b-values it is possible to write print(gtab.bvals). Instantiate the MAPMRI Model. radial_order is the radial order of the MAPMRI basis. For details regarding the parameters see [Ozarslan2013]_. """ radial_order = 4 map_model = MapmriModel(gtab, radial_order=radial_order, lambd=2e-1, eap_cons=False) """ Fit the MAPMRI model to the data """ mapfit = map_model.fit(data_small) """ Load an odf reconstruction sphere """ sphere = get_sphere('symmetric724') """ Compute the ODFs