Example #1
0
 def __init__(self, profile_type='CORED_DENSITY'):
     if profile_type == 'CORED_DENSITY':
         self._profile = CoredDensity()
     elif profile_type == 'CORED_DENSITY_2':
         self._profile = CoredDensity2()
     else:
         raise ValueError(
             'profile_type %s not supported for CoredDensityMST instance.' %
             profile_type)
     self._convergence = Convergence()
     super(CoredDensityMST, self).__init__()
Example #2
0
 def __init__(self, profile_type='CORED_DENSITY'):
     if profile_type == 'CORED_DENSITY':
         self._profile = CoredDensity()
     elif profile_type == 'CORED_DENSITY_2':
         self._profile = CoredDensity2()
     elif profile_type == 'CORED_DENSITY_EXP':
         self._profile = CoredDensityExp()
     # Due to parameters name conventions/positioning, right now only the free soliton with
     # the default value of slope = 8 is supported 
     elif profile_type == 'CORED_DENSITY_ULDM':
         self._profile = Uldm()
     else:
         raise ValueError('profile_type %s not supported for CoredDensityMST instance.' % profile_type)
     self._convergence = Convergence()
     super(CoredDensityMST, self).__init__()
Example #3
0
class TestConvergence(object):
    """
    tests the Gaussian methods
    """
    def setup(self):
        self.profile = Convergence()
        self.kwargs_lens = {'kappa_ext': 0.1}

    def test_function(self):
        x = np.array([1])
        y = np.array([0])
        values = self.profile.function(x, y, **self.kwargs_lens)
        npt.assert_almost_equal(values[0],
                                self.kwargs_lens['kappa_ext'] / 2,
                                decimal=5)
        x = np.array([0])
        y = np.array([0])
        values = self.profile.function(x, y, **self.kwargs_lens)
        npt.assert_almost_equal(values[0], 0, decimal=5)

        x = np.array([2, 3, 4])
        y = np.array([1, 1, 1])
        values = self.profile.function(x, y, **self.kwargs_lens)
        npt.assert_almost_equal(values[0], 0.25, decimal=5)
        npt.assert_almost_equal(values[1], 0.5, decimal=5)

    def test_derivatives(self):
        x = np.array([1])
        y = np.array([2])
        f_x, f_y = self.profile.derivatives(x, y, **self.kwargs_lens)
        npt.assert_almost_equal(f_x[0], 0.1, decimal=5)
        npt.assert_almost_equal(f_y[0], 0.2, decimal=5)

        x = np.array([1, 3, 4])
        y = np.array([2, 1, 1])
        values = self.profile.derivatives(x, y, **self.kwargs_lens)
        npt.assert_almost_equal(values[0][0], 0.1, decimal=5)
        npt.assert_almost_equal(values[1][0], 0.2, decimal=5)

    def test_hessian(self):
        x = np.array([1])
        y = np.array([2])
        f_xx, f_xy, f_yx, f_yy = self.profile.hessian(x, y, **self.kwargs_lens)
        npt.assert_almost_equal(f_xx, 0.1, decimal=5)
        npt.assert_almost_equal(f_yy, 0.1, decimal=5)
        npt.assert_almost_equal(f_xy, 0, decimal=5)
        npt.assert_almost_equal(f_yx, 0, decimal=5)

        x = np.array([1, 3, 4])
        y = np.array([2, 1, 1])
        values = self.profile.hessian(x, y, **self.kwargs_lens)
        npt.assert_almost_equal(values[0], 0.1, decimal=5)
        npt.assert_almost_equal(values[3], 0.1, decimal=5)
        npt.assert_almost_equal(values[1], 0, decimal=5)
class TestCurvedArcSISMST(object):
    """
    tests the source model routines
    """
    def setup(self):
        self.model = CurvedArcSISMST()
        self.sis = SIS()
        self.mst = Convergence()

    def test_spp2stretch(self):
        center_x, center_y = 1, 1
        theta_E = 1
        kappa = 0.1
        center_x_spp, center_y_spp = 0., 0

        tangential_stretch, radial_stretch, curvature, direction = self.model.sis_mst2stretch(theta_E, kappa, center_x_spp, center_y_spp, center_x, center_y)
        theta_E_new, kappa_new, center_x_spp_new, center_y_spp_new = self.model.stretch2sis_mst(tangential_stretch, radial_stretch, curvature, direction, center_x, center_y)
        npt.assert_almost_equal(center_x_spp_new, center_x_spp, decimal=8)
        npt.assert_almost_equal(center_y_spp_new, center_y_spp, decimal=8)
        npt.assert_almost_equal(theta_E_new, theta_E, decimal=8)
        npt.assert_almost_equal(kappa_new, kappa, decimal=8)

        center_x, center_y = -1, 1
        tangential_stretch, radial_stretch, curvature, direction = self.model.sis_mst2stretch(theta_E, kappa,
                                                                                            center_x_spp, center_y_spp,
                                                                                            center_x, center_y)
        theta_E_new, kappa_new, center_x_spp_new, center_y_spp_new = self.model.stretch2sis_mst(tangential_stretch,
                                                                                            radial_stretch, curvature,
                                                                                            direction, center_x,
                                                                                            center_y)
        npt.assert_almost_equal(center_x_spp_new, center_x_spp, decimal=8)
        npt.assert_almost_equal(center_y_spp_new, center_y_spp, decimal=8)
        npt.assert_almost_equal(theta_E_new, theta_E, decimal=8)
        npt.assert_almost_equal(kappa_new, kappa, decimal=8)

        center_x, center_y = 0, 0.5
        tangential_stretch, radial_stretch, curvature, direction = self.model.sis_mst2stretch(theta_E, kappa,
                                                                                            center_x_spp, center_y_spp,
                                                                                            center_x, center_y)
        theta_E_new, kappa_new, center_x_spp_new, center_y_spp_new = self.model.stretch2sis_mst(tangential_stretch,
                                                                                            radial_stretch, curvature,
                                                                                            direction, center_x,
                                                                                            center_y)
        npt.assert_almost_equal(center_x_spp_new, center_x_spp, decimal=8)
        npt.assert_almost_equal(center_y_spp_new, center_y_spp, decimal=8)
        npt.assert_almost_equal(theta_E_new, theta_E, decimal=8)
        npt.assert_almost_equal(kappa_new, kappa, decimal=8)

        center_x, center_y = 0, -1.5
        tangential_stretch, radial_stretch, r_curvature, direction = self.model.sis_mst2stretch(theta_E, kappa,
                                                                                            center_x_spp, center_y_spp,
                                                                                            center_x, center_y)
        print(tangential_stretch, radial_stretch, r_curvature, direction)
        theta_E_new, kappa_new, center_x_spp_new, center_y_spp_new = self.model.stretch2sis_mst(tangential_stretch,
                                                                                            radial_stretch, r_curvature,
                                                                                            direction, center_x,
                                                                                            center_y)
        npt.assert_almost_equal(center_x_spp_new, center_x_spp, decimal=8)
        npt.assert_almost_equal(center_y_spp_new, center_y_spp, decimal=8)
        npt.assert_almost_equal(theta_E_new, theta_E, decimal=8)
        npt.assert_almost_equal(kappa_new, kappa, decimal=8)

    def test_function(self):
        center_x, center_y = 0., 0.
        x, y = 1, 1
        radial_stretch = 1
        output = self.model.function(x, y, tangential_stretch=2, radial_stretch=radial_stretch, curvature=1./2, direction=0, center_x=center_x, center_y=center_y)
        theta_E, kappa_ext, center_x_sis, center_y_sis = self.model.stretch2sis_mst(tangential_stretch=2, radial_stretch=radial_stretch, curvature=1./2, direction=0,
                                                                            center_x=center_x, center_y=center_y)
        f_sis_out = self.sis.function(1, 1, theta_E, center_x_sis, center_y_sis)  # - self.sis.function(0, 0, theta_E, center_x_sis, center_y_sis)
        alpha_x, alpha_y = self.sis.derivatives(center_x, center_y, theta_E, center_x_sis, center_y_sis)
        f_sis_0_out = alpha_x * (x - center_x) + alpha_y * (y - center_y)

        f_mst_out = self.mst.function(x, y, kappa_ext, ra_0=center_x, dec_0=center_y)
        lambda_mst = 1. / radial_stretch
        f_out = lambda_mst * (f_sis_out - f_sis_0_out) + f_mst_out
        npt.assert_almost_equal(output, f_out, decimal=8)

    def test_derivatives(self):
        tangential_stretch = 5
        radial_stretch = 1
        curvature = 1./10
        direction = 0.3
        center_x = 0
        center_y = 0
        x, y = 1, 1
        theta_E, kappa, center_x_spp, center_y_spp = self.model.stretch2sis_mst(tangential_stretch,
                                                                            radial_stretch, curvature,
                                                                            direction, center_x, center_y)
        f_x_sis, f_y_sis = self.sis.derivatives(x, y, theta_E, center_x_spp, center_y_spp)
        f_x_mst, f_y_mst = self.mst.derivatives(x, y, kappa, ra_0=center_x, dec_0=center_y)
        f_x0, f_y0 = self.sis.derivatives(center_x, center_y, theta_E, center_x_spp, center_y_spp)
        f_x_new, f_y_new = self.model.derivatives(x, y, tangential_stretch, radial_stretch, curvature, direction, center_x, center_y)
        npt.assert_almost_equal(f_x_new, f_x_sis + f_x_mst - f_x0, decimal=8)
        npt.assert_almost_equal(f_y_new, f_y_sis + f_y_mst - f_y0, decimal=8)

    def test_hessian(self):
        lens = LensModel(lens_model_list=['CURVED_ARC_SIS_MST'])
        center_x, center_y = 0, 0
        tangential_stretch = 10
        radial_stretch = 1
        kwargs_lens = [
            {'tangential_stretch': tangential_stretch, 'radial_stretch': radial_stretch, 'curvature': 1./10.5, 'direction': 0.,
             'center_x': center_x, 'center_y': center_y}]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag, tangential_stretch * radial_stretch, decimal=8)

        center_x, center_y = 2, 3
        tangential_stretch = 10
        radial_stretch = 1
        kwargs_lens = [
            {'tangential_stretch': tangential_stretch, 'radial_stretch': radial_stretch, 'curvature': 1./10.5, 'direction': 0.,
             'center_x': center_x, 'center_y': center_y}]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag, tangential_stretch * radial_stretch, decimal=8)

        center_x, center_y = 0, 0
        tangential_stretch = 5
        radial_stretch = 1.2
        kwargs_lens = [
            {'tangential_stretch': tangential_stretch, 'radial_stretch': radial_stretch, 'curvature': 1. / 10.5,
             'direction': 0.,
             'center_x': center_x, 'center_y': center_y}]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag, tangential_stretch * radial_stretch, decimal=8)

        center_x, center_y = 0, 0
        tangential_stretch = 3
        radial_stretch = -1
        kwargs_lens = [
            {'tangential_stretch': tangential_stretch, 'radial_stretch': radial_stretch, 'curvature': 1./10.5,
             'direction': 0.,
             'center_x': center_x, 'center_y': center_y}]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        print(tangential_stretch, radial_stretch, 'stretches')
        npt.assert_almost_equal(mag, tangential_stretch * radial_stretch, decimal=8)

        center_x, center_y = 0, 0
        tangential_stretch = -3
        radial_stretch = -1
        kwargs_lens = [
            {'tangential_stretch': tangential_stretch, 'radial_stretch': radial_stretch, 'curvature': 1./10.5,
             'direction': 0.,
             'center_x': center_x, 'center_y': center_y}]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag, tangential_stretch * radial_stretch, decimal=8)

        center_x, center_y = 0, 0
        tangential_stretch = 10.4
        radial_stretch = 0.6
        kwargs_lens = [
            {'tangential_stretch': tangential_stretch, 'radial_stretch': radial_stretch, 'curvature': 1./10.5,
             'direction': 0.,
             'center_x': center_x, 'center_y': center_y}]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag, tangential_stretch * radial_stretch, decimal=8)

    def test_curved_arc_recovery(self):
        """
        test whether the curved arc parameters are satisfied in differential form
        """

        ext = LensModelExtensions(LensModel(lens_model_list=['CURVED_ARC_SIS_MST']))
        center_x, center_y = 1, 1.  # test works except at (0,0) where the direction angle is not well defined
        tangential_stretch = 10.
        radial_stretch = 1.2
        curvature, direction = 0.02, 0.5
        kwargs_lens = {'tangential_stretch': tangential_stretch, 'radial_stretch': radial_stretch,
                       'curvature': curvature, 'direction': direction, 'center_x': center_x, 'center_y': center_y}

        self._test_curved_arc_recovery(kwargs_lens)

    def _test_curved_arc_recovery(self, kwargs_arc_init):
        ext = LensModelExtensions(LensModel(lens_model_list=['CURVED_ARC_SIS_MST']))
        center_x, center_y = kwargs_arc_init['center_x'], kwargs_arc_init['center_y']
        kwargs_arc = ext.curved_arc_estimate(center_x, center_y, [kwargs_arc_init])
        lambda_rad, lambda_tan, orientation_angle, dlambda_tan_dtan, dlambda_tan_drad, dlambda_rad_drad, dlambda_rad_dtan, dphi_tan_dtan, dphi_tan_drad, dphi_rad_drad, dphi_rad_dtan = ext.radial_tangential_differentials(center_x, center_y, [kwargs_arc_init])
        npt.assert_almost_equal(kwargs_arc['tangential_stretch'], kwargs_arc_init['tangential_stretch'], decimal=3)
        npt.assert_almost_equal(kwargs_arc['radial_stretch'], kwargs_arc_init['radial_stretch'], decimal=3)
        npt.assert_almost_equal(kwargs_arc['curvature'], kwargs_arc_init['curvature'], decimal=3)
        npt.assert_almost_equal(dphi_tan_dtan, kwargs_arc_init['curvature'], decimal=3)
        npt.assert_almost_equal(kwargs_arc['direction'], kwargs_arc_init['direction'], decimal=3)
        npt.assert_almost_equal(dlambda_tan_dtan, 0, decimal=3)
class CoredDensityMST(LensProfileBase):
    """
    approximate mass-sheet transform of a density core. This routine takes the parameters of the density core and
    subtracts a mass=sheet that approximates the cored profile in it's center to counter-act (in approximation) this
    model. This allows for better sampling of the mass-sheet transformed quantities that do not have strong covariances.
    Attention!!! The interpretation of the result is that the mass sheet as 'CONVERGENCE' that is present needs to be
    subtracted in post-processing.
    """
    param_names = ['lambda_approx', 'r_core', 'center_x', 'center_y']
    lower_limit_default = {
        'lambda_approx': -1,
        'r_core': 0,
        'center_x': -100,
        'center_y': -100
    }
    upper_limit_default = {
        'lambda_approx': 10,
        'r_core': 100,
        'center_x': 100,
        'center_y': 100
    }

    def __init__(self, profile_type='CORED_DENSITY'):
        if profile_type == 'CORED_DENSITY':
            self._profile = CoredDensity()
        elif profile_type == 'CORED_DENSITY_2':
            self._profile = CoredDensity2()
        elif profile_type == 'CORED_DENSITY_EXP':
            self._profile = CoredDensityExp()
        else:
            raise ValueError(
                'profile_type %s not supported for CoredDensityMST instance.' %
                profile_type)
        self._convergence = Convergence()
        super(CoredDensityMST, self).__init__()

    def function(self, x, y, lambda_approx, r_core, center_x=0, center_y=0):
        """
        lensing potential of approximate mass-sheet correction

        :param x: x-coordinate
        :param y: y-coordinate
        :param lambda_approx: approximate mass sheet transform
        :param r_core: core radius of the cored density profile
        :param center_x: x-center of the profile
        :param center_y: y-center of the profile
        :return: lensing potential correction
        """
        kappa_ext = 1 - lambda_approx
        f_cored_density = self._profile.function(x, y, kappa_ext, r_core,
                                                 center_x, center_y)
        f_ms = self._convergence.function(x, y, kappa_ext, center_x, center_y)
        return f_cored_density - f_ms

    def derivatives(self, x, y, lambda_approx, r_core, center_x=0, center_y=0):
        """
        deflection angles of approximate mass-sheet correction

        :param x: x-coordinate
        :param y: y-coordinate
        :param lambda_approx: approximate mass sheet transform
        :param r_core: core radius of the cored density profile
        :param center_x: x-center of the profile
        :param center_y: y-center of the profile
        :return: alpha_x, alpha_y
        """
        kappa_ext = 1 - lambda_approx
        f_x_cd, f_y_cd = self._profile.derivatives(x, y, kappa_ext, r_core,
                                                   center_x, center_y)
        f_x_ms, f_y_ms = self._convergence.derivatives(x, y, kappa_ext,
                                                       center_x, center_y)
        return f_x_cd - f_x_ms, f_y_cd - f_y_ms

    def hessian(self, x, y, lambda_approx, r_core, center_x=0, center_y=0):
        """
        Hessian terms of approximate mass-sheet correction

        :param x: x-coordinate
        :param y: y-coordinate
        :param lambda_approx: approximate mass sheet transform
        :param r_core: core radius of the cored density profile
        :param center_x: x-center of the profile
        :param center_y: y-center of the profile
        :return: df/dxx, df/dyy, df/dxy
        """
        kappa_ext = 1 - lambda_approx
        f_xx_cd, f_yy_cd, f_xy_cd = self._profile.hessian(
            x, y, kappa_ext, r_core, center_x, center_y)
        f_xx_ms, f_yy_ms, f_xy_ms = self._convergence.hessian(
            x, y, kappa_ext, center_x, center_y)
        return f_xx_cd - f_xx_ms, f_yy_cd - f_yy_ms, f_xy_cd - f_xy_ms
Example #6
0
class CurvedArcTanDiff(LensProfileBase):
    """
    Curved arc model with an additional non-zero tangential stretch differential in tangential direction component

    Observables are:
    - curvature radius (basically bending relative to the center of the profile)
    - radial stretch (plus sign) thickness of arc with parity (more generalized than the power-law slope)
    - tangential stretch (plus sign). Infinity means at critical curve
    - direction of curvature
    - position of arc

    Requirements:
    - Should work with other perturbative models without breaking its meaning (say when adding additional shear terms)
    - Must best reflect the observables in lensing
    - minimal covariances between the parameters, intuitive parameterization.

    """
    param_names = [
        'tangential_stretch', 'radial_stretch', 'curvature', 'dtan_dtan',
        'direction', 'center_x', 'center_y'
    ]
    lower_limit_default = {
        'tangential_stretch': -100,
        'radial_stretch': -5,
        'curvature': 0.000001,
        'dtan_dtan': -10,
        'direction': -np.pi,
        'center_x': -100,
        'center_y': -100
    }
    upper_limit_default = {
        'tangential_stretch': 100,
        'radial_stretch': 5,
        'curvature': 100,
        'dtan_dtan': 10,
        'direction': np.pi,
        'center_x': 100,
        'center_y': 100
    }

    def __init__(self):
        self._sie = SIE(NIE=True)
        self._mst = Convergence()
        super(CurvedArcTanDiff, self).__init__()

    @staticmethod
    def stretch2sie_mst(tangential_stretch, radial_stretch, curvature,
                        dtan_dtan, direction, center_x, center_y):
        """

        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param dtan_dtan: d(tangential_stretch) / d(tangential direction) / tangential stretch
        :param direction: float, angle in radian
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return: parameters in terms of a spherical SIS + MST resulting in the same observables
        """
        center_x_sis, center_y_sis = center_deflector(curvature, direction,
                                                      center_x, center_y)
        r_curvature = 1. / curvature
        lambda_mst = 1. / radial_stretch
        kappa_ext = 1 - lambda_mst
        theta_E = r_curvature * (1. - radial_stretch / tangential_stretch)
        # analytic relation (see Birrer 2021)
        dlambda_tan_dr = tangential_stretch / r_curvature * (
            1 - tangential_stretch / radial_stretch)

        # translate tangential eigenvalue gradient in lens ellipticity
        dtan_dtan_ = dtan_dtan * tangential_stretch
        epsilon = np.abs(dtan_dtan_ / dlambda_tan_dr)
        # bound epsilon by (-1, 1)
        epsilon = np.minimum(epsilon, 0.99999)
        q = np.sqrt((1 - epsilon) / (1 + epsilon))

        if dtan_dtan_ < 0:
            phi = direction - np.pi / 4
        else:
            phi = direction + np.pi / 4
        e1_sie, e2_sie = param_util.phi_q2_ellipticity(phi, q)

        # ellipticity adopted Einstein radius to match local tangential and radial stretch
        factor = np.sqrt(1 + q**2) / np.sqrt(2 * q)
        theta_E_sie = theta_E * factor
        return theta_E_sie, e1_sie, e2_sie, kappa_ext, center_x_sis, center_y_sis

    def function(self, x, y, tangential_stretch, radial_stretch, curvature,
                 dtan_dtan, direction, center_x, center_y):
        """
        ATTENTION: there may not be a global lensing potential!

        :param x:
        :param y:
        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param dtan_dtan: d(tangential_stretch) / d(tangential direction) / tangential stretch
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return:
        """
        lambda_mst = 1. / radial_stretch
        theta_E_sie, e1_sie, e2_sie, kappa_ext, center_x_sis, center_y_sis = self.stretch2sie_mst(
            tangential_stretch, radial_stretch, curvature, dtan_dtan,
            direction, center_x, center_y)
        f_sis = self._sie.function(
            x, y, theta_E_sie, e1_sie, e2_sie, center_x_sis, center_y_sis
        )  # - self._sis.function(center_x, center_y, theta_E, center_x_sis, center_y_sis)
        alpha_x, alpha_y = self._sie.derivatives(center_x, center_y,
                                                 theta_E_sie, e1_sie, e2_sie,
                                                 center_x_sis, center_y_sis)
        f_sis_0 = alpha_x * (x - center_x) + alpha_y * (y - center_y)
        f_mst = self._mst.function(x,
                                   y,
                                   kappa_ext,
                                   ra_0=center_x,
                                   dec_0=center_y)
        return lambda_mst * (f_sis - f_sis_0) + f_mst

    def derivatives(self, x, y, tangential_stretch, radial_stretch, curvature,
                    dtan_dtan, direction, center_x, center_y):
        """

        :param x:
        :param y:
        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param dtan_dtan: d(tangential_stretch) / d(tangential direction) / tangential stretch
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return:
        """
        lambda_mst = 1. / radial_stretch
        theta_E_sie, e1_sie, e2_sie, kappa_ext, center_x_sis, center_y_sis = self.stretch2sie_mst(
            tangential_stretch, radial_stretch, curvature, dtan_dtan,
            direction, center_x, center_y)
        f_x_sis, f_y_sis = self._sie.derivatives(x, y, theta_E_sie, e1_sie,
                                                 e2_sie, center_x_sis,
                                                 center_y_sis)
        f_x0, f_y0 = self._sie.derivatives(center_x, center_y, theta_E_sie,
                                           e1_sie, e2_sie, center_x_sis,
                                           center_y_sis)
        f_x_mst, f_y_mst = self._mst.derivatives(x,
                                                 y,
                                                 kappa_ext,
                                                 ra_0=center_x,
                                                 dec_0=center_y)
        f_x = lambda_mst * (f_x_sis - f_x0) + f_x_mst
        f_y = lambda_mst * (f_y_sis - f_y0) + f_y_mst
        return f_x, f_y

    def hessian(self, x, y, tangential_stretch, radial_stretch, curvature,
                dtan_dtan, direction, center_x, center_y):
        """

        :param x:
        :param y:
        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param dtan_dtan: d(tangential_stretch) / d(tangential direction) / tangential stretch
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return:
        """
        lambda_mst = 1. / radial_stretch
        theta_E_sie, e1_sie, e2_sie, kappa_ext, center_x_sis, center_y_sis = self.stretch2sie_mst(
            tangential_stretch, radial_stretch, curvature, dtan_dtan,
            direction, center_x, center_y)
        f_xx_sis, f_xy_sis, f_yx_sis, f_yy_sis = self._sie.hessian(
            x, y, theta_E_sie, e1_sie, e2_sie, center_x_sis, center_y_sis)
        f_xx_mst, f_xy_mst, f_yx_mst, f_yy_mst = self._mst.hessian(
            x, y, kappa_ext, ra_0=center_x, dec_0=center_y)
        return lambda_mst * f_xx_sis + f_xx_mst, lambda_mst * f_xy_sis + f_xy_mst, lambda_mst * f_yx_sis + f_yx_mst, lambda_mst * f_yy_sis + f_yy_mst
Example #7
0
 def __init__(self):
     self._sie = SIE(NIE=True)
     self._mst = Convergence()
     super(CurvedArcTanDiff, self).__init__()
    def _import_class(self, lens_type, i, custom_class):

        if lens_type == 'SHIFT':
            from lenstronomy.LensModel.Profiles.alpha_shift import Shift
            return Shift()
        elif lens_type == 'SHEAR':
            from lenstronomy.LensModel.Profiles.shear import Shear
            return Shear()
        elif lens_type == 'CONVERGENCE':
            from lenstronomy.LensModel.Profiles.convergence import Convergence
            return Convergence()
        elif lens_type == 'FLEXION':
            from lenstronomy.LensModel.Profiles.flexion import Flexion
            return Flexion()
        elif lens_type == 'POINT_MASS':
            from lenstronomy.LensModel.Profiles.point_mass import PointMass
            return PointMass()
        elif lens_type == 'SIS':
            from lenstronomy.LensModel.Profiles.sis import SIS
            return SIS()
        elif lens_type == 'SIS_TRUNCATED':
            from lenstronomy.LensModel.Profiles.sis_truncate import SIS_truncate
            return SIS_truncate()
        elif lens_type == 'SIE':
            from lenstronomy.LensModel.Profiles.sie import SIE
            return SIE()
        elif lens_type == 'SPP':
            from lenstronomy.LensModel.Profiles.spp import SPP
            return SPP()
        elif lens_type == 'NIE':
            from lenstronomy.LensModel.Profiles.nie import NIE
            return NIE()
        elif lens_type == 'NIE_SIMPLE':
            from lenstronomy.LensModel.Profiles.nie import NIE_simple
            return NIE_simple()
        elif lens_type == 'CHAMELEON':
            from lenstronomy.LensModel.Profiles.chameleon import Chameleon
            return Chameleon()
        elif lens_type == 'DOUBLE_CHAMELEON':
            from lenstronomy.LensModel.Profiles.chameleon import DoubleChameleon
            return DoubleChameleon()
        elif lens_type == 'SPEP':
            from lenstronomy.LensModel.Profiles.spep import SPEP
            return SPEP()
        elif lens_type == 'SPEMD':
            from lenstronomy.LensModel.Profiles.spemd import SPEMD
            return SPEMD()
        elif lens_type == 'SPEMD_SMOOTH':
            from lenstronomy.LensModel.Profiles.spemd_smooth import SPEMD_SMOOTH
            return SPEMD_SMOOTH()
        elif lens_type == 'NFW':
            from lenstronomy.LensModel.Profiles.nfw import NFW
            return NFW()
        elif lens_type == 'NFW_ELLIPSE':
            from lenstronomy.LensModel.Profiles.nfw_ellipse import NFW_ELLIPSE
            return NFW_ELLIPSE()
        elif lens_type == 'TNFW':
            from lenstronomy.LensModel.Profiles.tnfw import TNFW
            return TNFW()
        elif lens_type == 'CNFW':
            from lenstronomy.LensModel.Profiles.cnfw import CNFW
            return CNFW()
        elif lens_type == 'SERSIC':
            from lenstronomy.LensModel.Profiles.sersic import Sersic
            return Sersic()
        elif lens_type == 'SERSIC_ELLIPSE':
            from lenstronomy.LensModel.Profiles.sersic_ellipse import SersicEllipse
            return SersicEllipse()
        elif lens_type == 'PJAFFE':
            from lenstronomy.LensModel.Profiles.p_jaffe import PJaffe
            return PJaffe()
        elif lens_type == 'PJAFFE_ELLIPSE':
            from lenstronomy.LensModel.Profiles.p_jaffe_ellipse import PJaffe_Ellipse
            return PJaffe_Ellipse()
        elif lens_type == 'HERNQUIST':
            from lenstronomy.LensModel.Profiles.hernquist import Hernquist
            return Hernquist()
        elif lens_type == 'HERNQUIST_ELLIPSE':
            from lenstronomy.LensModel.Profiles.hernquist_ellipse import Hernquist_Ellipse
            return Hernquist_Ellipse()
        elif lens_type == 'GAUSSIAN':
            from lenstronomy.LensModel.Profiles.gaussian_potential import Gaussian
            return Gaussian()
        elif lens_type == 'GAUSSIAN_KAPPA':
            from lenstronomy.LensModel.Profiles.gaussian_kappa import GaussianKappa
            return GaussianKappa()
        elif lens_type == 'GAUSSIAN_KAPPA_ELLIPSE':
            from lenstronomy.LensModel.Profiles.gaussian_kappa_ellipse import GaussianKappaEllipse
            return GaussianKappaEllipse()
        elif lens_type == 'MULTI_GAUSSIAN_KAPPA':
            from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappa
            return MultiGaussianKappa()
        elif lens_type == 'MULTI_GAUSSIAN_KAPPA_ELLIPSE':
            from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappaEllipse
            return MultiGaussianKappaEllipse()
        elif lens_type == 'INTERPOL':
            from lenstronomy.LensModel.Profiles.interpol import Interpol
            return Interpol(grid=False, min_grid_number=100)
        elif lens_type == 'INTERPOL_SCALED':
            from lenstronomy.LensModel.Profiles.interpol import InterpolScaled
            return InterpolScaled()
        elif lens_type == 'SHAPELETS_POLAR':
            from lenstronomy.LensModel.Profiles.shapelet_pot_polar import PolarShapelets
            return PolarShapelets()
        elif lens_type == 'SHAPELETS_CART':
            from lenstronomy.LensModel.Profiles.shapelet_pot_cartesian import CartShapelets
            return CartShapelets()
        elif lens_type == 'DIPOLE':
            from lenstronomy.LensModel.Profiles.dipole import Dipole
            return Dipole()
        elif lens_type == 'FOREGROUND_SHEAR':
            from lenstronomy.LensModel.Profiles.shear import Shear
            self._foreground_shear = True
            self._foreground_shear_idex = i
            return Shear()
        elif lens_type == 'coreBURKERT':
            from lenstronomy.LensModel.Profiles.coreBurkert import coreBurkert
            return coreBurkert()
        elif lens_type == 'NumericalAlpha':
            from lenstronomy.LensModel.Profiles.numerical_deflections import NumericalAlpha
            return NumericalAlpha(custom_class[i])
        else:
            raise ValueError('%s is not a valid lens model' % lens_type)
Example #9
0
 def __init__(self):
     self._shear = Shear()
     self._convergence = Convergence()
     super(ShearReduced, self).__init__()
Example #10
0
class CurvedArcConstMST(LensProfileBase):
    """
    lens model that describes a section of a highly magnified deflector region.
    The parameterization is chosen to describe local observables efficient.

    Observables are:
    - curvature radius (basically bending relative to the center of the profile)
    - radial stretch (plus sign) thickness of arc with parity (more generalized than the power-law slope)
    - tangential stretch (plus sign). Infinity means at critical curve
    - direction of curvature
    - position of arc

    Requirements:
    - Should work with other perturbative models without breaking its meaning (say when adding additional shear terms)
    - Must best reflect the observables in lensing
    - minimal covariances between the parameters, intuitive parameterization.

    """
    param_names = [
        'tangential_stretch', 'radial_stretch', 'curvature', 'direction',
        'center_x', 'center_y'
    ]
    lower_limit_default = {
        'tangential_stretch': -100,
        'radial_stretch': -5,
        'curvature': 0.000001,
        'direction': -np.pi,
        'center_x': -100,
        'center_y': -100
    }
    upper_limit_default = {
        'tangential_stretch': 100,
        'radial_stretch': 5,
        'curvature': 100,
        'direction': np.pi,
        'center_x': 100,
        'center_y': 100
    }

    def __init__(self):
        self._mst = Convergence()
        self._curve = CurvedArcConst()
        super(CurvedArcConstMST, self).__init__()

    def function(self, x, y, tangential_stretch, radial_stretch, curvature,
                 direction, center_x, center_y):
        """
        ATTENTION: there may not be a global lensing potential!

        :param x:
        :param y:
        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return:
        """
        raise NotImplemented(
            'lensing potential for regularly curved arc is not implemented')

    def derivatives(self, x, y, tangential_stretch, radial_stretch, curvature,
                    direction, center_x, center_y):
        """

        :param x:
        :param y:
        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return:
        """
        lambda_mst = 1. / radial_stretch
        kappa_ext = 1 - lambda_mst
        curve_stretch = tangential_stretch / radial_stretch

        f_x_curve, f_y_curve = self._curve.derivatives(x, y, curve_stretch,
                                                       curvature, direction,
                                                       center_x, center_y)
        f_x_mst, f_y_mst = self._mst.derivatives(x,
                                                 y,
                                                 kappa_ext,
                                                 ra_0=center_x,
                                                 dec_0=center_y)
        f_x = lambda_mst * f_x_curve + f_x_mst
        f_y = lambda_mst * f_y_curve + f_y_mst
        return f_x, f_y

    def hessian(self, x, y, tangential_stretch, radial_stretch, curvature,
                direction, center_x, center_y):
        """

        :param x:
        :param y:
        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return:
        """
        lambda_mst = 1. / radial_stretch
        kappa_ext = 1 - lambda_mst
        curve_stretch = tangential_stretch / radial_stretch
        f_xx_c, f_xy_c, f_yx_c, f_yy_c = self._curve.hessian(
            x, y, curve_stretch, curvature, direction, center_x, center_y)
        f_xx_mst, f_xy_mst, f_yx_mst, f_yy_mst = self._mst.hessian(
            x, y, kappa_ext, ra_0=center_x, dec_0=center_y)
        f_xx = lambda_mst * f_xx_c + f_xx_mst
        f_xy = lambda_mst * f_xy_c + f_xy_mst
        f_yx = lambda_mst * f_yx_c + f_yx_mst
        f_yy = lambda_mst * f_yy_c + f_yy_mst
        return f_xx, f_xy, f_yx, f_yy
Example #11
0
class TestCurvedArcSISMST(object):
    """
    tests the source model routines
    """
    def setup(self):
        self.model = CurvedArcSISMST()
        self.sis = SIS()
        self.mst = Convergence()

    def test_spp2stretch(self):
        center_x, center_y = 1, 1
        theta_E = 1
        kappa = 0.1
        center_x_spp, center_y_spp = 0., 0

        tangential_stretch, radial_stretch, curvature, direction = self.model.sis_mst2stretch(
            theta_E, kappa, center_x_spp, center_y_spp, center_x, center_y)
        theta_E_new, kappa_new, center_x_spp_new, center_y_spp_new = self.model.stretch2sis_mst(
            tangential_stretch, radial_stretch, curvature, direction, center_x,
            center_y)
        npt.assert_almost_equal(center_x_spp_new, center_x_spp, decimal=8)
        npt.assert_almost_equal(center_y_spp_new, center_y_spp, decimal=8)
        npt.assert_almost_equal(theta_E_new, theta_E, decimal=8)
        npt.assert_almost_equal(kappa_new, kappa, decimal=8)

        center_x, center_y = -1, 1
        tangential_stretch, radial_stretch, curvature, direction = self.model.sis_mst2stretch(
            theta_E, kappa, center_x_spp, center_y_spp, center_x, center_y)
        theta_E_new, kappa_new, center_x_spp_new, center_y_spp_new = self.model.stretch2sis_mst(
            tangential_stretch, radial_stretch, curvature, direction, center_x,
            center_y)
        npt.assert_almost_equal(center_x_spp_new, center_x_spp, decimal=8)
        npt.assert_almost_equal(center_y_spp_new, center_y_spp, decimal=8)
        npt.assert_almost_equal(theta_E_new, theta_E, decimal=8)
        npt.assert_almost_equal(kappa_new, kappa, decimal=8)

        center_x, center_y = 0, 0.5
        tangential_stretch, radial_stretch, curvature, direction = self.model.sis_mst2stretch(
            theta_E, kappa, center_x_spp, center_y_spp, center_x, center_y)
        theta_E_new, kappa_new, center_x_spp_new, center_y_spp_new = self.model.stretch2sis_mst(
            tangential_stretch, radial_stretch, curvature, direction, center_x,
            center_y)
        npt.assert_almost_equal(center_x_spp_new, center_x_spp, decimal=8)
        npt.assert_almost_equal(center_y_spp_new, center_y_spp, decimal=8)
        npt.assert_almost_equal(theta_E_new, theta_E, decimal=8)
        npt.assert_almost_equal(kappa_new, kappa, decimal=8)

        center_x, center_y = 0, -1.5
        tangential_stretch, radial_stretch, r_curvature, direction = self.model.sis_mst2stretch(
            theta_E, kappa, center_x_spp, center_y_spp, center_x, center_y)
        print(tangential_stretch, radial_stretch, r_curvature, direction)
        theta_E_new, kappa_new, center_x_spp_new, center_y_spp_new = self.model.stretch2sis_mst(
            tangential_stretch, radial_stretch, r_curvature, direction,
            center_x, center_y)
        npt.assert_almost_equal(center_x_spp_new, center_x_spp, decimal=8)
        npt.assert_almost_equal(center_y_spp_new, center_y_spp, decimal=8)
        npt.assert_almost_equal(theta_E_new, theta_E, decimal=8)
        npt.assert_almost_equal(kappa_new, kappa, decimal=8)

    def test_function(self):
        center_x, center_y = 0., 0.
        x, y = 1, 1
        radial_stretch = 1
        output = self.model.function(x,
                                     y,
                                     tangential_stretch=2,
                                     radial_stretch=radial_stretch,
                                     curvature=1. / 2,
                                     direction=0,
                                     center_x=center_x,
                                     center_y=center_y)
        theta_E, kappa_ext, center_x_sis, center_y_sis = self.model.stretch2sis_mst(
            tangential_stretch=2,
            radial_stretch=radial_stretch,
            curvature=1. / 2,
            direction=0,
            center_x=center_x,
            center_y=center_y)
        f_sis_out = self.sis.function(
            1, 1, theta_E, center_x_sis, center_y_sis
        )  # - self.sis.function(0, 0, theta_E, center_x_sis, center_y_sis)
        alpha_x, alpha_y = self.sis.derivatives(center_x, center_y, theta_E,
                                                center_x_sis, center_y_sis)
        f_sis_0_out = alpha_x * (x - center_x) + alpha_y * (y - center_y)

        f_mst_out = self.mst.function(x,
                                      y,
                                      kappa_ext,
                                      ra_0=center_x,
                                      dec_0=center_y)
        lambda_mst = 1. / radial_stretch
        f_out = lambda_mst * (f_sis_out - f_sis_0_out) + f_mst_out
        npt.assert_almost_equal(output, f_out, decimal=8)

    def test_derivatives(self):
        tangential_stretch = 5
        radial_stretch = 1
        curvature = 1. / 10
        direction = 0.3
        center_x = 0
        center_y = 0
        x, y = 1, 1
        theta_E, kappa, center_x_spp, center_y_spp = self.model.stretch2sis_mst(
            tangential_stretch, radial_stretch, curvature, direction, center_x,
            center_y)
        f_x_sis, f_y_sis = self.sis.derivatives(x, y, theta_E, center_x_spp,
                                                center_y_spp)
        f_x_mst, f_y_mst = self.mst.derivatives(x,
                                                y,
                                                kappa,
                                                ra_0=center_x,
                                                dec_0=center_y)
        f_x0, f_y0 = self.sis.derivatives(center_x, center_y, theta_E,
                                          center_x_spp, center_y_spp)
        f_x_new, f_y_new = self.model.derivatives(x, y, tangential_stretch,
                                                  radial_stretch, curvature,
                                                  direction, center_x,
                                                  center_y)
        npt.assert_almost_equal(f_x_new, f_x_sis + f_x_mst - f_x0, decimal=8)
        npt.assert_almost_equal(f_y_new, f_y_sis + f_y_mst - f_y0, decimal=8)

    def test_hessian(self):
        lens = LensModel(lens_model_list=['CURVED_ARC_SIS_MST'])
        center_x, center_y = 0, 0
        tangential_stretch = 10
        radial_stretch = 1
        kwargs_lens = [{
            'tangential_stretch': tangential_stretch,
            'radial_stretch': radial_stretch,
            'curvature': 1. / 10.5,
            'direction': 0.,
            'center_x': center_x,
            'center_y': center_y
        }]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag,
                                tangential_stretch * radial_stretch,
                                decimal=8)

        center_x, center_y = 2, 3
        tangential_stretch = 10
        radial_stretch = 1
        kwargs_lens = [{
            'tangential_stretch': tangential_stretch,
            'radial_stretch': radial_stretch,
            'curvature': 1. / 10.5,
            'direction': 0.,
            'center_x': center_x,
            'center_y': center_y
        }]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag,
                                tangential_stretch * radial_stretch,
                                decimal=8)

        center_x, center_y = 0, 0
        tangential_stretch = 5
        radial_stretch = 1.2
        kwargs_lens = [{
            'tangential_stretch': tangential_stretch,
            'radial_stretch': radial_stretch,
            'curvature': 1. / 10.5,
            'direction': 0.,
            'center_x': center_x,
            'center_y': center_y
        }]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag,
                                tangential_stretch * radial_stretch,
                                decimal=8)

        center_x, center_y = 0, 0
        tangential_stretch = 3
        radial_stretch = -1
        kwargs_lens = [{
            'tangential_stretch': tangential_stretch,
            'radial_stretch': radial_stretch,
            'curvature': 1. / 10.5,
            'direction': 0.,
            'center_x': center_x,
            'center_y': center_y
        }]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        print(tangential_stretch, radial_stretch, 'stretches')
        npt.assert_almost_equal(mag,
                                tangential_stretch * radial_stretch,
                                decimal=8)

        center_x, center_y = 0, 0
        tangential_stretch = -3
        radial_stretch = -1
        kwargs_lens = [{
            'tangential_stretch': tangential_stretch,
            'radial_stretch': radial_stretch,
            'curvature': 1. / 10.5,
            'direction': 0.,
            'center_x': center_x,
            'center_y': center_y
        }]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag,
                                tangential_stretch * radial_stretch,
                                decimal=8)

        center_x, center_y = 0, 0
        tangential_stretch = 10.4
        radial_stretch = 0.6
        kwargs_lens = [{
            'tangential_stretch': tangential_stretch,
            'radial_stretch': radial_stretch,
            'curvature': 1. / 10.5,
            'direction': 0.,
            'center_x': center_x,
            'center_y': center_y
        }]
        mag = lens.magnification(center_x, center_y, kwargs=kwargs_lens)
        npt.assert_almost_equal(mag,
                                tangential_stretch * radial_stretch,
                                decimal=8)
class CurvedArcSISMST(LensProfileBase):
    """
    lens model that describes a section of a highly magnified deflector region.
    The parameterization is chosen to describe local observables efficient.

    Observables are:
    - curvature radius (basically bending relative to the center of the profile)
    - radial stretch (plus sign) thickness of arc with parity (more generalized than the power-law slope)
    - tangential stretch (plus sign). Infinity means at critical curve
    - direction of curvature
    - position of arc

    Requirements:
    - Should work with other perturbative models without breaking its meaning (say when adding additional shear terms)
    - Must best reflect the observables in lensing
    - minimal covariances between the parameters, intuitive parameterization.

    """
    param_names = [
        'tangential_stretch', 'radial_stretch', 'curvature', 'direction',
        'center_x', 'center_y'
    ]
    lower_limit_default = {
        'tangential_stretch': -100,
        'radial_stretch': -5,
        'curvature': 0.000001,
        'direction': -np.pi,
        'center_x': -100,
        'center_y': -100
    }
    upper_limit_default = {
        'tangential_stretch': 100,
        'radial_stretch': 5,
        'curvature': 100,
        'direction': np.pi,
        'center_x': 100,
        'center_y': 100
    }

    def __init__(self):
        self._sis = SIS()
        self._mst = Convergence()
        super(CurvedArcSISMST, self).__init__()

    @staticmethod
    def stretch2sis_mst(tangential_stretch, radial_stretch, curvature,
                        direction, center_x, center_y):
        """

        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return: parameters in terms of a spherical SIS + MST resulting in the same observables
        """
        center_x_sis, center_y_sis = center_deflector(curvature, direction,
                                                      center_x, center_y)
        r_curvature = 1. / curvature
        lambda_mst = 1. / radial_stretch
        kappa_ext = 1 - lambda_mst
        theta_E = r_curvature * (1. - radial_stretch / tangential_stretch)
        return theta_E, kappa_ext, center_x_sis, center_y_sis

    @staticmethod
    def sis_mst2stretch(theta_E, kappa_ext, center_x_sis, center_y_sis,
                        center_x, center_y):
        """
        turn Singular power-law lens model into stretch parameterization at position (center_x, center_y)
        This is the inverse function of stretch2spp()

        :param theta_E: Einstein radius of SIS profile
        :param kappa_ext: external convergence (MST factor 1 - kappa_ext)
        :param center_x_sis: center of SPP model
        :param center_y_sis: center of SPP model
        :param center_x: center of curved model definition
        :param center_y: center of curved model definition
        :return: tangential_stretch, radial_stretch, curvature, direction
        :return:
        """
        r_curvature = np.sqrt((center_x_sis - center_x)**2 +
                              (center_y_sis - center_y)**2)
        direction = np.arctan2(center_y - center_y_sis,
                               center_x - center_x_sis)
        radial_stretch = 1. / (1 - kappa_ext)
        tangential_stretch = 1 / (1 - (theta_E / r_curvature)) * radial_stretch
        curvature = 1. / r_curvature
        return tangential_stretch, radial_stretch, curvature, direction

    def function(self, x, y, tangential_stretch, radial_stretch, curvature,
                 direction, center_x, center_y):
        """
        ATTENTION: there may not be a global lensing potential!

        :param x:
        :param y:
        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return:
        """
        lambda_mst = 1. / radial_stretch
        theta_E, kappa_ext, center_x_sis, center_y_sis = self.stretch2sis_mst(
            tangential_stretch, radial_stretch, curvature, direction, center_x,
            center_y)
        f_sis = self._sis.function(
            x, y, theta_E, center_x_sis, center_y_sis
        )  # - self._sis.function(center_x, center_y, theta_E, center_x_sis, center_y_sis)
        alpha_x, alpha_y = self._sis.derivatives(center_x, center_y, theta_E,
                                                 center_x_sis, center_y_sis)
        f_sis_0 = alpha_x * (x - center_x) + alpha_y * (y - center_y)
        f_mst = self._mst.function(x,
                                   y,
                                   kappa_ext,
                                   ra_0=center_x,
                                   dec_0=center_y)
        return lambda_mst * (f_sis - f_sis_0) + f_mst

    def derivatives(self, x, y, tangential_stretch, radial_stretch, curvature,
                    direction, center_x, center_y):
        """

        :param x:
        :param y:
        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return:
        """
        lambda_mst = 1. / radial_stretch
        theta_E, kappa_ext, center_x_sis, center_y_sis = self.stretch2sis_mst(
            tangential_stretch, radial_stretch, curvature, direction, center_x,
            center_y)
        f_x_sis, f_y_sis = self._sis.derivatives(x, y, theta_E, center_x_sis,
                                                 center_y_sis)
        f_x0, f_y0 = self._sis.derivatives(center_x, center_y, theta_E,
                                           center_x_sis, center_y_sis)
        f_x_mst, f_y_mst = self._mst.derivatives(x,
                                                 y,
                                                 kappa_ext,
                                                 ra_0=center_x,
                                                 dec_0=center_y)
        f_x = lambda_mst * (f_x_sis - f_x0) + f_x_mst
        f_y = lambda_mst * (f_y_sis - f_y0) + f_y_mst
        return f_x, f_y

    def hessian(self, x, y, tangential_stretch, radial_stretch, curvature,
                direction, center_x, center_y):
        """

        :param x:
        :param y:
        :param tangential_stretch: float, stretch of intrinsic source in tangential direction
        :param radial_stretch: float, stretch of intrinsic source in radial direction
        :param curvature: 1/curvature radius
        :param direction: float, angle in radian
        :param center_x: center of source in image plane
        :param center_y: center of source in image plane
        :return:
        """
        lambda_mst = 1. / radial_stretch
        theta_E, kappa_ext, center_x_sis, center_y_sis = self.stretch2sis_mst(
            tangential_stretch, radial_stretch, curvature, direction, center_x,
            center_y)
        f_xx_sis, f_yy_sis, f_xy_sis = self._sis.hessian(
            x, y, theta_E, center_x_sis, center_y_sis)
        f_xx_mst, f_yy_mst, f_xy_mst = self._mst.hessian(x,
                                                         y,
                                                         kappa_ext,
                                                         ra_0=center_x,
                                                         dec_0=center_y)
        return lambda_mst * f_xx_sis + f_xx_mst, lambda_mst * f_yy_sis + f_yy_mst, lambda_mst * f_xy_sis + f_xy_mst
 def __init__(self):
     self._sis = SIS()
     self._mst = Convergence()
     super(CurvedArcSISMST, self).__init__()
 def setup(self):
     self.model = CurvedArcTanDiff()
     self.sie = SIE()
     self.mst = Convergence()
Example #15
0
 def setup(self):
     self.profile = Convergence()
     self.kwargs_lens = {'kappa_ext': 0.1}
 def setup(self):
     self.model = CurvedArcSISMST()
     self.sis = SIS()
     self.mst = Convergence()
Example #17
0
 def __init__(self):
     self._mst = Convergence()
     self._curve = CurvedArcConst()
     super(CurvedArcConstMST, self).__init__()
Example #18
0
    def _import_class(lens_type,
                      custom_class,
                      kwargs_interp,
                      z_lens=None,
                      z_source=None):
        """

        :param lens_type: string, lens model type
        :param custom_class: custom class
        :param z_lens: lens redshift  # currently only used in NFW_MC model as this is redshift dependent
        :param z_source: source redshift  # currently only used in NFW_MC model as this is redshift dependent
        :param kwargs_interp: interpolation keyword arguments specifying the numerics.
         See description in the Interpolate() class. Only applicable for 'INTERPOL' and 'INTERPOL_SCALED' models.
        :return: class instance of the lens model type
        """

        if lens_type == 'SHIFT':
            from lenstronomy.LensModel.Profiles.constant_shift import Shift
            return Shift()
        elif lens_type == 'NIE_POTENTIAL':
            from lenstronomy.LensModel.Profiles.nie_potential import NIE_POTENTIAL
            return NIE_POTENTIAL()
        elif lens_type == 'CONST_MAG':
            from lenstronomy.LensModel.Profiles.const_mag import ConstMag
            return ConstMag()
        elif lens_type == 'SHEAR':
            from lenstronomy.LensModel.Profiles.shear import Shear
            return Shear()
        elif lens_type == 'SHEAR_GAMMA_PSI':
            from lenstronomy.LensModel.Profiles.shear import ShearGammaPsi
            return ShearGammaPsi()
        elif lens_type == 'SHEAR_REDUCED':
            from lenstronomy.LensModel.Profiles.shear import ShearReduced
            return ShearReduced()
        elif lens_type == 'CONVERGENCE':
            from lenstronomy.LensModel.Profiles.convergence import Convergence
            return Convergence()
        elif lens_type == 'HESSIAN':
            from lenstronomy.LensModel.Profiles.hessian import Hessian
            return Hessian()
        elif lens_type == 'FLEXION':
            from lenstronomy.LensModel.Profiles.flexion import Flexion
            return Flexion()
        elif lens_type == 'FLEXIONFG':
            from lenstronomy.LensModel.Profiles.flexionfg import Flexionfg
            return Flexionfg()
        elif lens_type == 'POINT_MASS':
            from lenstronomy.LensModel.Profiles.point_mass import PointMass
            return PointMass()
        elif lens_type == 'SIS':
            from lenstronomy.LensModel.Profiles.sis import SIS
            return SIS()
        elif lens_type == 'SIS_TRUNCATED':
            from lenstronomy.LensModel.Profiles.sis_truncate import SIS_truncate
            return SIS_truncate()
        elif lens_type == 'SIE':
            from lenstronomy.LensModel.Profiles.sie import SIE
            return SIE()
        elif lens_type == 'SPP':
            from lenstronomy.LensModel.Profiles.spp import SPP
            return SPP()
        elif lens_type == 'NIE':
            from lenstronomy.LensModel.Profiles.nie import NIE
            return NIE()
        elif lens_type == 'NIE_SIMPLE':
            from lenstronomy.LensModel.Profiles.nie import NIEMajorAxis
            return NIEMajorAxis()
        elif lens_type == 'CHAMELEON':
            from lenstronomy.LensModel.Profiles.chameleon import Chameleon
            return Chameleon()
        elif lens_type == 'DOUBLE_CHAMELEON':
            from lenstronomy.LensModel.Profiles.chameleon import DoubleChameleon
            return DoubleChameleon()
        elif lens_type == 'TRIPLE_CHAMELEON':
            from lenstronomy.LensModel.Profiles.chameleon import TripleChameleon
            return TripleChameleon()
        elif lens_type == 'SPEP':
            from lenstronomy.LensModel.Profiles.spep import SPEP
            return SPEP()
        elif lens_type == 'PEMD':
            from lenstronomy.LensModel.Profiles.pemd import PEMD
            return PEMD()
        elif lens_type == 'SPEMD':
            from lenstronomy.LensModel.Profiles.spemd import SPEMD
            return SPEMD()
        elif lens_type == 'EPL':
            from lenstronomy.LensModel.Profiles.epl import EPL
            return EPL()
        elif lens_type == 'EPL_NUMBA':
            from lenstronomy.LensModel.Profiles.epl_numba import EPL_numba
            return EPL_numba()
        elif lens_type == 'SPL_CORE':
            from lenstronomy.LensModel.Profiles.splcore import SPLCORE
            return SPLCORE()
        elif lens_type == 'NFW':
            from lenstronomy.LensModel.Profiles.nfw import NFW
            return NFW()
        elif lens_type == 'NFW_ELLIPSE':
            from lenstronomy.LensModel.Profiles.nfw_ellipse import NFW_ELLIPSE
            return NFW_ELLIPSE()
        elif lens_type == 'NFW_ELLIPSE_GAUSS_DEC':
            from lenstronomy.LensModel.Profiles.gauss_decomposition import NFWEllipseGaussDec
            return NFWEllipseGaussDec()
        elif lens_type == 'NFW_ELLIPSE_CSE':
            from lenstronomy.LensModel.Profiles.nfw_ellipse_cse import NFW_ELLIPSE_CSE
            return NFW_ELLIPSE_CSE()
        elif lens_type == 'TNFW':
            from lenstronomy.LensModel.Profiles.tnfw import TNFW
            return TNFW()
        elif lens_type == 'TNFW_ELLIPSE':
            from lenstronomy.LensModel.Profiles.tnfw_ellipse import TNFW_ELLIPSE
            return TNFW_ELLIPSE()
        elif lens_type == 'CNFW':
            from lenstronomy.LensModel.Profiles.cnfw import CNFW
            return CNFW()
        elif lens_type == 'CNFW_ELLIPSE':
            from lenstronomy.LensModel.Profiles.cnfw_ellipse import CNFW_ELLIPSE
            return CNFW_ELLIPSE()
        elif lens_type == 'CTNFW_GAUSS_DEC':
            from lenstronomy.LensModel.Profiles.gauss_decomposition import CTNFWGaussDec
            return CTNFWGaussDec()
        elif lens_type == 'NFW_MC':
            from lenstronomy.LensModel.Profiles.nfw_mass_concentration import NFWMC
            return NFWMC(z_lens=z_lens, z_source=z_source)
        elif lens_type == 'SERSIC':
            from lenstronomy.LensModel.Profiles.sersic import Sersic
            return Sersic()
        elif lens_type == 'SERSIC_ELLIPSE_POTENTIAL':
            from lenstronomy.LensModel.Profiles.sersic_ellipse_potential import SersicEllipse
            return SersicEllipse()
        elif lens_type == 'SERSIC_ELLIPSE_KAPPA':
            from lenstronomy.LensModel.Profiles.sersic_ellipse_kappa import SersicEllipseKappa
            return SersicEllipseKappa()
        elif lens_type == 'SERSIC_ELLIPSE_GAUSS_DEC':
            from lenstronomy.LensModel.Profiles.gauss_decomposition import SersicEllipseGaussDec
            return SersicEllipseGaussDec()
        elif lens_type == 'PJAFFE':
            from lenstronomy.LensModel.Profiles.p_jaffe import PJaffe
            return PJaffe()
        elif lens_type == 'PJAFFE_ELLIPSE':
            from lenstronomy.LensModel.Profiles.p_jaffe_ellipse import PJaffe_Ellipse
            return PJaffe_Ellipse()
        elif lens_type == 'HERNQUIST':
            from lenstronomy.LensModel.Profiles.hernquist import Hernquist
            return Hernquist()
        elif lens_type == 'HERNQUIST_ELLIPSE':
            from lenstronomy.LensModel.Profiles.hernquist_ellipse import Hernquist_Ellipse
            return Hernquist_Ellipse()
        elif lens_type == 'HERNQUIST_ELLIPSE_CSE':
            from lenstronomy.LensModel.Profiles.hernquist_ellipse_cse import HernquistEllipseCSE
            return HernquistEllipseCSE()
        elif lens_type == 'GAUSSIAN':
            from lenstronomy.LensModel.Profiles.gaussian_potential import Gaussian
            return Gaussian()
        elif lens_type == 'GAUSSIAN_KAPPA':
            from lenstronomy.LensModel.Profiles.gaussian_kappa import GaussianKappa
            return GaussianKappa()
        elif lens_type == 'GAUSSIAN_ELLIPSE_KAPPA':
            from lenstronomy.LensModel.Profiles.gaussian_ellipse_kappa import GaussianEllipseKappa
            return GaussianEllipseKappa()
        elif lens_type == 'GAUSSIAN_ELLIPSE_POTENTIAL':
            from lenstronomy.LensModel.Profiles.gaussian_ellipse_potential import GaussianEllipsePotential
            return GaussianEllipsePotential()
        elif lens_type == 'MULTI_GAUSSIAN_KAPPA':
            from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappa
            return MultiGaussianKappa()
        elif lens_type == 'MULTI_GAUSSIAN_KAPPA_ELLIPSE':
            from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappaEllipse
            return MultiGaussianKappaEllipse()
        elif lens_type == 'INTERPOL':
            from lenstronomy.LensModel.Profiles.interpol import Interpol
            return Interpol(**kwargs_interp)
        elif lens_type == 'INTERPOL_SCALED':
            from lenstronomy.LensModel.Profiles.interpol import InterpolScaled
            return InterpolScaled(**kwargs_interp)
        elif lens_type == 'SHAPELETS_POLAR':
            from lenstronomy.LensModel.Profiles.shapelet_pot_polar import PolarShapelets
            return PolarShapelets()
        elif lens_type == 'SHAPELETS_CART':
            from lenstronomy.LensModel.Profiles.shapelet_pot_cartesian import CartShapelets
            return CartShapelets()
        elif lens_type == 'DIPOLE':
            from lenstronomy.LensModel.Profiles.dipole import Dipole
            return Dipole()
        elif lens_type == 'CURVED_ARC_CONST':
            from lenstronomy.LensModel.Profiles.curved_arc_const import CurvedArcConst
            return CurvedArcConst()
        elif lens_type == 'CURVED_ARC_CONST_MST':
            from lenstronomy.LensModel.Profiles.curved_arc_const import CurvedArcConstMST
            return CurvedArcConstMST()
        elif lens_type == 'CURVED_ARC_SPP':
            from lenstronomy.LensModel.Profiles.curved_arc_spp import CurvedArcSPP
            return CurvedArcSPP()
        elif lens_type == 'CURVED_ARC_SIS_MST':
            from lenstronomy.LensModel.Profiles.curved_arc_sis_mst import CurvedArcSISMST
            return CurvedArcSISMST()
        elif lens_type == 'CURVED_ARC_SPT':
            from lenstronomy.LensModel.Profiles.curved_arc_spt import CurvedArcSPT
            return CurvedArcSPT()
        elif lens_type == 'CURVED_ARC_TAN_DIFF':
            from lenstronomy.LensModel.Profiles.curved_arc_tan_diff import CurvedArcTanDiff
            return CurvedArcTanDiff()
        elif lens_type == 'ARC_PERT':
            from lenstronomy.LensModel.Profiles.arc_perturbations import ArcPerturbations
            return ArcPerturbations()
        elif lens_type == 'coreBURKERT':
            from lenstronomy.LensModel.Profiles.coreBurkert import CoreBurkert
            return CoreBurkert()
        elif lens_type == 'CORED_DENSITY':
            from lenstronomy.LensModel.Profiles.cored_density import CoredDensity
            return CoredDensity()
        elif lens_type == 'CORED_DENSITY_2':
            from lenstronomy.LensModel.Profiles.cored_density_2 import CoredDensity2
            return CoredDensity2()
        elif lens_type == 'CORED_DENSITY_EXP':
            from lenstronomy.LensModel.Profiles.cored_density_exp import CoredDensityExp
            return CoredDensityExp()
        elif lens_type == 'CORED_DENSITY_MST':
            from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST
            return CoredDensityMST(profile_type='CORED_DENSITY')
        elif lens_type == 'CORED_DENSITY_2_MST':
            from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST
            return CoredDensityMST(profile_type='CORED_DENSITY_2')
        elif lens_type == 'CORED_DENSITY_EXP_MST':
            from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST
            return CoredDensityMST(profile_type='CORED_DENSITY_EXP')
        elif lens_type == 'NumericalAlpha':
            from lenstronomy.LensModel.Profiles.numerical_deflections import NumericalAlpha
            return NumericalAlpha(custom_class)
        elif lens_type == 'MULTIPOLE':
            from lenstronomy.LensModel.Profiles.multipole import Multipole
            return Multipole()
        elif lens_type == 'CSE':
            from lenstronomy.LensModel.Profiles.cored_steep_ellipsoid import CSE
            return CSE()
        elif lens_type == 'ElliSLICE':
            from lenstronomy.LensModel.Profiles.elliptical_density_slice import ElliSLICE
            return ElliSLICE()
        elif lens_type == 'ULDM':
            from lenstronomy.LensModel.Profiles.uldm import Uldm
            return Uldm()
        elif lens_type == 'CORED_DENSITY_ULDM_MST':
            from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST
            return CoredDensityMST(profile_type='CORED_DENSITY_ULDM')
        else:
            raise ValueError(
                '%s is not a valid lens model. Supported are: %s.' %
                (lens_type, _SUPPORTED_MODELS))
    def _import_class(lens_type, custom_class, z_lens=None, z_source=None):
        """

        :param lens_type: string, lens model type
        :param custom_class: custom class
        :param z_lens: lens redshift  # currently only used in NFW_MC model as this is redshift dependent
        :param z_source: source redshift  # currently only used in NFW_MC model as this is redshift dependent
        :return: class instance of the lens model type
        """

        if lens_type == 'SHIFT':
            from lenstronomy.LensModel.Profiles.alpha_shift import Shift
            return Shift()
        elif lens_type == 'SHEAR':
            from lenstronomy.LensModel.Profiles.shear import Shear
            return Shear()
        elif lens_type == 'SHEAR_GAMMA_PSI':
            from lenstronomy.LensModel.Profiles.shear import ShearGammaPsi
            return ShearGammaPsi()
        elif lens_type == 'CONVERGENCE':
            from lenstronomy.LensModel.Profiles.convergence import Convergence
            return Convergence()
        elif lens_type == 'FLEXION':
            from lenstronomy.LensModel.Profiles.flexion import Flexion
            return Flexion()
        elif lens_type == 'FLEXIONFG':
            from lenstronomy.LensModel.Profiles.flexionfg import Flexionfg
            return Flexionfg()
        elif lens_type == 'POINT_MASS':
            from lenstronomy.LensModel.Profiles.point_mass import PointMass
            return PointMass()
        elif lens_type == 'SIS':
            from lenstronomy.LensModel.Profiles.sis import SIS
            return SIS()
        elif lens_type == 'SIS_TRUNCATED':
            from lenstronomy.LensModel.Profiles.sis_truncate import SIS_truncate
            return SIS_truncate()
        elif lens_type == 'SIE':
            from lenstronomy.LensModel.Profiles.sie import SIE
            return SIE()
        elif lens_type == 'SPP':
            from lenstronomy.LensModel.Profiles.spp import SPP
            return SPP()
        elif lens_type == 'NIE':
            from lenstronomy.LensModel.Profiles.nie import NIE
            return NIE()
        elif lens_type == 'NIE_SIMPLE':
            from lenstronomy.LensModel.Profiles.nie import NIEMajorAxis
            return NIEMajorAxis()
        elif lens_type == 'CHAMELEON':
            from lenstronomy.LensModel.Profiles.chameleon import Chameleon
            return Chameleon()
        elif lens_type == 'DOUBLE_CHAMELEON':
            from lenstronomy.LensModel.Profiles.chameleon import DoubleChameleon
            return DoubleChameleon()
        elif lens_type == 'TRIPLE_CHAMELEON':
            from lenstronomy.LensModel.Profiles.chameleon import TripleChameleon
            return TripleChameleon()
        elif lens_type == 'SPEP':
            from lenstronomy.LensModel.Profiles.spep import SPEP
            return SPEP()
        elif lens_type == 'SPEMD':
            from lenstronomy.LensModel.Profiles.spemd import SPEMD
            return SPEMD()
        elif lens_type == 'SPEMD_SMOOTH':
            from lenstronomy.LensModel.Profiles.spemd_smooth import SPEMD_SMOOTH
            return SPEMD_SMOOTH()
        elif lens_type == 'NFW':
            from lenstronomy.LensModel.Profiles.nfw import NFW
            return NFW()
        elif lens_type == 'NFW_ELLIPSE':
            from lenstronomy.LensModel.Profiles.nfw_ellipse import NFW_ELLIPSE
            return NFW_ELLIPSE()
        elif lens_type == 'NFW_ELLIPSE_GAUSS_DEC':
            from lenstronomy.LensModel.Profiles.gauss_decomposition import NFWEllipseGaussDec
            return NFWEllipseGaussDec()
        elif lens_type == 'TNFW':
            from lenstronomy.LensModel.Profiles.tnfw import TNFW
            return TNFW()
        elif lens_type == 'CNFW':
            from lenstronomy.LensModel.Profiles.cnfw import CNFW
            return CNFW()
        elif lens_type == 'CNFW_ELLIPSE':
            from lenstronomy.LensModel.Profiles.cnfw_ellipse import CNFW_ELLIPSE
            return CNFW_ELLIPSE()
        elif lens_type == 'CTNFW_GAUSS_DEC':
            from lenstronomy.LensModel.Profiles.gauss_decomposition import CTNFWGaussDec
            return CTNFWGaussDec()
        elif lens_type == 'NFW_MC':
            from lenstronomy.LensModel.Profiles.nfw_mass_concentration import NFWMC
            return NFWMC(z_lens=z_lens, z_source=z_source)
        elif lens_type == 'SERSIC':
            from lenstronomy.LensModel.Profiles.sersic import Sersic
            return Sersic()
        elif lens_type == 'SERSIC_ELLIPSE_POTENTIAL':
            from lenstronomy.LensModel.Profiles.sersic_ellipse_potential import SersicEllipse
            return SersicEllipse()
        elif lens_type == 'SERSIC_ELLIPSE_KAPPA':
            from lenstronomy.LensModel.Profiles.sersic_ellipse_kappa import SersicEllipseKappa
            return SersicEllipseKappa()
        elif lens_type == 'SERSIC_ELLIPSE_GAUSS_DEC':
            from lenstronomy.LensModel.Profiles.gauss_decomposition \
                import SersicEllipseGaussDec
            return SersicEllipseGaussDec()
        elif lens_type == 'PJAFFE':
            from lenstronomy.LensModel.Profiles.p_jaffe import PJaffe
            return PJaffe()
        elif lens_type == 'PJAFFE_ELLIPSE':
            from lenstronomy.LensModel.Profiles.p_jaffe_ellipse import PJaffe_Ellipse
            return PJaffe_Ellipse()
        elif lens_type == 'HERNQUIST':
            from lenstronomy.LensModel.Profiles.hernquist import Hernquist
            return Hernquist()
        elif lens_type == 'HERNQUIST_ELLIPSE':
            from lenstronomy.LensModel.Profiles.hernquist_ellipse import Hernquist_Ellipse
            return Hernquist_Ellipse()
        elif lens_type == 'GAUSSIAN':
            from lenstronomy.LensModel.Profiles.gaussian_potential import Gaussian
            return Gaussian()
        elif lens_type == 'GAUSSIAN_KAPPA':
            from lenstronomy.LensModel.Profiles.gaussian_kappa import GaussianKappa
            return GaussianKappa()
        elif lens_type == 'GAUSSIAN_ELLIPSE_KAPPA':
            from lenstronomy.LensModel.Profiles.gaussian_ellipse_kappa import GaussianEllipseKappa
            return GaussianEllipseKappa()
        elif lens_type == 'GAUSSIAN_ELLIPSE_POTENTIAL':
            from lenstronomy.LensModel.Profiles.gaussian_ellipse_potential import GaussianEllipsePotential
            return GaussianEllipsePotential()
        elif lens_type == 'MULTI_GAUSSIAN_KAPPA':
            from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappa
            return MultiGaussianKappa()
        elif lens_type == 'MULTI_GAUSSIAN_KAPPA_ELLIPSE':
            from lenstronomy.LensModel.Profiles.multi_gaussian_kappa import MultiGaussianKappaEllipse
            return MultiGaussianKappaEllipse()
        elif lens_type == 'INTERPOL':
            from lenstronomy.LensModel.Profiles.interpol import Interpol
            return Interpol()
        elif lens_type == 'INTERPOL_SCALED':
            from lenstronomy.LensModel.Profiles.interpol import InterpolScaled
            return InterpolScaled()
        elif lens_type == 'SHAPELETS_POLAR':
            from lenstronomy.LensModel.Profiles.shapelet_pot_polar import PolarShapelets
            return PolarShapelets()
        elif lens_type == 'SHAPELETS_CART':
            from lenstronomy.LensModel.Profiles.shapelet_pot_cartesian import CartShapelets
            return CartShapelets()
        elif lens_type == 'DIPOLE':
            from lenstronomy.LensModel.Profiles.dipole import Dipole
            return Dipole()
        elif lens_type == 'CURVED_ARC':
            from lenstronomy.LensModel.Profiles.curved_arc import CurvedArc
            return CurvedArc()
        elif lens_type == 'ARC_PERT':
            from lenstronomy.LensModel.Profiles.arc_perturbations import ArcPerturbations
            return ArcPerturbations()
        elif lens_type == 'coreBURKERT':
            from lenstronomy.LensModel.Profiles.coreBurkert import CoreBurkert
            return CoreBurkert()
        elif lens_type == 'CORED_DENSITY':
            from lenstronomy.LensModel.Profiles.cored_density import CoredDensity
            return CoredDensity()
        elif lens_type == 'CORED_DENSITY_2':
            from lenstronomy.LensModel.Profiles.cored_density_2 import CoredDensity2
            return CoredDensity2()
        elif lens_type == 'CORED_DENSITY_MST':
            from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST
            return CoredDensityMST(profile_type='CORED_DENSITY')
        elif lens_type == 'CORED_DENSITY_2_MST':
            from lenstronomy.LensModel.Profiles.cored_density_mst import CoredDensityMST
            return CoredDensityMST(profile_type='CORED_DENSITY_2')
        elif lens_type == 'NumericalAlpha':
            from lenstronomy.LensModel.Profiles.numerical_deflections import NumericalAlpha
            return NumericalAlpha(custom_class)
        else:
            raise ValueError('%s is not a valid lens model' % lens_type)
Example #20
0
class ShearReduced(LensProfileBase):
    """
    reduced shear distortions :math:`\\gamma' = \\gamma / (1-\\kappa)`.
    This distortion keeps the magnification as unity and, thus, does not change the size of apparent objects.
    To keep the magnification at unity, it requires

    .. math::
        (1-\\kappa)^2 - \\gamma_1^2 - \\gamma_2^ = 1

    Thus, for given pair of reduced shear :math:`(\\gamma'_1, \\gamma'_2)`, an additional convergence term is calculated
    and added to the lensing distortions.
    """
    param_names = ['gamma1', 'gamma2', 'ra_0', 'dec_0']
    lower_limit_default = {
        'gamma1': -0.5,
        'gamma2': -0.5,
        'ra_0': -100,
        'dec_0': -100
    }
    upper_limit_default = {
        'gamma1': 0.5,
        'gamma2': 0.5,
        'ra_0': 100,
        'dec_0': 100
    }

    def __init__(self):
        self._shear = Shear()
        self._convergence = Convergence()
        super(ShearReduced, self).__init__()

    @staticmethod
    def _kappa_reduced(gamma1, gamma2):
        """
        compute convergence such that magnification is unity

        :param gamma1: reduced shear
        :param gamma2: reduced shear
        :return: kappa
        """
        kappa = 1 - 1. / np.sqrt(1 - gamma1**2 - gamma2**2)
        gamma1_ = (1 - kappa) * gamma1
        gamma2_ = (1 - kappa) * gamma2
        return kappa, gamma1_, gamma2_

    def function(self, x, y, gamma1, gamma2, ra_0=0, dec_0=0):
        """

        :param x: x-coordinate (angle)
        :param y: y0-coordinate (angle)
        :param gamma1: shear component
        :param gamma2: shear component
        :param ra_0: x/ra position where shear deflection is 0
        :param dec_0: y/dec position where shear deflection is 0
        :return: lensing potential
        """
        kappa, gamma1_, gamma2_ = self._kappa_reduced(gamma1, gamma2)
        f_shear = self._shear.function(x, y, gamma1_, gamma2_, ra_0, dec_0)
        f_kappa = self._convergence.function(x, y, kappa, ra_0, dec_0)
        return f_shear + f_kappa

    def derivatives(self, x, y, gamma1, gamma2, ra_0=0, dec_0=0):
        """

        :param x: x-coordinate (angle)
        :param y: y0-coordinate (angle)
        :param gamma1: shear component
        :param gamma2: shear component
        :param ra_0: x/ra position where shear deflection is 0
        :param dec_0: y/dec position where shear deflection is 0
        :return: deflection angles
        """
        kappa, gamma1_, gamma2_ = self._kappa_reduced(gamma1, gamma2)
        f_x_shear, f_y_shear = self._shear.derivatives(x, y, gamma1_, gamma2_,
                                                       ra_0, dec_0)
        f_x_kappa, f_y_kappa = self._convergence.derivatives(
            x, y, kappa, ra_0, dec_0)
        return f_x_shear + f_x_kappa, f_y_shear + f_y_kappa

    def hessian(self, x, y, gamma1, gamma2, ra_0=0, dec_0=0):
        """

        :param x: x-coordinate (angle)
        :param y: y0-coordinate (angle)
        :param gamma1: shear component
        :param gamma2: shear component
        :param ra_0: x/ra position where shear deflection is 0
        :param dec_0: y/dec position where shear deflection is 0
        :return: f_xx, f_xy, f_yx, f_yy
        """
        kappa, gamma1_, gamma2_ = self._kappa_reduced(gamma1, gamma2)
        f_xx_g, f_xy_g, f_yx_g, f_yy_g = self._shear.hessian(
            x, y, gamma1_, gamma2_, ra_0, dec_0)
        f_xx_k, f_xy_k, f_yx_k, f_yy_k = self._convergence.hessian(
            x, y, kappa, ra_0, dec_0)
        f_xx = f_xx_g + f_xx_k
        f_yy = f_yy_g + f_yy_k
        f_xy = f_xy_g + f_xy_k
        return f_xx, f_xy, f_xy, f_yy