def test_shear_convergence_unittests(modeling_data): """ Unit and validation tests for the shear and convergence calculations """ helper_physics_functions(theo.compute_tangential_shear) helper_physics_functions(theo.compute_convergence) helper_physics_functions(theo.compute_reduced_tangential_shear) helper_physics_functions(theo.compute_magnification) reltol = modeling_data['theory_reltol'] # Validation Tests ------------------------- # NumCosmo makes different choices for constants (Msun). We make this conversion # by passing the ratio of SOLAR_MASS in kg from numcosmo and CLMM cfg = load_validation_config() constants_conversion = clc.SOLAR_MASS.value / cfg['TEST_CASE']['Msun[kg]'] # First compute SigmaCrit to correct cosmology changes cosmo = cfg['cosmo'] sigma_c = theo.compute_critical_surface_density( cosmo, cfg['GAMMA_PARAMS']['z_cluster'], cfg['z_source']) # Compute sigma_c in the new cosmology and get a correction factor sigma_c_undo = theo.compute_critical_surface_density( cosmo, cfg['GAMMA_PARAMS']['z_cluster'], cfg['z_source']) sigmac_corr = (sigma_c_undo / sigma_c) # Chech error is raised if too small radius assert_raises(ValueError, theo.compute_tangential_shear, 1.e-12, 1.e15, 4, 0.2, 0.45, cosmo) # Validate tangential shear gammat = theo.compute_tangential_shear(cosmo=cosmo, **cfg['GAMMA_PARAMS']) assert_allclose(gammat * sigmac_corr, cfg['numcosmo_profiles']['gammat'], reltol) # Validate convergence kappa = theo.compute_convergence(cosmo=cosmo, **cfg['GAMMA_PARAMS']) assert_allclose(kappa * sigmac_corr, cfg['numcosmo_profiles']['kappa'], reltol) # Validate reduced tangential shear assert_allclose( theo.compute_reduced_tangential_shear(cosmo=cosmo, **cfg['GAMMA_PARAMS']), gammat / (1.0 - kappa), 1.0e-10) assert_allclose(gammat * sigmac_corr / (1. - (kappa * sigmac_corr)), cfg['numcosmo_profiles']['gt'], 1.e2 * reltol) # Validate magnification assert_allclose( theo.compute_magnification(cosmo=cosmo, **cfg['GAMMA_PARAMS']), 1. / ((1 - kappa)**2 - abs(gammat)**2), 1.0e-10) assert_allclose(1. / ((1 - kappa)**2 - abs(gammat)**2), cfg['numcosmo_profiles']['mu'], 1.e2 * reltol) # Check that shear, reduced shear and convergence return zero and magnification returns one if source is in front of the cluster # First, check for a array of radius and single source z r = np.logspace(-2, 2, 10) z_cluster = 0.3 z_source = 0.2 assert_allclose( theo.compute_convergence(r, mdelta=1.e15, cdelta=4., z_cluster=z_cluster, z_source=z_source, cosmo=cosmo), np.zeros(len(r)), 1.0e-10) assert_allclose( theo.compute_tangential_shear(r, mdelta=1.e15, cdelta=4., z_cluster=z_cluster, z_source=z_source, cosmo=cosmo), np.zeros(len(r)), 1.0e-10) assert_allclose( theo.compute_reduced_tangential_shear(r, mdelta=1.e15, cdelta=4., z_cluster=z_cluster, z_source=z_source, cosmo=cosmo), np.zeros(len(r)), 1.0e-10) assert_allclose( theo.compute_magnification(r, mdelta=1.e15, cdelta=4., z_cluster=z_cluster, z_source=z_source, cosmo=cosmo), np.ones(len(r)), 1.0e-10) # Second, check a single radius and array of source z r = 1. z_source = [0.25, 0.1, 0.14, 0.02] assert_allclose( theo.compute_convergence(r, mdelta=1.e15, cdelta=4., z_cluster=z_cluster, z_source=z_source, cosmo=cosmo), np.zeros(len(z_source)), 1.0e-10) assert_allclose( theo.compute_tangential_shear(r, mdelta=1.e15, cdelta=4., z_cluster=z_cluster, z_source=z_source, cosmo=cosmo), np.zeros(len(z_source)), 1.0e-10) assert_allclose( theo.compute_reduced_tangential_shear(r, mdelta=1.e15, cdelta=4., z_cluster=z_cluster, z_source=z_source, cosmo=cosmo), np.zeros(len(z_source)), 1.0e-10) assert_allclose( theo.compute_magnification(r, mdelta=1.e15, cdelta=4., z_cluster=z_cluster, z_source=z_source, cosmo=cosmo), np.ones(len(z_source)), 1.0e-10) # Object Oriented tests m = theo.Modeling() m.set_cosmo(cosmo) m.set_halo_density_profile( halo_profile_model=cfg['GAMMA_PARAMS']['halo_profile_model']) m.set_concentration(cfg['GAMMA_PARAMS']['cdelta']) m.set_mass(cfg['GAMMA_PARAMS']['mdelta']) # First compute SigmaCrit to correct cosmology changes sigma_c = m.eval_critical_surface_density(cfg['GAMMA_PARAMS']['z_cluster'], cfg['GAMMA_PARAMS']['z_source']) # Compute sigma_c in the new cosmology and get a correction factor sigma_c_undo = m.eval_critical_surface_density( cfg['GAMMA_PARAMS']['z_cluster'], cfg['GAMMA_PARAMS']['z_source']) sigmac_corr = (sigma_c_undo / sigma_c) # Validate tangential shear profile_pars = (cfg['GAMMA_PARAMS']['r_proj'], cfg['GAMMA_PARAMS']['z_cluster'], cfg['GAMMA_PARAMS']['z_source']) gammat = m.eval_tangential_shear(*profile_pars) assert_allclose(gammat * sigmac_corr, cfg['numcosmo_profiles']['gammat'], reltol) # Validate convergence kappa = m.eval_convergence(*profile_pars) assert_allclose(kappa * sigmac_corr, cfg['numcosmo_profiles']['kappa'], reltol) # Validate reduced tangential shear assert_allclose(m.eval_reduced_tangential_shear(*profile_pars), gammat / (1.0 - kappa), 1.0e-10) assert_allclose(gammat * sigmac_corr / (1. - (kappa * sigmac_corr)), cfg['numcosmo_profiles']['gt'], 1.e2 * reltol) # Validate magnification assert_allclose(m.eval_magnification(*profile_pars), 1. / ((1 - kappa)**2 - abs(gammat)**2), 1.0e-10) assert_allclose(1. / ((1 - kappa)**2 - abs(gammat)**2), cfg['numcosmo_profiles']['mu'], 1.e2 * reltol) # Check that shear, reduced shear and convergence return zero and magnification returns one if source is in front of the cluster # First, check for a array of radius and single source z r = np.logspace(-2, 2, 10) z_cluster = 0.3 z_source = 0.2 assert_allclose(m.eval_convergence(r, z_cluster, z_source), np.zeros(len(r)), 1.0e-10) assert_allclose(m.eval_tangential_shear(r, z_cluster, z_source), np.zeros(len(r)), 1.0e-10) assert_allclose(m.eval_reduced_tangential_shear(r, z_cluster, z_source), np.zeros(len(r)), 1.0e-10) assert_allclose(m.eval_magnification(r, z_cluster, z_source), np.ones(len(r)), 1.0e-10) # Second, check a single radius and array of source z r = 1. z_source = [0.25, 0.1, 0.14, 0.02] assert_allclose(m.eval_convergence(r, z_cluster, z_source), np.zeros(len(z_source)), 1.0e-10) assert_allclose(m.eval_tangential_shear(r, z_cluster, z_source), np.zeros(len(z_source)), 1.0e-10) assert_allclose(m.eval_reduced_tangential_shear(r, z_cluster, z_source), np.zeros(len(z_source)), 1.0e-10) assert_allclose(m.eval_magnification(r, z_cluster, z_source), np.ones(len(z_source)), 1.0e-10)
def _generate_galaxy_catalog(cluster_m, cluster_z, cluster_c, cosmo, ngals, zsrc, Delta_SO=None, massdef=None, halo_profile_model=None, zsrc_min=None, zsrc_max=None, shapenoise=None, photoz_sigma_unscaled=None, field_size=None): """A private function that skips the sanity checks on derived properties. This function should only be used when called directly from `generate_galaxy_catalog`. For a detailed description of each of the parameters, see the documentation of `generate_galaxy_catalog`. """ # Set the source galaxy redshifts galaxy_catalog = _draw_source_redshifts(zsrc, zsrc_min, zsrc_max, ngals) # Add photo-z errors and pdfs to source galaxy redshifts if photoz_sigma_unscaled is not None: galaxy_catalog = _compute_photoz_pdfs(galaxy_catalog, photoz_sigma_unscaled) # Draw galaxy positions galaxy_catalog = _draw_galaxy_positions(galaxy_catalog, ngals, cluster_z, cosmo, field_size) # Compute the shear on each source galaxy gamt = compute_tangential_shear(galaxy_catalog['r_mpc'], mdelta=cluster_m, cdelta=cluster_c, z_cluster=cluster_z, z_source=galaxy_catalog['ztrue'], cosmo=cosmo, delta_mdef=Delta_SO, halo_profile_model=halo_profile_model, massdef=massdef, z_src_model='single_plane') gamx = np.zeros(ngals) kappa = compute_convergence(galaxy_catalog['r_mpc'], mdelta=cluster_m, cdelta=cluster_c, z_cluster=cluster_z, z_source=galaxy_catalog['z'], cosmo=cosmo, delta_mdef=Delta_SO, halo_profile_model=halo_profile_model, massdef=massdef, z_src_model='single_plane') galaxy_catalog['gammat'] = gamt galaxy_catalog['gammax'] = np.zeros(ngals) galaxy_catalog['posangle'] = np.arctan2(galaxy_catalog['y_mpc'], galaxy_catalog['x_mpc']) #corresponding shear1,2 components gam1 = -gamt * np.cos(2 * galaxy_catalog['posangle']) + gamx * np.sin( 2 * galaxy_catalog['posangle']) gam2 = -gamt * np.sin(2 * galaxy_catalog['posangle']) - gamx * np.cos( 2 * galaxy_catalog['posangle']) #instrinsic ellipticities e1_intrinsic = 0 e2_intrinsic = 0 # Add shape noise to source galaxy shears if shapenoise is not None: e1_intrinsic = shapenoise * np.random.standard_normal(ngals) e2_intrinsic = shapenoise * np.random.standard_normal(ngals) # Compute ellipticities galaxy_catalog['e1'], galaxy_catalog['e2'] = compute_lensed_ellipticity( e1_intrinsic, e2_intrinsic, gam1, gam2, kappa) if photoz_sigma_unscaled is not None: return galaxy_catalog['ra', 'dec', 'e1', 'e2', 'z', 'ztrue', 'pzbins', 'pzpdf'] return galaxy_catalog['ra', 'dec', 'e1', 'e2', 'z', 'ztrue']