示例#1
0
def delta_sigma_kawai(r,
                      dm_fraction,
                      lambda_dB,
                      halo_mass,
                      halo_redshift,
                      mc_scatter=True):
    """
    Returns standard deviation of the density fluctuations in projection in convergence units
    using Equation 30 in Kawai et al. (2021)
    :param r: the radius at which to evaluate the fluctuation amplitude [units kpc]
    :param f: the fraction of projected mass in dark matter at the radius r
    :param lambda_dB: de Broglie wavelength in kpc
    :param rhos: the density normalization of NFW proifle
    :param rs: the scale radius of NFW profile
    :param concentration:
    :param mc_scatter:
    :return:
    """

    l = LensCosmo()
    c = l.NFW_concentration(halo_mass, halo_redshift, scatter=mc_scatter)
    rhos, rs, _ = l.NFW_params_physical(halo_mass, c, halo_redshift)
    halo_size = effective_halo_size(r, rhos, rs, c)

    relative_length_scale = lambda_dB / halo_size
    prefactor = 16 * np.pi**2 / 3  # extra 4pi from
    # integrating over the exponential
    delta_kappa_square = dm_fraction**2 * prefactor * relative_length_scale
    return delta_kappa_square**0.5
示例#2
0
def solve_from_Mz(M,
                  z,
                  cross_section_type,
                  kwargs_cross_section,
                  z_collapse=10.,
                  include_c_scatter=False,
                  c_scatter_add_dex=0.,
                  **kwargs_solver):
    """
    This routine solves for the SIDM central density given the normalization of an NFW halo rhos, the scale radius rs,
    and a specific interaction cross section
    """
    try:
        from pyHalo.Halos.lens_cosmo import LensCosmo
        from pyHalo.Cosmology.cosmology import Cosmology
        cosmo = Cosmology()
        lens_cosmo = LensCosmo()
    except:
        raise Exception(
            'error importing pyHalo, which is needed to use this routine')

    c = lens_cosmo.NFW_concentration(M, z, scatter=include_c_scatter)
    if include_c_scatter is False and c_scatter_add_dex != 0:
        c = 10**(np.log10(c) + c_scatter_add_dex)

    rhos, rs, _ = lens_cosmo.NFW_params_physical(M, c, z)
    halo_age = cosmo.halo_age(z, z_collapse)
    if halo_age < 0.:
        raise Exception(
            'the halo age is negative, you have probably specified a collapse redshift < halo redshift'
        )

    return solve_from_NFW_params(rhos, rs, halo_age, cross_section_type,
                                 kwargs_cross_section, **kwargs_solver)
示例#3
0
def delta_sigma(m, z, rein, de_Broglie_wavelength):
    """
    Returns the mean ULDM fluctuation ampltiude of the host dark matter halo in units M_sun/kpc^2
    :param m:
    :param z:
    :param rein:
    :param de_Broglie_wavelength:
    :return:
    """
    l = LensCosmo(None, None)
    c = l.NFW_concentration(m, z, scatter=False)
    rhos, rs, _ = l.NFW_params_physical(m, c, z)
    nfw_rho_squared = projected_density_squared(rein, rhos, rs, c)
    delta_sigma = (np.sqrt(np.pi) * nfw_rho_squared *
                   de_Broglie_wavelength)**0.5
    return delta_sigma
示例#4
0
def delta_sigmaNFW(z_lens, m, rein, de_Broglie_wavelength):
    '''
    Returns standard deviation of the density fluctuations in projection normalized by the projected
    density of the host halo

    :param z_lens,z_source: lens and source redshifts
    :param m: main deflector halo mass in M_solar
    :param rein: Einstein radius in kpc
    :param de_Broglie_wavelength: de Broglie wavelength of axion in kpc
    '''

    l = LensCosmo(None, None)
    c = l.NFW_concentration(m, z_lens, scatter=False)
    rhos, rs, _ = l.NFW_params_physical(m, c, z_lens)
    kappa_host = projected_squared_density(rein, rhos, rs, c)**0.5
    ds = delta_sigma(m, z_lens, rein, de_Broglie_wavelength)
    return ds / kappa_host
示例#5
0
class TestLensCosmo(object):

    def setup(self):

        kwargs_cosmo = {'Om0': 0.2}
        self.cosmo = Cosmology(cosmo_kwargs=kwargs_cosmo)
        zlens, zsource = 0.3, 1.7
        self.lens_cosmo = LensCosmo(zlens, zsource, self.cosmo)
        self.h = self.cosmo.h
        self.con = Concentration(self.lens_cosmo)

        self._colossus_nfw = NFWProfile

    def test_const(self):

        D_ds = self.cosmo.D_A(0.3, 1.7)
        D_d = self.cosmo.D_A_z(0.3)
        D_s = self.cosmo.D_A_z(1.7)

        c_Mpc_sec = un.Quantity(c, unit=un.Mpc / un.s)
        G_Mpc3_Msun_sec2 = un.Quantity(G, unit=un.Mpc ** 3 / un.s ** 2 / un.solMass)

        const = c_Mpc_sec ** 2 / (4 * np.pi * G_Mpc3_Msun_sec2)
        sigma_crit_mpc = const.value * D_s / (D_d * D_ds)
        sigma_crit_kpc = sigma_crit_mpc * 1000 ** -2

        npt.assert_almost_equal(self.lens_cosmo.sigma_crit_lensing/sigma_crit_mpc, 1, 4)
        npt.assert_almost_equal(self.lens_cosmo.sigma_crit_lens_kpc/sigma_crit_kpc, 1, 4)

    def test_sigma_crit_mass(self):

        area = 2.
        sigma_crit_mass = self.lens_cosmo.sigma_crit_mass(0.7, area)
        sigma_crit = self.lens_cosmo.get_sigma_crit_lensing(0.7, 1.7)
        npt.assert_almost_equal(sigma_crit_mass, sigma_crit * area)

    def test_colossus(self):

        colossus = self.lens_cosmo.colossus
        npt.assert_almost_equal(colossus.Om0, 0.2)

    def test_truncate_roche(self):

        m = 10**9.
        norm = 1.4
        power = 0.9
        r3d = 1000

        rt = norm * (m / 10 ** 7) ** (1./3) * (r3d / 50) ** power
        rtrunc = self.lens_cosmo.truncation_roche(m, r3d, norm, power)
        npt.assert_almost_equal(rt, rtrunc, 3)

    def test_LOS_trunc(self):

        rt = self.lens_cosmo.LOS_truncation_rN(10**8, 0.2, 90)
        rtrunc = self.lens_cosmo.rN_M_nfw_comoving(10**8 * self.lens_cosmo.cosmo.h, 90, 0.2)
        npt.assert_almost_equal(rt, 1000 * rtrunc * (1+0.2)**-1 / self.lens_cosmo.cosmo.h)

    def test_NFW_concentration(self):

        c = self.lens_cosmo.NFW_concentration(10 ** 9, 0.2, model='diemer19', scatter=False)
        c2 = self.lens_cosmo.NFW_concentration(10 ** 9, 0.2, model='diemer19', scatter=True)
        npt.assert_raises(AssertionError, npt.assert_array_equal, c, c2)

        logmhm = 8.
        kwargs_suppression, suppression_model = {'c_scale': 60., 'c_power': -0.17}, 'polynomial'
        c_wdm = self.lens_cosmo.NFW_concentration(10 ** 9, 0.2, model='diemer19', scatter=False, logmhm=logmhm,
                                                  kwargs_suppresion=kwargs_suppression, suppression_model=suppression_model)

        suppresion = WDM_concentration_suppresion_factor(10**9, 0.2, logmhm, suppression_model, kwargs_suppression)
        npt.assert_almost_equal(suppresion * c, c_wdm)

        kwargs_suppression, suppression_model = {'a_mc': 0.5, 'b_mc': 0.17}, 'hyperbolic'
        c_wdm = self.lens_cosmo.NFW_concentration(10 ** 9, 0.2, model='diemer19', scatter=False, logmhm=logmhm,
                                                  kwargs_suppresion=kwargs_suppression,
                                                  suppression_model=suppression_model)

        suppresion = WDM_concentration_suppresion_factor(10 ** 9, 0.2, logmhm, suppression_model, kwargs_suppression)
        npt.assert_almost_equal(suppresion * c, c_wdm)

    def test_subhalo_accretion(self):

        zi = [self.lens_cosmo.z_accreted_from_zlens(10**8, 0.5)
              for _ in range(0, 20000)]

        h, b = np.histogram(zi, bins=np.linspace(0.5, 6, 20))

        # number at the lens redshift should be about 5x that at redshift 4
        ratio = h[0]/h[12]
        npt.assert_almost_equal(ratio/5 - 1, 0., 1)

    def test_nfw_fundamental_parameters(self):

        for z in [0., 0.74, 1.2]:

            M, c = 10**8, 17.5
            rho_crit_z = self.cosmo.rho_crit(z)

            rhos, rs, r200 = self.lens_cosmo.nfwParam_physical_Mpc(M, c, z)

            h = self.cosmo.h
            _rhos, _rs = self._colossus_nfw.fundamentalParameters(M * h, c, z, '200c')
            # output in units (M h^2 / kpc^2, kpc/h)
            rhos_col = _rhos * h ** 2 * 1000 ** 3
            rs_col = _rs / h / 1000
            r200_col = rs * c

            npt.assert_almost_equal(rhos/rhos_col, 1, 3)
            npt.assert_almost_equal(rs/rs_col, 1, 3)
            npt.assert_almost_equal(r200/r200_col, 1, 3)

            def _profile(x):
                fac = x * (1 + x) ** 2
                return 1. / fac
            def _integrand(x):
                return 4 * np.pi * x ** 2 * _profile(x)

            volume = 4 * np.pi/3 * r200 ** 3
            integral = quad(_integrand, 0, r200/rs)[0]
            mean_density = rhos * rs ** 3 * integral / volume
            ratio = mean_density/rho_crit_z

            npt.assert_almost_equal(ratio/200, 1., 3)

    def test_mhm_convert(self):

        mthermal = 5.3
        mhm = self.lens_cosmo.mthermal_to_halfmode(mthermal)
        mthermal_out = self.lens_cosmo.halfmode_to_thermal(mhm)
        npt.assert_almost_equal(mthermal/mthermal_out, 1, 2)

        fsl = self.lens_cosmo.mhm_to_fsl(10**8.)
        npt.assert_array_less(fsl, 100)

    def test_NFW_phys2angle(self):

        c = self.lens_cosmo.NFW_concentration(10**8, 0.5, scatter=False)
        out = self.lens_cosmo.nfw_physical2angle(10**8, c, 0.5)
        out2 = self.lens_cosmo.nfw_physical2angle_fromM(10**8, 0.5)
        for (x, y) in zip(out, out2):
            npt.assert_almost_equal(x, y)

        rhos_kpc, rs_kpc, _ = self.lens_cosmo.NFW_params_physical(10**8, c, 0.5)
        rhos_mpc = rhos_kpc * 1000 ** 3
        rs_mpc = rs_kpc * 1e-3
        rs, theta_rs = self.lens_cosmo.nfw_physical2angle_fromNFWparams(rhos_mpc, rs_mpc, 0.5)
        npt.assert_almost_equal(rs, out[0])
        npt.assert_almost_equal(theta_rs, out[1])
示例#6
0
class TestPjaffeHalo(object):

    def setup(self):

        mass = 10**7.
        x = 0.5
        y = 1.
        r3d = np.sqrt(1 + 0.5 ** 2 + 70**2)
        self.r3d = r3d
        mdef = 'PJAFFE'
        self.z = 0.25
        sub_flag = True

        self.H0 = 70
        self.omega_baryon = 0.03
        self.omega_DM = 0.25
        self.sigma8 = 0.82
        curvature = 'flat'
        self.ns = 0.9608
        cosmo_params = {'H0': self.H0, 'Om0': self.omega_baryon + self.omega_DM, 'Ob0': self.omega_baryon,
                        'sigma8': self.sigma8, 'ns': self.ns, 'curvature': curvature}
        self._dm, self._bar = self.omega_DM, self.omega_baryon
        cosmo = Cosmology(cosmo_kwargs=cosmo_params)
        self.lens_cosmo = LensCosmo(self.z, 2., cosmo)
        kwargs_suppression = {'c_scale': 10.5, 'c_power': -0.2}
        suppression_model = 'polynomial'
        profile_args = {'RocheNorm': 1.2, 'RocheNu': 2/3,
                        'evaluate_mc_at_zlens': True,
                        'log_mc': 0., 'kwargs_suppression': kwargs_suppression,
                        'suppression_model': suppression_model, 'c_scatter': False,
                        'mc_model': 'diemer19', 'LOS_truncation_factor': 40,
                        'mc_mdef': '200c',
                        'c_scatter_dex': 0.1}

        self.profile_args = profile_args

        self.mass_subhalo = mass
        self.subhalo = PJaffeSubhalo(mass, x, y, r3d, mdef, self.z,
                            sub_flag, self.lens_cosmo,
                            profile_args, unique_tag=np.random.rand())

        mass_field_halo = 10 ** 7.
        sub_flag = False
        self.mass_field_halo = mass_field_halo
        self.field_halo = PJaffeSubhalo(self.mass_field_halo, x, y, r3d, mdef, self.z,
                            sub_flag, self.lens_cosmo,
                            profile_args, unique_tag=np.random.rand())

        self._model_lenstronomy = PJaffe()


    def test_lenstronomy_ID(self):
        id = self.subhalo.lenstronomy_ID
        npt.assert_string_equal(id[0], 'PJAFFE')

        id = self.field_halo.lenstronomy_ID
        npt.assert_string_equal(id[0], 'PJAFFE')

    def test_z_infall(self):

        z_infall = self.subhalo.z_infall
        npt.assert_equal(True, self.z <= z_infall)

    def test_total_mass(self):

        c = float(self.subhalo.profile_args)
        rhos, rs, r200 = self.lens_cosmo.NFW_params_physical(self.subhalo.mass, c, self.z)
        fc = np.log(1 + c) - c / (1 + c)
        m_nfw = 4 * np.pi * rs ** 3 * rhos * fc

        lenstronomy_kwargs, _ = self.subhalo.lenstronomy_params
        sigma0, ra, rs = lenstronomy_kwargs[0]['sigma0'], lenstronomy_kwargs[0]['Ra'], lenstronomy_kwargs[0]['Rs']

        arcsec_to_kpc = self.lens_cosmo.cosmo.kpc_proper_per_asec(self.z)
        ra *= arcsec_to_kpc ** -1
        rs *= arcsec_to_kpc ** -1
        rho = self.subhalo._rho(m_nfw, rs, ra, c*rs)

        m3d = self._model_lenstronomy.mass_3d(c*rs, rho, ra, rs)
        npt.assert_almost_equal(np.log10(m3d), np.log10(m_nfw))

    def test_profile_args(self):

        profile_args = self.subhalo.profile_args

        (c) = profile_args
        con = concentration(self.lens_cosmo.cosmo.h * self.mass_subhalo, '200c', self.z,
                            model='diemer19')
        npt.assert_almost_equal(c/con, 1, 2)

        profile_args = self.field_halo.profile_args
        (c) = profile_args
        con = concentration(self.lens_cosmo.cosmo.h * self.mass_field_halo, '200c', self.z,
                            model='diemer19')
        npt.assert_almost_equal(c / con, 1, 2)

        profile_args = self.field_halo.profile_args

        (c) = profile_args
        con = concentration(self.lens_cosmo.cosmo.h * self.mass_subhalo, '200c', self.z,
                            model='diemer19')
        npt.assert_almost_equal(c / con, 1, 2)

        profile_args = self.field_halo.profile_args
        (c) = profile_args
        con = concentration(self.lens_cosmo.cosmo.h * self.mass_field_halo, '200c', self.z,
                            model='diemer19')
        npt.assert_almost_equal(c / con, 1, 2)

    def test_params_physical(self):

        params_physical = self.subhalo.params_physical
        npt.assert_equal(len(params_physical), 4)