def test_C2_watson_gamma_equals_gamma_watson(): scheme = wu_minn_hcp_acquisition_scheme() cylinder = cylinder_models.C2CylinderStejskalTannerApproximation() watsoncyl = distribute_models.SD1WatsonDistributed([cylinder]) gammawatsoncyl = distribute_models.DD1GammaDistributed( [watsoncyl], target_parameter='C2CylinderStejskalTannerApproximation_1_diameter') param_name = 'C2CylinderStejskalTannerApproximation_1_lambda_par' params1 = { 'SD1WatsonDistributed_1_' + param_name: 1.7e-9, 'DD1Gamma_1_alpha': 2., 'DD1Gamma_1_beta': 4e-6, 'SD1WatsonDistributed_1_SD1Watson_1_odi': 0.4, 'SD1WatsonDistributed_1_SD1Watson_1_mu': [0., 0.] } gammacyl = distribute_models.DD1GammaDistributed([cylinder]) watsongammacyl = distribute_models.SD1WatsonDistributed([gammacyl]) params2 = { 'DD1GammaDistributed_1_' + param_name: 1.7e-9, 'DD1GammaDistributed_1_DD1Gamma_1_alpha': 2., 'DD1GammaDistributed_1_DD1Gamma_1_beta': 4e-6, 'SD1Watson_1_odi': 0.4, 'SD1Watson_1_mu': [0., 0.] } assert_array_almost_equal(watsongammacyl(scheme, **params2), gammawatsoncyl(scheme, **params1), 5)
def test_all_fitted_model_properties(): stick = cylinder_models.C1Stick() watsonstick = distribute_models.SD1WatsonDistributed([stick]) params = {} for parameter, card, in watsonstick.parameter_cardinality.items(): params[parameter] = (np.random.rand(card) * watsonstick.parameter_scales[parameter]) data = np.atleast_2d(watsonstick(scheme, **params)) mcmod = modeling_framework.MultiCompartmentModel([watsonstick]) mcfit = mcmod.fit(scheme, data) vertices = np.random.rand(10, 3) vertices /= np.linalg.norm(vertices, axis=1)[:, None] assert_(isinstance(mcfit.fitted_parameters, dict)) assert_(isinstance(mcfit.fitted_parameters_vector, np.ndarray)) assert_(isinstance(mcfit.fod(vertices), np.ndarray)) assert_(isinstance(mcfit.fod_sh(), np.ndarray)) assert_(isinstance(mcfit.peaks_spherical(), np.ndarray)) assert_(isinstance(mcfit.peaks_cartesian(), np.ndarray)) assert_(isinstance(mcfit.mean_squared_error(data), np.ndarray)) assert_(isinstance(mcfit.R2_coefficient_of_determination(data), np.ndarray)) assert_(isinstance(mcfit.predict(), np.ndarray)) mcmod_sm = modeling_framework.MultiCompartmentSphericalMeanModel([stick]) mcfit_sm = mcmod_sm.fit(scheme, data) assert_(isinstance(mcfit_sm.fitted_parameters, dict)) assert_(isinstance(mcfit_sm.fitted_parameters_vector, np.ndarray)) assert_(isinstance(mcfit.mean_squared_error(data), np.ndarray)) assert_(isinstance(mcfit.R2_coefficient_of_determination(data), np.ndarray)) assert_(isinstance(mcfit.predict(), np.ndarray))
def test_equivalence_csd_and_parametric_fod( odi=0.15, mu=[0., 0.], lambda_par=1.7e-9): stick = cylinder_models.C1Stick() watsonstick = distribute_models.SD1WatsonDistributed( [stick]) params = {'SD1Watson_1_odi': odi, 'SD1Watson_1_mu': mu, 'C1Stick_1_lambda_par': lambda_par} data = watsonstick(scheme, **params) sh_mod = modeling_framework.MultiCompartmentSphericalHarmonicsModel( [stick]) sh_mod.set_fixed_parameter('C1Stick_1_lambda_par', lambda_par) sh_fit = sh_mod.fit(scheme, data) fod = sh_fit.fod(sphere.vertices) watson = distributions.SD1Watson(mu=[0., 0.], odi=0.15) sf = watson(sphere.vertices) assert_array_almost_equal(fod[0], sf, 2) fitted_signal = sh_fit.predict() assert_array_almost_equal(data, fitted_signal[0], 4)
def test_multi_compartment_fod_with_parametric_model( odi=0.15, mu=[0., 0.], lambda_iso=3e-9, lambda_par=1.7e-9, vf_intra=0.7): stick = cylinder_models.C1Stick() ball = gaussian_models.G1Ball() watsonstick = distribute_models.SD1WatsonDistributed( [stick]) mc_mod = modeling_framework.MultiCompartmentModel([watsonstick, ball]) sh_mod = modeling_framework.MultiCompartmentSphericalHarmonicsModel( [stick, ball]) sh_mod.set_fixed_parameter('G1Ball_1_lambda_iso', lambda_iso) sh_mod.set_fixed_parameter('C1Stick_1_lambda_par', lambda_par) simulation_parameters = mc_mod.parameters_to_parameter_vector( G1Ball_1_lambda_iso=lambda_iso, SD1WatsonDistributed_1_SD1Watson_1_mu=mu, SD1WatsonDistributed_1_C1Stick_1_lambda_par=lambda_par, SD1WatsonDistributed_1_SD1Watson_1_odi=odi, partial_volume_0=vf_intra, partial_volume_1=1 - vf_intra) data = mc_mod.simulate_signal(scheme, simulation_parameters) sh_fit = sh_mod.fit(scheme, data) vf_intra_estimated = sh_fit.fitted_parameters['partial_volume_0'] assert_almost_equal(vf_intra, vf_intra_estimated) predicted_signal = sh_fit.predict() assert_array_almost_equal(data, predicted_signal[0], 4)
def test_laplacian_and_AI_with_regularization(odi=0.15, mu=[0., 0.], lambda_par=1.7e-9): stick = cylinder_models.C1Stick() watsonstick = distribute_models.SD1WatsonDistributed([stick]) params = { 'SD1Watson_1_odi': odi, 'SD1Watson_1_mu': mu, 'C1Stick_1_lambda_par': lambda_par } data = watsonstick(scheme, **params) sh_mod = modeling_framework.MultiCompartmentSphericalHarmonicsModel( [stick]) sh_mod.set_fixed_parameter('C1Stick_1_lambda_par', lambda_par) for solver in ['csd_tournier07', 'csd_cvxpy']: sh_fit = sh_mod.fit(scheme, data, solver=solver, lambda_lb=0.) sh_fit_reg = sh_mod.fit(scheme, data, solver=solver, lambda_lb=1e-3) ai = sh_fit.anisotropy_index() lb = sh_fit.norm_of_laplacian_fod() ai_reg = sh_fit_reg.anisotropy_index() lb_reg = sh_fit_reg.norm_of_laplacian_fod() assert_(ai > ai_reg) assert_(lb > lb_reg)
def test_spherical_harmonics_model_raises(odi=0.15, mu=[0., 0.], lambda_par=1.7e-9): stick = cylinder_models.C1Stick() ball = gaussian_models.G1Ball() watsonstick = distribute_models.SD1WatsonDistributed([stick]) params = { 'SD1Watson_1_odi': odi, 'SD1Watson_1_mu': mu, 'C1Stick_1_lambda_par': lambda_par } data = watsonstick(scheme, **params) assert_raises(ValueError, modeling_framework.MultiCompartmentSphericalHarmonicsModel, [ball]) sh_mod = modeling_framework.MultiCompartmentSphericalHarmonicsModel( [stick]) assert_raises(ValueError, sh_mod.fit, scheme, data, solver='csd_cvxpy') sh_mod = modeling_framework.MultiCompartmentSphericalHarmonicsModel( [stick, ball]) sh_mod.set_fixed_parameter('C1Stick_1_lambda_par', lambda_par) sh_mod.set_fixed_parameter('G1Ball_1_lambda_iso', 3e-9) assert_raises(ValueError, sh_mod.fit, scheme, data, solver='csd_tournier07')
def test_set_fixed_parameter_raises(): cyl = cylinder_models.C1Stick() distcyl = distribute_models.SD1WatsonDistributed([cyl]) assert_raises(ValueError, distcyl.set_fixed_parameter, 'SD1Watson_1_odi', [1]) assert_raises(ValueError, distcyl.set_fixed_parameter, 'SD1Watson_1_mu', [1]) assert_raises(ValueError, distcyl.set_fixed_parameter, 'blabla', [1])
def test_set_equal_param(): cylinder = cylinder_models.C2CylinderStejskalTannerApproximation() watsoncyl = distribute_models.SD1WatsonDistributed([cylinder]) p1 = 'C2CylinderStejskalTannerApproximation_1_lambda_par' p2 = 'C2CylinderStejskalTannerApproximation_1_diameter' watsoncyl.set_equal_parameter(p1, p2) isnone = False reset = watsoncyl.set_equal_parameter(p1, p2) if reset is None: isnone = True assert_equal(isnone, True)
def test_C4_watson_gamma_equals_gamma_watson(): scheme = wu_minn_hcp_acquisition_scheme() cylinder = cylinder_models.C4CylinderGaussianPhaseApproximation() watsoncyl = distribute_models.SD1WatsonDistributed([cylinder]) gammawatsoncyl = distribute_models.DD1GammaDistributed( [watsoncyl], target_parameter='C4CylinderGaussianPhaseApproximation_1_diameter') param = 'SD1WatsonDistributed_1_C4CylinderGaussianPhaseApproximation' param += '_1_lambda_par' params1 = { param: 1.7e-9, 'DD1Gamma_1_alpha': 2., 'DD1Gamma_1_beta': 4e-6, 'SD1WatsonDistributed_1_SD1Watson_1_odi': 0.4, 'SD1WatsonDistributed_1_SD1Watson_1_mu': [0., 0.] } gammacyl = distribute_models.DD1GammaDistributed([cylinder]) watsongammacyl = distribute_models.SD1WatsonDistributed( [gammacyl], target_parameter='C4CylinderGaussianPhaseApproximation_1_mu') param = 'DD1GammaDistributed_1_C4CylinderGaussianPhaseApproximation' param += '_1_lambda_par' params2 = { param: 1.7e-9, 'DD1GammaDistributed_1_DD1Gamma_1_alpha': 2., 'DD1GammaDistributed_1_DD1Gamma_1_beta': 4e-6, 'SD1Watson_1_odi': 0.4, 'SD1Watson_1_mu': [0., 0.] } assert_array_almost_equal(watsongammacyl(scheme, **params2), gammawatsoncyl(scheme, **params1), 5)
def test_equivalence_sh_distributed_mc_with_mcsh(): """ We test if we can input a Watson-distributed zeppelin and stick into an SD3SphericalHarmonicsDistributedModel in an MC-model, and compare it with an MCSH model with the same watson distribution as a kernel. """ stick = cylinder_models.C1Stick() zep = gaussian_models.G2Zeppelin() mck_dist = distribute_models.SD1WatsonDistributed([stick, zep]) mck_dist.set_equal_parameter('G2Zeppelin_1_lambda_par', 'C1Stick_1_lambda_par') mck_dist.set_tortuous_parameter('G2Zeppelin_1_lambda_perp', 'G2Zeppelin_1_lambda_par', 'partial_volume_0') mcsh = modeling_framework.MultiCompartmentSphericalHarmonicsModel( models=[mck_dist], sh_order=8) mc = modeling_framework.MultiCompartmentModel([ distribute_models.SD3SphericalHarmonicsDistributed([mck_dist], sh_order=8) ]) lambda_par = 0. odi = .02 sh_coeff = np.ones(45) sh_coeff[0] = 1 / (2 * np.sqrt(np.pi)) pv0 = .3 params_mcsh = { 'SD1WatsonDistributed_1_partial_volume_0': pv0, 'SD1WatsonDistributed_1_G2Zeppelin_1_lambda_par': lambda_par, 'SD1WatsonDistributed_1_SD1Watson_1_odi': odi, 'sh_coeff': sh_coeff } basemod = 'SD3SphericalHarmonicsDistributed_1_' params_mc = { basemod + 'SD1WatsonDistributed_1_partial_volume_0': pv0, basemod + 'SD1WatsonDistributed_1_G2Zeppelin_1_lambda_par': lambda_par, basemod + 'SD1WatsonDistributed_1_SD1Watson_1_odi': odi, basemod + 'SD3SphericalHarmonics_1_sh_coeff': sh_coeff } E_mcsh = mcsh.simulate_signal(scheme, params_mcsh) E_mc = mc.simulate_signal(scheme, params_mc) np.testing.assert_array_almost_equal(E_mcsh, E_mc)
def test_construction_observation_matrix( odi=0.15, mu=[0., 0.], lambda_par=1.7e-9, lmax=8): stick = cylinder_models.C1Stick(lambda_par=lambda_par) watsonstick = distribute_models.SD1WatsonDistributed( [stick]) params = {'SD1Watson_1_odi': odi, 'SD1Watson_1_mu': mu, 'C1Stick_1_lambda_par': lambda_par} data = watsonstick(scheme, **params) watson = distributions.SD1Watson(mu=mu, odi=odi) sh_watson = watson.spherical_harmonics_representation(lmax) stick_rh = stick.rotational_harmonics_representation(scheme) A = construct_model_based_A_matrix(scheme, stick_rh, lmax) data_approximated = A.dot(sh_watson) np.testing.assert_array_almost_equal(data_approximated, data, 4)
def _make_single_and_crossing(): zeppelin = G2Zeppelin(lambda_par=1.7e-9, lambda_perp=1e-9, mu=[0., 0.]) data_aniso = zeppelin(scheme) S0_aniso, aniso_model = estimate_TR2_anisotropic_tissue_response_model( scheme, np.atleast_2d(data_aniso)) watson_mod = distribute_models.SD1WatsonDistributed([aniso_model]) watson_params_par = { 'SD1Watson_1_mu': np.array([0., 0.]), 'SD1Watson_1_odi': .2 } watson_params_perp = { 'SD1Watson_1_mu': np.array([np.pi / 2., np.pi / 2.]), 'SD1Watson_1_odi': .2 } data_watson_par = watson_mod(scheme, **watson_params_par) data_watson_perp = watson_mod(scheme, **watson_params_perp) data_cross = np.array( [data_watson_par, data_watson_par + data_watson_perp]) return data_cross
def test_watson_dispersed_stick_tortuous_zeppelin(): stick = cylinder_models.C1Stick() zeppelin = gaussian_models.G2Zeppelin() watson_bundle = distribute_models.SD1WatsonDistributed( models=[stick, zeppelin]) watson_bundle.set_tortuous_parameter( 'G2Zeppelin_1_lambda_perp', 'G2Zeppelin_1_lambda_par', 'partial_volume_0' ) watson_bundle.set_equal_parameter( 'G2Zeppelin_1_lambda_par', 'C1Stick_1_lambda_par') watson_bundle.set_fixed_parameter( 'G2Zeppelin_1_lambda_par', 1.7e-9) mc_watson = ( modeling_framework.MultiCompartmentModel( models=[watson_bundle]) ) beta0 = camino_dispersed.beta == 0. diff17 = camino_dispersed.diffusivities == 1.7e-9 mask = np.all([beta0, diff17], axis=0) E_watson = camino_dispersed.signal_attenuation[mask] fractions_watson = camino_dispersed.fractions[mask] fitted_params = ( mc_watson.fit(scheme, E_watson[::20]).fitted_parameters ) mean_abs_error = np.mean( abs(fitted_params['SD1WatsonDistributed_1_partial_volume_0'].squeeze( ) - fractions_watson[::20])) assert_equal(mean_abs_error < 0.03, True)
def test_parametric_fod_spherical_mean_model(): stick = cylinder_models.C1Stick() watsonstick = distribute_models.SD1WatsonDistributed([stick]) params = {} for parameter, card, in watsonstick.parameter_cardinality.items(): params[parameter] = (np.random.rand(card) * watsonstick.parameter_scales[parameter]) data = np.atleast_2d(watsonstick(scheme, **params)) stick = cylinder_models.C1Stick() zeppelin = gaussian_models.G2Zeppelin() smt = modeling_framework.MultiCompartmentSphericalMeanModel( [stick, zeppelin]) smt.set_tortuous_parameter('G2Zeppelin_1_lambda_perp', 'C1Stick_1_lambda_par', 'partial_volume_0', 'partial_volume_1') smt.set_equal_parameter('G2Zeppelin_1_lambda_par', 'C1Stick_1_lambda_par') smt_fit = smt.fit(scheme, data) assert_raises(ValueError, smt_fit.return_parametric_fod_model, Ncompartments=1.5) assert_raises(ValueError, smt_fit.return_parametric_fod_model, Ncompartments=0) assert_raises(ValueError, smt_fit.return_parametric_fod_model, distribution='bla') for distribution_name in ['watson', 'bingham']: fod_model = smt_fit.return_parametric_fod_model( distribution=distribution_name, Ncompartments=1) fitted_fod_model = fod_model.fit(scheme, data) assert_(isinstance(fitted_fod_model.fitted_parameters, dict))
def test_tissue_response_model_multi_compartment_models(): ball = G1Ball(lambda_iso=2.5e-9) data_iso = ball(scheme) data_iso_sm = ball.spherical_mean(scheme) S0_iso, iso_model = estimate_TR1_isotropic_tissue_response_model( scheme, np.atleast_2d(data_iso)) zeppelin = G2Zeppelin(lambda_par=1.7e-9, lambda_perp=1e-9, mu=[np.pi / 2, np.pi / 2]) data_aniso = zeppelin(scheme) data_aniso_sm = zeppelin.spherical_mean(scheme) S0_aniso, aniso_model = estimate_TR2_anisotropic_tissue_response_model( scheme, np.atleast_2d(data_aniso)) models = [iso_model, aniso_model] mc = MultiCompartmentModel(models) mc_smt = MultiCompartmentSphericalMeanModel(models) test_mc_data = 0.5 * data_iso + 0.5 * data_aniso test_mc_data_sm = 0.5 * data_iso_sm + 0.5 * data_aniso_sm test_data = [test_mc_data, test_mc_data_sm] params = { 'partial_volume_0': [0.5], 'partial_volume_1': [0.5], 'TR2AnisotropicTissueResponseModel_1_mu': np.array([np.pi / 2, np.pi / 2]) } mc_models = [mc, mc_smt] for model, data in zip(mc_models, test_data): data_mc = model(scheme, **params) assert_array_almost_equal(data, data_mc, 3) # csd model with single models mc_csd = MultiCompartmentSphericalHarmonicsModel([aniso_model]) watson_mod = distribute_models.SD1WatsonDistributed([aniso_model]) watson_params = { 'SD1Watson_1_mu': np.array([np.pi / 2, np.pi / 2]), 'SD1Watson_1_odi': .3 } data_watson = watson_mod(scheme, **watson_params) mc_csd_fit = mc_csd.fit(scheme, data_watson) assert_array_almost_equal(mc_csd_fit.predict()[0], data_watson, 2) # csd model with multiple models mc_csd = MultiCompartmentSphericalHarmonicsModel(models) watson_mod = distribute_models.SD1WatsonDistributed( [iso_model, aniso_model]) watson_params = { 'SD1Watson_1_mu': np.array([np.pi / 2, np.pi / 2]), 'SD1Watson_1_odi': .3, 'partial_volume_0': 0.5 } data_watson = watson_mod(scheme, **watson_params) mc_csd_fit = mc_csd.fit(scheme, data_watson) assert_array_almost_equal(mc_csd_fit.predict()[0], data_watson, 2) scheme_panagiotaki = panagiotaki_verdict_acquisition_scheme() assert_raises(ValueError, mc_csd.fit, acquisition_scheme=scheme_panagiotaki, data=data_watson)
def test_raise_spherical_distribution_in_spherical_mean(): zeppelin = gaussian_models.G2Zeppelin() watson = distribute_models.SD1WatsonDistributed([zeppelin]) assert_raises(ValueError, modeling_framework.MultiCompartmentSphericalMeanModel, [watson])
def test_multi_voxel_parametric_to_sm_to_sh_fod_watson(): stick = cylinder_models.C1Stick() zeppelin = gaussian_models.G2Zeppelin() watsonstick = distribute_models.SD1WatsonDistributed([stick, zeppelin]) watsonstick.set_equal_parameter('G2Zeppelin_1_lambda_par', 'C1Stick_1_lambda_par') watsonstick.set_tortuous_parameter('G2Zeppelin_1_lambda_perp', 'G2Zeppelin_1_lambda_par', 'partial_volume_0') mc_mod = modeling_framework.MultiCompartmentModel([watsonstick]) parameter_dict = { 'SD1WatsonDistributed_1_SD1Watson_1_mu': np.random.rand(10, 2), 'SD1WatsonDistributed_1_partial_volume_0': np.linspace(0.1, 0.9, 10), 'SD1WatsonDistributed_1_G2Zeppelin_1_lambda_par': np.linspace(1.5, 2.5, 10) * 1e-9, 'SD1WatsonDistributed_1_SD1Watson_1_odi': np.linspace(0.3, 0.7, 10) } data = mc_mod.simulate_signal(scheme, parameter_dict) sm_mod = modeling_framework.MultiCompartmentSphericalMeanModel( [stick, zeppelin]) sm_mod.set_equal_parameter('G2Zeppelin_1_lambda_par', 'C1Stick_1_lambda_par') sm_mod.set_tortuous_parameter('G2Zeppelin_1_lambda_perp', 'G2Zeppelin_1_lambda_par', 'partial_volume_0', 'partial_volume_1') sf_watson = [] for mu, odi in zip( parameter_dict['SD1WatsonDistributed_1_SD1Watson_1_mu'], parameter_dict['SD1WatsonDistributed_1_SD1Watson_1_odi']): watson = distributions.SD1Watson(mu=mu, odi=odi) sf_watson.append(watson(sphere.vertices)) sf_watson = np.array(sf_watson) sm_fit = sm_mod.fit(scheme, data) sh_mod = sm_fit.return_spherical_harmonics_fod_model() sh_fit_auto = sh_mod.fit(scheme, data) # will pick tournier fod_tournier = sh_fit_auto.fod(sphere.vertices) assert_array_almost_equal(fod_tournier, sf_watson, 1) sh_fit_tournier = sh_mod.fit(scheme, data, solver='csd_tournier07', unity_constraint=False) fod_tournier = sh_fit_tournier.fod(sphere.vertices) assert_array_almost_equal(fod_tournier, sf_watson, 1) sh_fit_cvxpy = sh_mod.fit(scheme, data, solver='csd_cvxpy', unity_constraint=True, lambda_lb=0.) fod_cvxpy = sh_fit_cvxpy.fod(sphere.vertices) assert_array_almost_equal(fod_cvxpy, sf_watson, 2) sh_fit_cvxpy = sh_mod.fit(scheme, data, solver='csd_cvxpy', unity_constraint=False, lambda_lb=0.) fod_cvxpy = sh_fit_cvxpy.fod(sphere.vertices) assert_array_almost_equal(fod_cvxpy, sf_watson, 2)