Source code for lenstronomy.LensModel.Profiles.chameleon

from lenstronomy.LensModel.Profiles.nie import NIE
from lenstronomy.LensModel.Profiles.point_mass import PointMass
from lenstronomy.LensModel.Profiles.base_profile import LensProfileBase
import lenstronomy.Util.param_util as param_util
import numpy as np

from lenstronomy.Util.package_util import exporter

export, __all__ = exporter()


[docs] @export 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, }
[docs] def __init__(self, static=False): self._nie_1 = NIE() self._nie_2 = NIE() super(Chameleon, self).__init__() self._static = static
[docs] 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_
[docs] 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
[docs] 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
[docs] def density_lens(self, r, alpha_1, w_c, w_t, e1=0, e2=0, center_x=0, center_y=0): """Spherical average density as a function of 3d radius. :param r: 3d radius :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: matter density at 3d radius r """ 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.density_lens( r, theta_E_conv, e1, e2, s_scale_1, center_x, center_y ) f_2 = self._nie_2.density_lens( r, theta_E_conv, e1, e2, s_scale_2, center_x, center_y ) f_ = f_1 - f_2 return f_
[docs] def mass_3d_lens(self, r, alpha_1, w_c, w_t, e1=0, e2=0, center_x=0, center_y=0): """Mass enclosed 3d radius. :param r: 3d radius :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: mass enclosed 3d radius r """ theta_E_conv, w_c, w_t, s_scale_1, s_scale_2 = self.param_convert( alpha_1, w_c, w_t, e1, e2 ) m_1 = self._nie_1.mass_3d_lens( r, theta_E_conv, e1, e2, s_scale_1, center_x, center_y ) m_2 = self._nie_2.mass_3d_lens( r, theta_E_conv, e1, e2, s_scale_2, center_x, center_y ) m_ = m_1 - m_2 return m_
[docs] 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 e2: 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) # TODO: is this next conversion really needed since the NIE definition is already in the average sense? s_scale_1 = np.sqrt(4 * w_c**2 / (1.0 + q) ** 2) s_scale_2 = np.sqrt(4 * w_t**2 / (1.0 + q) ** 2) return theta_E_convert, w_c, w_t, s_scale_1, s_scale_2
[docs] def set_static(self, alpha_1, w_c, w_t, e1, e2, center_x=0, center_y=0): """ :param alpha_1: :param w_c: :param w_t: :param e1: :param e2: :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, )
[docs] 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()
[docs] @export class DoubleChameleon(LensProfileBase): """Class of the Chameleon model (See Suyu+2014) an elliptical truncated double isothermal profile.""" param_names = [ "alpha_1", "ratio", "w_c1", "w_t1", "e11", "e21", "w_c2", "w_t2", "e12", "e22", "center_x", "center_y", ] lower_limit_default = { "alpha_1": 0, "ratio": 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": 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, }
[docs] def __init__(self): self._chameleon_1 = Chameleon() self._chameleon_2 = Chameleon() super(DoubleChameleon, self).__init__()
[docs] def function( self, x, y, alpha_1, ratio, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, 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 ratio: ratio of deflection amplitude at radius = 1 of the first to second Chameleon profile :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: lensing potential """ f_1 = self._chameleon_1.function( x, y, alpha_1 / (1.0 + 1.0 / ratio), w_c1, w_t1, e11, e21, center_x, center_y, ) f_2 = self._chameleon_2.function( x, y, alpha_1 / (1.0 + ratio), w_c2, w_t2, e12, e22, center_x, center_y ) return f_1 + f_2
[docs] def derivatives( self, x, y, alpha_1, ratio, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, 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 ratio: ratio of deflection amplitude at radius = 1 of the first to second Chameleon profile :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^V :param center_x: ra center :param center_y: dec center :return: deflection angles (RA, DEC) """ f_x1, f_y1 = self._chameleon_1.derivatives( x, y, alpha_1 / (1.0 + 1.0 / ratio), w_c1, w_t1, e11, e21, center_x, center_y, ) f_x2, f_y2 = self._chameleon_2.derivatives( x, y, alpha_1 / (1.0 + ratio), w_c2, w_t2, e12, e22, center_x, center_y ) return f_x1 + f_x2, f_y1 + f_y2
[docs] def hessian( self, x, y, alpha_1, ratio, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, 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 ratio: ratio of deflection amplitude at radius = 1 of the first to second Chameleon profile :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: second derivatives of the lensing potential (Hessian: f_xx, f_yy, f_xy) """ ( f_xx1, f_xy1, f_yx1, f_yy1, ) = self._chameleon_1.hessian( x, y, alpha_1 / (1.0 + 1.0 / ratio), w_c1, w_t1, e11, e21, center_x, center_y, ) f_xx2, f_xy2, f_yx2, f_yy2 = self._chameleon_2.hessian( x, y, alpha_1 / (1.0 + ratio), w_c2, w_t2, e12, e22, center_x, center_y ) return f_xx1 + f_xx2, f_xy1 + f_xy2, f_xy1 + f_xy2, f_yy1 + f_yy2
[docs] def density_lens( self, r, alpha_1, ratio, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x=0, center_y=0, ): """ :param r: 3d radius :param alpha_1: deflection angle at 1 (arcseconds) from the center :param ratio: ratio of deflection amplitude at radius = 1 of the first to second Chameleon profile :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: 3d density at radius r """ f_1 = self._chameleon_1.density_lens( r, alpha_1 / (1.0 + 1.0 / ratio), w_c1, w_t1, e11, e21, center_x, center_y ) f_2 = self._chameleon_2.density_lens( r, alpha_1 / (1.0 + ratio), w_c2, w_t2, e12, e22, center_x, center_y ) return f_1 + f_2
[docs] def mass_3d_lens( self, r, alpha_1, ratio, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x=0, center_y=0, ): """ :param r: 3d radius :param alpha_1: deflection angle at 1 (arcseconds) from the center :param ratio: ratio of deflection amplitude at radius = 1 of the first to second Chameleon profile :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: mass enclosed 3d radius """ m_1 = self._chameleon_1.mass_3d_lens( r, alpha_1 / (1.0 + 1.0 / ratio), w_c1, w_t1, e11, e21, center_x, center_y ) m_2 = self._chameleon_2.mass_3d_lens( r, alpha_1 / (1.0 + ratio), w_c2, w_t2, e12, e22, center_x, center_y ) return m_1 + m_2
[docs] def set_static( self, alpha_1, ratio, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, center_x=0, center_y=0, ): self._chameleon_1.set_static( alpha_1 / (1.0 + 1.0 / ratio), w_c1, w_t1, e11, e21, center_x, center_y ) self._chameleon_2.set_static( alpha_1 / (1.0 + ratio), w_c2, w_t2, e12, e22, center_x, center_y )
[docs] def set_dynamic(self): self._chameleon_1.set_dynamic() self._chameleon_2.set_dynamic()
[docs] @export class TripleChameleon(LensProfileBase): """Class of the Chameleon model (See Suyu+2014) an elliptical truncated double isothermal profile.""" param_names = [ "alpha_1", "ratio12", "ratio13", "w_c1", "w_t1", "e11", "e21", "w_c2", "w_t2", "e12", "e22", "w_c3", "w_t3", "e13", "e23", "center_x", "center_y", ] lower_limit_default = { "alpha_1": 0, "ratio12": 0, "ratio13": 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, "w_c3": 0, "w_t3": 0, "e13": -0.8, "e23": -0.8, "center_x": -100, "center_y": -100, } upper_limit_default = { "alpha_1": 100, "ratio12": 100, "ratio13": 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, "w_c3": 100, "w_t3": 100, "e13": 0.8, "e23": 0.8, "center_x": 100, "center_y": 100, }
[docs] def __init__(self): self._chameleon_1 = Chameleon() self._chameleon_2 = Chameleon() self._chameleon_3 = Chameleon() super(TripleChameleon, self).__init__()
@staticmethod def _ratio_definition(alpha_1, ratio12, ratio13): """ :param alpha_1: deflection angle at 1 arcsecond :param ratio12: ratio of first to second amplitude :param ratio13: ratio of first to third amplitude :return: amplitudes of individual chameleon profiles """ amp1 = alpha_1 / (1.0 + 1.0 / ratio12 + 1.0 / ratio13) amp2 = amp1 / ratio12 amp3 = amp1 / ratio13 return amp1, amp2, amp3
[docs] def function( self, x, y, alpha_1, ratio12, ratio13, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, w_c3, w_t3, e13, e23, center_x=0, center_y=0, ): """ :param alpha_1: :param ratio12: ratio of first to second amplitude :param ratio13: ratio of first to third amplitude :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: """ amp1, amp2, amp3 = self._ratio_definition(alpha_1, ratio12, ratio13) f_1 = self._chameleon_1.function( x, y, amp1, w_c1, w_t1, e11, e21, center_x, center_y ) f_2 = self._chameleon_2.function( x, y, amp2, w_c2, w_t2, e12, e22, center_x, center_y ) f_3 = self._chameleon_3.function( x, y, amp3, w_c3, w_t3, e13, e23, center_x, center_y ) return f_1 + f_2 + f_3
[docs] def derivatives( self, x, y, alpha_1, ratio12, ratio13, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, w_c3, w_t3, e13, e23, center_x=0, center_y=0, ): """ :param alpha_1: :param ratio12: ratio of first to second amplitude :param ratio13: ratio of first to third amplidute :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: """ amp1, amp2, amp3 = self._ratio_definition(alpha_1, ratio12, ratio13) f_x1, f_y1 = self._chameleon_1.derivatives( x, y, amp1, w_c1, w_t1, e11, e21, center_x, center_y ) f_x2, f_y2 = self._chameleon_2.derivatives( x, y, amp2, w_c2, w_t2, e12, e22, center_x, center_y ) f_x3, f_y3 = self._chameleon_3.derivatives( x, y, amp3, w_c3, w_t3, e13, e23, center_x, center_y ) return f_x1 + f_x2 + f_x3, f_y1 + f_y2 + f_y3
[docs] def hessian( self, x, y, alpha_1, ratio12, ratio13, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, w_c3, w_t3, e13, e23, center_x=0, center_y=0, ): """ :param alpha_1: :param ratio12: ratio of first to second amplitude :param ratio13: ratio of first to third amplidute :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: """ amp1, amp2, amp3 = self._ratio_definition(alpha_1, ratio12, ratio13) f_xx1, f_xy1, f_yx1, f_yy1 = self._chameleon_1.hessian( x, y, amp1, w_c1, w_t1, e11, e21, center_x, center_y ) f_xx2, f_xy2, f_yx2, f_yy2 = self._chameleon_2.hessian( x, y, amp2, w_c2, w_t2, e12, e22, center_x, center_y ) f_xx3, f_xy3, f_yx3, f_yy3 = self._chameleon_3.hessian( x, y, amp3, w_c3, w_t3, e13, e23, center_x, center_y ) return ( f_xx1 + f_xx2 + f_xx3, f_xy1 + f_xy2 + f_xy3, f_yx1 + f_yx2 + f_yx3, f_yy1 + f_yy2 + f_yy3, )
[docs] def density_lens( self, r, alpha_1, ratio12, ratio13, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, w_c3, w_t3, e13, e23, center_x=0, center_y=0, ): """ :param r: 3d radius :param alpha_1: :param ratio12: ratio of first to second amplitude :param ratio13: ratio of first to third amplitude :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: density at radius r (spherical average) """ amp1, amp2, amp3 = self._ratio_definition(alpha_1, ratio12, ratio13) f_1 = self._chameleon_1.density_lens( r, amp1, w_c1, w_t1, e11, e21, center_x, center_y ) f_2 = self._chameleon_2.density_lens( r, amp2, w_c2, w_t2, e12, e22, center_x, center_y ) f_3 = self._chameleon_3.density_lens( r, amp3, w_c3, w_t3, e13, e23, center_x, center_y ) return f_1 + f_2 + f_3
[docs] def mass_3d_lens( self, r, alpha_1, ratio12, ratio13, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, w_c3, w_t3, e13, e23, center_x=0, center_y=0, ): """ :param r: 3d radius :param alpha_1: :param ratio12: ratio of first to second amplitude :param ratio13: ratio of first to third amplitude :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: mass enclosed 3d radius """ amp1, amp2, amp3 = self._ratio_definition(alpha_1, ratio12, ratio13) m_1 = self._chameleon_1.mass_3d_lens( r, amp1, w_c1, w_t1, e11, e21, center_x, center_y ) m_2 = self._chameleon_2.mass_3d_lens( r, amp2, w_c2, w_t2, e12, e22, center_x, center_y ) m_3 = self._chameleon_3.mass_3d_lens( r, amp3, w_c3, w_t3, e13, e23, center_x, center_y ) return m_1 + m_2 + m_3
[docs] def set_static( self, alpha_1, ratio12, ratio13, w_c1, w_t1, e11, e21, w_c2, w_t2, e12, e22, w_c3, w_t3, e13, e23, center_x=0, center_y=0, ): amp1, amp2, amp3 = self._ratio_definition(alpha_1, ratio12, ratio13) self._chameleon_1.set_static(amp1, w_c1, w_t1, e11, e21, center_x, center_y) self._chameleon_2.set_static(amp2, w_c2, w_t2, e12, e22, center_x, center_y) self._chameleon_3.set_static(amp3, w_c3, w_t3, e13, e23, center_x, center_y)
[docs] def set_dynamic(self): self._chameleon_1.set_dynamic() self._chameleon_2.set_dynamic() self._chameleon_3.set_dynamic()
[docs] @export 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, }
[docs] def __init__(self): self.chameleon = DoubleChameleon() self.pointMass = PointMass() super(DoubleChameleonPointMass, self).__init__()
[docs] 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: lensing potential """ f_1 = self.pointMass.function( x, y, alpha_1 / (1.0 + 1.0 / ratio_pointmass), center_x, center_y ) f_2 = self.chameleon.function( x, y, alpha_1 / (1.0 + 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
[docs] 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.0 + 1.0 / ratio_pointmass), center_x, center_y ) f_x2, f_y2 = self.chameleon.derivatives( x, y, alpha_1 / (1.0 + 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
[docs] 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.0 + 1.0 / ratio_pointmass), center_x, center_y ) f_xx2, f_xy2, f_yx2, f_yy2 = self.chameleon.hessian( x, y, alpha_1 / (1.0 + 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