Exemple #1
0
 def __init__(self, mass, x, y, r3d, mdef, z, sub_flag, lens_cosmo_instance,
              args, unique_tag):
     """
     See documentation in base class (Halos/halo_base.py)
     """
     self._prof = SPLCORE()
     self._lens_cosmo = lens_cosmo_instance
     super(PowerLawSubhalo,
           self).__init__(mass, x, y, r3d, mdef, z, sub_flag,
                          lens_cosmo_instance, args, unique_tag)
Exemple #2
0
 def setup(self):
     self.gnfw = GNFW()
     self.splcore = SPLCORE()
     self.kwargs_lens = {
         'alpha_Rs': 2.1,
         'Rs': 1.5,
         'gamma_inner': 1.0,
         'gamma_outer': 3.0,
         'center_x': 0.04,
         'center_y': -1.0
     }
Exemple #3
0
class PowerLawSubhalo(Halo):
    """
    The base class for a halo modeled as a power law profile
    """
    def __init__(self, mass, x, y, r3d, mdef, z, sub_flag, lens_cosmo_instance,
                 args, unique_tag):
        """
        See documentation in base class (Halos/halo_base.py)
        """
        self._prof = SPLCORE()
        self._lens_cosmo = lens_cosmo_instance
        super(PowerLawSubhalo,
              self).__init__(mass, x, y, r3d, mdef, z, sub_flag,
                             lens_cosmo_instance, args, unique_tag)

    @property
    def params_physical(self):
        """
        See documentation in base class (Halos/halo_base.py)
        """

        if not hasattr(self, '_params_physical'):
            (concentration, gamma, x_core_halo) = self.profile_args
            rhos, rs, _ = self._lens_cosmo.NFW_params_physical(
                self.mass, concentration, self.z)
            kpc_per_arcsec = self._lens_cosmo.cosmo.kpc_proper_per_asec(self.z)

            if 'x_match' in self._args.keys():
                x_match = self._args['x_match']
            else:
                # r_vmax = 2.16 * rs
                x_match = 2.16

            r_match_arcsec = x_match * rs / kpc_per_arcsec
            fx = np.log(1 + x_match) - x_match / (1 + x_match)
            m = 4 * np.pi * rs**3 * rhos * fx
            r_core_arcsec = x_core_halo * r_match_arcsec / x_match

            sigma_crit_mpc = self._lens_cosmo.get_sigma_crit_lensing(
                self.z, self._lens_cosmo.z_source)
            sigma_crit_arcsec = sigma_crit_mpc * (0.001 * kpc_per_arcsec)**2

            rho0 = m / self._prof.mass_3d(r_match_arcsec, sigma_crit_arcsec,
                                          r_core_arcsec, gamma)
            # units 1 / arcsec

            rho0 *= sigma_crit_arcsec * kpc_per_arcsec**-3
            self._params_physical = {'rho0': rho0, 'r_core': x_core_halo * rs}

        return self._params_physical

    @property
    def lenstronomy_params(self):
        """
        See documentation in base class (Halos/halo_base.py)
        """
        if not hasattr(self, '_lenstronomy_args'):

            (concentration, gamma, x_core_halo) = self.profile_args
            rhos, rs, _ = self._lens_cosmo.NFW_params_physical(
                self.mass, concentration, self.z)
            kpc_per_arcsec = self._lens_cosmo.cosmo.kpc_proper_per_asec(self.z)

            if 'x_match' in self._args.keys():
                x_match = self._args['x_match']
            else:
                # r_vmax = 2.16 * rs
                x_match = 2.16

            r_match_arcsec = x_match * rs / kpc_per_arcsec
            fx = np.log(1 + x_match) - x_match / (1 + x_match)
            m = 4 * np.pi * rs**3 * rhos * fx
            r_core_arcsec = x_core_halo * r_match_arcsec / x_match

            sigma_crit_mpc = self._lens_cosmo.get_sigma_crit_lensing(
                self.z, self._lens_cosmo.z_source)
            sigma_crit_arcsec = sigma_crit_mpc * (0.001 * kpc_per_arcsec)**2

            rho0 = m / self._prof.mass_3d(r_match_arcsec, sigma_crit_arcsec,
                                          r_core_arcsec, gamma)
            sigma0 = rho0 * r_core_arcsec

            self._lenstronomy_args = [{
                'sigma0': sigma0,
                'gamma': gamma,
                'center_x': self.x,
                'center_y': self.y,
                'r_core': r_core_arcsec
            }]

        return self._lenstronomy_args, None

    @property
    def lenstronomy_ID(self):
        """
        See documentation in base class (Halos/halo_base.py)
        """
        return ['SPL_CORE']

    @property
    def profile_args(self):
        """
        See documentation in base class (Halos/halo_base.py)
        """
        if not hasattr(self, '_profile_args'):

            if self._args['evaluate_mc_at_zlens']:
                z_eval = self.z
            else:
                z_eval = self.z_infall

            concentration = self._lens_cosmo.NFW_concentration(
                self.mass, z_eval, self._args['mc_model'],
                self._args['mc_mdef'], self._args['log_mc'],
                self._args['c_scatter'], self._args['c_scatter_dex'],
                self._args['kwargs_suppression'],
                self._args['suppression_model'])

            gamma = self._args['log_slope_halo']
            x_core_halo = self._args['x_core_halo']
            self._profile_args = (concentration, gamma, x_core_halo)

        return self._profile_args
Exemple #4
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 setup(self):

        self.profile = SPLCORE()
class TestSPLCORE(object):
    def setup(self):

        self.profile = SPLCORE()

    def test_no_potential(self):

        npt.assert_raises(Exception, self.profile.function, 0., 0., 0., 0., 0.)

    def test_origin(self):

        x = 0.
        y = 0.
        sigma0 = 1.
        r_core = 0.1
        gamma = 2.4
        alpha_x, alpha_y = self.profile.derivatives(x, y, sigma0, r_core,
                                                    gamma)
        npt.assert_almost_equal(alpha_x, 0.)
        npt.assert_almost_equal(alpha_y, 0.)

        fxx, fyy, fxy = self.profile.hessian(x, y, sigma0, r_core, gamma)
        kappa = self.profile.density_2d(x, y, sigma0 / r_core, r_core, gamma)
        npt.assert_almost_equal(fxx, kappa)
        npt.assert_almost_equal(fyy, kappa)
        npt.assert_almost_equal(fxy, 0.)

        r = 0.01
        xmin = 0.001
        rmin = self.profile._safe_r_division(r, 1., xmin)
        npt.assert_equal(rmin, r)

        r = 1e-9
        rmin = self.profile._safe_r_division(r, 1., xmin)
        npt.assert_equal(rmin, xmin)

        xmin = 1e-2
        r = np.logspace(-3, 0, 100)
        inds = np.where(r < xmin)
        rmin = self.profile._safe_r_division(r, 1., xmin)
        npt.assert_almost_equal(rmin[inds], xmin)

    def test_g_function(self):

        gamma = 2.5
        rc = 0.01
        rho0 = 1.
        R = 5.

        args = (rho0, rc, gamma)
        mass_numerical = quad(self._mass_integrand3d, 0, R, args=args)[0]
        mass_analytic = self.profile.mass_3d(R, rho0, rc, gamma)
        npt.assert_almost_equal(mass_analytic, mass_numerical)

        gamma = 2.
        args = (rho0, rc, gamma)
        mass_numerical = quad(self._mass_integrand3d, 0, R, args=args)[0]
        mass_analytic = self.profile.mass_3d(R, rho0, rc, gamma)
        npt.assert_almost_equal(mass_analytic, mass_numerical)

        gamma = 3.
        args = (rho0, rc, gamma)
        mass_numerical = quad(self._mass_integrand3d, 0, R, args=args)[0]
        mass_analytic = self.profile.mass_3d(R, rho0, rc, gamma)
        npt.assert_almost_equal(mass_analytic, mass_numerical)

        gamma = 1.4
        args = (rho0, rc, gamma)
        mass_numerical = quad(self._mass_integrand3d, 0, R, args=args)[0]
        mass_analytic = self.profile.mass_3d(R, rho0, rc, gamma)
        npt.assert_almost_equal(mass_analytic, mass_numerical)
        sigma0 = rho0 * rc
        mass_analytic_from_sigm0 = self.profile.mass_3d_lens(
            R, sigma0, rc, gamma)
        npt.assert_almost_equal(mass_analytic_from_sigm0, mass_numerical)

    def test_f_function(self):

        gamma = 2.5
        rc = 0.01
        rho0 = 1.
        R = 5.

        args = (rho0, rc, gamma)
        mass_numerical = quad(self._mass_integrand2d, 0, R, args=args)[0]
        mass_analytic = self.profile.mass_2d(R, rho0, rc, gamma)
        npt.assert_almost_equal(mass_analytic, mass_numerical)
        sigma0 = rho0 * rc
        mass_analytic_from_sigm0 = self.profile.mass_2d_lens(
            R, sigma0, rc, gamma)
        npt.assert_almost_equal(mass_analytic_from_sigm0, mass_numerical)

        gamma = 2.
        args = (rho0, rc, gamma)
        mass_numerical = quad(self._mass_integrand2d, 0, R, args=args)[0]
        mass_analytic = self.profile.mass_2d(R, rho0, rc, gamma)
        npt.assert_almost_equal(mass_analytic, mass_numerical)
        sigma0 = rho0 * rc
        mass_analytic_from_sigm0 = self.profile.mass_2d_lens(
            R, sigma0, rc, gamma)
        npt.assert_almost_equal(mass_analytic_from_sigm0, mass_numerical)

        gamma = 3.
        args = (rho0, rc, gamma)
        mass_numerical = quad(self._mass_integrand2d, 0, R, args=args)[0]
        mass_analytic = self.profile.mass_2d(R, rho0, rc, gamma)
        npt.assert_almost_equal(mass_analytic, mass_numerical)
        sigma0 = rho0 * rc
        mass_analytic_from_sigm0 = self.profile.mass_2d_lens(
            R, sigma0, rc, gamma)
        npt.assert_almost_equal(mass_analytic_from_sigm0, mass_numerical)

        gamma = 1.4
        args = (rho0, rc, gamma)
        mass_numerical = quad(self._mass_integrand2d, 0, R, args=args)[0]
        mass_analytic = self.profile.mass_2d(R, rho0, rc, gamma)
        npt.assert_almost_equal(mass_analytic, mass_numerical)
        sigma0 = rho0 * rc
        mass_analytic_from_sigm0 = self.profile.mass_2d_lens(
            R, sigma0, rc, gamma)
        npt.assert_almost_equal(mass_analytic_from_sigm0, mass_numerical)

    def _mass_integrand3d(self, r, rho0, rc, gamma):
        return 4 * np.pi * r**2 * rho0 * rc**gamma / (rc**2 + r**2)**(gamma /
                                                                      2)

    def _mass_integrand2d(self, r, rho0, rc, gamma):
        return 2 * np.pi * r * self.profile.density_2d(r, 0, rho0, rc, gamma)
Exemple #7
0
class TestGNFW(object):
    def setup(self):
        self.gnfw = GNFW()
        self.splcore = SPLCORE()
        self.kwargs_lens = {
            'alpha_Rs': 2.1,
            'Rs': 1.5,
            'gamma_inner': 1.0,
            'gamma_outer': 3.0,
            'center_x': 0.04,
            'center_y': -1.0
        }

    def test_alphaRs(self):

        alpha_rs = self.gnfw.derivatives(self.kwargs_lens['Rs'], 0.0,
                                         self.kwargs_lens['Rs'],
                                         self.kwargs_lens['alpha_Rs'],
                                         self.kwargs_lens['gamma_inner'],
                                         self.kwargs_lens['gamma_outer'])[0]
        npt.assert_almost_equal(alpha_rs, self.kwargs_lens['alpha_Rs'], 8)

    def test_alphaRs_rho0_conversion(self):

        rho0 = self.gnfw.alpha2rho0(self.kwargs_lens['alpha_Rs'],
                                    self.kwargs_lens['Rs'],
                                    self.kwargs_lens['gamma_inner'],
                                    self.kwargs_lens['gamma_outer'])
        alpha_Rs = self.gnfw.rho02alpha(rho0, self.kwargs_lens['Rs'],
                                        self.kwargs_lens['gamma_inner'],
                                        self.kwargs_lens['gamma_outer'])
        npt.assert_almost_equal(alpha_Rs, self.kwargs_lens['alpha_Rs'], 5)

    def test_lensing_quantities(self):

        lensmodel = LensModel(['GNFW'])
        f_x, f_y = self.gnfw.derivatives(1.0, 1.5, **self.kwargs_lens)
        f_x_, f_y_ = lensmodel.alpha(1.0, 1.5, [self.kwargs_lens])
        npt.assert_almost_equal(f_x, f_x_, 5)
        npt.assert_almost_equal(f_y, f_y_, 5)

        f_xx, f_xy, f_yx, f_yy = self.gnfw.hessian(1.0, 1.5,
                                                   **self.kwargs_lens)
        f_xx_, f_xy_, f_yx_, f_yy_ = lensmodel.hessian(1.0, 1.5,
                                                       [self.kwargs_lens])
        npt.assert_almost_equal(f_xx, f_xx_, 5)
        npt.assert_almost_equal(f_yy, f_yy_, 5)
        npt.assert_almost_equal(f_xy, f_xy_, 5)

    def test_mass2d(self):

        rho0 = self.gnfw.alpha2rho0(self.kwargs_lens['alpha_Rs'],
                                    self.kwargs_lens['Rs'],
                                    self.kwargs_lens['gamma_inner'],
                                    self.kwargs_lens['gamma_outer'])
        m2d = self.gnfw.mass_2d(10.0, self.kwargs_lens['Rs'], rho0,
                                self.kwargs_lens['gamma_inner'],
                                self.kwargs_lens['gamma_outer'])
        integrand = lambda x: 2 * 3.14159265 * x * self.gnfw.density_2d(
            x, 0.0, self.kwargs_lens['Rs'], rho0, self.kwargs_lens[
                'gamma_inner'], self.kwargs_lens['gamma_outer'])
        m2d_num = quad(integrand, 0, 10.)[0]
        npt.assert_almost_equal(m2d_num / m2d, 1.0, 5)

    def test_spl_core_match(self):

        rs = 1.5
        kwargs_spl = {'sigma0': 1e13, 'gamma': 3.0, 'r_core': 0.00000001}
        alpha_rs = self.splcore.derivatives(rs, 0.0, **kwargs_spl)[0]
        kwargs_gnfw = {
            'alpha_Rs': alpha_rs,
            'Rs': rs,
            'gamma_inner': 2.99999,
            'gamma_outer': 3.00001
        }
        m3d_gnfw = self.gnfw.mass_3d_lens(5 * rs, **kwargs_gnfw)
        m3d_splcore = self.splcore.mass_3d_lens(5 * rs, **kwargs_spl)
        npt.assert_almost_equal(m3d_gnfw / m3d_splcore, 0.935, 3)