Ejemplo n.º 1
0
class Chameleon(LensProfileBase):
    """
    class of the Chameleon model (See Suyu+2014) an elliptical truncated double isothermal profile

    """
    param_names = ['alpha_1', 'w_c', 'w_t', 'e1', 'e2', 'center_x', 'center_y']
    lower_limit_default = {'alpha_1': 0, 'w_c': 0, 'w_t': 0, 'e1': -0.8, 'e2': -0.8, 'center_x': -100, 'center_y': -100}
    upper_limit_default = {'alpha_1': 100, 'w_c': 100, 'w_t': 100, 'e1': 0.8, 'e2': 0.8, 'center_x': 100, 'center_y': 100}

    def __init__(self, static=False):
        self._nie_1 = NIE()
        self._nie_2 = NIE()
        super(Chameleon, self).__init__()
        self._static = static

    def function(self, x, y, alpha_1, w_c, w_t, e1, e2, center_x=0, center_y=0):
        """

        :param x: ra-coordinate
        :param y: dec-coordinate
        :param alpha_1: deflection angle at 1 (arcseconds) from the center
        :param w_c: see Suyu+2014
        :param w_t: see Suyu+2014
        :param e1: ellipticity parameter
        :param e2: ellipticity parameter
        :param center_x: ra center
        :param center_y: dec center
        :return: lensing potential
        """

        theta_E_conv, w_c, w_t, s_scale_1, s_scale_2 = self.param_convert(alpha_1, w_c, w_t, e1, e2)
        f_1 = self._nie_1.function(x, y, theta_E_conv, e1, e2, s_scale_1, center_x, center_y)
        f_2 = self._nie_2.function(x, y, theta_E_conv, e1, e2, s_scale_2, center_x, center_y)
        f_ = f_1 - f_2
        return f_

    def derivatives(self, x, y, alpha_1, w_c, w_t, e1, e2, center_x=0, center_y=0):
        """

        :param x: ra-coordinate
        :param y: dec-coordinate
        :param alpha_1: deflection angle at 1 (arcseconds) from the center
        :param w_c: see Suyu+2014
        :param w_t: see Suyu+2014
        :param e1: ellipticity parameter
        :param e2: ellipticity parameter
        :param center_x: ra center
        :param center_y: dec center
        :return: deflection angles (RA, DEC)
        """
        theta_E_conv, w_c, w_t, s_scale_1, s_scale_2 = self.param_convert(alpha_1, w_c, w_t, e1, e2)
        f_x_1, f_y_1 = self._nie_1.derivatives(x, y, theta_E_conv, e1, e2, s_scale_1, center_x, center_y)
        f_x_2, f_y_2 = self._nie_2.derivatives(x, y, theta_E_conv, e1, e2, s_scale_2, center_x, center_y)
        f_x = f_x_1 - f_x_2
        f_y = f_y_1 - f_y_2
        return f_x, f_y

    def hessian(self, x, y, alpha_1, w_c, w_t, e1, e2, center_x=0, center_y=0):
        """

        :param x: ra-coordinate
        :param y: dec-coordinate
        :param alpha_1: deflection angle at 1 (arcseconds) from the center
        :param w_c: see Suyu+2014
        :param w_t: see Suyu+2014
        :param e1: ellipticity parameter
        :param e2: ellipticity parameter
        :param center_x: ra center
        :param center_y: dec center
        :return: second derivatives of the lensing potential (Hessian: f_xx, f_xy, f_yx, f_yy)
        """
        theta_E_conv, w_c, w_t, s_scale_1, s_scale_2 = self.param_convert(alpha_1, w_c, w_t, e1, e2)
        f_xx_1, f_xy_1, f_yx_1, f_yy_1 = self._nie_1.hessian(x, y, theta_E_conv, e1, e2, s_scale_1, center_x, center_y)
        f_xx_2, f_xy_2, f_yx_2, f_yy_2 = self._nie_2.hessian(x, y, theta_E_conv, e1, e2, s_scale_2, center_x, center_y)
        f_xx = f_xx_1 - f_xx_2
        f_yy = f_yy_1 - f_yy_2
        f_xy = f_xy_1 - f_xy_2
        f_yx = f_yx_1 - f_yx_2
        return f_xx, f_xy, f_yx, f_yy

    def param_convert(self, alpha_1, w_c, w_t, e1, e2):
        """
        convert the parameter alpha_1 (deflection angle one arcsecond from the center) into the
        "Einstein radius" scale parameter of the two NIE profiles

        :param alpha_1: deflection angle at 1 (arcseconds) from the center
        :param w_c: see Suyu+2014
        :param w_t: see Suyu+2014
        :param e1: eccentricity modulus
        :param ee: eccentricity modulus
        :return:
        """
        if self._static is True:
            return self._theta_convert_static, self._w_c_static, self._w_t_stactic, self._s_scale_1_static, self._s_scale_2_static
        return self._param_convert(alpha_1, w_c, w_t, e1, e2)

    def _param_convert(self, alpha_1, w_c, w_t, e1, e2):
        if not w_t >= w_c:
            return 0, w_t, w_c, 1, 1
        s_scale_1 = w_c
        s_scale_2 = w_t
        f_x_1, f_y_1 = self._nie_1.derivatives(1, 0, theta_E=1, e1=0, e2=0, s_scale=s_scale_1)
        f_x_2, f_y_2 = self._nie_2.derivatives(1, 0, theta_E=1, e1=0, e2=0, s_scale=s_scale_2)
        f_x = f_x_1 - f_x_2
        theta_E_convert = alpha_1 / f_x
        phi_G, q = param_util.ellipticity2phi_q(e1, e2)
        s_scale_1 = np.sqrt(4 * w_c ** 2 / (1. + q) ** 2)
        s_scale_2 = np.sqrt(4 * w_t ** 2 / (1. + q) ** 2)
        return theta_E_convert, w_c, w_t, s_scale_1, s_scale_2

    def set_static(self, alpha_1, w_c, w_t, e1, e2, center_x=0, center_y=0):
        """

        :param logM:
        :param concentration:
        :param center_x:
        :param center_y:
        :return:
        """
        self._static = True
        self._theta_convert_static, self._w_c_static, self._w_t_stactic, self._s_scale_1_static, self._s_scale_2_static = self._param_convert(alpha_1, w_c, w_t, e1, e2)
        self._nie_1.set_static(self._theta_convert_static, e1, e2, self._s_scale_1_static, center_x, center_y)
        self._nie_2.set_static(self._theta_convert_static, e1, e2, self._s_scale_2_static, center_x, center_y)

    def set_dynamic(self):
        """

        :return:
        """
        self._static = False
        if hasattr(self, '_theta_convert_static'):
            del self._theta_convert_static
        if hasattr(self, '_w_c_static'):
            del self._w_c_static
        if hasattr(self, '_w_t_stactic'):
            del self._w_t_stactic
        if hasattr(self, '_s_scale_1_static'):
            del self._s_scale_1_static
        if hasattr(self, '_s_scale_2_static'):
            del self._s_scale_2_static
        self._nie_1.set_dynamic()
        self._nie_2.set_dynamic()
Ejemplo n.º 2
0
class TestNIE(object):
    """
    tests the Gaussian methods
    """
    def setup(self):

        self.nie = NIE()
        self.spemd = SPEMD(suppress_fastell=True)
        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
Ejemplo n.º 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)

    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