def physical2lensing_conversion(self, kwargs_mass): """ :param kwargs_mass: list of keyword arguments of all the lens models. Einstein radius 'theta_E' are replaced by 'sigma_v', velocity dispersion in km/s, 'alpha_Rs' and 'Rs' of NFW profiles are replaced by 'M200' and 'concentration' :return: kwargs_lens in reduced deflection angles compatible with the lensModel instance of this module """ kwargs_lens = copy.deepcopy(kwargs_mass) for i in range(len(kwargs_mass)): kwargs_mass_i = kwargs_mass[i] if self._lens_redshift_list is None: z_lens = self._z_lens else: z_lens = self._lens_redshift_list[i] lens_cosmo = LensCosmo(z_lens, self._z_source_convention, cosmo=self._cosmo) if 'sigma_v' in kwargs_mass_i: sigma_v = kwargs_mass_i['sigma_v'] theta_E = lens_cosmo.sis_sigma_v2theta_E(sigma_v) kwargs_lens[i]['theta_E'] = theta_E del kwargs_lens[i]['sigma_v'] elif 'M200' in kwargs_mass_i: M200 = kwargs_mass_i['M200'] c = kwargs_mass_i['concentration'] Rs, alpha_RS = lens_cosmo.nfw_physical2angle(M200, c) kwargs_lens[i]['Rs'] = Rs kwargs_lens[i]['alpha_Rs'] = alpha_RS del kwargs_lens[i]['M200'] del kwargs_lens[i]['concentration'] return kwargs_lens
def get_theta_E_SIS(self, vel_disp_iso, z_lens, z_src): """Compute the Einstein radius for a given isotropic velocity dispersion assuming a singular isothermal sphere (SIS) mass profile Parameters ---------- vel_disp_iso : float isotropic velocity dispersion, or an approximation to it, in km/s z_lens : float the lens redshift z_src : float the source redshift Note ---- The computation is purely analytic. .. math:: \theta_E = 4 \pi \frac{\sigma_V^2}{c^2} \frac{D_{ls}}{D_s} Returns ------- float the Einstein radius for an SIS in arcsec """ lens_cosmo = LensCosmo(z_lens, z_src, cosmo=self.cosmo) theta_E_SIS = lens_cosmo.sis_sigma_v2theta_E(vel_disp_iso) return theta_E_SIS
def test_physical2lensing_conversion(self): lens_redshift_list = [0.5, 1] z_source_convention = 2 api = ModelAPI(lens_model_list=['SIS', 'NFW'], lens_redshift_list=lens_redshift_list, z_source_convention=z_source_convention, cosmo=None, z_source=z_source_convention) kwargs_mass = [{ 'sigma_v': 200, 'center_x': 0, 'center_y': 0 }, { 'M200': 10**13, 'concentration': 5, 'center_x': 1, 'center_y': 1 }] kwargs_lens = api.physical2lensing_conversion(kwargs_mass) theta_E = kwargs_lens[0]['theta_E'] lens_cosmo = LensCosmo(z_lens=lens_redshift_list[0], z_source=z_source_convention) theta_E_test = lens_cosmo.sis_sigma_v2theta_E( kwargs_mass[0]['sigma_v']) npt.assert_almost_equal(theta_E, theta_E_test, decimal=7) alpha_Rs = kwargs_lens[1]['alpha_Rs'] lens_cosmo = LensCosmo(z_lens=lens_redshift_list[1], z_source=z_source_convention) Rs_new, alpha_Rs_new = lens_cosmo.nfw_physical2angle( kwargs_mass[1]['M200'], kwargs_mass[1]['concentration']) npt.assert_almost_equal(alpha_Rs, alpha_Rs_new, decimal=7)
def get_lens_params(lens_info, z_src, cosmo): """Get SIE lens parameters into a form Lenstronomy understands Parameters ---------- lens_info : dict SIE lens and external shear parameters for a system, where `ellip_lens` is 1 minus the axis ratio z_src : float source redshift, required for Einstein radius approximation cosmo : astropy.cosmology object cosmology to use to get distances """ lens_phie_rad = np.pi * (lens_info['phie_lens'] / 180.0) + 0.5 * np.pi # in rad, origin at y-axis lens_e1, lens_e2 = param_util.phi_q2_ellipticity( lens_phie_rad, 1 - lens_info['ellip_lens']) # Instantiate cosmology-aware models lens_cosmo = LensCosmo(z_lens=lens_info['redshift'], z_source=z_src, cosmo=cosmo) theta_E = lens_cosmo.sis_sigma_v2theta_E(lens_info['vel_disp_lenscat']) lam = get_lambda_factor( lens_info['ellip_lens'] ) # removed because lenstronomy accepts the spherically-averaged Einstein radius as input phi, q = param_util.ellipticity2phi_q(lens_e1, lens_e2) gravlens_to_lenstronomy = np.sqrt( (1.0 + q**2.0) / (2.0 * q) ) # factor converting the grav lens ellipticity convention (square average) to lenstronomy's (product average) sie_mass = dict( center_x=0.0, center_y=0.0, #s_scale=0.0, theta_E=theta_E * gravlens_to_lenstronomy, e1=lens_e1, e2=lens_e2) external_shear = dict(gamma_ext=lens_info['gamma_lenscat'], psi_ext=np.deg2rad(lens_info['phig_lenscat'])) #external_shear = dict( # gamma1=lens_info['shear_1_lenscat'], # gamma2=lens_info['shear_2_lenscat'] # ) return [sie_mass, external_shear]
class TestLensCosmo(object): """ tests the UnitManager class routines """ def setup(self): z_L = 0.8 z_S = 3.0 from astropy.cosmology import FlatLambdaCDM cosmo = FlatLambdaCDM(H0=70, Om0=0.3, Ob0=0.05) self.lensCosmo = LensCosmo(z_L, z_S, cosmo=cosmo) def test_ang_dist(self): npt.assert_almost_equal(self.lensCosmo.ds, 1588.9213590743666, decimal=8) npt.assert_almost_equal(self.lensCosmo.dd, 1548.7055203661785, decimal=8) npt.assert_almost_equal(self.lensCosmo.dds, 892.0038749095863, decimal=8) def test_epsilon_crit(self): npt.assert_almost_equal(self.lensCosmo.sigma_crit / 1.9121e+15, 1, decimal=3) def test_arcsec2phys(self): arcsec = np.array([1, 2]) # pixel coordinate from center physcoord = self.lensCosmo.arcsec2phys_lens(arcsec) npt.assert_almost_equal(physcoord[0], 0.0075083362428338641, decimal=8) npt.assert_almost_equal(physcoord[1], 0.015016672485667728, decimal=8) physcoord = self.lensCosmo.arcsec2phys_source(arcsec) npt.assert_almost_equal(physcoord[0], 0.007703308130864105, decimal=8) npt.assert_almost_equal(physcoord[1], 0.01540661626172821, decimal=8) def test_phys2arcsec_lens(self): phys = 1. arc_sec = self.lensCosmo.phys2arcsec_lens(phys) phys_new = self.lensCosmo.arcsec2phys_lens(arc_sec) npt.assert_almost_equal(phys_new, phys, decimal=8) def test_mass_in_phi_E(self): phi_E = 1.5 mass = self.lensCosmo.mass_in_theta_E(phi_E) npt.assert_almost_equal(mass, 761967261292.6725, decimal=2) def test_kappa2proj_mass(self): kappa = 0.5 mass = self.lensCosmo.kappa2proj_mass(kappa) npt.assert_almost_equal(mass, kappa * self.lensCosmo.sigma_crit, decimal=3) def test_mass_in_coin(self): theta_E = 1. m_coin = self.lensCosmo.mass_in_coin(theta_E) npt.assert_almost_equal(m_coin, 165279526936.52194, decimal=0) def test_D_dt_model(self): D_dt = self.lensCosmo.ddt npt.assert_almost_equal(D_dt, 4965.660384441859, decimal=8) def test_nfw_angle2physical(self): Rs_angle = 6. alpha_Rs = 1. rho0, Rs, c, r200, M200 = self.lensCosmo.nfw_angle2physical( Rs_angle, alpha_Rs) assert Rs * c == r200 def test_nfw_physical2angle(self): M = 10.**13.5 c = 4 Rs_angle, alpha_Rs = self.lensCosmo.nfw_physical2angle(M, c) rho0, Rs, c_out, r200, M200 = self.lensCosmo.nfw_angle2physical( Rs_angle, alpha_Rs) npt.assert_almost_equal(c_out, c, decimal=3) npt.assert_almost_equal(np.log10(M200), np.log10(M), decimal=4) def test_sis_theta_E2sigma_v(self): theta_E = 2. sigma_v = self.lensCosmo.sis_theta_E2sigma_v(theta_E) theta_E_out = self.lensCosmo.sis_sigma_v2theta_E(sigma_v) npt.assert_almost_equal(theta_E_out, theta_E, decimal=5) def test_fermat2delays(self): fermat_pot = 0.5 dt_days = self.lensCosmo.time_delay_units(fermat_pot) fermat_pot_out = self.lensCosmo.time_delay2fermat_pot(dt_days) npt.assert_almost_equal(fermat_pot, fermat_pot_out, decimal=10) def test_uldm_angular2phys(self): kappa_0, theta_c = 0.1, 3 mlog10, Mlog10 = self.lensCosmo.uldm_angular2phys(kappa_0, theta_c) npt.assert_almost_equal(mlog10, -24.3610006, decimal=5) npt.assert_almost_equal(Mlog10, 11.7195843, decimal=5) def test_uldm_mphys2angular(self): m_log10, M_log10 = -24, 11 kappa_0, theta_c = self.lensCosmo.uldm_mphys2angular(m_log10, M_log10) mcheck, Mcheck = self.lensCosmo.uldm_angular2phys(kappa_0, theta_c) npt.assert_almost_equal(mcheck, m_log10, decimal=4) npt.assert_almost_equal(Mcheck, M_log10, decimal=4) def test_a_z(self): a = self.lensCosmo.a_z(z=1) npt.assert_almost_equal(a, 0.5)
class TestLensCosmo(object): """ tests the UnitManager class routines """ def setup(self): z_L = 0.8 z_S = 3.0 from astropy.cosmology import FlatLambdaCDM cosmo = FlatLambdaCDM(H0=70, Om0=0.3, Ob0=0.05) self.lensCosmo = LensCosmo(z_L, z_S, cosmo=cosmo) def test_ang_dist(self): npt.assert_almost_equal(self.lensCosmo.D_s, 1588.9213590743666, decimal=8) npt.assert_almost_equal(self.lensCosmo.D_d, 1548.7055203661785, decimal=8) npt.assert_almost_equal(self.lensCosmo.D_ds, 892.0038749095863, decimal=8) def test_epsilon_crit(self): npt.assert_almost_equal(self.lensCosmo.epsilon_crit / 1.9121e+15, 1, decimal=3) def test_arcsec2phys(self): arcsec = np.array([1, 2]) # pixel coordinate from center physcoord = self.lensCosmo.arcsec2phys_lens(arcsec) assert physcoord[0] == 0.0075083362428338641 assert physcoord[1] == 0.015016672485667728 physcoord = self.lensCosmo.arcsec2phys_source(arcsec) assert physcoord[0] == 0.007703308130864105 assert physcoord[1] == 0.01540661626172821 def test_phys2arcsec_lens(self): phys = 1. arc_sec = self.lensCosmo.phys2arcsec_lens(phys) phys_new = self.lensCosmo.arcsec2phys_lens(arc_sec) assert phys_new == phys def test_mass_in_phi_E(self): phi_E = 1.5 mass = self.lensCosmo.mass_in_theta_E(phi_E) assert mass == 761967261292.6725 def test_kappa2proj_mass(self): kappa = 0.5 mass = self.lensCosmo.kappa2proj_mass(kappa) npt.assert_almost_equal(mass, kappa * self.lensCosmo.epsilon_crit, decimal=3) def test_mass_in_coin(self): theta_E = 1. m_coin = self.lensCosmo.mass_in_coin(theta_E) npt.assert_almost_equal(m_coin, 165279526936.52194, decimal=0) def test_D_dt_model(self): D_dt = self.lensCosmo.D_dt assert D_dt == 4965.660384441859 def test_nfw_angle2physical(self): Rs_angle = 6. theta_Rs = 1. rho0, Rs, c, r200, M200 = self.lensCosmo.nfw_angle2physical( Rs_angle, theta_Rs) assert Rs * c == r200 def test_nfw_physical2angle(self): M = 10.**13.5 c = 4 Rs_angle, theta_Rs = self.lensCosmo.nfw_physical2angle(M, c) rho0, Rs, c_out, r200, M200 = self.lensCosmo.nfw_angle2physical( Rs_angle, theta_Rs) npt.assert_almost_equal(c_out, c, decimal=3) npt.assert_almost_equal(np.log10(M200), np.log10(M), decimal=4) def test_sis_theta_E2sigma_v(self): theta_E = 2. sigma_v = self.lensCosmo.sis_theta_E2sigma_v(theta_E) theta_E_out = self.lensCosmo.sis_sigma_v2theta_E(sigma_v) npt.assert_almost_equal(theta_E_out, theta_E, decimal=5)