def setup(self): from lenstronomy.LensModel.Profiles.sie import SIE from lenstronomy.LensModel.Profiles.epl import EPL from lenstronomy.LensModel.Profiles.nie import NIE self.sie = SIE(NIE=False) self.sie_nie = SIE(NIE=True) self.epl = EPL() self.nie = NIE()
def setup(self): try: import fastell4py self._fastell4py_bool = True except: print("Warning: fastell4py not available, tests will be trivially fulfilled without giving the right answer!") self._fastell4py_bool = False from lenstronomy.LensModel.Profiles.epl import EPL self.epl = EPL() from lenstronomy.LensModel.Profiles.pemd import PEMD self.pemd = PEMD(suppress_fastell=True)
def __init__(self, NIE=True): """ :param NIE: bool, if True, is using the NIE analytic model. Otherwise it uses PEMD with gamma=2 from fastell4py """ self._nie = NIE if NIE: from lenstronomy.LensModel.Profiles.nie import NIE self.profile = NIE() else: from lenstronomy.LensModel.Profiles.epl import EPL self.profile = EPL() self._s_scale = 0.0000000001 self._gamma = 2 super(SIE, self).__init__()
class TestEPLvsPEMD(object): """ Test EPL model vs PEMD with FASTELL This tests get only executed if fastell is installed """ def setup(self): try: import fastell4py self._fastell4py_bool = True except: print("Warning: fastell4py not available, tests will be trivially fulfilled without giving the right answer!") self._fastell4py_bool = False from lenstronomy.LensModel.Profiles.epl import EPL self.epl = EPL() from lenstronomy.LensModel.Profiles.pemd import PEMD self.pemd = PEMD(suppress_fastell=True) def test_epl_pemd_convention(self): """ tests convention of EPL and PEMD model on the deflection angle basis """ if self._fastell4py_bool is False: return 0 x, y = util.make_grid(numPix=10, deltapix=0.2) theta_E_list = [0.5, 1, 2] gamma_list = [1.8, 2., 2.2] e1_list = [-0.2, 0., 0.2] e2_list = [-0.2, 0., 0.2] for gamma in gamma_list: for e1 in e1_list: for e2 in e2_list: for theta_E in theta_E_list: kwargs = {'theta_E': theta_E, 'gamma': gamma, 'e1': e1, 'e2': e2, 'center_x': 0, 'center_y': 0} f_x, f_y = self.epl.derivatives(x, y, **kwargs) f_x_pemd, f_y_pemd = self.pemd.derivatives(x, y, **kwargs) npt.assert_almost_equal(f_x, f_x_pemd, decimal=4) npt.assert_almost_equal(f_y, f_y_pemd, decimal=4)
def setup(self): from lenstronomy.LensModel.Profiles.epl import EPL self.EPL = EPL() from lenstronomy.LensModel.Profiles.nie import NIE self.NIE = NIE()
class TestEPLvsNIE(object): """ tests the Gaussian methods """ def setup(self): from lenstronomy.LensModel.Profiles.epl import EPL self.EPL = EPL() from lenstronomy.LensModel.Profiles.nie import NIE self.NIE = NIE() def test_function(self): phi_E = 1. gamma = 2. q = 0.999 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = np.array([1., 2]) y = np.array([2, 0]) values = self.EPL.function(x, y, phi_E, gamma, e1, e2) values_nie = self.NIE.function(x, y, phi_E, e1, e2, 0.) delta_f = values[0] - values[1] delta_f_nie = values_nie[0] - values_nie[1] npt.assert_almost_equal(delta_f, delta_f_nie, decimal=5) q = 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = np.array([1., 2]) y = np.array([2, 0]) values = self.EPL.function(x, y, phi_E, gamma, e1, e2) values_nie = self.NIE.function(x, y, phi_E, e1, e2, 0.) delta_f = values[0] - values[1] delta_f_nie = values_nie[0] - values_nie[1] npt.assert_almost_equal(delta_f, delta_f_nie, decimal=5) q = 0.4 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = np.array([1., 2]) y = np.array([2, 0]) values = self.EPL.function(x, y, phi_E, gamma, e1, e2) values_nie = self.NIE.function(x, y, phi_E, e1, e2, 0.) delta_f = values[0] - values[1] delta_f_nie = values_nie[0] - values_nie[1] npt.assert_almost_equal(delta_f, delta_f_nie, decimal=5) def test_derivatives(self): x = np.array([1]) y = np.array([2]) phi_E = 1. gamma = 2. q = 1. phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) f_x, f_y = self.EPL.derivatives(x, y, phi_E, gamma, e1, e2) f_x_nie, f_y_nie = self.NIE.derivatives(x, y, phi_E, e1, e2, 0.) npt.assert_almost_equal(f_x, f_x_nie, decimal=4) npt.assert_almost_equal(f_y, f_y_nie, decimal=4) q = 0.7 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) f_x, f_y = self.EPL.derivatives(x, y, phi_E, gamma, e1, e2) f_x_nie, f_y_nie = self.NIE.derivatives(x, y, phi_E, e1, e2, 0.) npt.assert_almost_equal(f_x, f_x_nie, decimal=4) npt.assert_almost_equal(f_y, f_y_nie, decimal=4) def test_hessian(self): x = np.array([1.]) y = np.array([2.]) phi_E = 1. gamma = 2. q = 0.9 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) f_xx, f_xy, f_yx, f_yy = self.EPL.hessian(x, y, phi_E, gamma, e1, e2) f_xx_nie, f_xy_nie, f_yx_nie, f_yy_nie = self.NIE.hessian(x, y, phi_E, e1, e2, 0.) npt.assert_almost_equal(f_xx, f_xx_nie, decimal=4) npt.assert_almost_equal(f_yy, f_yy_nie, decimal=4) npt.assert_almost_equal(f_xy, f_xy_nie, decimal=4) npt.assert_almost_equal(f_xy, f_yx, decimal=8) def test_density_lens(self): r = 1 kwargs = {'theta_E': 1, 'gamma': 2, 'e1': 0, 'e2': 0} rho = self.EPL.density_lens(r, **kwargs) from lenstronomy.LensModel.Profiles.spep import SPEP spep = SPEP() rho_spep = spep.density_lens(r, **kwargs) npt.assert_almost_equal(rho, rho_spep, decimal=7) def test_mass_3d_lens(self): r = 1 kwargs = {'theta_E': 1, 'gamma': 2, 'e1': 0, 'e2': 0} rho = self.EPL.mass_3d_lens(r, **kwargs) from lenstronomy.LensModel.Profiles.spep import SPEP spep = SPEP() rho_spep = spep.mass_3d_lens(r, **kwargs) npt.assert_almost_equal(rho, rho_spep, decimal=7) def test_static(self): x, y = 1., 1. phi_G, q = 0.3, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) kwargs_lens = {'theta_E': 1., 'gamma': 1.5, 'e1': e1, 'e2': e2} f_ = self.EPL.function(x, y, **kwargs_lens) self.EPL.set_static(**kwargs_lens) f_static = self.EPL.function(x, y, **kwargs_lens) npt.assert_almost_equal(f_, f_static, decimal=8) self.EPL.set_dynamic() kwargs_lens = {'theta_E': 2., 'gamma': 1.9, 'e1': e1, 'e2': e2} f_dyn = self.EPL.function(x, y, **kwargs_lens) assert f_dyn != f_static def test_regularization(self): phi_E = 1. gamma = 2. q = 1. phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = 0. y = 0. f_x, f_y = self.EPL.derivatives(x, y, phi_E, gamma, e1, e2) npt.assert_almost_equal(f_x, 0.) npt.assert_almost_equal(f_y, 0.) x = 0. y = 0. f_xx, f_xy, f_yx, f_yy = self.EPL.hessian(x, y, phi_E, gamma, e1, e2) assert f_xx > 10 ** 5 assert f_yy > 10 ** 5 #npt.assert_almost_equal(f_xx, 10**10) #npt.assert_almost_equal(f_yy, 10**10) npt.assert_almost_equal(f_xy, 0) npt.assert_almost_equal(f_yx, 0)
def _import_class(lens_type, custom_class, z_lens=None, z_source=None): """ :param lens_type: string, lens model type :param custom_class: custom class :param z_lens: lens redshift # currently only used in NFW_MC model as this is redshift dependent :param z_source: source redshift # currently only used in NFW_MC model as this is redshift dependent :return: class instance of the lens model type """ if lens_type == 'SHIFT': from lenstronomy.LensModel.Profiles.alpha_shift import Shift return Shift() elif lens_type == 'NIE_POTENTIAL': from lenstronomy.LensModel.Profiles.nie_potential import NIE_POTENTIAL return NIE_POTENTIAL() elif lens_type == 'CONST_MAG': from lenstronomy.LensModel.Profiles.const_mag import ConstMag return ConstMag() elif lens_type == 'SHEAR': from lenstronomy.LensModel.Profiles.shear import Shear return Shear() elif lens_type == 'SHEAR_GAMMA_PSI': from lenstronomy.LensModel.Profiles.shear import ShearGammaPsi return ShearGammaPsi() elif lens_type == 'CONVERGENCE': from lenstronomy.LensModel.Profiles.convergence import Convergence return Convergence() elif lens_type == 'FLEXION': from lenstronomy.LensModel.Profiles.flexion import Flexion return Flexion() elif lens_type == 'FLEXIONFG': from lenstronomy.LensModel.Profiles.flexionfg import Flexionfg return Flexionfg() elif lens_type == 'POINT_MASS': from lenstronomy.LensModel.Profiles.point_mass import PointMass return PointMass() elif lens_type == 'SIS': from lenstronomy.LensModel.Profiles.sis import SIS return SIS() elif lens_type == 'SIS_TRUNCATED': from lenstronomy.LensModel.Profiles.sis_truncate import SIS_truncate return SIS_truncate() elif lens_type == 'SIE': from lenstronomy.LensModel.Profiles.sie import SIE return SIE() elif lens_type == 'SPP': from lenstronomy.LensModel.Profiles.spp import SPP return SPP() elif lens_type == 'NIE': from lenstronomy.LensModel.Profiles.nie import NIE return NIE() elif lens_type == 'NIE_SIMPLE': from lenstronomy.LensModel.Profiles.nie import NIEMajorAxis return NIEMajorAxis() elif lens_type == 'CHAMELEON': from lenstronomy.LensModel.Profiles.chameleon import Chameleon return Chameleon() elif lens_type == 'DOUBLE_CHAMELEON': from lenstronomy.LensModel.Profiles.chameleon import DoubleChameleon return DoubleChameleon() elif lens_type == 'TRIPLE_CHAMELEON': from lenstronomy.LensModel.Profiles.chameleon import TripleChameleon return TripleChameleon() elif lens_type == 'SPEP': from lenstronomy.LensModel.Profiles.spep import SPEP return SPEP() elif lens_type == 'PEMD': from lenstronomy.LensModel.Profiles.pemd import PEMD return PEMD() elif lens_type == 'SPEMD': from lenstronomy.LensModel.Profiles.spemd import SPEMD return SPEMD() elif lens_type == 'EPL': from lenstronomy.LensModel.Profiles.epl import EPL return EPL() elif lens_type == 'NFW': from lenstronomy.LensModel.Profiles.nfw import NFW return NFW() elif lens_type == 'NFW_ELLIPSE': from lenstronomy.LensModel.Profiles.nfw_ellipse import NFW_ELLIPSE return NFW_ELLIPSE() elif lens_type == 'NFW_ELLIPSE_GAUSS_DEC': from lenstronomy.LensModel.Profiles.gauss_decomposition import NFWEllipseGaussDec return NFWEllipseGaussDec() elif lens_type == 'TNFW': from lenstronomy.LensModel.Profiles.tnfw import TNFW return TNFW() elif lens_type == 'CNFW': from lenstronomy.LensModel.Profiles.cnfw import CNFW return CNFW() elif lens_type == 'CNFW_ELLIPSE': from lenstronomy.LensModel.Profiles.cnfw_ellipse import CNFW_ELLIPSE return CNFW_ELLIPSE() elif lens_type == 'CTNFW_GAUSS_DEC': from lenstronomy.LensModel.Profiles.gauss_decomposition import CTNFWGaussDec return CTNFWGaussDec() elif lens_type == 'NFW_MC': from lenstronomy.LensModel.Profiles.nfw_mass_concentration import NFWMC return NFWMC(z_lens=z_lens, z_source=z_source) elif lens_type == 'SERSIC': from lenstronomy.LensModel.Profiles.sersic import Sersic return Sersic() elif lens_type == 'SERSIC_ELLIPSE_POTENTIAL': from lenstronomy.LensModel.Profiles.sersic_ellipse_potential import SersicEllipse return SersicEllipse() elif lens_type == 'SERSIC_ELLIPSE_KAPPA': from lenstronomy.LensModel.Profiles.sersic_ellipse_kappa import SersicEllipseKappa return SersicEllipseKappa() elif lens_type == 'SERSIC_ELLIPSE_GAUSS_DEC': from lenstronomy.LensModel.Profiles.gauss_decomposition \ import SersicEllipseGaussDec return SersicEllipseGaussDec() elif lens_type == 'PJAFFE': from lenstronomy.LensModel.Profiles.p_jaffe import PJaffe return PJaffe() elif lens_type == 'PJAFFE_ELLIPSE': from lenstronomy.LensModel.Profiles.p_jaffe_ellipse import PJaffe_Ellipse return PJaffe_Ellipse() elif lens_type == 'HERNQUIST': from lenstronomy.LensModel.Profiles.hernquist import Hernquist return Hernquist() elif lens_type == 'HERNQUIST_ELLIPSE': from lenstronomy.LensModel.Profiles.hernquist_ellipse import Hernquist_Ellipse return Hernquist_Ellipse() elif lens_type == 'GAUSSIAN': from lenstronomy.LensModel.Profiles.gaussian_potential import Gaussian return Gaussian() elif lens_type == 'GAUSSIAN_KAPPA': from lenstronomy.LensModel.Profiles.gaussian_kappa import GaussianKappa return GaussianKappa() elif lens_type == 'GAUSSIAN_ELLIPSE_KAPPA': from lenstronomy.LensModel.Profiles.gaussian_ellipse_kappa import GaussianEllipseKappa return GaussianEllipseKappa() elif lens_type == 'GAUSSIAN_ELLIPSE_POTENTIAL': from lenstronomy.LensModel.Profiles.gaussian_ellipse_potential import GaussianEllipsePotential return GaussianEllipsePotential() elif lens_type == 'MULTI_GAUSSIAN_KAPPA': from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappa return MultiGaussianKappa() elif lens_type == 'MULTI_GAUSSIAN_KAPPA_ELLIPSE': from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappaEllipse return MultiGaussianKappaEllipse() elif lens_type == 'INTERPOL': from lenstronomy.LensModel.Profiles.interpol import Interpol return Interpol() elif lens_type == 'INTERPOL_SCALED': from lenstronomy.LensModel.Profiles.interpol import InterpolScaled return InterpolScaled() elif lens_type == 'SHAPELETS_POLAR': from lenstronomy.LensModel.Profiles.shapelet_pot_polar import PolarShapelets return PolarShapelets() elif lens_type == 'SHAPELETS_CART': from lenstronomy.LensModel.Profiles.shapelet_pot_cartesian import CartShapelets return CartShapelets() elif lens_type == 'DIPOLE': from lenstronomy.LensModel.Profiles.dipole import Dipole return Dipole() elif lens_type == 'CURVED_ARC': from lenstronomy.LensModel.Profiles.curved_arc import CurvedArc return CurvedArc() elif lens_type == 'ARC_PERT': from lenstronomy.LensModel.Profiles.arc_perturbations import ArcPerturbations return ArcPerturbations() elif lens_type == 'coreBURKERT': from lenstronomy.LensModel.Profiles.coreBurkert import CoreBurkert return CoreBurkert() elif lens_type == 'CORED_DENSITY': from lenstronomy.LensModel.Profiles.cored_density import CoredDensity return CoredDensity() elif lens_type == 'CORED_DENSITY_2': from lenstronomy.LensModel.Profiles.cored_density_2 import CoredDensity2 return CoredDensity2() elif lens_type == 'CORED_DENSITY_MST': from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST return CoredDensityMST(profile_type='CORED_DENSITY') elif lens_type == 'CORED_DENSITY_2_MST': from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST return CoredDensityMST(profile_type='CORED_DENSITY_2') elif lens_type == 'NumericalAlpha': from lenstronomy.LensModel.Profiles.numerical_deflections import NumericalAlpha return NumericalAlpha(custom_class) elif lens_type == 'MULTIPOLE': from lenstronomy.LensModel.Profiles.multipole import Multipole return Multipole() else: raise ValueError('%s is not a valid lens model' % lens_type)
def _import_class(lens_type, custom_class, kwargs_interp, z_lens=None, z_source=None): """ :param lens_type: string, lens model type :param custom_class: custom class :param z_lens: lens redshift # currently only used in NFW_MC model as this is redshift dependent :param z_source: source redshift # currently only used in NFW_MC model as this is redshift dependent :param kwargs_interp: interpolation keyword arguments specifying the numerics. See description in the Interpolate() class. Only applicable for 'INTERPOL' and 'INTERPOL_SCALED' models. :return: class instance of the lens model type """ if lens_type == 'SHIFT': from lenstronomy.LensModel.Profiles.constant_shift import Shift return Shift() elif lens_type == 'NIE_POTENTIAL': from lenstronomy.LensModel.Profiles.nie_potential import NIE_POTENTIAL return NIE_POTENTIAL() elif lens_type == 'CONST_MAG': from lenstronomy.LensModel.Profiles.const_mag import ConstMag return ConstMag() elif lens_type == 'SHEAR': from lenstronomy.LensModel.Profiles.shear import Shear return Shear() elif lens_type == 'SHEAR_GAMMA_PSI': from lenstronomy.LensModel.Profiles.shear import ShearGammaPsi return ShearGammaPsi() elif lens_type == 'SHEAR_REDUCED': from lenstronomy.LensModel.Profiles.shear import ShearReduced return ShearReduced() elif lens_type == 'CONVERGENCE': from lenstronomy.LensModel.Profiles.convergence import Convergence return Convergence() elif lens_type == 'HESSIAN': from lenstronomy.LensModel.Profiles.hessian import Hessian return Hessian() elif lens_type == 'FLEXION': from lenstronomy.LensModel.Profiles.flexion import Flexion return Flexion() elif lens_type == 'FLEXIONFG': from lenstronomy.LensModel.Profiles.flexionfg import Flexionfg return Flexionfg() elif lens_type == 'POINT_MASS': from lenstronomy.LensModel.Profiles.point_mass import PointMass return PointMass() elif lens_type == 'SIS': from lenstronomy.LensModel.Profiles.sis import SIS return SIS() elif lens_type == 'SIS_TRUNCATED': from lenstronomy.LensModel.Profiles.sis_truncate import SIS_truncate return SIS_truncate() elif lens_type == 'SIE': from lenstronomy.LensModel.Profiles.sie import SIE return SIE() elif lens_type == 'SPP': from lenstronomy.LensModel.Profiles.spp import SPP return SPP() elif lens_type == 'NIE': from lenstronomy.LensModel.Profiles.nie import NIE return NIE() elif lens_type == 'NIE_SIMPLE': from lenstronomy.LensModel.Profiles.nie import NIEMajorAxis return NIEMajorAxis() elif lens_type == 'CHAMELEON': from lenstronomy.LensModel.Profiles.chameleon import Chameleon return Chameleon() elif lens_type == 'DOUBLE_CHAMELEON': from lenstronomy.LensModel.Profiles.chameleon import DoubleChameleon return DoubleChameleon() elif lens_type == 'TRIPLE_CHAMELEON': from lenstronomy.LensModel.Profiles.chameleon import TripleChameleon return TripleChameleon() elif lens_type == 'SPEP': from lenstronomy.LensModel.Profiles.spep import SPEP return SPEP() elif lens_type == 'PEMD': from lenstronomy.LensModel.Profiles.pemd import PEMD return PEMD() elif lens_type == 'SPEMD': from lenstronomy.LensModel.Profiles.spemd import SPEMD return SPEMD() elif lens_type == 'EPL': from lenstronomy.LensModel.Profiles.epl import EPL return EPL() elif lens_type == 'EPL_NUMBA': from lenstronomy.LensModel.Profiles.epl_numba import EPL_numba return EPL_numba() elif lens_type == 'SPL_CORE': from lenstronomy.LensModel.Profiles.splcore import SPLCORE return SPLCORE() elif lens_type == 'NFW': from lenstronomy.LensModel.Profiles.nfw import NFW return NFW() elif lens_type == 'NFW_ELLIPSE': from lenstronomy.LensModel.Profiles.nfw_ellipse import NFW_ELLIPSE return NFW_ELLIPSE() elif lens_type == 'NFW_ELLIPSE_GAUSS_DEC': from lenstronomy.LensModel.Profiles.gauss_decomposition import NFWEllipseGaussDec return NFWEllipseGaussDec() elif lens_type == 'NFW_ELLIPSE_CSE': from lenstronomy.LensModel.Profiles.nfw_ellipse_cse import NFW_ELLIPSE_CSE return NFW_ELLIPSE_CSE() elif lens_type == 'TNFW': from lenstronomy.LensModel.Profiles.tnfw import TNFW return TNFW() elif lens_type == 'TNFW_ELLIPSE': from lenstronomy.LensModel.Profiles.tnfw_ellipse import TNFW_ELLIPSE return TNFW_ELLIPSE() elif lens_type == 'CNFW': from lenstronomy.LensModel.Profiles.cnfw import CNFW return CNFW() elif lens_type == 'CNFW_ELLIPSE': from lenstronomy.LensModel.Profiles.cnfw_ellipse import CNFW_ELLIPSE return CNFW_ELLIPSE() elif lens_type == 'CTNFW_GAUSS_DEC': from lenstronomy.LensModel.Profiles.gauss_decomposition import CTNFWGaussDec return CTNFWGaussDec() elif lens_type == 'NFW_MC': from lenstronomy.LensModel.Profiles.nfw_mass_concentration import NFWMC return NFWMC(z_lens=z_lens, z_source=z_source) elif lens_type == 'SERSIC': from lenstronomy.LensModel.Profiles.sersic import Sersic return Sersic() elif lens_type == 'SERSIC_ELLIPSE_POTENTIAL': from lenstronomy.LensModel.Profiles.sersic_ellipse_potential import SersicEllipse return SersicEllipse() elif lens_type == 'SERSIC_ELLIPSE_KAPPA': from lenstronomy.LensModel.Profiles.sersic_ellipse_kappa import SersicEllipseKappa return SersicEllipseKappa() elif lens_type == 'SERSIC_ELLIPSE_GAUSS_DEC': from lenstronomy.LensModel.Profiles.gauss_decomposition import SersicEllipseGaussDec return SersicEllipseGaussDec() elif lens_type == 'PJAFFE': from lenstronomy.LensModel.Profiles.p_jaffe import PJaffe return PJaffe() elif lens_type == 'PJAFFE_ELLIPSE': from lenstronomy.LensModel.Profiles.p_jaffe_ellipse import PJaffe_Ellipse return PJaffe_Ellipse() elif lens_type == 'HERNQUIST': from lenstronomy.LensModel.Profiles.hernquist import Hernquist return Hernquist() elif lens_type == 'HERNQUIST_ELLIPSE': from lenstronomy.LensModel.Profiles.hernquist_ellipse import Hernquist_Ellipse return Hernquist_Ellipse() elif lens_type == 'HERNQUIST_ELLIPSE_CSE': from lenstronomy.LensModel.Profiles.hernquist_ellipse_cse import HernquistEllipseCSE return HernquistEllipseCSE() elif lens_type == 'GAUSSIAN': from lenstronomy.LensModel.Profiles.gaussian_potential import Gaussian return Gaussian() elif lens_type == 'GAUSSIAN_KAPPA': from lenstronomy.LensModel.Profiles.gaussian_kappa import GaussianKappa return GaussianKappa() elif lens_type == 'GAUSSIAN_ELLIPSE_KAPPA': from lenstronomy.LensModel.Profiles.gaussian_ellipse_kappa import GaussianEllipseKappa return GaussianEllipseKappa() elif lens_type == 'GAUSSIAN_ELLIPSE_POTENTIAL': from lenstronomy.LensModel.Profiles.gaussian_ellipse_potential import GaussianEllipsePotential return GaussianEllipsePotential() elif lens_type == 'MULTI_GAUSSIAN_KAPPA': from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappa return MultiGaussianKappa() elif lens_type == 'MULTI_GAUSSIAN_KAPPA_ELLIPSE': from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappaEllipse return MultiGaussianKappaEllipse() elif lens_type == 'INTERPOL': from lenstronomy.LensModel.Profiles.interpol import Interpol return Interpol(**kwargs_interp) elif lens_type == 'INTERPOL_SCALED': from lenstronomy.LensModel.Profiles.interpol import InterpolScaled return InterpolScaled(**kwargs_interp) elif lens_type == 'SHAPELETS_POLAR': from lenstronomy.LensModel.Profiles.shapelet_pot_polar import PolarShapelets return PolarShapelets() elif lens_type == 'SHAPELETS_CART': from lenstronomy.LensModel.Profiles.shapelet_pot_cartesian import CartShapelets return CartShapelets() elif lens_type == 'DIPOLE': from lenstronomy.LensModel.Profiles.dipole import Dipole return Dipole() elif lens_type == 'CURVED_ARC_CONST': from lenstronomy.LensModel.Profiles.curved_arc_const import CurvedArcConst return CurvedArcConst() elif lens_type == 'CURVED_ARC_CONST_MST': from lenstronomy.LensModel.Profiles.curved_arc_const import CurvedArcConstMST return CurvedArcConstMST() elif lens_type == 'CURVED_ARC_SPP': from lenstronomy.LensModel.Profiles.curved_arc_spp import CurvedArcSPP return CurvedArcSPP() elif lens_type == 'CURVED_ARC_SIS_MST': from lenstronomy.LensModel.Profiles.curved_arc_sis_mst import CurvedArcSISMST return CurvedArcSISMST() elif lens_type == 'CURVED_ARC_SPT': from lenstronomy.LensModel.Profiles.curved_arc_spt import CurvedArcSPT return CurvedArcSPT() elif lens_type == 'CURVED_ARC_TAN_DIFF': from lenstronomy.LensModel.Profiles.curved_arc_tan_diff import CurvedArcTanDiff return CurvedArcTanDiff() elif lens_type == 'ARC_PERT': from lenstronomy.LensModel.Profiles.arc_perturbations import ArcPerturbations return ArcPerturbations() elif lens_type == 'coreBURKERT': from lenstronomy.LensModel.Profiles.coreBurkert import CoreBurkert return CoreBurkert() elif lens_type == 'CORED_DENSITY': from lenstronomy.LensModel.Profiles.cored_density import CoredDensity return CoredDensity() elif lens_type == 'CORED_DENSITY_2': from lenstronomy.LensModel.Profiles.cored_density_2 import CoredDensity2 return CoredDensity2() elif lens_type == 'CORED_DENSITY_EXP': from lenstronomy.LensModel.Profiles.cored_density_exp import CoredDensityExp return CoredDensityExp() elif lens_type == 'CORED_DENSITY_MST': from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST return CoredDensityMST(profile_type='CORED_DENSITY') elif lens_type == 'CORED_DENSITY_2_MST': from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST return CoredDensityMST(profile_type='CORED_DENSITY_2') elif lens_type == 'CORED_DENSITY_EXP_MST': from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST return CoredDensityMST(profile_type='CORED_DENSITY_EXP') elif lens_type == 'NumericalAlpha': from lenstronomy.LensModel.Profiles.numerical_deflections import NumericalAlpha return NumericalAlpha(custom_class) elif lens_type == 'MULTIPOLE': from lenstronomy.LensModel.Profiles.multipole import Multipole return Multipole() elif lens_type == 'CSE': from lenstronomy.LensModel.Profiles.cored_steep_ellipsoid import CSE return CSE() elif lens_type == 'ElliSLICE': from lenstronomy.LensModel.Profiles.elliptical_density_slice import ElliSLICE return ElliSLICE() elif lens_type == 'ULDM': from lenstronomy.LensModel.Profiles.uldm import Uldm return Uldm() elif lens_type == 'CORED_DENSITY_ULDM_MST': from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST return CoredDensityMST(profile_type='CORED_DENSITY_ULDM') else: raise ValueError( '%s is not a valid lens model. Supported are: %s.' % (lens_type, _SUPPORTED_MODELS))
class SIE(LensProfileBase): """ class for singular isothermal ellipsoid (SIS with ellipticity) .. math:: \\kappa(x, y) = \\frac{1}{2} \\left(\\frac{\\theta_{E}}{\\sqrt{q x^2 + y^2/q}} \\right) with :math:`\\theta_{E}` is the (circularized) Einstein radius, :math:`q` is the minor/major axis ratio, and :math:`x` and :math:`y` are defined in a coordinate sys- tem aligned with the major and minor axis of the lens. In terms of eccentricities, this profile is defined as .. math:: \\kappa(r) = \\frac{1}{2} \\left(\\frac{\\theta'_{E}}{r \\sqrt{1 − e*\\cos(2*\\phi)}} \\right) with :math:`\\epsilon` is the ellipticity defined as .. math:: \\epsilon = \\frac{1-q^2}{1+q^2} And an Einstein radius :math:`\\theta'_{\\rm E}` related to the definition used is .. math:: \\left(\\frac{\\theta'_{\\rm E}}{\\theta_{\\rm E}}\\right)^{2} = \\frac{2q}{1+q^2}. """ param_names = ['theta_E', 'e1', 'e2', 'center_x', 'center_y'] lower_limit_default = { 'theta_E': 0, 'e1': -0.5, 'e2': -0.5, 'center_x': -100, 'center_y': -100 } upper_limit_default = { 'theta_E': 100, 'e1': 0.5, 'e2': 0.5, 'center_x': 100, 'center_y': 100 } def __init__(self, NIE=True): """ :param NIE: bool, if True, is using the NIE analytic model. Otherwise it uses PEMD with gamma=2 from fastell4py """ self._nie = NIE if NIE: from lenstronomy.LensModel.Profiles.nie import NIE self.profile = NIE() else: from lenstronomy.LensModel.Profiles.epl import EPL self.profile = EPL() self._s_scale = 0.0000000001 self._gamma = 2 super(SIE, self).__init__() def function(self, x, y, theta_E, e1, e2, center_x=0, center_y=0): """ :param x: x-coordinate (angular coordinates) :param y: y-coordinate (angular coordinates) :param theta_E: Einstein radius :param e1: eccentricity :param e2: eccentricity :param center_x: centroid :param center_y: centroid :return: """ if self._nie: return self.profile.function(x, y, theta_E, e1, e2, self._s_scale, center_x, center_y) else: return self.profile.function(x, y, theta_E, self._gamma, e1, e2, center_x, center_y) def derivatives(self, x, y, theta_E, e1, e2, center_x=0, center_y=0): """ :param x: x-coordinate (angular coordinates) :param y: y-coordinate (angular coordinates) :param theta_E: Einstein radius :param e1: eccentricity :param e2: eccentricity :param center_x: centroid :param center_y: centroid :return: """ if self._nie: return self.profile.derivatives(x, y, theta_E, e1, e2, self._s_scale, center_x, center_y) else: return self.profile.derivatives(x, y, theta_E, self._gamma, e1, e2, center_x, center_y) def hessian(self, x, y, theta_E, e1, e2, center_x=0, center_y=0): """ :param x: x-coordinate (angular coordinates) :param y: y-coordinate (angular coordinates) :param theta_E: Einstein radius :param e1: eccentricity :param e2: eccentricity :param center_x: centroid :param center_y: centroid :return: """ if self._nie: return self.profile.hessian(x, y, theta_E, e1, e2, self._s_scale, center_x, center_y) else: return self.profile.hessian(x, y, theta_E, self._gamma, e1, e2, center_x, center_y) @staticmethod def theta2rho(theta_E): """ converts projected density parameter (in units of deflection) into 3d density parameter :param theta_E: :return: """ fac1 = np.pi * 2 rho0 = theta_E / fac1 return rho0 @staticmethod def mass_3d(r, rho0, e1=0, e2=0): """ mass enclosed a 3d sphere or radius r :param r: radius in angular units :param rho0: density at angle=1 :return: mass in angular units """ mass_3d = 4 * np.pi * rho0 * r return mass_3d def mass_3d_lens(self, r, theta_E, e1=0, e2=0): """ mass enclosed a 3d sphere or radius r given a lens parameterization with angular units :param r: radius in angular units :param theta_E: Einstein radius :return: mass in angular units """ rho0 = self.theta2rho(theta_E) return self.mass_3d(r, rho0) def mass_2d(self, r, rho0, e1=0, e2=0): """ mass enclosed projected 2d sphere of radius r :param r: :param rho0: :param e1: :param e2: :return: """ alpha = 2 * rho0 * np.pi**2 mass_2d = alpha * r return mass_2d def mass_2d_lens(self, r, theta_E, e1=0, e2=0): """ :param r: :param theta_E: :param e1: :param e2: :return: """ rho0 = self.theta2rho(theta_E) return self.mass_2d(r, rho0) def grav_pot(self, x, y, rho0, e1=0, e2=0, center_x=0, center_y=0): """ gravitational potential (modulo 4 pi G and rho0 in appropriate units) :param x: :param y: :param rho0: :param e1: :param e2: :param center_x: :param center_y: :return: """ x_ = x - center_x y_ = y - center_y r = np.sqrt(x_**2 + y_**2) mass_3d = self.mass_3d(r, rho0) pot = mass_3d / r return pot def density_lens(self, r, theta_E, e1=0, e2=0): """ computes the density at 3d radius r given lens model parameterization. The integral in the LOS projection of this quantity results in the convergence quantity. :param r: radius in angles :param theta_E: Einstein radius :param e1: eccentricity component :param e2: eccentricity component :return: density """ rho0 = self.theta2rho(theta_E) return self.density(r, rho0) @staticmethod def density(r, rho0, e1=0, e2=0): """ computes the density :param r: radius in angles :param rho0: density at angle=1 :return: density at r """ rho = rho0 / r**2 return rho @staticmethod def density_2d(x, y, rho0, e1=0, e2=0, center_x=0, center_y=0): """ projected density :param x: :param y: :param rho0: :param e1: :param e2: :param center_x: :param center_y: :return: """ x_ = x - center_x y_ = y - center_y r = np.sqrt(x_**2 + y_**2) sigma = np.pi * rho0 / r return sigma
class TestSIE(object): """ tests the Gaussian methods """ def setup(self): from lenstronomy.LensModel.Profiles.sie import SIE from lenstronomy.LensModel.Profiles.epl import EPL from lenstronomy.LensModel.Profiles.nie import NIE self.sie = SIE(NIE=False) self.sie_nie = SIE(NIE=True) self.epl = EPL() self.nie = NIE() def test_function(self): x = np.array([1]) y = np.array([2]) theta_E = 1. q = 0.9 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) values = self.sie.function(x, y, theta_E, e1, e2) gamma = 2 values_spemd = self.epl.function(x, y, theta_E, gamma, e1, e2) assert values == values_spemd values_nie = self.sie_nie.function(x, y, theta_E, e1, e2) s_scale = 0.0000001 values_spemd = self.nie.function(x, y, theta_E, e1, e2, s_scale) npt.assert_almost_equal(values_nie, values_spemd, decimal=6) def test_derivatives(self): x = np.array([1]) y = np.array([2]) theta_E = 1. q = 0.7 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) values = self.sie.derivatives(x, y, theta_E, e1, e2) gamma = 2 values_spemd = self.epl.derivatives(x, y, theta_E, gamma, e1, e2) assert values == values_spemd values = self.sie_nie.derivatives(x, y, theta_E, e1, e2) s_scale = 0.0000001 values_spemd = self.nie.derivatives(x, y, theta_E, e1, e2, s_scale) npt.assert_almost_equal(values, values_spemd, decimal=6) def test_hessian(self): x = np.array([1]) y = np.array([2]) theta_E = 1. q = 0.7 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) values = self.sie.hessian(x, y, theta_E, e1, e2) gamma = 2 values_spemd = self.epl.hessian(x, y, theta_E, gamma, e1, e2) assert values[0] == values_spemd[0] values = self.sie_nie.hessian(x, y, theta_E, e1, e2) s_scale = 0.0000001 values_spemd = self.nie.hessian(x, y, theta_E, e1, e2, s_scale) npt.assert_almost_equal(values, values_spemd, decimal=5)
class TestEPL(object): """ tests the Gaussian methods """ def setup(self): from lenstronomy.LensModel.Profiles.epl import EPL self.EPL = EPL() from lenstronomy.LensModel.Profiles.nie import NIE self.NIE = NIE() def test_function(self): phi_E = 1. t = 1. q = 0.999 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = np.array([1., 2]) y = np.array([2, 0]) values = self.EPL.function(x, y, phi_E, e1, e2, t) values_nie = self.NIE.function(x, y, phi_E, e1, e2, 0.) delta_f = values[0] - values[1] delta_f_nie = values_nie[0] - values_nie[1] npt.assert_almost_equal(delta_f, delta_f_nie, decimal=5) q = 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = np.array([1., 2]) y = np.array([2, 0]) values = self.EPL.function(x, y, phi_E, e1, e2, t) values_nie = self.NIE.function(x, y, phi_E, e1, e2, 0.) delta_f = values[0] - values[1] delta_f_nie = values_nie[0] - values_nie[1] npt.assert_almost_equal(delta_f, delta_f_nie, decimal=5) q = 0.4 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = np.array([1., 2]) y = np.array([2, 0]) values = self.EPL.function(x, y, phi_E, e1, e2, t) values_nie = self.NIE.function(x, y, phi_E, e1, e2, 0.) delta_f = values[0] - values[1] delta_f_nie = values_nie[0] - values_nie[1] npt.assert_almost_equal(delta_f, delta_f_nie, decimal=5) def test_derivatives(self): x = np.array([1]) y = np.array([2]) phi_E = 1. t = 1. q = 1. phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) f_x, f_y = self.EPL.derivatives(x, y, phi_E, e1, e2, t) f_x_nie, f_y_nie = self.NIE.derivatives(x, y, phi_E, e1, e2, 0.) npt.assert_almost_equal(f_x, f_x_nie, decimal=4) npt.assert_almost_equal(f_y, f_y_nie, decimal=4) q = 0.7 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) f_x, f_y = self.EPL.derivatives(x, y, phi_E, e1, e2, t) f_x_nie, f_y_nie = self.NIE.derivatives(x, y, phi_E, e1, e2, 0.) npt.assert_almost_equal(f_x, f_x_nie, decimal=4) npt.assert_almost_equal(f_y, f_y_nie, decimal=4) def test_hessian(self): x = np.array([1.]) y = np.array([2.]) phi_E = 1. t = 1. q = 0.9 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) f_xx, f_yy, f_xy = self.EPL.hessian(x, y, phi_E, e1, e2, t) f_xx_nie, f_yy_nie, f_xy_nie = self.NIE.hessian( x, y, phi_E, e1, e2, 0.) npt.assert_almost_equal(f_xx, f_xx_nie, decimal=4) npt.assert_almost_equal(f_yy, f_yy_nie, decimal=4) npt.assert_almost_equal(f_xy, f_xy_nie, decimal=4) def test_static(self): x, y = 1., 1. phi_G, q = 0.3, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) kwargs_lens = {'theta_E': 1., 't': 1.5, 'e1': e1, 'e2': e2} f_ = self.EPL.function(x, y, **kwargs_lens) self.EPL.set_static(**kwargs_lens) f_static = self.EPL.function(x, y, **kwargs_lens) npt.assert_almost_equal(f_, f_static, decimal=8) self.EPL.set_dynamic() kwargs_lens = {'theta_E': 2., 't': 0.5, 'e1': e1, 'e2': e2} f_dyn = self.EPL.function(x, y, **kwargs_lens) assert f_dyn != f_static
class TestEPL_numba(object): """ tests the Gaussian methods """ def setup(self): from lenstronomy.LensModel.Profiles.epl import EPL self.EPL = EPL() from lenstronomy.LensModel.Profiles.epl_numba import EPL_numba self.EPL_numba = EPL_numba() def test_function(self): phi_E = 1. gamma = 2. q = 0.999 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = np.array([1., 2]) y = np.array([2, 0]) values = self.EPL.function(x, y, phi_E, gamma, e1, e2) values_nb = self.EPL_numba.function(x, y, phi_E, gamma, e1, e2) delta_f = values[0] - values[1] delta_f_nb = values_nb[0] - values_nb[1] npt.assert_almost_equal(delta_f, delta_f_nb, decimal=10) q = 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = np.array([1., 2]) y = np.array([2, 0]) values = self.EPL.function(x, y, phi_E, gamma, e1, e2) values_nb = self.EPL_numba.function(x, y, phi_E, gamma, e1, e2) delta_f = values[0] - values[1] delta_f_nb = values_nb[0] - values_nb[1] npt.assert_almost_equal(delta_f, delta_f_nb, decimal=10) q = 0.4 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = np.array([1., 2]) y = np.array([2, 0]) values = self.EPL.function(x, y, phi_E, gamma, e1, e2) values_nb = self.EPL_numba.function(x, y, phi_E, gamma, e1, e2) delta_f = values[0] - values[1] delta_f_nb = values_nb[0] - values_nb[1] npt.assert_almost_equal(delta_f, delta_f_nb, decimal=10) def test_derivatives(self): x = np.array([1]) y = np.array([2]) phi_E = 1. gamma = 1.8 q = 1. phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) f_x, f_y = self.EPL.derivatives(x, y, phi_E, gamma, e1, e2) f_x_nb, f_y_nb = self.EPL_numba.derivatives(x, y, phi_E, gamma, e1, e2) npt.assert_almost_equal(f_x, f_x_nb, decimal=10) npt.assert_almost_equal(f_y, f_y_nb, decimal=10) q = 0.7 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) f_x, f_y = self.EPL.derivatives(x, y, phi_E, gamma, e1, e2) f_x_nb, f_y_nb = self.EPL_numba.derivatives(x, y, phi_E, gamma, e1, e2) npt.assert_almost_equal(f_x, f_x_nb, decimal=10) npt.assert_almost_equal(f_y, f_y_nb, decimal=10) def test_hessian(self): x = np.array([1.]) y = np.array([2.]) phi_E = 1. gamma = 2.2 q = 0.9 phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) f_xx, f_xy, f_yx, f_yy = self.EPL.hessian(x, y, phi_E, gamma, e1, e2) f_xx_nb, f_xy_nb, f_yx_nb, f_yy_nb = self.EPL_numba.hessian( x, y, phi_E, gamma, e1, e2) npt.assert_almost_equal(f_xx, f_xx_nb, decimal=10) npt.assert_almost_equal(f_yy, f_yy_nb, decimal=10) npt.assert_almost_equal(f_xy, f_xy_nb, decimal=10) def test_regularization(self): phi_E = 1. gamma = 2. q = 1. phi_G = 1. e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) x = 0. y = 0. f_x, f_y = self.EPL_numba.derivatives(x, y, phi_E, gamma, e1, e2) npt.assert_almost_equal(f_x, 0.) npt.assert_almost_equal(f_y, 0.) x = 0. y = 0. f_x, f_y = self.EPL.derivatives(x, y, phi_E, gamma, e1, e2) npt.assert_almost_equal(f_x, 0.) npt.assert_almost_equal(f_y, 0.) x = 0. y = 0. f_x, f_y = self.EPL.derivatives(x, y, phi_E, gamma + 0.1, e1, e2) npt.assert_almost_equal(f_x, 0.) npt.assert_almost_equal(f_y, 0.) x = 0. y = 0. f = self.EPL_numba.function(x, y, phi_E, gamma, e1, e2) npt.assert_almost_equal(f, 0.) x = 0. y = 0. f_xx, f_xy, f_yx, f_yy = self.EPL_numba.hessian( x, y, phi_E, gamma, e1, e2) npt.assert_almost_equal(f_xx, 1e10, decimal=10) npt.assert_almost_equal(f_yy, 0, decimal=10) npt.assert_almost_equal( f_xy, 0, decimal=5) # floating point cancellation, so less precise # Magnification: npt.assert_almost_equal(1 / ((1 - f_xx) * (1 - f_yy) - f_xy**2), 0., decimal=10)
def setup(self): from lenstronomy.LensModel.Profiles.epl import EPL self.EPL = EPL() from lenstronomy.LensModel.Profiles.epl_numba import EPL_numba self.EPL_numba = EPL_numba()
class SIE(LensProfileBase): """ class for singular isothermal ellipsoid (SIS with ellipticity) """ param_names = ['theta_E', 'e1', 'e2', 'center_x', 'center_y'] lower_limit_default = { 'theta_E': 0, 'e1': -0.5, 'e2': -0.5, 'center_x': -100, 'center_y': -100 } upper_limit_default = { 'theta_E': 100, 'e1': 0.5, 'e2': 0.5, 'center_x': 100, 'center_y': 100 } def __init__(self, NIE=True): """ :param NIE: bool, if True, is using the NIE analytic model. Otherwise it uses PEMD with gamma=2 from fastell4py """ self._nie = NIE if NIE: from lenstronomy.LensModel.Profiles.nie import NIE self.profile = NIE() else: from lenstronomy.LensModel.Profiles.epl import EPL self.profile = EPL() self._s_scale = 0.0000000001 self._gamma = 2 super(SIE, self).__init__() def function(self, x, y, theta_E, e1, e2, center_x=0, center_y=0): """ :param x: :param y: :param theta_E: :param q: :param phi_G: :param center_x: :param center_y: :return: """ if self._nie: return self.profile.function(x, y, theta_E, e1, e2, self._s_scale, center_x, center_y) else: return self.profile.function(x, y, theta_E, self._gamma, e1, e2, center_x, center_y) def derivatives(self, x, y, theta_E, e1, e2, center_x=0, center_y=0): """ :param x: :param y: :param theta_E: :param q: :param phi_G: :param center_x: :param center_y: :return: """ if self._nie: return self.profile.derivatives(x, y, theta_E, e1, e2, self._s_scale, center_x, center_y) else: return self.profile.derivatives(x, y, theta_E, self._gamma, e1, e2, center_x, center_y) def hessian(self, x, y, theta_E, e1, e2, center_x=0, center_y=0): """ :param x: :param y: :param theta_E: :param q: :param phi_G: :param center_x: :param center_y: :return: """ if self._nie: return self.profile.hessian(x, y, theta_E, e1, e2, self._s_scale, center_x, center_y) else: return self.profile.hessian(x, y, theta_E, self._gamma, e1, e2, center_x, center_y) @staticmethod def theta2rho(theta_E): """ converts projected density parameter (in units of deflection) into 3d density parameter :param theta_E: :return: """ fac1 = np.pi * 2 rho0 = theta_E / fac1 return rho0 @staticmethod def mass_3d(r, rho0, e1=0, e2=0): """ mass enclosed a 3d sphere or radius r :param r: radius in angular units :param rho0: density at angle=1 :return: mass in angular units """ mass_3d = 4 * np.pi * rho0 * r return mass_3d def mass_3d_lens(self, r, theta_E, e1=0, e2=0): """ mass enclosed a 3d sphere or radius r given a lens parameterization with angular units :param r: radius in angular units :param theta_E: Einstein radius :return: mass in angular units """ rho0 = self.theta2rho(theta_E) return self.mass_3d(r, rho0) def mass_2d(self, r, rho0, e1=0, e2=0): """ mass enclosed projected 2d sphere of radius r :param r: :param rho0: :param a: :param s: :return: """ alpha = np.pi * np.pi * 2 * rho0 mass_2d = alpha * r return mass_2d def mass_2d_lens(self, r, theta_E, e1=0, e2=0): """ :param r: :param theta_E: :return: """ rho0 = self.theta2rho(theta_E) return self.mass_2d(r, rho0) def grav_pot(self, x, y, rho0, e1=0, e2=0, center_x=0, center_y=0): """ gravitational potential (modulo 4 pi G and rho0 in appropriate units) :param x: :param y: :param rho0: :param a: :param s: :param center_x: :param center_y: :return: """ x_ = x - center_x y_ = y - center_y r = np.sqrt(x_**2 + y_**2) mass_3d = self.mass_3d(r, rho0) pot = mass_3d / r return pot def density_lens(self, r, theta_E, e1=0, e2=0): """ computes the density at 3d radius r given lens model parameterization. The integral in the LOS projection of this quantity results in the convergence quantity. :param r: radius in angles :param theta_E: Einstein radius :param e1: eccentricity component :param e2: eccentricity component :return: density """ rho0 = self.theta2rho(theta_E) return self.density(r, rho0) @staticmethod def density(r, rho0, e1=0, e2=0): """ computes the density :param r: radius in angles :param rho0: density at angle=1 :return: density at r """ rho = rho0 / r**2 return rho @staticmethod def density_2d(x, y, rho0, e1=0, e2=0, center_x=0, center_y=0): """ projected density :param x: :param y: :param rho0: :param center_x: :param center_y: :return: """ x_ = x - center_x y_ = y - center_y r = np.sqrt(x_**2 + y_**2) sigma = np.pi * rho0 / r return sigma