Exemple #1
0
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, suppress_fastell=False):
        """

        :param NIE: bool, if True, is using the NIE analytic model. Otherwise it uses PEMD with gamma=2 from fastell4py
        :param suppress_fastell: bool, if True, does not raise if fastell4py is not installed
        """
        self._nie = NIE
        if NIE:
            from lenstronomy.LensModel.Profiles.nie import NIE
            self.profile = NIE()
        else:
            from lenstronomy.LensModel.Profiles.pemd import PEMD
            self.profile = PEMD(suppress_fastell=suppress_fastell)
        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
Exemple #2
0
class TestSPEMD(object):
    """
    tests the Gaussian methods
    """
    def setup(self):
        from lenstronomy.LensModel.Profiles.pemd import PEMD
        from lenstronomy.LensModel.Profiles.spep import SPEP
        self.PEMD = PEMD(suppress_fastell=True)
        self.SPEP = SPEP()

    def test_function(self):
        phi_E = 1.
        gamma = 1.9
        q = 0.9
        phi_G = 1.
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        x = np.array([1.])
        y = np.array([2])
        a = np.zeros_like(x)
        values = self.PEMD.function(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(values[0], 2.1571106351401803, decimal=5)
        else:
            assert values == 0
        a += values
        x = np.array(1.)
        y = np.array(2.)
        a = np.zeros_like(x)
        values = self.PEMD.function(x, y, phi_E, gamma, e1, e2)
        print(x, values)
        a += values
        if fastell4py_bool:
            npt.assert_almost_equal(values, 2.1571106351401803, decimal=5)
        else:
            assert values == 0
        assert type(x) == type(values)

        x = np.array([2, 3, 4])
        y = np.array([1, 1, 1])
        values = self.PEMD.function(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(values[0], 2.180188584782964, decimal=7)
            npt.assert_almost_equal(values[1], 3.2097137160951874, decimal=7)
            npt.assert_almost_equal(values[2], 4.3109976673748, decimal=7)
        else:
            npt.assert_almost_equal(values[0], 0, decimal=7)
            npt.assert_almost_equal(values[1], 0, decimal=7)
            npt.assert_almost_equal(values[2], 0, decimal=7)

    def test_derivatives(self):
        x = np.array([1])
        y = np.array([2])
        phi_E = 1.
        gamma = 1.9
        q = 0.9
        phi_G = 1.
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_x, f_y = self.PEMD.derivatives(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_x[0], 0.46664118422711387, decimal=7)
            npt.assert_almost_equal(f_y[0], 0.9530892465981603, decimal=7)
        else:
            npt.assert_almost_equal(f_x[0], 0, decimal=7)
            npt.assert_almost_equal(f_y[0], 0, decimal=7)

        x = np.array([1., 3, 4])
        y = np.array([2., 1, 1])
        a = np.zeros_like(x)
        values = self.PEMD.derivatives(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(values[0][0],
                                    0.46664118422711387,
                                    decimal=7)
            npt.assert_almost_equal(values[1][0],
                                    0.9530892465981603,
                                    decimal=7)
            npt.assert_almost_equal(values[0][1],
                                    1.0722265330847958,
                                    decimal=7)
            npt.assert_almost_equal(values[1][1],
                                    0.3140067377020791,
                                    decimal=7)
        else:
            npt.assert_almost_equal(values[0][0], 0, decimal=7)
            npt.assert_almost_equal(values[1][0], 0, decimal=7)
            npt.assert_almost_equal(values[0][1], 0, decimal=7)
            npt.assert_almost_equal(values[1][1], 0, decimal=7)
        a += values[0]
        x = 1.
        y = 2.
        phi_E = 1.
        gamma = 1.9
        q = 0.9
        phi_G = 1.
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_x, f_y = self.PEMD.derivatives(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_x, 0.46664118422711387, decimal=7)
            npt.assert_almost_equal(f_y, 0.9530892465981603, decimal=7)
        else:
            npt.assert_almost_equal(f_x, 0, decimal=7)
            npt.assert_almost_equal(f_y, 0, decimal=7)
        x = 0.
        y = 0.
        f_x, f_y = self.PEMD.derivatives(x, y, phi_E, gamma, e1, e2)
        assert f_x == 0.
        assert f_y == 0.

    def test_hessian(self):
        x = np.array([1])
        y = np.array([2])
        phi_E = 1.
        gamma = 1.9
        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.PEMD.hessian(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_xx, 0.4179041, decimal=7)
            npt.assert_almost_equal(f_yy, 0.1404714, decimal=7)
            npt.assert_almost_equal(f_xy, -0.1856134, decimal=7)
        else:
            npt.assert_almost_equal(f_xx, 0, decimal=7)
            npt.assert_almost_equal(f_yy, 0, decimal=7)
            npt.assert_almost_equal(f_xy, 0, decimal=7)
        npt.assert_almost_equal(f_xy, f_yx, decimal=8)

        x = 1.
        y = 2.
        phi_E = 1.
        gamma = 1.9
        q = 0.9
        phi_G = 1.
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        a = np.zeros_like(x)
        f_xx, f_xy, f_yx, f_yy = self.PEMD.hessian(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_xx, 0.41790408341142493, decimal=7)
            npt.assert_almost_equal(f_yy, 0.14047143086334482, decimal=7)
            npt.assert_almost_equal(f_xy, -0.1856133848300859, decimal=7)
        else:
            npt.assert_almost_equal(f_xx, 0, decimal=7)
            npt.assert_almost_equal(f_yy, 0, decimal=7)
            npt.assert_almost_equal(f_xy, 0, decimal=7)
        a += f_xx
        x = np.array([1, 3, 4])
        y = np.array([2, 1, 1])
        values = self.PEMD.hessian(x, y, phi_E, gamma, e1, e2)
        print(values, 'values')
        if fastell4py_bool:
            npt.assert_almost_equal(values[0][0],
                                    0.41789957732890953,
                                    decimal=5)
            npt.assert_almost_equal(values[3][0],
                                    0.14047593655054141,
                                    decimal=5)
            npt.assert_almost_equal(values[1][0],
                                    -0.18560737698052343,
                                    decimal=5)
            npt.assert_almost_equal(values[0][1],
                                    0.068359818958208918,
                                    decimal=5)
            npt.assert_almost_equal(values[3][1],
                                    0.32494089371516482,
                                    decimal=5)
            npt.assert_almost_equal(values[1][1],
                                    -0.097845438684594374,
                                    decimal=5)
        else:
            npt.assert_almost_equal(values[0][0], 0, decimal=7)

    def test_spep_spemd(self):
        x = np.array([1])
        y = np.array([0])
        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.PEMD.derivatives(x, y, phi_E, gamma, e1, e2)
        f_x_spep, f_y_spep = self.SPEP.derivatives(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_x[0], f_x_spep[0], decimal=2)
        else:
            pass

        theta_E = 2.
        gamma = 2.
        q = 1.
        phi_G = 1.
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_x, f_y = self.PEMD.derivatives(x, y, theta_E, gamma, e1, e2)
        f_x_spep, f_y_spep = self.SPEP.derivatives(x, y, theta_E, gamma, e1,
                                                   e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_x[0], f_x_spep[0], decimal=2)
        else:
            pass

        theta_E = 2.
        gamma = 1.7
        q = 1.
        phi_G = 1.
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_x, f_y = self.PEMD.derivatives(x, y, theta_E, gamma, e1, e2)
        f_x_spep, f_y_spep = self.SPEP.derivatives(x, y, theta_E, gamma, e1,
                                                   e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_x[0], f_x_spep[0], decimal=4)

    def test_bounds(self):
        from lenstronomy.LensModel.Profiles.spemd import SPEMD
        profile = SPEMD(suppress_fastell=True)
        compute_bool = profile._parameter_constraints(q_fastell=-1,
                                                      gam=-1,
                                                      s2=-1,
                                                      q=-1)
        assert compute_bool is False

    def test_is_not_empty(self):
        func = self.PEMD.spemd_smooth.is_not_empty

        assert func(0.1, 0.2)
        assert func([0.1], [0.2])
        assert func((0.1, 0.3), (0.2, 0.4))
        assert func(np.array([0.1]), np.array([0.2]))
        assert not func([], [])
        assert not func(np.array([]), np.array([]))

    def test_density_lens(self):
        r = 1
        kwargs = {'theta_E': 1, 'gamma': 2, 'e1': 0, 'e2': 0}
        rho = self.PEMD.density_lens(r, **kwargs)
        rho_spep = self.SPEP.density_lens(r, **kwargs)
        npt.assert_almost_equal(rho, rho_spep, decimal=7)
Exemple #3
0
class TestSIE(object):
        """
        tests the Gaussian methods
        """
        def setup(self):
            from lenstronomy.LensModel.Profiles.sie import SIE
            from lenstronomy.LensModel.Profiles.pemd import PEMD
            from lenstronomy.LensModel.Profiles.nie import NIE
            self.sie = SIE(NIE=False, suppress_fastell=True)
            self.sie_nie = SIE(NIE=True)
            self.spemd = PEMD(suppress_fastell=True)
            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.spemd.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.spemd.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.spemd.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)