Esempio n. 1
0
class SIE(object):
    """
    class for singular isothermal ellipsoid (SIS with ellipticity)
    """
    def __init__(self):
        self.spemd = SPEMD()

    def function(self, x, y, theta_E, q, phi_G, 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:
        """
        gamma = 2
        return self.spemd.function(x, y, theta_E, gamma, q, phi_G, center_x,
                                   center_y)

    def derivatives(self, x, y, theta_E, q, phi_G, 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:
        """
        gamma = 2
        return self.spemd.derivatives(x, y, theta_E, gamma, q, phi_G, center_x,
                                      center_y)

    def hessian(self, x, y, theta_E, q, phi_G, 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:
        """
        gamma = 2
        return self.spemd.hessian(x, y, theta_E, gamma, q, phi_G, center_x,
                                  center_y)
Esempio n. 2
0
class TestSIE(object):
        """
        tests the Gaussian methods
        """
        def setup(self):
            from lenstronomy.LensModel.Profiles.sie import SIE
            from lenstronomy.LensModel.Profiles.spemd import SPEMD
            self.sie = SIE()
            self.spemd = SPEMD()

        def test_function(self):
            x = np.array([1])
            y = np.array([2])
            theta_E = 1.
            q = 0.9
            phi_G = 1.
            values = self.sie.function(x, y, theta_E, q, phi_G)
            gamma = 2
            values_spemd = self.spemd.function(x, y, theta_E, gamma, q, phi_G)
            assert values == values_spemd

        def test_derivatives(self):
            x = np.array([1])
            y = np.array([2])
            theta_E = 1.
            q = 0.9
            phi_G = 1.
            values = self.sie.derivatives(x, y, theta_E, q, phi_G)
            gamma = 2
            values_spemd = self.spemd.derivatives(x, y, theta_E, gamma, q, phi_G)
            assert values == values_spemd

        def test_hessian(self):
            x = np.array([1])
            y = np.array([2])
            theta_E = 1.
            q = 0.9
            phi_G = 1.
            values = self.sie.hessian(x, y, theta_E, q, phi_G)
            gamma = 2
            values_spemd = self.spemd.hessian(x, y, theta_E, gamma, q, phi_G)
            assert values[0] == values_spemd[0]
Esempio n. 3
0
class TestSPEMD(object):
    """
    tests the Gaussian methods
    """
    def setup(self):
        from lenstronomy.LensModel.Profiles.spemd import SPEMD
        self.SPEMD = SPEMD(suppress_fastell=True)
        from lenstronomy.LensModel.Profiles.nie import NIE
        self.NIE = NIE()

    def test_function(self):
        phi_E = 1.
        gamma = 2.
        q = 0.999
        phi_G = 1.
        s_scale = 0.1
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        x = np.array([1., 2])
        y = np.array([2, 0])
        values = self.SPEMD.function(x, y, phi_E, gamma, e1, e2, s_scale)
        if fastell4py_bool:
            values_nie = self.NIE.function(x, y, phi_E, e1, e2, s_scale)
            delta_f = values[0] - values[1]
            delta_f_nie = values_nie[0] - values_nie[1]
            npt.assert_almost_equal(delta_f, delta_f_nie, decimal=5)
        else:
            npt.assert_almost_equal(values, 0, decimal=5)

    def test_derivatives(self):
        x = np.array([1])
        y = np.array([2])
        phi_E = 1.
        gamma = 2.
        q = 1.
        phi_G = 1.
        s_scale = 0.1
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_x, f_y = self.SPEMD.derivatives(x, y, phi_E, gamma, e1, e2, s_scale)
        if fastell4py_bool:
            f_x_nie, f_y_nie = self.NIE.derivatives(x, y, phi_E, e1, e2,
                                                    s_scale)
            npt.assert_almost_equal(f_x, f_x_nie, decimal=4)
            npt.assert_almost_equal(f_y, f_y_nie, decimal=4)
        else:
            npt.assert_almost_equal(f_x, 0, decimal=7)
            npt.assert_almost_equal(f_y, 0, decimal=7)

        q = 0.7
        phi_G = 1.
        s_scale = 0.001
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_x, f_y = self.SPEMD.derivatives(x, y, phi_E, gamma, e1, e2, s_scale)
        if fastell4py_bool:
            f_x_nie, f_y_nie = self.NIE.derivatives(x, y, phi_E, e1, e2,
                                                    s_scale)
            npt.assert_almost_equal(f_x, f_x_nie, decimal=4)
            npt.assert_almost_equal(f_y, f_y_nie, decimal=4)
        else:
            npt.assert_almost_equal(f_x, 0, decimal=7)
            npt.assert_almost_equal(f_y, 0, decimal=7)

    def test_hessian(self):
        x = np.array([1.])
        y = np.array([2.])
        phi_E = 1.
        gamma = 2.
        q = 0.9
        phi_G = 1.
        s_scale = 0.001
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_xx, f_xy, f_yx, f_yy = self.SPEMD.hessian(x, y, phi_E, gamma, e1, e2,
                                                    s_scale)
        if fastell4py_bool:
            f_xx_nie, f_xy_nie, f_yx_nie, f_yy_nie = self.NIE.hessian(
                x, y, phi_E, e1, e2, s_scale)
            npt.assert_almost_equal(f_xx, f_xx_nie, decimal=4)
            npt.assert_almost_equal(f_yy, f_yy_nie, decimal=4)
            npt.assert_almost_equal(f_xy, f_xy_nie, decimal=4)
            npt.assert_almost_equal(f_yx, f_yx_nie, decimal=4)
        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)

    def test_bounds(self):
        compute_bool = self.SPEMD._parameter_constraints(q_fastell=-1,
                                                         gam=-1,
                                                         s2=-1,
                                                         q=-1)
        assert compute_bool is False

    def test_is_not_empty(self):
        func = self.SPEMD.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([]))
Esempio n. 4
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):
        self._nie = NIE
        if NIE:
            from lenstronomy.LensModel.Profiles.nie import NIE
            self.profile = NIE()
        else:
            from lenstronomy.LensModel.Profiles.spemd import SPEMD
            self.profile = SPEMD()
        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
Esempio n. 5
0
class PEMD(LensProfileBase):
    """
    class for power law ellipse mass density profile.
    This class effectively calls the class SPEMD_SMOOTH with a fixed and very small central smoothing scale
    to perform the numerical integral using the FASTELL code by Renan Barkana.

    .. math::
        \\kappa(x, y) = \\frac{3-\\gamma}{2} \\left(\\frac{\\theta_{E}}{\\sqrt{q x^2 + y^2/q}} \\right)^{\\gamma-1}

    with :math:`\\theta_{E}` is the (circularized) Einstein radius,
    :math:`\\gamma` is the negative power-law slope of the 3D mass distributions,
    :math:`q` is the minor/major axis ratio,
    and :math:`x` and :math:`y` are defined in a coordinate system aligned with the major and minor axis of the lens.

    In terms of eccentricities, this profile is defined as

    .. math::
        \\kappa(r) = \\frac{3-\\gamma}{2} \\left(\\frac{\\theta'_{E}}{r \\sqrt{1 − e*\\cos(2*\\phi)}} \\right)^{\\gamma-1}

    with :math:`\\epsilon` is the ellipticity defined as

    .. math::
        \\epsilon = \\frac{1-q^2}{1+q^2}

    And an Einstein radius :math:`\\theta'_{\\rm E}` related to the definition used is

    .. math::
        \\left(\\frac{\\theta'_{\\rm E}}{\\theta_{\\rm E}}\\right)^{2} = \\frac{2q}{1+q^2}.


    """
    param_names = ['theta_E', 'gamma', 'e1', 'e2', 'center_x', 'center_y']
    lower_limit_default = {
        'theta_E': 0,
        'gamma': 1.5,
        'e1': -0.5,
        'e2': -0.5,
        'center_x': -100,
        'center_y': -100
    }
    upper_limit_default = {
        'theta_E': 100,
        'gamma': 2.5,
        'e1': 0.5,
        'e2': 0.5,
        'center_x': 100,
        'center_y': 100
    }

    def __init__(self, suppress_fastell=False):
        """

        :param suppress_fastell: bool, if True, does not raise if fastell4py is not installed
        """
        self._s_scale = 0.0000001  # smoothing scale as used to numerically compute a power-law profile
        self.spp = SPP()
        self.spemd_smooth = SPEMD(suppress_fastell=suppress_fastell)
        super(PEMD, self).__init__()

    def function(self, x, y, theta_E, gamma, e1, e2, center_x=0, center_y=0):
        """

        :param x: x-coordinate (angle)
        :param y: y-coordinate (angle)
        :param theta_E: Einstein radius (angle), pay attention to specific definition!
        :param gamma: logarithmic slope of the power-law profile. gamma=2 corresponds to isothermal
        :param e1: eccentricity component
        :param e2: eccentricity component
        :param center_x: x-position of lens center
        :param center_y: y-position of lens center
        :return: lensing potential
        """
        return self.spemd_smooth.function(x, y, theta_E, gamma, e1, e2,
                                          self._s_scale, center_x, center_y)

    def derivatives(self,
                    x,
                    y,
                    theta_E,
                    gamma,
                    e1,
                    e2,
                    center_x=0,
                    center_y=0):
        """

        :param x: x-coordinate (angle)
        :param y: y-coordinate (angle)
        :param theta_E: Einstein radius (angle), pay attention to specific definition!
        :param gamma: logarithmic slope of the power-law profile. gamma=2 corresponds to isothermal
        :param e1: eccentricity component
        :param e2: eccentricity component
        :param center_x: x-position of lens center
        :param center_y: y-position of lens center
        :return: deflection angles alpha_x, alpha_y
        """
        return self.spemd_smooth.derivatives(x, y, theta_E, gamma, e1, e2,
                                             self._s_scale, center_x, center_y)

    def hessian(self, x, y, theta_E, gamma, e1, e2, center_x=0, center_y=0):
        """

        :param x: x-coordinate (angle)
        :param y: y-coordinate (angle)
        :param theta_E: Einstein radius (angle), pay attention to specific definition!
        :param gamma: logarithmic slope of the power-law profile. gamma=2 corresponds to isothermal
        :param e1: eccentricity component
        :param e2: eccentricity component
        :param center_x: x-position of lens center
        :param center_y: y-position of lens center
        :return: Hessian components f_xx, f_xy, f_yx, f_yy
        """
        return self.spemd_smooth.hessian(x, y, theta_E, gamma, e1, e2,
                                         self._s_scale, center_x, center_y)

    def mass_3d_lens(self, r, theta_E, gamma, e1=None, e2=None):
        """
        computes the spherical power-law mass enclosed (with SPP routine)
        :param r: radius within the mass is computed
        :param theta_E: Einstein radius
        :param gamma: power-law slope
        :param e1: eccentricity component (not used)
        :param e2: eccentricity component (not used)
        :return: mass enclosed a 3D radius r
        """
        return self.spp.mass_3d_lens(r, theta_E, gamma)

    def density_lens(self, r, theta_E, gamma, e1=None, e2=None):
        """
        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 within the mass is computed
        :param theta_E: Einstein radius
        :param gamma: power-law slope
        :param e1: eccentricity component (not used)
        :param e2: eccentricity component (not used)
        :return: mass enclosed a 3D radius r
        """
        return self.spp.density_lens(r, theta_E, gamma)
Esempio n. 6
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):
        self._nie = NIE
        if NIE:
            from lenstronomy.LensModel.Profiles.nie import NIE
            self.profile = NIE()
        else:
            from lenstronomy.LensModel.Profiles.spemd import SPEMD
            self.profile = SPEMD()
        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)
Esempio n. 7
0
class TestSIE(object):
    """
        tests the Gaussian methods
        """
    def setup(self):
        from lenstronomy.LensModel.Profiles.sie import SIE
        from lenstronomy.LensModel.Profiles.spemd import SPEMD
        from lenstronomy.LensModel.Profiles.nie import NIE
        self.sie = SIE(NIE=False)
        self.sie_nie = SIE(NIE=True)
        self.spemd = SPEMD()
        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 = 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, values_spemd, decimal=6)

    def test_derivatives(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.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.9
        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)
Esempio n. 8
0
class TestSPEMD(object):
    """
    tests the Gaussian methods
    """
    def setup(self):
        from lenstronomy.LensModel.Profiles.spemd import SPEMD
        from lenstronomy.LensModel.Profiles.spep import SPEP
        self.SPEMD = SPEMD()
        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.SPEMD.function(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            assert values == 2.1567297115381039
        else:
            assert values == 0
        a += values
        x = np.array(1.)
        y = np.array(2.)
        a = np.zeros_like(x)
        values = self.SPEMD.function(x, y, phi_E, gamma, e1, e2)
        print(x, values)
        a += values
        if fastell4py_bool:
            assert values == 2.1567297115381039
        else:
            assert values == 0
        assert type(x) == type(values)

        x = np.array([2, 3, 4])
        y = np.array([1, 1, 1])
        values = self.SPEMD.function(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(values[0], 2.1798076611034141, decimal=7)
            npt.assert_almost_equal(values[1], 3.209319798597186, decimal=7)
            npt.assert_almost_equal(values[2], 4.3105937398856398, 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.SPEMD.derivatives(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_x[0], 0.46663367437984204, decimal=7)
            npt.assert_almost_equal(f_y[0], 0.95307422686028065, 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.SPEMD.derivatives(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(values[0][0],
                                    0.46663367437984204,
                                    decimal=7)
            npt.assert_almost_equal(values[1][0],
                                    0.95307422686028065,
                                    decimal=7)
            npt.assert_almost_equal(values[0][1],
                                    1.0722152681324291,
                                    decimal=7)
            npt.assert_almost_equal(values[1][1],
                                    0.31400298272329669,
                                    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.SPEMD.derivatives(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_x, 0.46663367437984204, decimal=7)
            npt.assert_almost_equal(f_y, 0.95307422686028065, 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.SPEMD.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_yy, f_xy = self.SPEMD.hessian(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_xx, 0.41789957732890953, decimal=7)
            npt.assert_almost_equal(f_yy, 0.14047593655054141, decimal=7)
            npt.assert_almost_equal(f_xy, -0.18560737698052343, 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)

        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_yy, f_xy = self.SPEMD.hessian(x, y, phi_E, gamma, e1, e2)
        if fastell4py_bool:
            npt.assert_almost_equal(f_xx, 0.41789957732890953, decimal=7)
            npt.assert_almost_equal(f_yy, 0.14047593655054141, decimal=7)
            npt.assert_almost_equal(f_xy, -0.18560737698052343, 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.SPEMD.hessian(x, y, phi_E, gamma, e1, e2)
        print(values, 'values')
        if fastell4py_bool:
            npt.assert_almost_equal(values[0][0],
                                    0.41789957732890953,
                                    decimal=7)
            npt.assert_almost_equal(values[1][0],
                                    0.14047593655054141,
                                    decimal=7)
            npt.assert_almost_equal(values[2][0],
                                    -0.18560737698052343,
                                    decimal=7)
            npt.assert_almost_equal(values[0][1],
                                    0.068359818958208918,
                                    decimal=7)
            npt.assert_almost_equal(values[1][1],
                                    0.32494089371516482,
                                    decimal=7)
            npt.assert_almost_equal(values[2][1],
                                    -0.097845438684594374,
                                    decimal=7)
        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.SPEMD.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.SPEMD.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.SPEMD.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_smooth import SPEMD_SMOOTH
        profile = SPEMD_SMOOTH()
        theta_E, gamma, q, phi_G, s_scale = profile._parameter_constraints(
            theta_E=-1, s_scale=0, gamma=3, q=2, phi_G=0)
        assert theta_E == 0

    def test_is_not_empty(self):
        func = self.SPEMD.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.SPEMD.density_lens(r, **kwargs)
        rho_spep = self.SPEP.density_lens(r, **kwargs)
        npt.assert_almost_equal(rho, rho_spep, decimal=7)
Esempio n. 9
0
class PEMD(LensProfileBase):
    """
    class for power law ellipse mass density profile.
    This class effectively calls the class SPEMD_SMOOTH with a fixed and very small central smoothing scale
    to perform the numerical integral using the FASTELL code by Renan Barkana.


    The Einstein ring parameter converts to the definition used by GRAVLENS as follow:
    (theta_E / theta_E_gravlens) = sqrt[ (1+q^2) / (2 q) ]
    """
    param_names = ['theta_E', 'gamma', 'e1', 'e2', 'center_x', 'center_y']
    lower_limit_default = {
        'theta_E': 0,
        'gamma': 1.5,
        'e1': -0.5,
        'e2': -0.5,
        'center_x': -100,
        'center_y': -100
    }
    upper_limit_default = {
        'theta_E': 100,
        'gamma': 2.5,
        'e1': 0.5,
        'e2': 0.5,
        'center_x': 100,
        'center_y': 100
    }

    def __init__(self, suppress_fastell=False):
        """

        :param suppress_fastell: bool, if True, does not raise if fastell4py is not installed
        """
        self._s_scale = 0.0001  # smoothing scale as used to numerically compute a power-law profile
        self.spp = SPP()
        self.spemd_smooth = SPEMD(suppress_fastell=suppress_fastell)
        super(PEMD, self).__init__()

    def function(self, x, y, theta_E, gamma, e1, e2, center_x=0, center_y=0):
        """

        :param x: x-coordinate (angle)
        :param y: y-coordinate (angle)
        :param theta_E: Einstein radius (angle), pay attention to specific definition!
        :param gamma: logarithmic slope of the power-law profile. gamma=2 corresponds to isothermal
        :param e1: eccentricity component
        :param e2: eccentricity component
        :param center_x: x-position of lens center
        :param center_y: y-position of lens center
        :return: lensing potential
        """
        return self.spemd_smooth.function(x, y, theta_E, gamma, e1, e2,
                                          self._s_scale, center_x, center_y)

    def derivatives(self,
                    x,
                    y,
                    theta_E,
                    gamma,
                    e1,
                    e2,
                    center_x=0,
                    center_y=0):
        """

        :param x: x-coordinate (angle)
        :param y: y-coordinate (angle)
        :param theta_E: Einstein radius (angle), pay attention to specific definition!
        :param gamma: logarithmic slope of the power-law profile. gamma=2 corresponds to isothermal
        :param e1: eccentricity component
        :param e2: eccentricity component
        :param center_x: x-position of lens center
        :param center_y: y-position of lens center
        :return: deflection angles alpha_x, alpha_y
        """
        return self.spemd_smooth.derivatives(x, y, theta_E, gamma, e1, e2,
                                             self._s_scale, center_x, center_y)

    def hessian(self, x, y, theta_E, gamma, e1, e2, center_x=0, center_y=0):
        """

        :param x: x-coordinate (angle)
        :param y: y-coordinate (angle)
        :param theta_E: Einstein radius (angle), pay attention to specific definition!
        :param gamma: logarithmic slope of the power-law profile. gamma=2 corresponds to isothermal
        :param e1: eccentricity component
        :param e2: eccentricity component
        :param center_x: x-position of lens center
        :param center_y: y-position of lens center
        :return: Hessian components f_xx, f_yy, f_xy
        """
        return self.spemd_smooth.hessian(x, y, theta_E, gamma, e1, e2,
                                         self._s_scale, center_x, center_y)

    def mass_3d_lens(self, r, theta_E, gamma, e1=None, e2=None):
        """
        computes the spherical power-law mass enclosed (with SPP routine)
        :param r: radius within the mass is computed
        :param theta_E: Einstein radius
        :param gamma: power-law slope
        :param e1: eccentricity component (not used)
        :param e2: eccentricity component (not used)
        :return: mass enclosed a 3D radius r
        """
        return self.spp.mass_3d_lens(r, theta_E, gamma)

    def density_lens(self, r, theta_E, gamma, e1=None, e2=None):
        """
        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 within the mass is computed
        :param theta_E: Einstein radius
        :param gamma: power-law slope
        :param e1: eccentricity component (not used)
        :param e2: eccentricity component (not used)
        :return: mass enclosed a 3D radius r
        """
        return self.spp.density_lens(r, theta_E, gamma)
Esempio n. 10
0
class TestSPEMD(object):
        """
        tests the Gaussian methods
        """
        def setup(self):
            from lenstronomy.LensModel.Profiles.spemd import SPEMD
            from lenstronomy.LensModel.Profiles.spep import SPEP
            self.SPEMD = SPEMD()
            self.SPEP = SPEP()

        def test_function(self):
            phi_E = 1.
            gamma = 1.9
            q = 0.9
            phi_G = 1.
            x = np.array([1.])
            y = np.array([2])
            a = np.zeros_like(x)
            values = self.SPEMD.function(x, y, phi_E, gamma, q, phi_G)
            if fastell4py_bool:
                assert values == 2.1567297115381039
            else:
                assert values == 0
            a += values
            x = np.array(1.)
            y = np.array(2.)
            a = np.zeros_like(x)
            values = self.SPEMD.function(x, y, phi_E, gamma, q, phi_G)
            print(x, values)
            a += values
            if fastell4py_bool:
                assert values == 2.1567297115381039
            else:
                assert values == 0
            assert type(x) == type(values)

            x = np.array([2, 3, 4])
            y = np.array([1, 1, 1])
            values = self.SPEMD.function(x, y, phi_E, gamma, q, phi_G)
            if fastell4py_bool:
                npt.assert_almost_equal(values[0], 2.1798076611034141, decimal=7)
                npt.assert_almost_equal(values[1], 3.209319798597186, decimal=7)
                npt.assert_almost_equal(values[2], 4.3105937398856398, 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.
            f_x, f_y = self.SPEMD.derivatives(x, y, phi_E, gamma, q, phi_G)
            if fastell4py_bool:
                npt.assert_almost_equal(f_x[0], 0.46663367437984204, decimal=7)
                npt.assert_almost_equal(f_y[0], 0.95307422686028065, 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.SPEMD.derivatives(x, y, phi_E, gamma, q, phi_G)
            if fastell4py_bool:
                npt.assert_almost_equal(values[0][0], 0.46663367437984204, decimal=7)
                npt.assert_almost_equal(values[1][0], 0.95307422686028065, decimal=7)
                npt.assert_almost_equal(values[0][1], 1.0722152681324291, decimal=7)
                npt.assert_almost_equal(values[1][1], 0.31400298272329669, 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.
            f_x, f_y = self.SPEMD.derivatives(x, y, phi_E, gamma, q, phi_G)
            if fastell4py_bool:
                npt.assert_almost_equal(f_x, 0.46663367437984204, decimal=7)
                npt.assert_almost_equal(f_y, 0.95307422686028065, 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.SPEMD.derivatives(x, y, phi_E, gamma, q, phi_G)
            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.
            f_xx, f_yy,f_xy = self.SPEMD.hessian(x, y, phi_E, gamma, q, phi_G)
            if fastell4py_bool:
                npt.assert_almost_equal(f_xx, 0.41789957732890953, decimal=7)
                npt.assert_almost_equal(f_yy, 0.14047593655054141, decimal=7)
                npt.assert_almost_equal(f_xy, -0.18560737698052343, 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)

            x = 1.
            y = 2.
            phi_E = 1.
            gamma = 1.9
            q = 0.9
            phi_G = 1.
            a = np.zeros_like(x)
            f_xx, f_yy,f_xy = self.SPEMD.hessian(x, y, phi_E, gamma, q, phi_G)
            if fastell4py_bool:
                npt.assert_almost_equal(f_xx, 0.41789957732890953, decimal=7)
                npt.assert_almost_equal(f_yy, 0.14047593655054141, decimal=7)
                npt.assert_almost_equal(f_xy, -0.18560737698052343, 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.SPEMD.hessian(x, y, phi_E, gamma, q, phi_G)
            print(values, 'values')
            if fastell4py_bool:
                npt.assert_almost_equal(values[0][0], 0.41789957732890953, decimal=7)
                npt.assert_almost_equal(values[1][0], 0.14047593655054141, decimal=7)
                npt.assert_almost_equal(values[2][0], -0.18560737698052343, decimal=7)
                npt.assert_almost_equal(values[0][1], 0.068359818958208918, decimal=7)
                npt.assert_almost_equal(values[1][1], 0.32494089371516482, decimal=7)
                npt.assert_almost_equal(values[2][1], -0.097845438684594374, decimal=7)
            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.
            f_x, f_y = self.SPEMD.derivatives(x, y, phi_E, gamma, q, phi_G)
            f_x_spep, f_y_spep = self.SPEP.derivatives(x, y, phi_E, gamma, q, phi_G)
            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.
            f_x, f_y = self.SPEMD.derivatives(x, y, theta_E, gamma, q, phi_G)
            f_x_spep, f_y_spep = self.SPEP.derivatives(x, y, theta_E, gamma, q, phi_G)
            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.
            f_x, f_y = self.SPEMD.derivatives(x, y, theta_E, gamma, q, phi_G)
            f_x_spep, f_y_spep = self.SPEP.derivatives(x, y, theta_E, gamma, q, phi_G)
            if fastell4py_bool:
                npt.assert_almost_equal(f_x[0], f_x_spep[0], decimal=4)