class SersicEllipse(LensProfileBase): """ this class contains functions to evaluate a Sersic mass profile: https://arxiv.org/pdf/astro-ph/0311559.pdf """ param_names = ['k_eff', 'R_sersic', 'n_sersic', 'e1', 'e2', 'center_x', 'center_y'] lower_limit_default = {'k_eff': 0, 'R_sersic': 0, 'n_sersic': 0.5, 'e1': -0.5, 'e2': -0.5, 'center_x': -100, 'center_y': -100} upper_limit_default = {'k_eff': 10, 'R_sersic': 100, 'n_sersic': 8, 'e1': 0.5, 'e2': 0.5, 'center_x': 100, 'center_y': 100} def __init__(self): self.sersic = Sersic() self._diff = 0.000001 super(SersicEllipse, self).__init__() def function(self, x, y, n_sersic, R_sersic, k_eff, e1, e2, center_x=0, center_y=0): """ returns Gaussian """ # phi_G, q = param_util.ellipticity2phi_q(e1, e2) x_, y_ = param_util.transform_e1e2_square_average(x, y, e1, e2, center_x, center_y) # x_, y_ = self._coord_transf(x, y, q, phi_G, center_x, center_y) f_ = self.sersic.function(x_, y_, n_sersic, R_sersic, k_eff) return f_ def derivatives(self, x, y, n_sersic, R_sersic, k_eff, e1, e2, center_x=0, center_y=0): """ returns df/dx and df/dy of the function """ phi_G, q = param_util.ellipticity2phi_q(e1, e2) e = param_util.q2e(q) # e = abs(1. - q) cos_phi = np.cos(phi_G) sin_phi = np.sin(phi_G) x_, y_ = param_util.transform_e1e2_square_average(x, y, e1, e2, center_x, center_y) # x_, y_ = self._coord_transf(x, y, q, phi_G, center_x, center_y) f_x_prim, f_y_prim = self.sersic.derivatives(x_, y_, n_sersic, R_sersic, k_eff) f_x_prim *= np.sqrt(1 - e) f_y_prim *= np.sqrt(1 + e) f_x = cos_phi*f_x_prim-sin_phi*f_y_prim f_y = sin_phi*f_x_prim+cos_phi*f_y_prim return f_x, f_y def hessian(self, x, y, n_sersic, R_sersic, k_eff, e1, e2, center_x=0, center_y=0): """ returns Hessian matrix of function d^2f/dx^2, d^2/dxdy, d^2/dydx, d^f/dy^2 """ alpha_ra, alpha_dec = self.derivatives(x, y, n_sersic, R_sersic, k_eff, e1, e2, center_x, center_y) diff = self._diff alpha_ra_dx, alpha_dec_dx = self.derivatives(x + diff, y, n_sersic, R_sersic, k_eff, e1, e2, center_x, center_y) alpha_ra_dy, alpha_dec_dy = self.derivatives(x, y + diff, n_sersic, R_sersic, k_eff, e1, e2, center_x, center_y) f_xx = (alpha_ra_dx - alpha_ra)/diff f_xy = (alpha_ra_dy - alpha_ra)/diff f_yx = (alpha_dec_dx - alpha_dec)/diff f_yy = (alpha_dec_dy - alpha_dec)/diff return f_xx, f_xy, f_yx, f_yy
def test_sersic(self): from lenstronomy.LensModel.Profiles.sersic import Sersic from lenstronomy.LightModel.Profiles.sersic import Sersic as SersicLight sersic_lens = Sersic() sersic_light = SersicLight() kwargs_light = { 'n_sersic': 2, 'R_sersic': 0.5, 'I0_sersic': 1, 'center_x': 0, 'center_y': 0 } kwargs_lens = { 'n_sersic': 2, 'R_sersic': 0.5, 'k_eff': 1, 'center_x': 0, 'center_y': 0 } deltaPix = 0.01 numPix = 1000 x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix) x_grid2d = util.array2image(x_grid) y_grid2d = util.array2image(y_grid) f_xx, f_yy, _ = sersic_lens.hessian(x_grid, y_grid, **kwargs_lens) f_x, f_y = sersic_lens.derivatives(x_grid, y_grid, **kwargs_lens) f_x = util.array2image(f_x) kappa = util.array2image((f_xx + f_yy) / 2.) f_x_num, f_y_num = convergence_integrals.deflection_from_kappa_grid( kappa, deltaPix) x1, y1 = 500, 550 x0, y0 = int(numPix / 2.), int(numPix / 2.) npt.assert_almost_equal(f_x[x1, y1], f_x_num[x1, y1], decimal=2) f_num = convergence_integrals.potential_from_kappa_grid( kappa, deltaPix) f_ = sersic_lens.function(x_grid2d[x1, y1], y_grid2d[x1, y1], **kwargs_lens) f_00 = sersic_lens.function(x_grid2d[x0, y0], y_grid2d[x0, y0], **kwargs_lens) npt.assert_almost_equal(f_ - f_00, f_num[x1, y1] - f_num[x0, y0], decimal=2)
def setup(self): self.composite = CompositeSersicNFW() self.sersic = Sersic() self.nfw = NFW_ELLIPSE()
def __init__(self, lens_model_list, **kwargs): """ :param lens_model_list: list of strings with lens model names :param foreground_shear: bool, when True, models a foreground non-linear shear distortion """ self.func_list = [] self._foreground_shear = False for i, lens_type in enumerate(lens_model_list): if lens_type == 'SHEAR': from lenstronomy.LensModel.Profiles.external_shear import ExternalShear self.func_list.append(ExternalShear()) elif lens_type == 'CONVERGENCE': from lenstronomy.LensModel.Profiles.mass_sheet import MassSheet self.func_list.append(MassSheet()) elif lens_type == 'FLEXION': from lenstronomy.LensModel.Profiles.flexion import Flexion self.func_list.append(Flexion()) elif lens_type == 'POINT_MASS': from lenstronomy.LensModel.Profiles.point_mass import PointMass self.func_list.append(PointMass()) elif lens_type == 'SIS': from lenstronomy.LensModel.Profiles.sis import SIS self.func_list.append(SIS()) elif lens_type == 'SIS_TRUNCATED': from lenstronomy.LensModel.Profiles.sis_truncate import SIS_truncate self.func_list.append(SIS_truncate()) elif lens_type == 'SIE': from lenstronomy.LensModel.Profiles.sie import SIE self.func_list.append(SIE()) elif lens_type == 'SPP': from lenstronomy.LensModel.Profiles.spp import SPP self.func_list.append(SPP()) elif lens_type == 'NIE': from lenstronomy.LensModel.Profiles.nie import NIE self.func_list.append(NIE()) elif lens_type == 'NIE_SIMPLE': from lenstronomy.LensModel.Profiles.nie import NIE_simple self.func_list.append(NIE_simple()) elif lens_type == 'CHAMELEON': from lenstronomy.LensModel.Profiles.chameleon import Chameleon self.func_list.append(Chameleon()) elif lens_type == 'DOUBLE_CHAMELEON': from lenstronomy.LensModel.Profiles.chameleon import DoubleChameleon self.func_list.append(DoubleChameleon()) elif lens_type == 'SPEP': from lenstronomy.LensModel.Profiles.spep import SPEP self.func_list.append(SPEP()) elif lens_type == 'SPEMD': from lenstronomy.LensModel.Profiles.spemd import SPEMD self.func_list.append(SPEMD()) elif lens_type == 'SPEMD_SMOOTH': from lenstronomy.LensModel.Profiles.spemd_smooth import SPEMD_SMOOTH self.func_list.append(SPEMD_SMOOTH()) elif lens_type == 'NFW': from lenstronomy.LensModel.Profiles.nfw import NFW self.func_list.append(NFW(**kwargs)) elif lens_type == 'NFW_ELLIPSE': from lenstronomy.LensModel.Profiles.nfw_ellipse import NFW_ELLIPSE self.func_list.append( NFW_ELLIPSE(interpol=False, num_interp_X=1000, max_interp_X=100)) elif lens_type == 'TNFW': from lenstronomy.LensModel.Profiles.tnfw import TNFW self.func_list.append(TNFW()) elif lens_type == 'SERSIC': from lenstronomy.LensModel.Profiles.sersic import Sersic self.func_list.append(Sersic()) elif lens_type == 'SERSIC_ELLIPSE': from lenstronomy.LensModel.Profiles.sersic_ellipse import SersicEllipse self.func_list.append(SersicEllipse()) elif lens_type == 'PJAFFE': from lenstronomy.LensModel.Profiles.p_jaffe import PJaffe self.func_list.append(PJaffe()) elif lens_type == 'PJAFFE_ELLIPSE': from lenstronomy.LensModel.Profiles.p_jaffe_ellipse import PJaffe_Ellipse self.func_list.append(PJaffe_Ellipse()) elif lens_type == 'HERNQUIST': from lenstronomy.LensModel.Profiles.hernquist import Hernquist self.func_list.append(Hernquist()) elif lens_type == 'HERNQUIST_ELLIPSE': from lenstronomy.LensModel.Profiles.hernquist_ellipse import Hernquist_Ellipse self.func_list.append(Hernquist_Ellipse()) elif lens_type == 'GAUSSIAN': from lenstronomy.LensModel.Profiles.gaussian_potential import Gaussian self.func_list.append(Gaussian()) elif lens_type == 'GAUSSIAN_KAPPA': from lenstronomy.LensModel.Profiles.gaussian_kappa import GaussianKappa self.func_list.append(GaussianKappa()) elif lens_type == 'GAUSSIAN_KAPPA_ELLIPSE': from lenstronomy.LensModel.Profiles.gaussian_kappa_ellipse import GaussianKappaEllipse self.func_list.append(GaussianKappaEllipse()) elif lens_type == 'MULTI_GAUSSIAN_KAPPA': from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappa self.func_list.append(MultiGaussianKappa()) elif lens_type == 'MULTI_GAUSSIAN_KAPPA_ELLIPSE': from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappaEllipse self.func_list.append(MultiGaussianKappaEllipse()) elif lens_type == 'INTERPOL': from lenstronomy.LensModel.Profiles.interpol import Interpol_func self.func_list.append( Interpol_func(grid=False, min_grid_number=100)) elif lens_type == 'INTERPOL_SCALED': from lenstronomy.LensModel.Profiles.interpol import Interpol_func_scaled self.func_list.append( Interpol_func_scaled(grid=False, min_grid_number=100)) elif lens_type == 'SHAPELETS_POLAR': from lenstronomy.LensModel.Profiles.shapelet_pot_polar import PolarShapelets self.func_list.append(PolarShapelets()) elif lens_type == 'SHAPELETS_CART': from lenstronomy.LensModel.Profiles.shapelet_pot_cartesian import CartShapelets self.func_list.append(CartShapelets()) elif lens_type == 'DIPOLE': from lenstronomy.LensModel.Profiles.dipole import Dipole self.func_list.append(Dipole()) elif lens_type == 'FOREGROUND_SHEAR': from lenstronomy.LensModel.Profiles.external_shear import ExternalShear self.func_list.append(ExternalShear()) self._foreground_shear = True self._foreground_shear_idex = i else: raise ValueError('%s is not a valid lens model' % lens_type) self._model_list = lens_model_list
class SersicEllipse(object): """ this class contains functions to evaluate a Sersic mass profile: https://arxiv.org/pdf/astro-ph/0311559.pdf """ def __init__(self): self.sersic = Sersic() self._diff = 0.000001 def function(self, x, y, n_sersic, r_eff, k_eff, q, phi_G, center_x=0, center_y=0): """ returns Gaussian """ x_, y_ = self._coord_transf(x, y, q, phi_G, center_x, center_y) f_ = self.sersic.function(x_, y_, n_sersic, r_eff, k_eff) return f_ def derivatives(self, x, y, n_sersic, r_eff, k_eff, q, phi_G, center_x=0, center_y=0): """ returns df/dx and df/dy of the function """ e = abs(1. - q) cos_phi = np.cos(phi_G) sin_phi = np.sin(phi_G) x_, y_ = self._coord_transf(x, y, q, phi_G, center_x, center_y) f_x_prim, f_y_prim = self.sersic.derivatives(x_, y_, n_sersic, r_eff, k_eff) f_x_prim *= np.sqrt(1 - e) f_y_prim *= np.sqrt(1 + e) f_x = cos_phi * f_x_prim - sin_phi * f_y_prim f_y = sin_phi * f_x_prim + cos_phi * f_y_prim return f_x, f_y def hessian(self, x, y, n_sersic, r_eff, k_eff, q, phi_G, center_x=0, center_y=0): """ returns Hessian matrix of function d^2f/dx^2, d^f/dy^2, d^2/dxdy """ alpha_ra, alpha_dec = self.derivatives(x, y, n_sersic, r_eff, k_eff, q, phi_G, center_x, center_y) diff = self._diff alpha_ra_dx, alpha_dec_dx = self.derivatives(x + diff, y, n_sersic, r_eff, k_eff, q, phi_G, center_x, center_y) alpha_ra_dy, alpha_dec_dy = self.derivatives(x, y + diff, n_sersic, r_eff, k_eff, q, phi_G, center_x, center_y) f_xx = (alpha_ra_dx - alpha_ra) / diff f_xy = (alpha_ra_dy - alpha_ra) / diff f_yx = (alpha_dec_dx - alpha_dec) / diff f_yy = (alpha_dec_dy - alpha_dec) / diff return f_xx, f_yy, f_xy def _coord_transf(self, x, y, q, phi_G, center_x, center_y): """ :param x: :param y: :param q: :param phi_G: :param center_x: :param center_y: :return: """ x_shift = x - center_x y_shift = y - center_y cos_phi = np.cos(phi_G) sin_phi = np.sin(phi_G) e = abs(1 - q) x_ = (cos_phi * x_shift + sin_phi * y_shift) * np.sqrt(1 - e) y_ = (-sin_phi * x_shift + cos_phi * y_shift) * np.sqrt(1 + e) return x_, y_
def __init__(self): self.sersic = Sersic() self._diff = 0.000001
def setup(self): self.sersic_gauss = SersicEllipseGaussDec() self.sersic_light = SersicElliptic(sersic_major_axis=False) self.sersic_sphere = Sersic(sersic_major_axis=False)
class SersicEllipseKappa(LensProfileBase): """ this class contains the function and the derivatives of an elliptical sersic profile with the ellipticity introduced in the convergence (not the potential). This requires the use of numerical integrals (Keeton 2004) """ param_names = [ 'k_eff', 'R_sersic', 'n_sersic', 'e1', 'e2', 'center_x', 'center_y' ] lower_limit_default = { 'k_eff': 0, 'R_sersic': 0, 'n_sersic': 0.5, 'e1': -0.5, 'e2': -0.5, 'center_x': -100, 'center_y': -100 } upper_limit_default = { 'k_eff': 10, 'R_sersic': 100, 'n_sersic': 8, 'e1': 0.5, 'e2': 0.5, 'center_x': 100, 'center_y': 100 } def __init__(self): self._sersic = Sersic() super(SersicEllipseKappa, self).__init__() def function(self, x, y, n_sersic, R_sersic, k_eff, e1, e2, center_x=0, center_y=0): raise Exception('not yet implemented') # phi_G, q = param_util.ellipticity2phi_q(e1, e2) # # if isinstance(x, float) and isinstance(y, float): # # x_, y_ = self._coord_rotate(x, y, phi_G, center_x, center_y) # integral = quad(self._integrand_I, 0, 1, args=(x_, y_, q, n_sersic, R_sersic, k_eff, center_x, center_y))[0] # # else: # # assert isinstance(x, np.ndarray) or isinstance(x, list) # assert isinstance(y, np.ndarray) or isinstance(y, list) # x = np.array(x) # y = np.array(y) # shape0 = x.shape # assert shape0 == y.shape # # if isinstance(phi_G, float) or isinstance(phi_G, int): # phiG = np.ones_like(x) * float(phi_G) # q = np.ones_like(x) * float(q) # integral = [] # for i, (x_i, y_i, phi_i, q_i) in \ # enumerate(zip(x.ravel(), y.ravel(), phiG.ravel(), q.ravel())): # # integral.append(quad(self._integrand_I, 0, 1, args=(x_, y_, q, n_sersic, # R_sersic, k_eff, center_x, center_y))[0]) # # # return 0.5 * q * integral def derivatives(self, x, y, n_sersic, R_sersic, k_eff, e1, e2, center_x=0, center_y=0): phi_G, gam = param_util.shear_cartesian2polar(e1, e2) q = max(1 - gam, 0.00001) x, y = self._coord_rotate(x, y, phi_G, center_x, center_y) if isinstance(x, float) and isinstance(y, float): alpha_x, alpha_y = self._compute_derivative_atcoord( x, y, n_sersic, R_sersic, k_eff, phi_G, q, center_x=center_x, center_y=center_y) else: assert isinstance(x, np.ndarray) or isinstance(x, list) assert isinstance(y, np.ndarray) or isinstance(y, list) x = np.array(x) y = np.array(y) shape0 = x.shape assert shape0 == y.shape alpha_x, alpha_y = np.empty_like(x).ravel(), np.empty_like( y).ravel() if isinstance(phi_G, float) or isinstance(phi_G, int): phiG = np.ones_like(alpha_x) * float(phi_G) q = np.ones_like(alpha_x) * float(q) for i, (x_i, y_i, phi_i, q_i) in \ enumerate(zip(x.ravel(), y.ravel(), phiG.ravel(), q.ravel())): fxi, fyi = self._compute_derivative_atcoord(x_i, y_i, n_sersic, R_sersic, k_eff, phi_i, q_i, center_x=center_x, center_y=center_y) alpha_x[i], alpha_y[i] = fxi, fyi alpha_x = alpha_x.reshape(shape0) alpha_y = alpha_y.reshape(shape0) alpha_x, alpha_y = self._coord_rotate(alpha_x, alpha_y, -phi_G, 0, 0) return alpha_x, alpha_y def hessian(self, x, y, n_sersic, R_sersic, k_eff, e1, e2, center_x=0, center_y=0): """ returns Hessian matrix of function d^2f/dx^2, d^2/dxdy, d^2/dydx, d^f/dy^2 """ alpha_ra, alpha_dec = self.derivatives(x, y, n_sersic, R_sersic, k_eff, e1, e2, center_x, center_y) diff = 0.000001 alpha_ra_dx, alpha_dec_dx = self.derivatives(x + diff, y, n_sersic, R_sersic, k_eff, e1, e2, center_x, center_y) alpha_ra_dy, alpha_dec_dy = self.derivatives(x, y + diff, n_sersic, R_sersic, k_eff, e1, e2, center_x, center_y) f_xx = (alpha_ra_dx - alpha_ra) / diff f_xy = (alpha_ra_dy - alpha_ra) / diff f_yx = (alpha_dec_dx - alpha_dec) / diff f_yy = (alpha_dec_dy - alpha_dec) / diff return f_xx, f_xy, f_yx, f_yy def projected_mass(self, x, y, q, n_sersic, R_sersic, k_eff, u=1, power=1): b_n = self._sersic.b_n(n_sersic) elliptical_coord = self._elliptical_coord_u(x, y, u, q)**power elliptical_coord *= R_sersic**-power exponent = -b_n * (elliptical_coord**(1. / n_sersic) - 1) return k_eff * np.exp(exponent) def _integrand_J(self, u, x, y, n_sersic, q, R_sersic, k_eff, n_integral): kappa = self.projected_mass(x, y, q, n_sersic, R_sersic, k_eff, u=u, power=1) power = -(n_integral + 0.5) return kappa * (1 - (1 - q**2) * u)**power def _integrand_I(self, u, x, y, q, n_sersic, R_sersic, keff, centerx, centery): ellip_coord = self._elliptical_coord_u(x, y, u, q) def_angle_circular = self._sersic.alpha_abs(ellip_coord, 0, n_sersic, R_sersic, keff, centerx, centery) return ellip_coord * def_angle_circular * ( 1 - (1 - q**2) * u)**-0.5 * u**-1 def _compute_derivative_atcoord(self, x, y, n_sersic, R_sersic, k_eff, phi_G, q, center_x=0, center_y=0): alpha_x = x * q * quad(self._integrand_J, 0, 1, args=(x, y, n_sersic, q, R_sersic, k_eff, 0))[0] alpha_y = y * q * quad(self._integrand_J, 0, 1, args=(x, y, n_sersic, q, R_sersic, k_eff, 1))[0] return alpha_x, alpha_y @staticmethod def _elliptical_coord_u(x, y, u, q): fac = 1 - (1 - q**2) * u return (u * (x**2 + y**2 * fac**-1))**0.5 @staticmethod def _coord_rotate(x, y, phi_G, center_x, center_y): x_shift = x - center_x y_shift = y - center_y cos_phi = np.cos(phi_G) sin_phi = np.sin(phi_G) x_ = cos_phi * x_shift + sin_phi * y_shift y_ = -sin_phi * x_shift + cos_phi * y_shift return x_, y_
def setup(self): self.sersic_2 = SersicEllipseKappa() self.sersic = Sersic() self.sersic_light = Sersic_light()
class TestSersic(object): """ tests the Gaussian methods """ def setup(self): self.sersic_2 = SersicEllipseKappa() self.sersic = Sersic() self.sersic_light = Sersic_light() def test_function(self): x = 1 y = 2 n_sersic = 2. R_sersic = 1. k_eff = 0.2 values = self.sersic.function(x, y, n_sersic, R_sersic, k_eff) npt.assert_almost_equal(values, 1.0272982586319199, decimal=10) x = np.array([0]) y = np.array([0]) values = self.sersic.function(x, y, n_sersic, R_sersic, k_eff) npt.assert_almost_equal(values[0], 0., decimal=9) x = np.array([2, 3, 4]) y = np.array([1, 1, 1]) values = self.sersic.function(x, y, n_sersic, R_sersic, k_eff) npt.assert_almost_equal(values[0], 1.0272982586319199, decimal=10) npt.assert_almost_equal(values[1], 1.3318743892966658, decimal=10) npt.assert_almost_equal(values[2], 1.584299393114988, decimal=10) def test_derivatives(self): x = np.array([1]) y = np.array([2]) n_sersic = 2. R_sersic = 1. k_eff = 0.2 f_x, f_y = self.sersic.derivatives(x, y, n_sersic, R_sersic, k_eff) f_x2, f_y2 = self.sersic_2.derivatives(x, y, n_sersic, R_sersic, k_eff, 0, 0.00000001) assert f_x[0] == 0.16556078301997193 assert f_y[0] == 0.33112156603994386 npt.assert_almost_equal(f_x2[0], f_x[0]) npt.assert_almost_equal(f_y2[0], f_y[0]) x = np.array([0]) y = np.array([0]) f_x, f_y = self.sersic.derivatives(x, y, n_sersic, R_sersic, k_eff) f_x2, f_y2 = self.sersic_2.derivatives(x, y, n_sersic, R_sersic, k_eff, 0, 0.00000001) assert f_x[0] == 0 assert f_y[0] == 0 npt.assert_almost_equal(f_x2[0], f_x[0]) npt.assert_almost_equal(f_y2[0], f_y[0]) x = np.array([1, 3, 4]) y = np.array([2, 1, 1]) values = self.sersic.derivatives(x, y, n_sersic, R_sersic, k_eff) values2 = self.sersic_2.derivatives(x, y, n_sersic, R_sersic, k_eff, 0, 0.00000001) assert values[0][0] == 0.16556078301997193 assert values[1][0] == 0.33112156603994386 assert values[0][1] == 0.2772992378623737 assert values[1][1] == 0.092433079287457892 npt.assert_almost_equal(values2[0][0], values[0][0]) npt.assert_almost_equal(values2[1][0], values[1][0]) npt.assert_almost_equal(values2[0][1], values[0][1]) npt.assert_almost_equal(values2[1][1], values[1][1]) values2 = self.sersic_2.derivatives(0.3, -0.2, n_sersic, R_sersic, k_eff, 0, 0.00000001) values = self.sersic.derivatives(0.3, -0.2, n_sersic, R_sersic, k_eff, 0, 0.00000001) npt.assert_almost_equal(values2[0], values[0]) npt.assert_almost_equal(values2[1], values[1]) def test_differentails(self): x_, y_ = 1., 1 n_sersic = 2. R_sersic = 1. k_eff = 0.2 r = np.sqrt(x_**2 + y_**2) d_alpha_dr = self.sersic.d_alpha_dr(x_, y_, n_sersic, R_sersic, k_eff) alpha = self.sersic.alpha_abs(x_, y_, n_sersic, R_sersic, k_eff) f_xx_ = d_alpha_dr * calc_util.d_r_dx( x_, y_) * x_ / r + alpha * calc_util.d_x_diffr_dx(x_, y_) f_yy_ = d_alpha_dr * calc_util.d_r_dy( x_, y_) * y_ / r + alpha * calc_util.d_y_diffr_dy(x_, y_) f_xy_ = d_alpha_dr * calc_util.d_r_dy( x_, y_) * x_ / r + alpha * calc_util.d_x_diffr_dy(x_, y_) f_xx = (d_alpha_dr / r - alpha / r**2) * y_**2 / r + alpha / r f_yy = (d_alpha_dr / r - alpha / r**2) * x_**2 / r + alpha / r f_xy = (d_alpha_dr / r - alpha / r**2) * x_ * y_ / r npt.assert_almost_equal(f_xx, f_xx_, decimal=10) npt.assert_almost_equal(f_yy, f_yy_, decimal=10) npt.assert_almost_equal(f_xy, f_xy_, decimal=10) def test_hessian(self): x = np.array([1]) y = np.array([2]) n_sersic = 2. R_sersic = 1. k_eff = 0.2 f_xx, f_xy, f_yx, f_yy = self.sersic.hessian(x, y, n_sersic, R_sersic, k_eff) assert f_xx[0] == 0.1123170666045793 npt.assert_almost_equal(f_yy[0], -0.047414082641598576, decimal=10) npt.assert_almost_equal(f_xy[0], -0.10648743283078525, decimal=10) npt.assert_almost_equal(f_xy, f_yx, decimal=5) x = np.array([1, 3, 4]) y = np.array([2, 1, 1]) values = self.sersic.hessian(x, y, n_sersic, R_sersic, k_eff) assert values[0][0] == 0.1123170666045793 npt.assert_almost_equal(values[3][0], -0.047414082641598576, decimal=10) npt.assert_almost_equal(values[1][0], -0.10648743283078525, decimal=10) npt.assert_almost_equal(values[0][1], -0.053273787681591328, decimal=10) npt.assert_almost_equal(values[3][1], 0.076243427402007985, decimal=10) npt.assert_almost_equal(values[1][1], -0.048568955656349749, decimal=10) f_xx2, f_xy2, f_yx2, f_yy2 = self.sersic_2.hessian( x, y, n_sersic, R_sersic, k_eff, 0.0000001, 0) npt.assert_almost_equal(f_xx2, values[0]) npt.assert_almost_equal(f_yy2, values[3], decimal=6) npt.assert_almost_equal(f_xy2, values[1], decimal=6) npt.assert_almost_equal(f_yx2, values[2], decimal=6) def test_alpha_abs(self): x = 1. dr = 0.0000001 n_sersic = 2.5 R_sersic = .5 k_eff = 0.2 alpha_abs = self.sersic.alpha_abs(x, 0, n_sersic, R_sersic, k_eff) f_dr = self.sersic.function(x + dr, 0, n_sersic, R_sersic, k_eff) f_ = self.sersic.function(x, 0, n_sersic, R_sersic, k_eff) alpha_abs_num = -(f_dr - f_) / dr npt.assert_almost_equal(alpha_abs_num, alpha_abs, decimal=3) def test_dalpha_dr(self): x = 1. dr = 0.0000001 n_sersic = 1. R_sersic = .5 k_eff = 0.2 d_alpha_dr = self.sersic.d_alpha_dr(x, 0, n_sersic, R_sersic, k_eff) alpha_dr = self.sersic.alpha_abs(x + dr, 0, n_sersic, R_sersic, k_eff) alpha = self.sersic.alpha_abs(x, 0, n_sersic, R_sersic, k_eff) d_alpha_dr_num = (alpha_dr - alpha) / dr npt.assert_almost_equal(d_alpha_dr, d_alpha_dr_num, decimal=3) def test_mag_sym(self): """ :return: """ r = 2. angle1 = 0. angle2 = 1.5 x1 = r * np.cos(angle1) y1 = r * np.sin(angle1) x2 = r * np.cos(angle2) y2 = r * np.sin(angle2) n_sersic = 4.5 R_sersic = 2.5 k_eff = 0.8 f_xx1, f_xy1, f_yx1, f_yy1 = self.sersic.hessian( x1, y1, n_sersic, R_sersic, k_eff) f_xx2, f_xy2, f_yx2, f_yy2 = self.sersic.hessian( x2, y2, n_sersic, R_sersic, k_eff) kappa_1 = (f_xx1 + f_yy1) / 2 kappa_2 = (f_xx2 + f_yy2) / 2 npt.assert_almost_equal(kappa_1, kappa_2, decimal=10) A_1 = (1 - f_xx1) * (1 - f_yy1) - f_xy1 * f_yx1 A_2 = (1 - f_xx2) * (1 - f_yy2) - f_xy2 * f_yx2 npt.assert_almost_equal(A_1, A_2, decimal=10) def test_convergernce(self): """ test the convergence and compares it with the original Sersic profile :return: """ x = np.array([0, 0, 0, 0, 0]) y = np.array([0.5, 1, 1.5, 2, 2.5]) n_sersic = 4.5 R_sersic = 2.5 k_eff = 0.2 f_xx, f_xy, f_yx, f_yy = self.sersic.hessian(x, y, n_sersic, R_sersic, k_eff) kappa = (f_xx + f_yy) / 2. assert kappa[0] > 0 flux = self.sersic_light.function(x, y, amp=1., R_sersic=R_sersic, n_sersic=n_sersic) flux /= flux[0] kappa /= kappa[0] npt.assert_almost_equal(flux[1], kappa[1], decimal=5) xvalues = np.linspace(0.5, 3., 100) e1, e2 = 0.4, 0. q = ellipticity2phi_q(e1, e2)[1] kappa_ellipse = self.sersic_2.projected_mass(xvalues, 0, q, n_sersic, R_sersic, k_eff) fxx, _, _, fyy = self.sersic_2.hessian(xvalues, 0, n_sersic, R_sersic, k_eff, e1, e2) npt.assert_almost_equal(kappa_ellipse, 0.5 * (fxx + fyy), decimal=5) def test_sersic_util(self): n = 1. Re = 2. k, bn = self.sersic.k_bn(n, Re) Re_new = self.sersic.k_Re(n, k) assert Re == Re_new
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))
def setup(self): self.sersic_gauss = SersicEllipseGaussDec() self.sersic_light = SersicElliptic() self.sersic_sphere = Sersic()
class TestSersicEllipseGaussDec(object): """ This class tests the methods for Gauss-decomposed elliptic Sersic convergence. """ def setup(self): self.sersic_gauss = SersicEllipseGaussDec() self.sersic_light = SersicElliptic() self.sersic_sphere = Sersic() def test_function(self): """ Test the potential function of Gauss-decomposed elliptical Sersic by asserting that the numerical derivative of the computed potential matches with the analytical derivative values. :return: :rtype: """ k_eff = 1. R_sersic = 1. n_sersic = 1. e1 = 0.2 e2 = 0.2 center_x = 0. center_y = 0. diff = 1.e-6 n = 5 xs = np.linspace(0.5 * R_sersic, 2. * R_sersic, n) ys = np.linspace(0.5 * R_sersic, 2. * R_sersic, n) for x, y in zip(xs, ys): func = self.sersic_gauss.function(x, y, e1=e1, e2=e2, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff ) func_dx = self.sersic_gauss.function(x+diff, y, e1=e1, e2=e2, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff ) func_dy = self.sersic_gauss.function(x, y+diff, e1=e1, e2=e2, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff ) f_x_num = (func_dx - func) / diff f_y_num = (func_dy - func) / diff f_x, f_y = self.sersic_gauss.derivatives(x, y, e1=e1, e2=e2, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff ) npt.assert_almost_equal(f_x_num, f_x, decimal=4) npt.assert_almost_equal(f_y_num, f_y, decimal=4) def test_derivatives(self): """ Test the derivative function of Gauss-decomposed elliptical Sersic by matching with the spherical case. :return: :rtype: """ k_eff = 1. R_sersic = 1. n_sersic = 1. e1 = 5.e-5 e2 = 0. center_x = 0. center_y = 0. n = 10 x = np.linspace(0.5*R_sersic, 2.*R_sersic, n) y = np.linspace(0.5*R_sersic, 2.*R_sersic, n) X, Y = np.meshgrid(x, y) f_x_s, f_y_s = self.sersic_sphere.derivatives(X, Y, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff ) f_x, f_y = self.sersic_gauss.derivatives(X, Y, e1=e1, e2=e2, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff ) npt.assert_allclose(f_x, f_x_s, rtol=1e-3, atol=0.) npt.assert_allclose(f_y, f_y_s, rtol=1e-3, atol=0.) npt.assert_almost_equal(f_x, f_x_s, decimal=3) npt.assert_almost_equal(f_y, f_y_s, decimal=3) def test_hessian(self): """ Test the Hessian function of Gauss-decomposed elliptical Sersic by matching with the spherical case. :return: :rtype: """ k_eff = 1. R_sersic = 1. n_sersic = 1. e1 = 5e-5 e2 = 0. center_x = 0. center_y = 0. n = 10 x = np.linspace(0.5 * R_sersic, 2. * R_sersic, n) y = np.linspace(0.5 * R_sersic, 2. * R_sersic, n) X, Y = np.meshgrid(x, y) f_xx_s, f_yy_s, f_xy_s = self.sersic_sphere.hessian(X, Y, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff) f_xx, f_yy, f_xy = self.sersic_gauss.hessian(X, Y, e1=e1, e2=e2, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff) npt.assert_almost_equal(f_xx_s, f_xx, decimal=3) npt.assert_almost_equal(f_yy_s, f_yy, decimal=3) npt.assert_almost_equal(f_xy_s, f_xy, decimal=3) def test_density_2d(self): """ Test the density function of Gauss-decomposed elliptical Sersic by checking with the spherical case. :return: :rtype: """ k_eff = 1. R_sersic = 1. n_sersic = 1. e1 = 0.2 e2 = 0.2 center_x = 0. center_y = 0. n = 100 x = np.logspace(-1., 1., n) y = np.logspace(-1., 1., n) X, Y = np.meshgrid(x, y) sersic_analytic = self.sersic_light.function(X, Y, e1=e1, e2=e2, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, amp=k_eff) sersic_gauss = self.sersic_gauss.density_2d(X, Y, e1=e1, e2=e2, center_x=center_x, center_y=center_y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff) assert np.all( np.abs(sersic_analytic - sersic_gauss) / np.sqrt(sersic_analytic) * 100. < 1.) def test_gauss_decompose_sersic(self): """ Test that `gauss_decompose_sersic()` decomposes the Sersic profile within 1% Poission noise at R_sersic. :return: :rtype: """ y = np.logspace(-1., 1., 100) k_eff = 1. R_sersic = 1. n_sersic = 1. amps, sigmas = self.sersic_gauss.gauss_decompose(n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff) sersic = self.sersic_gauss.get_kappa_1d(y, n_sersic=n_sersic, R_sersic=R_sersic, k_eff=k_eff) back_sersic = np.zeros_like(y) for a, s in zip(amps, sigmas): back_sersic += a * np.exp(-y ** 2 / 2. / s ** 2) assert np.all(np.abs(sersic-back_sersic)/np.sqrt(sersic)*100. < 1.)
def __init__(self): self._sersic = Sersic()
def setup(self): self.sersic = Sersic() self.sersic_light = Sersic_light()
class TestMassAngleConversion(object): """ test angular to mass unit conversions """ def setup(self): self.composite = CompositeSersicNFW() self.sersic = Sersic() self.nfw = NFW_ELLIPSE() def test_convert(self): theta_E = 1. mass_light = 1 / 2. Rs = 5. n_sersic = 2. r_eff = 0.7 theta_Rs, k_eff = self.composite.convert_mass(theta_E, mass_light, Rs, n_sersic, r_eff) alpha_E_sersic, _ = self.sersic.derivatives(theta_E, 0, n_sersic, r_eff, k_eff=1) alpha_E_nfw, _ = self.nfw.derivatives(theta_E, 0, Rs, theta_Rs=1, q=1, phi_G=0) a = theta_Rs * alpha_E_nfw + (k_eff * alpha_E_sersic) b = theta_Rs * alpha_E_nfw / (k_eff * alpha_E_sersic) npt.assert_almost_equal(a, theta_E, decimal=10) npt.assert_almost_equal(b, mass_light, decimal=10) def test_function(self): theta_E = 1. mass_light = 1 / 2. Rs = 5. n_sersic = 2. r_eff = 0.7 q, phi_G = 0.9, 0 q_s, phi_G_s = 0.7, 0.5 x, y, = 1, 1 f_ = self.composite.function(x, y, theta_E, mass_light, Rs, q, phi_G, n_sersic, r_eff, q_s, phi_G_s, center_x=0, center_y=0) npt.assert_almost_equal(f_, 1.1983595285200526, decimal=10) def test_derivatives(self): theta_E = 1. mass_light = 1 / 2. Rs = 5. n_sersic = 2. r_eff = 0.7 q, phi_G = 0.9, 0 q_s, phi_G_s = 0.7, 0.5 x, y, = 1, 1 f_x, f_y = self.composite.derivatives(x, y, theta_E, mass_light, Rs, q, phi_G, n_sersic, r_eff, q_s, phi_G_s, center_x=0, center_y=0) npt.assert_almost_equal(f_x, 0.54138666294863724, decimal=10) npt.assert_almost_equal(f_y, 0.75841883763728535, decimal=10) def test_hessian(self): theta_E = 1. mass_light = 1 / 2. Rs = 5. n_sersic = 2. r_eff = 0.7 q, phi_G = 0.9, 0 q_s, phi_G_s = 0.7, 0.5 x, y, = 1, 1 f_xx, f_yy, f_xy = self.composite.hessian(x, y, theta_E, mass_light, Rs, q, phi_G, n_sersic, r_eff, q_s, phi_G_s, center_x=0, center_y=0) npt.assert_almost_equal(f_xx, 0.43275276043197586, decimal=10) npt.assert_almost_equal(f_yy, 0.37688935994317774, decimal=10) npt.assert_almost_equal(f_xy, -0.46895575042671389, decimal=10)
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 == '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 == 'SPEMD': from lenstronomy.LensModel.Profiles.spemd import SPEMD return SPEMD() elif lens_type == 'SPEMD_SMOOTH': from lenstronomy.LensModel.Profiles.spemd_smooth import SPEMD_SMOOTH return SPEMD_SMOOTH() 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) else: raise ValueError('%s is not a valid lens model' % lens_type)
def __init__(self): self.sersic = Sersic() self._diff = 0.000001 super(SersicEllipse, self).__init__()
def __init__(self): self._sersic = Sersic() super(SersicEllipseKappa, self).__init__()
def _import_class(self, lens_type, i, custom_class): if lens_type == 'SHIFT': from lenstronomy.LensModel.Profiles.alpha_shift import Shift return Shift() elif lens_type == 'SHEAR': from lenstronomy.LensModel.Profiles.shear import Shear return Shear() 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 == '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 NIE_simple return NIE_simple() 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 == 'SPEP': from lenstronomy.LensModel.Profiles.spep import SPEP return SPEP() elif lens_type == 'SPEMD': from lenstronomy.LensModel.Profiles.spemd import SPEMD return SPEMD() elif lens_type == 'SPEMD_SMOOTH': from lenstronomy.LensModel.Profiles.spemd_smooth import SPEMD_SMOOTH return SPEMD_SMOOTH() 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 == '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 == 'SERSIC': from lenstronomy.LensModel.Profiles.sersic import Sersic return Sersic() elif lens_type == 'SERSIC_ELLIPSE': from lenstronomy.LensModel.Profiles.sersic_ellipse import SersicEllipse return SersicEllipse() 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_KAPPA_ELLIPSE': from lenstronomy.LensModel.Profiles.gaussian_kappa_ellipse import GaussianKappaEllipse return GaussianKappaEllipse() 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(grid=False, min_grid_number=100) 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 == 'FOREGROUND_SHEAR': from lenstronomy.LensModel.Profiles.shear import Shear self._foreground_shear = True self._foreground_shear_idex = i return Shear() elif lens_type == 'coreBURKERT': from lenstronomy.LensModel.Profiles.coreBurkert import coreBurkert return coreBurkert() elif lens_type == 'NumericalAlpha': from lenstronomy.LensModel.Profiles.numerical_deflections import NumericalAlpha return NumericalAlpha(custom_class[i]) else: raise ValueError('%s is not a valid lens model' % lens_type)