Example #1
0
 def test_mass_2d(self):
     lensModel = SinglePlane(['GAUSSIAN_KAPPA'])
     output = lensModel.mass_2d(r=1, kwargs=self.kwargs)
     assert output == 0.11750309741540453
Example #2
0
class LensModel(object):
    """
    class to handle an arbitrary list of lens models
    """

    def __init__(self, lens_model_list, z_source=None, redshift_list=None, cosmo=None, multi_plane=False):
        """

        :param lens_model_list: list of strings with lens model names
        :param foreground_shear: bool, when True, models a foreground non-linear shear distortion
        """
        self.lens_model_list = lens_model_list
        self.z_source = z_source
        self.redshift_list = redshift_list
        self.cosmo = cosmo
        self.multi_plane = multi_plane
        if multi_plane is True:
            self.lens_model = MultiLens(z_source, lens_model_list, redshift_list, cosmo=cosmo)
        else:
            self.lens_model = SinglePlane(lens_model_list)


    def ray_shooting(self, x, y, kwargs, k=None):
        """
        maps image to source position (inverse deflection)

        :param x: x-position (preferentially arcsec)
        :type x: numpy array
        :param y: y-position (preferentially arcsec)
        :type y: numpy array
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param k: only evaluate the k-th lens model
        :return: source plane positions corresponding to (x, y) in the image plane
        """
        return self.lens_model.ray_shooting(x, y, kwargs, k=k)

    def fermat_potential(self, x_image, y_image, x_source, y_source, kwargs_lens):
        """
        fermat potential (negative sign means earlier arrival time)

        :param x_image: image position
        :param y_image: image position
        :param x_source: source position
        :param y_source: source position
        :param kwargs_lens: list of keyword arguments of lens model parameters matching the lens model classes
        :return: fermat potential in arcsec**2 without geometry term (second part of Eqn 1 in Suyu et al. 2013) as a list
        """
        if self.multi_plane:
            raise ValueError("Fermat potential is not defined in multi-plane lensing. Please use single plane lens models.")
        else:
            return self.lens_model.fermat_potential(x_image, y_image, x_source, y_source, kwargs_lens)

    def arrival_time(self, x_image, y_image, kwargs_lens):
        """

        :param x_image:
        :param y_image:
        :param kwargs_lens:
        :return:
        """
        if self.multi_plane:
            return self.lens_model.arrival_time(x_image, y_image, kwargs_lens)
        else:
            raise ValueError(
                "arrival_time routine not defined for single plane lensing. Please use Fermat potential instead")

    def mass(self, x, y, epsilon_crit, kwargs):
        """

        :param x: position
        :param y: position
        :param epsilon_crit: critical mass density of a lens
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :return: projected mass density in units of input epsilon_crit
        """
        kappa = self.kappa(x, y, kwargs)
        mass = epsilon_crit * kappa
        return mass

    def potential(self, x, y, kwargs, k=None):
        """
        lensing potential

        :param x: x-position (preferentially arcsec)
        :type x: numpy array
        :param y: y-position (preferentially arcsec)
        :type y: numpy array
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param k: only evaluate the k-th lens model
        :return: lensing potential in units of arcsec^2
        """
        return self.lens_model.potential(x, y, kwargs, k=k)

    def alpha(self, x, y, kwargs, k=None):
        """
        deflection angles

        :param x: x-position (preferentially arcsec)
        :type x: numpy array
        :param y: y-position (preferentially arcsec)
        :type y: numpy array
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param k: only evaluate the k-th lens model
        :return: deflection angles in units of arcsec
        """
        return self.lens_model.alpha(x, y, kwargs, k=k)

    def kappa(self, x, y, kwargs, k=None):
        """
        lensing convergence k = 1/2 laplacian(phi)

        :param x: x-position (preferentially arcsec)
        :type x: numpy array
        :param y: y-position (preferentially arcsec)
        :type y: numpy array
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param k: only evaluate the k-th lens model
        :return: lensing convergence
        """

        f_xx, f_xy, f_yy = self.hessian(x, y, kwargs, k=k)
        kappa = 1./2 * (f_xx + f_yy)  # attention on units
        return kappa

    def gamma(self, x, y, kwargs, k=None):
        """
        shear computation
        g1 = 1/2(d^2phi/dx^2 - d^2phi/dy^2)
        g2 = d^2phi/dxdy

        :param x: x-position (preferentially arcsec)
        :type x: numpy array
        :param y: y-position (preferentially arcsec)
        :type y: numpy array
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param k: only evaluate the k-th lens model
        :return: gamma1, gamma2
        """

        f_xx, f_xy, f_yy = self.hessian(x, y, kwargs, k=k)
        gamma1 = 1./2 * (f_xx - f_yy)  # attention on units
        gamma2 = f_xy  # attention on units
        return gamma1, gamma2

    def magnification(self, x, y, kwargs, k=None):
        """
        magnification
        mag = 1/det(A)
        A = 1 - d^2phi/d_ij

        :param x: x-position (preferentially arcsec)
        :type x: numpy array
        :param y: y-position (preferentially arcsec)
        :type y: numpy array
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param k: only evaluate the k-th lens model
        :return: magnification
        """

        f_xx, f_xy, f_yy = self.hessian(x, y, kwargs, k=k)
        det_A = (1 - f_xx) * (1 - f_yy) - f_xy*f_xy
        return 1./det_A  # attention, if dividing by zero

    def hessian(self, x, y, kwargs, k=None):
        """
        hessian matrix

        :param x: x-position (preferentially arcsec)
        :type x: numpy array
        :param y: y-position (preferentially arcsec)
        :type y: numpy array
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param k: only evaluate the k-th lens model
        :return: f_xx, f_xy, f_yy components
        """
        return self.lens_model.hessian(x, y, kwargs, k=k)

    def mass_3d(self, r, kwargs, bool_list=None):
        """
        computes the mass within a 3d sphere of radius r

        :param r: radius (in angular units)
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param bool_list: list of bools that are part of the output
        :return: mass (in angular units, modulo epsilon_crit)
        """
        if self.multi_plane is True:
            raise ValueError("mass_3d is not supported for multi-lane lensing. Please use single plane instead.")
        else:
            return self.lens_model.mass_3d(r, kwargs, bool_list=bool_list)

    def mass_2d(self, r, kwargs, bool_list=None):
        """
        computes the mass enclosed a projected (2d) radius r

        :param r: radius (in angular units)
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param bool_list: list of bools that are part of the output
        :return: projected mass (in angular units, modulo epsilon_crit)
        """
        if self.multi_plane is True:
            raise ValueError("mass_2d is not supported for multi-lane lensing. Please use single plane instead.")
        else:
            return self.lens_model.mass_2d(r, kwargs, bool_list=bool_list)
 def test_mass_2d(self):
     lensModel = SinglePlane(['GAUSSIAN_KAPPA'])
     kwargs = [{'amp': 1., 'sigma': 2., 'center_x': 0., 'center_y': 0.}]
     output = lensModel.mass_2d(r=1, kwargs=kwargs)
     assert output == 0.11750309741540453