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)
Beispiel #2
0
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