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)
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)
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_
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
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.)