示例#1
0
class SPEMD(object):
    """
    class for smooth power law ellipse mass density profile
    """
    param_names = ['theta_E', 'gamma', 'e1', 'e2', 'center_x', 'center_y']
    lower_limit_default = {'theta_E': 0, 'gamma': 0, 'e1': -0.5, 'e2': -0.5, 'center_x': -100, 'center_y': -100}
    upper_limit_default = {'theta_E': 100, 'gamma': 100, 'e1': 0.5, 'e2': 0.5, 'center_x': 100, 'center_y': 100}

    def __init__(self):
        self.s2 = 0.00000001
        self.spp = SPP()
        self.spemd_smooth = SPEMD_SMOOTH()

    def function(self, x, y, theta_E, gamma, e1, e2, center_x=0, center_y=0):
        return self.spemd_smooth.function(x, y, theta_E, gamma, e1, e2, self.s2, center_x, center_y)

    def derivatives(self, x, y, theta_E, gamma, e1, e2, center_x=0, center_y=0):
        return self.spemd_smooth.derivatives(x, y, theta_E, gamma, e1, e2, self.s2, center_x, center_y)

    def hessian(self, x, y, theta_E, gamma, e1, e2, center_x=0, center_y=0):
        return self.spemd_smooth.hessian(x, y, theta_E, gamma, e1, e2, self.s2, center_x, center_y)

    def mass_3d_lens(self, r, theta_E, gamma, e1, e2):
        """
        computes the spherical power-law mass enclosed (with SPP routiune)
        :param r:
        :param theta_E:
        :param gamma:
        :param q:
        :param phi_G:
        :return:
        """
        return self.spp.mass_3d_lens(r, theta_E, gamma)
示例#2
0
class SPEMD(object):
    """
    class for smooth power law ellipse mass density profile
    """
    def __init__(self):
        self.s2 = 0.00000001
        self.spp = SPP()
        self.spemd_smooth = SPEMD_SMOOTH()

    def function(self, x, y, theta_E, gamma, q, phi_G, center_x=0, center_y=0):
        return self.spemd_smooth.function(x, y, theta_E, gamma, q, phi_G, self.s2, center_x, center_y)

    def derivatives(self, x, y, theta_E, gamma, q, phi_G, center_x=0, center_y=0):
        return self.spemd_smooth.derivatives(x, y, theta_E, gamma, q, phi_G, self.s2, center_x, center_y)

    def hessian(self, x, y, theta_E, gamma, q, phi_G, center_x=0, center_y=0):
        return self.spemd_smooth.hessian(x, y, theta_E, gamma, q, phi_G, self.s2, center_x, center_y)

    def mass_3d_lens(self, r, theta_E, gamma, q, phi_G):
        """
        computes the spherical power-law mass enclosed (with SPP routiune)
        :param r:
        :param theta_E:
        :param gamma:
        :param q:
        :param phi_G:
        :return:
        """
        return self.spp.mass_3d_lens(r, theta_E, gamma)

    def convert_params(self, theta_E, gamma, q):
        """

        :param theta_E: Einstein radius
        :param gamma: power law slope
        :param q: axis ratio
        :return:   prefactor to SPEMP profile for FASTELL
        """
        return self.spemd_smooth.convert_params(theta_E, gamma, q)
示例#3
0
class TestNIE(object):
    """
        tests the Gaussian methods
        """
    def setup(self):
        from lenstronomy.LensModel.Profiles.nie import NIE
        from lenstronomy.LensModel.Profiles.spemd_smooth import SPEMD_SMOOTH
        from lenstronomy.LensModel.Profiles.sis import SIS
        self.nie = NIE()
        self.spemd = SPEMD_SMOOTH()
        self.sis = SIS()

    def test_function(self):
        y = np.array([1., 2])
        x = np.array([0., 0.])
        theta_E = 1.
        q = 0.9999
        s = 0.00001
        phi_G = 0
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)

        values = self.nie.function(x, y, theta_E, e1, e2, s_scale=s)
        delta_pot = values[1] - values[0]
        values_spemd = self.sis.function(x, y, theta_E)
        delta_pot_spemd = values_spemd[1] - values_spemd[0]
        npt.assert_almost_equal(delta_pot, delta_pot_spemd, decimal=4)
        if bool_test is True:
            q = 0.99
            s = 0.000001
            phi_G = 0
            e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
            values = self.nie.function(x, y, theta_E, e1, e2, s_scale=s)
            delta_pot = values[1] - values[0]
            gamma = 2.
            values_spemd = self.spemd.function(x,
                                               y,
                                               theta_E,
                                               gamma,
                                               e1,
                                               e2,
                                               s_scale=s)
            delta_pot_spemd = values_spemd[1] - values_spemd[0]
            npt.assert_almost_equal(delta_pot, delta_pot_spemd, decimal=2)

    def test_derivatives(self):
        x = np.array([1])
        y = np.array([2])
        theta_E = 1.
        q = 0.99999
        phi_G = 0
        s = 0.0000001
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_x, f_y = self.nie.derivatives(x, y, theta_E, e1, e2, s_scale=s)
        f_x_spemd, f_y_spemd = self.sis.derivatives(x, y, theta_E)
        npt.assert_almost_equal(f_x, f_x_spemd, decimal=4)
        npt.assert_almost_equal(f_y, f_y_spemd, decimal=4)
        if bool_test is True:
            q = 0.99
            s = 0.000001
            phi_G = 0
            e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
            f_x, f_y = self.nie.derivatives(x, y, theta_E, e1, e2, s_scale=s)
            gamma = 2.
            f_x_spemd, f_y_spemd = self.spemd.derivatives(x,
                                                          y,
                                                          theta_E,
                                                          gamma,
                                                          e1,
                                                          e2,
                                                          s_scale=s)
            print(f_x / f_x_spemd, 'ratio deflections')
            print(1 + (1 - q) / 2)
            npt.assert_almost_equal(f_x, f_x_spemd, decimal=2)
            npt.assert_almost_equal(f_y, f_y_spemd, decimal=2)

    def test_hessian(self):
        x = np.array([1])
        y = np.array([2])
        theta_E = 1.
        q = 0.999999
        phi_G = 0
        s = 0.0000001
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_xx, f_yy, f_xy = self.nie.hessian(x, y, theta_E, e1, e2, s_scale=s)
        f_xx_spemd, f_yy_spemd, f_xy_spemd = self.sis.hessian(x, y, theta_E)
        npt.assert_almost_equal(f_xx, f_xx_spemd, decimal=4)
        npt.assert_almost_equal(f_yy, f_yy_spemd, decimal=4)
        npt.assert_almost_equal(f_xy, f_xy_spemd, decimal=4)
示例#4
0
class TestNIE(object):
    """
    tests the Gaussian methods
    """
    def setup(self):

        self.nie = NIE()
        self.spemd = SPEMD_SMOOTH()
        self.sis = SIS()

    def test_function(self):
        y = np.array([1., 2])
        x = np.array([0., 0.])
        theta_E = 1.
        q = 0.9999
        s = 0.00001
        phi_G = 0
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)

        values = self.nie.function(x, y, theta_E, e1, e2, s_scale=s)
        delta_pot = values[1] - values[0]
        values_spemd = self.sis.function(x, y, theta_E)
        delta_pot_spemd = values_spemd[1] - values_spemd[0]
        npt.assert_almost_equal(delta_pot, delta_pot_spemd, decimal=4)
        if bool_test is True:
            q = 0.99
            s = 0.000001
            phi_G = 0
            e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
            values = self.nie.function(x, y, theta_E, e1, e2, s_scale=s)
            delta_pot = values[1] - values[0]
            gamma = 2.
            values_spemd = self.spemd.function(x,
                                               y,
                                               theta_E,
                                               gamma,
                                               e1,
                                               e2,
                                               s_scale=s)
            delta_pot_spemd = values_spemd[1] - values_spemd[0]
            npt.assert_almost_equal(delta_pot, delta_pot_spemd, decimal=2)

    def test_derivatives(self):
        x = np.array([1])
        y = np.array([2])
        theta_E = 1.
        q = 0.99999
        phi_G = 0
        s = 0.0000001
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_x, f_y = self.nie.derivatives(x, y, theta_E, e1, e2, s_scale=s)
        f_x_spemd, f_y_spemd = self.sis.derivatives(x, y, theta_E)
        npt.assert_almost_equal(f_x, f_x_spemd, decimal=4)
        npt.assert_almost_equal(f_y, f_y_spemd, decimal=4)
        if bool_test is True:
            q = 0.99
            s = 0.000001
            phi_G = 0
            e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
            f_x, f_y = self.nie.derivatives(x, y, theta_E, e1, e2, s_scale=s)
            gamma = 2.
            f_x_spemd, f_y_spemd = self.spemd.derivatives(x,
                                                          y,
                                                          theta_E,
                                                          gamma,
                                                          e1,
                                                          e2,
                                                          s_scale=s)
            print(f_x / f_x_spemd, 'ratio deflections')
            print(1 + (1 - q) / 2)
            npt.assert_almost_equal(f_x, f_x_spemd, decimal=2)
            npt.assert_almost_equal(f_y, f_y_spemd, decimal=2)

    def test_hessian(self):
        x = np.array([1])
        y = np.array([2])
        theta_E = 1.
        q = 0.999999
        phi_G = 0
        s = 0.0000001
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_xx, f_yy, f_xy = self.nie.hessian(x, y, theta_E, e1, e2, s_scale=s)
        f_xx_spemd, f_yy_spemd, f_xy_spemd = self.sis.hessian(x, y, theta_E)
        npt.assert_almost_equal(f_xx, f_xx_spemd, decimal=4)
        npt.assert_almost_equal(f_yy, f_yy_spemd, decimal=4)
        npt.assert_almost_equal(f_xy, f_xy_spemd, decimal=4)

    def test_convergence2surface_brightness(self):
        from lenstronomy.LightModel.Profiles.nie import NIE as NIE_Light
        nie_light = NIE_Light()
        kwargs = {'e1': 0.3, 'e2': -0.05, 's_scale': 0.5}
        x, y = util.make_grid(numPix=10, deltapix=0.1)
        f_xx, f_yy, f_xy = self.nie.hessian(x, y, theta_E=1, **kwargs)
        kappa = 1 / 2. * (f_xx + f_yy)
        flux = nie_light.function(x, y, amp=1, **kwargs)
        npt.assert_almost_equal(kappa / np.sum(kappa),
                                flux / np.sum(flux),
                                decimal=5)

    def test_static(self):
        x, y = 1., 1.
        phi_G, q = 0.3, 0.8
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        kwargs_lens = {'theta_E': 1., 's_scale': .1, 'e1': e1, 'e2': e2}
        f_ = self.nie.function(x, y, **kwargs_lens)
        self.nie.set_static(**kwargs_lens)
        f_static = self.nie.function(x, y, **kwargs_lens)
        npt.assert_almost_equal(f_, f_static, decimal=8)
        self.nie.set_dynamic()
        kwargs_lens = {'theta_E': 2., 's_scale': .1, 'e1': e1, 'e2': e2}
        f_dyn = self.nie.function(x, y, **kwargs_lens)
        assert f_dyn != f_static
示例#5
0
class SPEMD(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):
        self.s2 = 0.00000001  # smoothing scale as used to numerically compute a power-law profile
        self.spp = SPP()
        self.spemd_smooth = SPEMD_SMOOTH()
        super(SPEMD, 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.s2, 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.s2, 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.s2, 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)
示例#6
0
class TestSPEMD(object):
    """
    tests the Gaussian methods
    """
    def setup(self):
        from lenstronomy.LensModel.Profiles.spemd_smooth import SPEMD_SMOOTH
        self.SPEMD_SMOOT = SPEMD_SMOOTH()
        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_SMOOT.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 = 0.7
        phi_G = 1.
        s_scale = 0.1
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_x, f_y = self.SPEMD_SMOOT.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)
            #TODO test with higher precision, convention of theta_E might be slightly different from NIE with SPEMD
            npt.assert_almost_equal(f_x, f_x_nie, decimal=2)
            npt.assert_almost_equal(f_y, f_y_nie, decimal=2)
        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.1
        e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
        f_xx, f_yy, f_xy = self.SPEMD_SMOOT.hessian(x, y, phi_E, gamma, e1, e2,
                                                    s_scale)
        if fastell4py_bool:
            f_xx_nie, f_yy_nie, f_xy_nie = self.NIE.hessian(
                x, y, phi_E, e1, e2, s_scale)
            npt.assert_almost_equal(f_xx, f_xx_nie, decimal=3)
            npt.assert_almost_equal(f_yy, f_yy_nie, decimal=3)
            npt.assert_almost_equal(f_xy, f_xy_nie, decimal=3)
        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)

    def test_bounds(self):
        theta_E, gamma, q, phi_G, s_scale = self.SPEMD_SMOOT._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_SMOOT.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([]))
示例#7
0
class TestSPEMD(object):
    """
    tests the Gaussian methods
    """
    def setup(self):
        from lenstronomy.LensModel.Profiles.spemd_smooth import SPEMD_SMOOTH
        self.SPEMD_SMOOT = SPEMD_SMOOTH()
        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_SMOOT.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_SMOOT.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_SMOOT.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_yy, f_xy = self.SPEMD_SMOOT.hessian(x, y, phi_E, gamma, e1, e2,
                                                    s_scale)
        if fastell4py_bool:
            f_xx_nie, f_yy_nie, f_xy_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)
        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)

    def test_bounds(self):
        compute_bool = self.SPEMD_SMOOT._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_SMOOT.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([]))