class DoubleChameleonPointMass(object): """ class of the Chameleon model (See Suyu+2014) an elliptical truncated double isothermal profile """ param_names = [ 'theta_E', 'ratio_chameleon', 'ratio_pointmass', 'w_c1', 'w_t1', 'e11', 'e21', 'w_c2', 'w_t2', 'e12', 'e22', 'center_x', 'center_y' ] def __init__(self): self.chameleon = DoubleChameleon() self.pointMass = PointMass() def function(self, x, y, theta_E, ratio_pointmass, ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x=0, center_y=0): """ :param x: :param y: :param theta_E: :param ratio_pointmass: :param ratio_chameleon: :param w_c1: :param w_t1: :param e11: :param e21: :param w_c2: :param w_t2: :param e12: :param e22: :param center_x: :param center_y: :return: """ f_1 = self.pointMass.function(x, y, theta_E / (1. + 1. / ratio_pointmass), center_x, center_y) f_2 = self.chameleon.function(x, y, theta_E / (1. + ratio_pointmass), ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x, center_y) return f_1 + f_2 def derivatives(self, x, y, theta_E, ratio_pointmass, ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x=0, center_y=0): """ :param x: :param y: :param theta_E: :param ratio_pointmass: :param ratio_chameleon: :param w_c1: :param w_t1: :param e11: :param e21: :param w_c2: :param w_t2: :param e12: :param e22: :param center_x: :param center_y: :return: """ f_x1, f_y1 = self.pointMass.derivatives( x, y, theta_E / (1. + 1. / ratio_pointmass), center_x, center_y) f_x2, f_y2 = self.chameleon.derivatives( x, y, theta_E / (1. + ratio_pointmass), ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x, center_y) return f_x1 + f_x2, f_y1 + f_y2 def hessian(self, x, y, theta_E, ratio_pointmass, ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x=0, center_y=0): """ :param x: :param y: :param theta_E: :param ratio_pointmass: :param ratio_chameleon: :param w_c1: :param w_t1: :param e11: :param e21: :param w_c2: :param w_t2: :param e12: :param e22: :param center_x: :param center_y: :return: """ f_xx1, f_yy1, f_xy1 = self.pointMass.hessian( x, y, theta_E / (1. + 1. / ratio_pointmass), center_x, center_y) f_xx2, f_yy2, f_xy2 = self.chameleon.hessian( x, y, theta_E / (1. + ratio_pointmass), ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x, center_y) return f_xx1 + f_xx2, f_yy1 + f_yy2, f_xy1 + f_xy2
class DoubleChameleonPointMass(LensProfileBase): """ class of the Chameleon model (See Suyu+2014) an elliptical truncated double isothermal profile """ param_names = ['alpha_1', 'ratio_chameleon', 'ratio_pointmass', 'w_c1', 'w_t1', 'e11', 'e21', 'w_c2', 'w_t2', 'e12', 'e22', 'center_x', 'center_y'] lower_limit_default = {'alpha_1': 0, 'ratio_chameleon': 0, 'ratio_pointmass': 0, 'w_c1': 0, 'w_t1': 0, 'e11': -0.8, 'e21': -0.8, 'w_c2': 0, 'w_t2': 0, 'e12': -0.8, 'e22': -0.8, 'center_x': -100, 'center_y': -100} upper_limit_default = {'alpha_1': 100, 'ratio_chameleon': 100, 'ratio_pointmass': 100, 'w_c1': 100, 'w_t1': 100, 'e11': 0.8, 'e21': 0.8, 'w_c2': 100, 'w_t2': 100, 'e12': 0.8, 'e22': 0.8, 'center_x': 100, 'center_y': 100} def __init__(self): self.chameleon = DoubleChameleon() self.pointMass = PointMass() super(DoubleChameleonPointMass, self).__init__() def function(self, x, y, alpha_1, ratio_pointmass, ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x=0, center_y=0): """ #TODO chose better parameterization for combining point mass and Chameleon profiles :param x: ra-coordinate :param y: dec-coordinate :param alpha_1: deflection angle at 1 (arcseconds) from the center :param ratio_pointmass: ratio of point source Einstein radius to combined Chameleon deflection angle at r=1 :param ratio_chameleon: ratio in deflection angles at r=1 for the two Chameleon profiles :param w_c1: Suyu+2014 for first profile :param w_t1: Suyu+2014 for first profile :param e11: ellipticity parameter for first profile :param e21: ellipticity parameter for first profile :param w_c2: Suyu+2014 for second profile :param w_t2: Suyu+2014 for second profile :param e12: ellipticity parameter for second profile :param e22: ellipticity parameter for second profile :param center_x: ra center :param center_y: dec center :return: """ f_1 = self.pointMass.function(x, y, alpha_1 / (1. + 1. / ratio_pointmass), center_x, center_y) f_2 = self.chameleon.function(x, y, alpha_1 / (1. + ratio_pointmass), ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x, center_y) return f_1 + f_2 def derivatives(self, x, y, alpha_1, ratio_pointmass, ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x=0, center_y=0): """ :param x: :param y: :param alpha_1: :param ratio_pointmass: ratio of point source Einstein radius to combined Chameleon deflection angle at r=1 :param ratio_chameleon: ratio in deflection angles at r=1 for the two Chameleon profiles :param w_c1: Suyu+2014 for first profile :param w_t1: Suyu+2014 for first profile :param e11: ellipticity parameter for first profile :param e21: ellipticity parameter for first profile :param w_c2: Suyu+2014 for second profile :param w_t2: Suyu+2014 for second profile :param e12: ellipticity parameter for second profile :param e22: ellipticity parameter for second profile :param center_x: ra center :param center_y: dec center :return: """ f_x1, f_y1 = self.pointMass.derivatives(x, y, alpha_1 / (1. + 1. / ratio_pointmass), center_x, center_y) f_x2, f_y2 = self.chameleon.derivatives(x, y, alpha_1 / (1. + ratio_pointmass), ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x, center_y) return f_x1 + f_x2, f_y1 + f_y2 def hessian(self, x, y, alpha_1, ratio_pointmass, ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x=0, center_y=0): """ :param x: :param y: :param alpha_1: :param ratio_pointmass: ratio of point source Einstein radius to combined Chameleon deflection angle at r=1 :param ratio_chameleon: ratio in deflection angles at r=1 for the two Chameleon profiles :param w_c1: Suyu+2014 for first profile :param w_t1: Suyu+2014 for first profile :param e11: ellipticity parameter for first profile :param e21: ellipticity parameter for first profile :param w_c2: Suyu+2014 for second profile :param w_t2: Suyu+2014 for second profile :param e12: ellipticity parameter for second profile :param e22: ellipticity parameter for second profile :param center_x: ra center :param center_y: dec center :return: """ f_xx1, f_xy1, f_yx1, f_yy1 = self.pointMass.hessian(x, y, alpha_1 / (1. + 1. / ratio_pointmass), center_x, center_y) f_xx2, f_xy2, f_yx2, f_yy2 = self.chameleon.hessian(x, y, alpha_1 / (1. + ratio_pointmass), ratio_chameleon, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x, center_y) return f_xx1 + f_xx2, f_xy1 + f_xy2, f_yx1 + f_yx2, f_yy1 + f_yy2
class TestSIS(object): """ tests the Gaussian methods """ def setup(self): self.pointmass = PointMass() def test_function(self): x = np.array([0]) y = np.array([1]) theta_E = 1. values = self.pointmass.function(x, y, theta_E) assert values[0] == 0 x = np.array([0]) y = np.array([0]) values = self.pointmass.function(x, y, theta_E) assert values[0] < 0 x = np.array([1, 3, 4]) y = np.array([0, 1, 1]) values = self.pointmass.function(x, y, theta_E) assert values[0] == 0 assert values[1] == 1.151292546497023 assert values[2] == 1.4166066720281081 def test_derivatives(self): x = np.array([1]) y = np.array([0]) theta_E = 1. f_x, f_y = self.pointmass.derivatives(x, y, theta_E) assert f_x[0] == 1 assert f_y[0] == 0 x = np.array([0]) y = np.array([0]) f_x, f_y = self.pointmass.derivatives(x, y, theta_E) assert f_x[0] == 0 assert f_y[0] == 0 x = np.array([1, 3, 4]) y = np.array([0, 1, 1]) values = self.pointmass.derivatives(x, y, theta_E) assert values[0][0] == 1 assert values[1][0] == 0 assert values[0][1] == 0.29999999999999999 assert values[1][1] == 0.099999999999999992 def test_hessian(self): x = np.array([1]) y = np.array([0]) theta_E = 1. f_xx, f_yy, f_xy = self.pointmass.hessian(x, y, theta_E) assert f_xx[0] == -1 assert f_yy[0] == 1 assert f_xy[0] == -0 x = np.array([1, 3, 4]) y = np.array([0, 1, 1]) values = self.pointmass.hessian(x, y, theta_E) assert values[0][0] == -1 assert values[1][0] == 1 assert values[2][0] == -0 assert values[0][1] == -0.080000000000000002 assert values[1][1] == 0.080000000000000002 assert values[2][1] == -0.059999999999999998