class TestCoredDensity(object): """ tests the Gaussian methods """ def setup(self): self.model = CoredDensity() def test_function(self): r = np.linspace(start=0.01, stop=2, num=10) sigma0 = 0.2 r_core = 5 f_ = self.model.function(r, 0, sigma0, r_core) delta = 0.0001 f_d = self.model.function(r + delta, 0, sigma0, r_core) f_x_num = (f_d - f_) / delta f_x, _ = self.model.derivatives(r, 0, sigma0, r_core) npt.assert_almost_equal(f_x_num, f_x, decimal=3) def test_derivatives(self): pass def test_dalpha_dr(self): x = np.array([1, 3, 4]) y = np.array([2, 1, 1]) r = np.sqrt(x**2 + y**2) sigma0 = 0.1 r_core = 7. dalpha_dr = self.model.d_alpha_dr(r, sigma0, r_core) alpha_r = self.model.alpha_r(r, sigma0, r_core) delta = 0.00001 d_alpha_r = self.model.alpha_r(r + delta, sigma0, r_core) d_alpha_dr_num = (d_alpha_r - alpha_r) / delta npt.assert_almost_equal(dalpha_dr, d_alpha_dr_num) def test_hessian(self): x = np.linspace(start=0.01, stop=100, num=100) y = 0 r = np.sqrt(x**2 + y**2) sigma0 = 0.1 r_core = 7 f_xx, f_xy, f_yx, f_yy = self.model.hessian(x, y, sigma0, r_core) kappa = 1. / 2 * (f_xx + f_yy) kappa_direct = self.model.kappa_r(r, sigma0, r_core) npt.assert_almost_equal(kappa, kappa_direct, decimal=5) npt.assert_almost_equal(f_xy, f_yx, decimal=8) def test_mass_3d(self): x = np.array([1, 3, 4]) y = np.array([2, 1, 1]) r = np.sqrt(x**2 + y**2) sigma0 = 0.1 r_core = 7 m3d = self.model.mass_3d(r, sigma0, r_core) m3d_lens = self.model.mass_3d_lens(r, sigma0, r_core) npt.assert_almost_equal(m3d, m3d_lens, decimal=8)
class CoredDensityMST(LensProfileBase): """ approximate mass-sheet transform of a density core. This routine takes the parameters of the density core and subtracts a mass=sheet that approximates the cored profile in it's center to counter-act (in approximation) this model. This allows for better sampling of the mass-sheet transformed quantities that do not have strong covariances. Attention!!! The interpretation of the result is that the mass sheet as 'CONVERGENCE' that is present needs to be subtracted in post-processing. """ param_names = ['lambda_approx', 'r_core', 'center_x', 'center_y'] lower_limit_default = { 'lambda_approx': -1, 'r_core': 0, 'center_x': -100, 'center_y': -100 } upper_limit_default = { 'lambda_approx': 10, 'r_core': 100, 'center_x': 100, 'center_y': 100 } def __init__(self, profile_type='CORED_DENSITY'): if profile_type == 'CORED_DENSITY': self._profile = CoredDensity() elif profile_type == 'CORED_DENSITY_2': self._profile = CoredDensity2() else: raise ValueError( 'profile_type %s not supported for CoredDensityMST instance.' % profile_type) self._convergence = Convergence() super(CoredDensityMST, self).__init__() def function(self, x, y, lambda_approx, r_core, center_x=0, center_y=0): """ lensing potential of approximate mass-sheet correction :param x: x-coordinate :param y: y-coordinate :param lambda_approx: approximate mass sheet transform :param r_core: core radius of the cored density profile :param center_x: x-center of the profile :param center_y: y-center of the profile :return: lensing potential correction """ kappa_ext = 1 - lambda_approx f_cored_density = self._profile.function(x, y, kappa_ext, r_core, center_x, center_y) f_ms = self._convergence.function(x, y, kappa_ext, center_x, center_y) return f_cored_density - f_ms def derivatives(self, x, y, lambda_approx, r_core, center_x=0, center_y=0): """ deflection angles of approximate mass-sheet correction :param x: x-coordinate :param y: y-coordinate :param lambda_approx: approximate mass sheet transform :param r_core: core radius of the cored density profile :param center_x: x-center of the profile :param center_y: y-center of the profile :return: alpha_x, alpha_y """ kappa_ext = 1 - lambda_approx f_x_cd, f_y_cd = self._profile.derivatives(x, y, kappa_ext, r_core, center_x, center_y) f_x_ms, f_y_ms = self._convergence.derivatives(x, y, kappa_ext, center_x, center_y) return f_x_cd - f_x_ms, f_y_cd - f_y_ms def hessian(self, x, y, lambda_approx, r_core, center_x=0, center_y=0): """ Hessian terms of approximate mass-sheet correction :param x: x-coordinate :param y: y-coordinate :param lambda_approx: approximate mass sheet transform :param r_core: core radius of the cored density profile :param center_x: x-center of the profile :param center_y: y-center of the profile :return: df/dxx, df/dyy, df/dxy """ kappa_ext = 1 - lambda_approx f_xx_cd, f_yy_cd, f_xy_cd = self._profile.hessian( x, y, kappa_ext, r_core, center_x, center_y) f_xx_ms, f_yy_ms, f_xy_ms = self._convergence.hessian( x, y, kappa_ext, center_x, center_y) return f_xx_cd - f_xx_ms, f_yy_cd - f_yy_ms, f_xy_cd - f_xy_ms