class Chameleon(object): """ class of the Chameleon model (See Dutton+ 2011, Suyu+2014) an elliptical truncated double isothermal profile """ param_names = ['amp', 'w_c', 'w_t', 'e1', 'e2', 'center_x', 'center_y'] lower_limit_default = {'amp': 0, 'w_c': 0, 'w_t': 0, 'e1': -0.5, 'e2': -0.5, 'center_x': -100, 'center_y': -100} upper_limit_default = {'amp': 100, 'w_c': 100, 'w_t': 100, 'e1': 0.5, 'e2': 0.5, 'center_x': 100, 'center_y': 100} def __init__(self): self.nie = NIE() self._chameleonLens = ChameleonLens() def function(self, x, y, amp, w_c, w_t, e1, e2, center_x=0, center_y=0): """ :param x: ra-coordinate :param y: dec-coordinate :param w_c: :param w_t: :param amp: amplitude of first power-law flux :param e1: eccentricity parameter :param e2: eccentricity parameter :param center_x: center :param center_y: center :return: flux of chameleon profile """ amp_new, w_c, w_t, s_scale_1, s_scale_2 = self._chameleonLens.param_convert(amp, w_c, w_t, e1, e2) flux1 = self.nie.function(x, y, 1, e1, e2, s_scale_1, center_x, center_y) flux2 = self.nie.function(x, y, 1, e1, e2, s_scale_2, center_x, center_y) flux = amp_new * (flux1 - flux2) return flux def light_3d(self, r, amp, w_c, w_t, e1, e2, center_x=0, center_y=0): """ :param r: 3d radius :param w_c: :param w_t: :param amp: amplitude of first power-law flux :param e1: eccentricity parameter :param e2: eccentricity parameter :param center_x: center :param center_y: center :return: 3d flux of chameleon profile at radius r """ amp_new, w_c, w_t, s_scale_1, s_scale_2 = self._chameleonLens.param_convert(amp, w_c, w_t, e1, e2) flux1 = self.nie.light_3d(r, 1, e1, e2, s_scale_1, center_x, center_y) flux2 = self.nie.light_3d(r, 1, e1, e2, s_scale_2, center_x, center_y) flux = amp_new * (flux1 - flux2) return flux
class Chameleon(object): """ class of the Chameleon model (See Suyu+2014) an elliptical truncated double isothermal profile """ param_names = ['amp', 'w_c', 'w_t', 'e1', 'e2', 'center_x', 'center_y'] lower_limit_default = { 'amp': 0, 'w_c': 0, 'w_t': 0, 'e1': -0.5, 'e2': -0.5, 'center_x': -100, 'center_y': -100 } upper_limit_default = { 'amp': 100, 'w_c': 100, 'w_t': 100, 'e1': 0.5, 'e2': 0.5, 'center_x': 100, 'center_y': 100 } def __init__(self): self.nie = NIE() self._chameleonLens = ChameleonLens() def function(self, x, y, amp, w_c, w_t, e1, e2, center_x=0, center_y=0): """ :param x: ra-coordinate :param y: dec-coordinate :param amp: amplitude of first power-law flux :param flux_ratio: ratio of amplitudes of first to second power-law profile :param gamma1: power-law slope :param gamma2: power-law slope :param e1: ellipticity parameter :param e2: ellipticity parameter :param center_x: center :param center_y: center :return: flux of chameleon profile """ amp_new, w_c, w_t, s_scale_1, s_scale_2 = self._chameleonLens.param_convert( amp, w_c, w_t, e1, e2) phi_G, q = param_util.ellipticity2phi_q(e1, e2) flux1 = self.nie.function(x, y, 1, e1, e2, s_scale_1, center_x, center_y) flux2 = self.nie.function(x, y, 1, e1, e2, s_scale_2, center_x, center_y) flux = amp_new / (1. + q) * (flux1 - flux2) return flux
class TestChameleon(object): """ class to test the Moffat profile """ def setup(self): self.chameleon = Chameleon() self.nie = NIE() def test_theta_E_convert(self): w_c, w_t = 2, 1 theta_E_convert, w_c, w_t, s_scale_1, s_scale_2 = self.chameleon.param_convert( alpha_1=1, w_c=w_c, w_t=w_t, e1=0, e2=0) assert w_c == 1 assert w_t == 2 assert theta_E_convert == 0 def test_function(self): """ :return: """ x = np.linspace(0.1, 10, 10) w_c, w_t = 0.5, 1. phi_G, q = 0.3, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) kwargs_light = { 'alpha_1': 1., 'w_c': .5, 'w_t': 1., 'e1': e1, 'e2': e2 } theta_E_convert, w_c, w_t, s_scale_1, s_scale_2 = self.chameleon.param_convert( alpha_1=1, w_c=0.5, w_t=1., e1=e1, e2=e2) kwargs_1 = { 'theta_E': theta_E_convert, 's_scale': s_scale_1, 'e1': e1, 'e2': e2 } kwargs_2 = { 'theta_E': theta_E_convert, 's_scale': s_scale_2, 'e1': e1, 'e2': e2 } f_ = self.chameleon.function(x=x, y=1., **kwargs_light) f_1 = self.nie.function(x=x, y=1., **kwargs_1) f_2 = self.nie.function(x=x, y=1., **kwargs_2) npt.assert_almost_equal(f_, (f_1 - f_2), decimal=5) def test_derivatives(self): """ :return: """ x = np.linspace(0.1, 10, 10) w_c, w_t = 0.5, 1. phi_G, q = 0.3, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) kwargs_light = { 'alpha_1': 1., 'w_c': .5, 'w_t': 1., 'e1': e1, 'e2': e2 } theta_E_convert, w_c, w_t, s_scale_1, s_scale_2 = self.chameleon.param_convert( alpha_1=1, w_c=0.5, w_t=1., e1=e1, e2=e2) kwargs_1 = { 'theta_E': theta_E_convert, 's_scale': s_scale_1, 'e1': e1, 'e2': e2 } kwargs_2 = { 'theta_E': theta_E_convert, 's_scale': s_scale_2, 'e1': e1, 'e2': e2 } f_x, f_y = self.chameleon.derivatives(x=x, y=1., **kwargs_light) f_x_1, f_y_1 = self.nie.derivatives(x=x, y=1., **kwargs_1) f_x_2, f_y_2 = self.nie.derivatives(x=x, y=1., **kwargs_2) npt.assert_almost_equal(f_x, (f_x_1 - f_x_2), decimal=5) npt.assert_almost_equal(f_y, (f_y_1 - f_y_2), decimal=5) f_x, f_y = self.chameleon.derivatives(x=1, y=0., **kwargs_light) npt.assert_almost_equal(f_x, 1, decimal=1) def test_hessian(self): """ :return: """ x = np.linspace(0.1, 10, 10) w_c, w_t = 0.5, 1. phi_G, q = 0.3, 0.8 e1, e2 = param_util.phi_q2_ellipticity(phi_G, q) kwargs_light = { 'alpha_1': 1., 'w_c': .5, 'w_t': 1., 'e1': e1, 'e2': e2 } theta_E_convert, w_c, w_t, s_scale_1, s_scale_2 = self.chameleon.param_convert( alpha_1=1, w_c=0.5, w_t=1., e1=e1, e2=e2) kwargs_1 = { 'theta_E': theta_E_convert, 's_scale': s_scale_1, 'e1': e1, 'e2': e2 } kwargs_2 = { 'theta_E': theta_E_convert, 's_scale': s_scale_2, 'e1': e1, 'e2': e2 } f_xx, f_xy, f_yx, f_yy = self.chameleon.hessian(x=x, y=1., **kwargs_light) f_xx_1, f_xy_1, f_yx_1, f_yy_1 = self.nie.hessian(x=x, y=1., **kwargs_1) f_xx_2, f_xy_2, f_yx_2, f_yy_2 = self.nie.hessian(x=x, y=1., **kwargs_2) npt.assert_almost_equal(f_xx, (f_xx_1 - f_xx_2), decimal=5) npt.assert_almost_equal(f_yy, (f_yy_1 - f_yy_2), decimal=5) npt.assert_almost_equal(f_xy, (f_xy_1 - f_xy_2), decimal=5) npt.assert_almost_equal(f_yx, (f_yx_1 - f_yx_2), 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_light = { 'alpha_1': 1., 'w_c': .5, 'w_t': 1., 'e1': e1, 'e2': e2 } f_ = self.chameleon.function(x, y, **kwargs_light) self.chameleon.set_static(**kwargs_light) f_static = self.chameleon.function(x, y, **kwargs_light) npt.assert_almost_equal(f_, f_static, decimal=8) self.chameleon.set_dynamic() kwargs_light = { 'alpha_1': 2., 'w_c': .5, 'w_t': 1., 'e1': e1, 'e2': e2 } f_dyn = self.chameleon.function(x, y, **kwargs_light) assert f_dyn != f_static