Пример #1
0
def test_cosmo_methods():
    """ Check that all pyccl functions that take cosmo
    as their first argument are methods of the Cosmology object.
    """
    from inspect import getmembers, isfunction, signature
    from pyccl import background, bcm, boltzmann, \
        cls, correlations, covariances, neutrinos, \
        pk2d, power, tk3d, tracers, halos, nl_pt
    from pyccl.core import CosmologyVanillaLCDM
    cosmo = CosmologyVanillaLCDM()
    subs = [
        background, boltzmann, bcm, cls, correlations, covariances, neutrinos,
        pk2d, power, tk3d, tracers, halos, nl_pt
    ]
    funcs = [getmembers(sub, isfunction) for sub in subs]
    funcs = [func for sub in funcs for func in sub]
    for name, func in funcs:
        pars = signature(func).parameters
        if list(pars)[0] == "cosmo":
            _ = getattr(cosmo, name)

    # quantitative
    assert ccl.sigma8(cosmo) == cosmo.sigma8()
    assert ccl.rho_x(cosmo, 1., "matter", is_comoving=False) == \
        cosmo.rho_x(1., "matter", is_comoving=False)
    assert ccl.get_camb_pk_lin(cosmo).eval(1., 1., cosmo) == \
        cosmo.get_camb_pk_lin().eval(1., 1., cosmo)
    prof = ccl.halos.HaloProfilePressureGNFW()
    hmd = ccl.halos.MassDef200m()
    hmf = ccl.halos.MassFuncTinker08(cosmo)
    hbf = ccl.halos.HaloBiasTinker10(cosmo)
    hmc = ccl.halos.HMCalculator(cosmo, massfunc=hmf, hbias=hbf, mass_def=hmd)
    assert ccl.halos.halomod_power_spectrum(cosmo, hmc, 1., 1., prof) == \
        cosmo.halomod_power_spectrum(hmc, 1., 1., prof)
Пример #2
0
    def pk(self, k, a, lmmin=6., lmmax=17., nlm=256, return_decomposed=False):
        """
        Returns power spectrum at redshift `z` sampled at all values of k in `k`.

        k : array of wavenumbers in CCL units
        a : scale factor
        lmmin, lmmax, nlm : mass edges and sampling rate for mass integral.
        return_decomposed : if True, returns 1-halo, 2-halo, bias, shot noise and total (see below for order).
        """
        z = 1. / a - 1.
        marr = np.logspace(lmmin, lmmax, nlm)
        dlm = np.log10(marr[1] / marr[0])
        u_s = self.u_sat(z, marr, k)
        hmf = ccl.massfunc(self.cosmo, marr, a)
        hbf = ccl.halo_bias(self.cosmo, marr, a)
        rhoM = ccl.rho_x(self.cosmo, a, "matter", is_comoving=True)
        n0_1h = (rhoM - np.sum(hmf * marr) * dlm) / marr[0]
        n0_2h = (rhoM - np.sum(hmf * hbf * marr) * dlm) / marr[0]

        #Number of galaxies
        fc = self.fc_f(z)
        ngm = self.n_tot(z, marr)
        ncm = self.n_cent(z, marr)
        nsm = self.n_sat(z, marr)

        #Number density
        ng = np.sum(hmf * ngm) * dlm + n0_1h * ngm[0]
        if ng <= 1E-16:  #Make sure we won't divide by 0
            return None

        #Bias
        b_hod = np.sum(
            (hmf * hbf * ncm)[None, :] * (fc + nsm[None, :] * u_s[:, :]),
            axis=1) * dlm + n0_2h * ncm[0] * (fc + nsm[0] * u_s[:, 0])
        b_hod /= ng

        #1-halo
        #p1h=np.sum((hmf*ncm**2)[None,:]*(fc+nsm[None,:]*u_s[:,:])**2,axis=1)*dlm+n0_1h*(ncm[0]*(fc+nsm[0]*u_s[:,0]))**2
        p1h = np.sum(
            (hmf * ncm)[None, :] * (2 * fc * nsm[None, :] * u_s[:, :] +
                                    (nsm[None, :] * u_s[:, :])**2),
            axis=1) * dlm + n0_1h * ncm[0] * (2 * fc * nsm[0] * u_s[:, 0] +
                                              (nsm[0] * u_s[:, 0])**2)
        p1h /= ng**2

        #2-halo
        p2h = b_hod**2 * ccl.linear_matter_power(self.cosmo, k, a)

        if return_decomposed:
            return p1h + p2h, p1h, p2h, np.ones_like(k) / ng, b_hod
        else:
            return p1h + p2h
Пример #3
0
    def _norm(self, cosmo, mass_def, M, a):
        """
        Battaglia profile normalization (P200, above Eq. (9) in Battaglia et al., 2012)
        N = G M200c 200 rho_crit,phys(a) f_b/(2 R200c,phys)
        f_b = Omega_b/Omega_m
        Units are Msun/(Mpc s^2)
        :param cosmo:
        :param mass_def:
        :param M:
        :param a:
        :return:
        """

        # Since the Battaglia profile is defined in physical units the norm needs to be in physical units as well
        R_Delta = mass_def.get_radius(cosmo, M, a)
        f_b = cosmo['Omega_b'] / cosmo['Omega_m']

        P_Delta = G_MPC_MSUN * M * mass_def.get_Delta(cosmo, a) * ccl.rho_x(
            cosmo, a, 'critical') * f_b / (2. * R_Delta)

        return P_Delta
Пример #4
0
def check_background(cosmo):
    """
    Check that background and growth functions can be run.
    """

    # Types of scale factor input (scalar, list, array)
    a_scl = 0.5
    is_comoving = 0
    a_lst = [0.2, 0.4, 0.6, 0.8, 1.]
    a_arr = np.linspace(0.2, 1., 5)

    # growth_factor
    assert_(all_finite(ccl.growth_factor(cosmo, a_scl)))
    assert_(all_finite(ccl.growth_factor(cosmo, a_lst)))
    assert_(all_finite(ccl.growth_factor(cosmo, a_arr)))

    # growth_factor_unnorm
    assert_(all_finite(ccl.growth_factor_unnorm(cosmo, a_scl)))
    assert_(all_finite(ccl.growth_factor_unnorm(cosmo, a_lst)))
    assert_(all_finite(ccl.growth_factor_unnorm(cosmo, a_arr)))

    # growth_rate
    assert_(all_finite(ccl.growth_rate(cosmo, a_scl)))
    assert_(all_finite(ccl.growth_rate(cosmo, a_lst)))
    assert_(all_finite(ccl.growth_rate(cosmo, a_arr)))

    # comoving_radial_distance
    assert_(all_finite(ccl.comoving_radial_distance(cosmo, a_scl)))
    assert_(all_finite(ccl.comoving_radial_distance(cosmo, a_lst)))
    assert_(all_finite(ccl.comoving_radial_distance(cosmo, a_arr)))

    # comoving_angular_distance
    assert_(all_finite(ccl.comoving_angular_distance(cosmo, a_scl)))
    assert_(all_finite(ccl.comoving_angular_distance(cosmo, a_lst)))
    assert_(all_finite(ccl.comoving_angular_distance(cosmo, a_arr)))

    # h_over_h0
    assert_(all_finite(ccl.h_over_h0(cosmo, a_scl)))
    assert_(all_finite(ccl.h_over_h0(cosmo, a_lst)))
    assert_(all_finite(ccl.h_over_h0(cosmo, a_arr)))

    # luminosity_distance
    assert_(all_finite(ccl.luminosity_distance(cosmo, a_scl)))
    assert_(all_finite(ccl.luminosity_distance(cosmo, a_lst)))
    assert_(all_finite(ccl.luminosity_distance(cosmo, a_arr)))

    # scale_factor_of_chi
    assert_(all_finite(ccl.scale_factor_of_chi(cosmo, a_scl)))
    assert_(all_finite(ccl.scale_factor_of_chi(cosmo, a_lst)))
    assert_(all_finite(ccl.scale_factor_of_chi(cosmo, a_arr)))

    # omega_m_a
    assert_(all_finite(ccl.omega_x(cosmo, a_scl, 'matter')))
    assert_(all_finite(ccl.omega_x(cosmo, a_lst, 'matter')))
    assert_(all_finite(ccl.omega_x(cosmo, a_arr, 'matter')))

    # Fractional density of different types of fluid
    assert_(all_finite(ccl.omega_x(cosmo, a_arr, 'dark_energy')))
    assert_(all_finite(ccl.omega_x(cosmo, a_arr, 'radiation')))
    assert_(all_finite(ccl.omega_x(cosmo, a_arr, 'curvature')))
    assert_(all_finite(ccl.omega_x(cosmo, a_arr, 'neutrinos_rel')))
    assert_(all_finite(ccl.omega_x(cosmo, a_arr, 'neutrinos_massive')))

    # Check that omega_x fails if invalid component type is passed
    assert_raises(ValueError, ccl.omega_x, cosmo, a_scl, 'xyz')

    # rho_crit_a
    assert_(all_finite(ccl.rho_x(cosmo, a_scl, 'critical', is_comoving)))
    assert_(all_finite(ccl.rho_x(cosmo, a_lst, 'critical', is_comoving)))
    assert_(all_finite(ccl.rho_x(cosmo, a_arr, 'critical', is_comoving)))

    # rho_m_a
    assert_(all_finite(ccl.rho_x(cosmo, a_scl, 'matter', is_comoving)))
    assert_(all_finite(ccl.rho_x(cosmo, a_lst, 'matter', is_comoving)))
    assert_(all_finite(ccl.rho_x(cosmo, a_arr, 'matter', is_comoving)))
Пример #5
0
def test_background_rho_x(a, kind, is_comoving):
    val = ccl.rho_x(COSMO_NU, a, kind, is_comoving)
    assert np.all(np.isfinite(val))
    assert np.shape(val) == np.shape(a)
Пример #6
0
def test_background_rho_x_raises():
    with pytest.raises(ValueError):
        ccl.rho_x(COSMO, 1, 'blah', False)
Пример #7
0
def hm_bias(cosmo,
            a,
            profile,
            logMrange=(6, 17),
            mpoints=128,
            selection=None,
            **kwargs):
    """Computes the halo model prediction for the bias of a given
    tracer.

    Args:
        cosmo (:obj:`ccl.Cosmology`): cosmology.
        a (array): array of scale factor values
        profile (`Profile`): a profile. Only Arnaud and HOD are
            implemented.
        logMrange (tuple): limits of integration in log10(M/Msun)
        mpoints (int): number of mass samples
        selection (function): selection function in (M,z) to include
            in the calculation. Pass None if you don't want to select
            a subset of the M-z plane.
        **kwargs: parameter used internally by the profiles.
    """
    # Input handling
    a = np.atleast_1d(a)

    # Profile normalisations
    Unorm = profile.profnorm(cosmo, a, squeeze=False, **kwargs)
    Unorm = Unorm[..., None]

    # Set up integration boundaries
    logMmin, logMmax = logMrange  # log of min and max halo mass [Msun]
    mpoints = int(mpoints)  # number of integration points
    M = np.logspace(logMmin, logMmax, mpoints)  # masses sampled

    # Out-of-loop optimisations
    Dm = profile.Delta / ccl.omega_x(cosmo, a, "matter")  # CCL uses Delta_m
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        mfunc = np.array(
            [ccl.massfunc(cosmo, M, A1, A2) for A1, A2 in zip(a, Dm)])
        bh = np.array(
            [ccl.halo_bias(cosmo, M, A1, A2) for A1, A2 in zip(a, Dm)])
    # shape transformations
    mfunc, bh = mfunc.T[..., None], bh.T[..., None]
    if selection is not None:
        select = np.array([selection(M, 1. / aa - 1) for aa in a])
        select = select.T[..., None]
    else:
        select = 1

    U, _ = profile.fourier_profiles(cosmo,
                                    np.array([0.001]),
                                    M,
                                    a,
                                    squeeze=False,
                                    **kwargs)

    # Tinker mass function is given in dn/dlog10M, so integrate over d(log10M)
    b2h = simps(bh * mfunc * select * U, x=np.log10(M), axis=0).squeeze()

    # Contribution from small masses (added in the beginning)
    rhoM = ccl.rho_x(cosmo, a, "matter", is_comoving=True)
    dlM = (logMmax - logMmin) / (mpoints - 1)
    mfunc, bh = mfunc.squeeze(), bh.squeeze()  # squeeze extra dimensions

    n0_2h = np.array((rhoM - np.dot(M, mfunc * bh) * dlM) / M[0])[None, ...,
                                                                  None]

    b2h += (n0_2h * U[0]).squeeze()
    b2h /= Unorm.squeeze()

    return b2h.squeeze()
Пример #8
0
def hm_power_spectrum(cosmo,
                      k,
                      a,
                      profiles,
                      logMrange=(6, 17),
                      mpoints=128,
                      include_1h=True,
                      include_2h=True,
                      squeeze=True,
                      hm_correction=None,
                      selection=None,
                      **kwargs):
    """Computes the halo model prediction for the 3D cross-power
    spectrum of two quantities.

    Args:
        cosmo (:obj:`ccl.Cosmology`): cosmology.
        k (array): array of wavenumbers in units of Mpc^-1
        a (array): array of scale factor values
        profiles (tuple): tuple of two profile objects (currently
            only Arnaud and HOD are implemented) corresponding to
            the two quantities being correlated.
        logMrange (tuple): limits of integration in log10(M/Msun)
        mpoints (int): number of mass samples
        include_1h (bool): whether to include the 1-halo term.
        include_2h (bool): whether to include the 2-halo term.
        hm_correction (:obj:`HalomodCorrection` or None):
            Correction to the halo model in the transition regime.
            If `None`, no correction is applied.
        selection (function): selection function in (M,z) to include
            in the calculation. Pass None if you don't want to select
            a subset of the M-z plane.
        **kwargs: parameter used internally by the profiles.
    """
    # Input handling
    a, k = np.atleast_1d(a), np.atleast_2d(k)

    # Profile normalisations
    p1, p2 = profiles
    Unorm = p1.profnorm(cosmo, a, squeeze=False, **kwargs)
    if p1.name == p2.name:
        Vnorm = Unorm
    else:
        Vnorm = p2.profnorm(cosmo, a, squeeze=False, **kwargs)
    if (Vnorm < 1e-16).any() or (Unorm < 1e-16).any():
        return None  # zero division
    Unorm, Vnorm = Unorm[..., None], Vnorm[..., None]  # transform axes

    # Set up integration boundaries
    logMmin, logMmax = logMrange  # log of min and max halo mass [Msun]
    mpoints = int(mpoints)  # number of integration points
    M = np.logspace(logMmin, logMmax, mpoints)  # masses sampled

    # Out-of-loop optimisations
    Pl = np.array(
        [ccl.linear_matter_power(cosmo, k[i], a) for i, a in enumerate(a)])
    Dm = p1.Delta / ccl.omega_x(cosmo, a, "matter")  # CCL uses Delta_m
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        mfunc = np.array(
            [ccl.massfunc(cosmo, M, A1, A2) for A1, A2 in zip(a, Dm)])

    if selection is not None:
        select = np.array([selection(M, 1. / aa - 1) for aa in a])
        mfunc *= select

    # tinker10 halo bias
    csm = ccl.Cosmology(Omega_c=cosmo["Omega_c"],
                        Omega_b=cosmo["Omega_b"],
                        h=cosmo["h"],
                        sigma8=cosmo["sigma8"],
                        n_s=cosmo["n_s"],
                        mass_function="tinker10")

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        bh = np.array([ccl.halo_bias(csm, M, A1, A2) for A1, A2 in zip(a, Dm)])

    # shape transformations
    mfunc, bh = mfunc.T[..., None], bh.T[..., None]
    if selection is not None:
        select = np.array([selection(M, 1. / aa - 1) for aa in a])
        select = select.T[..., None]
    else:
        select = 1

    U, UU = p1.fourier_profiles(cosmo, k, M, a, squeeze=False, **kwargs)
    # optimise for autocorrelation (no need to recompute)
    if p1.name == p2.name:
        V = U
        UV = UU
    else:
        V, VV = p2.fourier_profiles(cosmo, k, M, a, squeeze=False, **kwargs)
        r = kwargs["r_corr"] if "r_corr" in kwargs else 0
        UV = U * V * (1 + r)

    # Tinker mass function is given in dn/dlog10M, so integrate over d(log10M)
    P1h = simps(mfunc * select * UV, x=np.log10(M), axis=0)
    b2h_1 = simps(bh * mfunc * select * U, x=np.log10(M), axis=0)
    b2h_2 = simps(bh * mfunc * select * V, x=np.log10(M), axis=0)

    # Contribution from small masses (added in the beginning)
    rhoM = ccl.rho_x(cosmo, a, "matter", is_comoving=True)
    dlM = (logMmax - logMmin) / (mpoints - 1)
    mfunc, bh = mfunc.squeeze(), bh.squeeze()  # squeeze extra dimensions

    n0_1h = np.array((rhoM - np.dot(M, mfunc) * dlM) / M[0])[None, ..., None]
    n0_2h = np.array((rhoM - np.dot(M, mfunc * bh) * dlM) / M[0])[None, ...,
                                                                  None]

    P1h += (n0_1h * U[0] * V[0]).squeeze()
    b2h_1 += (n0_2h * U[0]).squeeze()
    b2h_2 += (n0_2h * V[0]).squeeze()

    F = (include_1h * P1h + include_2h *
         (Pl * b2h_1 * b2h_2)) / (Unorm * Vnorm)
    if hm_correction is not None:
        for ia, (aa, kk) in enumerate(zip(a, k)):
            R = hm_correction.rk_interp(kk, aa)
            F[ia, :] *= R

    return F.squeeze() if squeeze else F
Пример #9
0
def get_halomod_pk(cp,karr,z,integrate=True,fname_out=None) :
    cosmo=ccl.Cosmology(Omega_c=cp['Om_m']-cp['Om_b'],Omega_b=cp['Om_b'],h=cp['h'],
                        sigma8=cp['sig8'],n_s=cp['n'],
                        transfer_function='eisenstein_hu',matter_power_spectrum='linear')

    lmarr=LMMIN+(LMMAX-LMMIN)*(np.arange(NM)+0.5)/NM #log(M*h/M_sum)
    dlm=(LMMAX-LMMIN)/NM
    lmarrb=np.zeros(NM+2); lmarrb[0]=lmarr[0]-dlm; lmarrb[1:-1]=lmarr; lmarrb[-1]=lmarr[-1]+dlm
    marr=10.**lmarr #M (in Msun/h) M_h Ms/h = M Ms
    marrb=10.**lmarrb #M (in Msun/h) M_h Ms/h = M Ms
    sigmarrb=ccl.sigmaM(cosmo,marrb/cp['h'],1./(1+z))
    sigmarr=sigmarrb[1:-1]
    dlsMdl10M=np.fabs((sigmarrb[2:]-sigmarrb[:-2])/(2*dlm))/sigmarr
    omega_z=cp['Om_m']*(1+z)**3/(cp['Om_m']*(1+z)**3+1-cp['Om_m'])
    delta_c=params['DELTA_C']*(1+0.012299*np.log10(omega_z))
    Delta_v=(18*np.pi**2+82*(omega_z-1)-39*(omega_z-1)**2)/omega_z
    fM=st_gs(sigmarr,delta_c)*dlsMdl10M
    bM=st_b1(sigmarr,delta_c)
    cM=duffy_c(marr,z)
    cMf=interp1d(lmarr,cM,kind='linear',bounds_error=False,fill_value=cM[0])
    rhoM=ccl.rho_x(cosmo,1.,'matter')/cp['h']**2

    #Compute mass function normalization
    fM0=1-np.sum(fM)*dlm
    fbM0=1-np.sum(fM*bM)*dlm

    rvM=(3*marr/(4*np.pi*rhoM*Delta_v))**0.333333333333
    rsM=rvM/cM
    rsM0=(3*10.**LM0/(4*np.pi*rhoM*Delta_v))**0.333333333/duffy_c(10.**LM0,z)
    rsMf=interp1d(lmarr,rsM,kind='linear',bounds_error=False,fill_value=rsM0)

    f1hf=interp1d(lmarr,marr*fM/rhoM,kind='linear',bounds_error=False,fill_value=0)
    f1h0=fM0*10.**LM0/rhoM
    f2hf=interp1d(lmarr,fM*bM,kind='linear',bounds_error=False,fill_value=0)
    f2h0=fbM0

    #NFW profile
    def u_nfw(lm,k) :
        x=k*rsMf(lm) #k*r_s
        c=cMf(lm)
        sic,cic=sici(x*(1+c))
        six,cix=sici(x)
        fsin=np.sin(x)*(sic-six)
        fcos=np.cos(x)*(cic-cix)
        fsic=np.sin(c*x)/(x*(1+c))
        fcon=np.log(1.+c)-c/(1+c)

        return (fsin+fcos-fsic)/fcon

    def p1h(k) :
        def integ(lm) :
            u=u_nfw(lm,k)
            f1h=f1hf(lm)
            return u*u*f1h
        if integrate :
            return quad(integ,lmarr[0],lmarr[-1])[0]+f1h0*(u_nfw(LM0,k))**2
        else :
            return np.sum(integ(lmarr))*dlm+f1h0*(u_nfw(LM0,k))**2
    
    def b2h(k) :
        def integ(lm) :
            u=u_nfw(lm,k)
            f2h=f2hf(lm)
            return u*f2h
        if integrate :
            return quad(integ,lmarr[0],lmarr[-1])[0]+f2h0*u_nfw(LM0,k)
        else :
            return np.sum(integ(lmarr))*dlm+f2h0*u_nfw(LM0,k)


    p1harr=np.array([p1h(kk) for kk in karr])
    b2harr=np.array([b2h(kk) for kk in karr])
    pklin=ccl.linear_matter_power(cosmo,karr*cp['h'],1./(1+z))*cp['h']**3

    p2harr=pklin*b2harr**2
    ptarr=p1harr+p2harr
    np.savetxt(fname_out,np.transpose([karr,pklin,p2harr,p1harr,ptarr]))
    return pklin,pklin*b2harr**2,p1harr,pklin*b2harr**2+p1harr
Пример #10
0
    def pk_gm(self,
              k,
              a,
              lmmin=6.,
              lmmax=17.,
              nlm=256,
              return_decomposed=False):
        """
        Returns galaxy-matter power spectrum at a single scale-factor a for array of wave vectors k.
        :param k: wave vector array
        :param a: single scale factor value
        :param lmmin: Mmin for HOD integrals
        :param lmmax: Mmax for HOD integrals
        :param nlm: sampling rate for mass integral
        :param return_decomposed: boolean tag, if True return 1h, 2h power spectrum separately
        :return:
        """

        z = 1. / a - 1.
        marr = np.logspace(lmmin, lmmax, nlm)
        dlm = np.log10(marr[1] / marr[0])
        u_nfw = self.u_sat(z, marr, k)
        hmf = ccl.massfunc(self.cosmo, marr, a)
        hbf = ccl.halo_bias(self.cosmo, marr, a)
        rhoM = ccl.rho_x(self.cosmo, a, "matter", is_comoving=True)
        n0_1h = (rhoM - np.sum(hmf * marr) * dlm) / marr[0]
        n0_2h = (rhoM - np.sum(hmf * hbf * marr) * dlm) / marr[0]
        # n0_2h = (rhoM - np.sum(hmf*hbf*marr)*dlm)

        #Number of galaxies
        fc = self.fc_f(z)
        ngm = self.n_tot(z, marr)
        ncm = self.n_cent(z, marr)
        nsm = self.n_sat(z, marr)

        #Number density
        ng = np.sum(hmf * ngm) * dlm + n0_1h * ngm[0]
        if ng <= 1E-16:  #Make sure we won't divide by 0
            return None

        #Bias
        b_hod=np.sum((hmf*hbf*ncm)[None,:]*(fc+nsm[None,:]*u_nfw[:,:]),axis=1)*dlm \
              + n0_2h*ncm[0]*(fc+nsm[0]*u_nfw[:,0])
        b_m = np.sum((hmf * hbf)[None, :] * marr[None, :] * u_nfw[:, :],
                     axis=1) * dlm + n0_2h * u_nfw[:, 0]

        b_hod /= ng
        b_m /= rhoM

        #1-halo
        #p1h=np.sum((hmf*ncm**2)[None,:]*(fc+nsm[None,:]*u_s[:,:])**2,axis=1)*dlm+n0_1h*(ncm[0]*(fc+nsm[0]*u_s[:,0]))**2
        p1h=np.sum((hmf*ncm)[None,:]*(fc+nsm[None,:]*u_nfw[:,:])*marr*u_nfw[:,:],axis=1)*dlm \
            + n0_1h*ncm[0]*(fc + nsm[0]*u_nfw[:,0])*u_nfw[:,0]
        p1h /= ng * rhoM

        #2-halo
        p2h = b_hod * b_m * ccl.linear_matter_power(self.cosmo, k, a)

        if return_decomposed:
            return p1h + p2h, p1h, p2h, np.ones_like(k) / ng, b_hod
        else:
            return p1h + p2h
Пример #11
0
def hm_1h_trispectrum(cosmo,
                      k,
                      a,
                      profiles,
                      logMrange=(8, 16),
                      mpoints=128,
                      selection=None,
                      **kwargs):
    """Computes the halo model prediction for the 1-halo 3D
    trispectrum of four quantities.

    Args:
        cosmo (:obj:`ccl.Cosmology`): cosmology.
        k (array): array of wavenumbers in units of Mpc^-1
        a (array): array of scale factor values
        profiles (tuple): tuple of four profile objects (currently
            only Arnaud and HOD are implemented) corresponding to
            the four quantities being correlated.
        logMrange (tuple): limits of integration in log10(M/Msun)
        mpoints (int): number of mass samples
        selection (function): selection function in (M,z) to include
            in the calculation. Pass None if you don't want to select
            a subset of the M-z plane.
        **kwargs: parameter used internally by the profiles.
    """
    k = np.atleast_1d(k)
    a = np.atleast_1d(a)
    pau, pav, pbu, pbv = profiles

    aUnorm = pau.profnorm(cosmo, a, squeeze=False, **kwargs)
    aVnorm = pav.profnorm(cosmo, a, squeeze=False, **kwargs)
    bUnorm = pbu.profnorm(cosmo, a, squeeze=False, **kwargs)
    bVnorm = pbv.profnorm(cosmo, a, squeeze=False, **kwargs)

    logMmin, logMmax = logMrange
    mpoints = int(mpoints)
    M = np.logspace(logMmin, logMmax, mpoints)

    Dm = pau.Delta / ccl.omega_x(cosmo, a, 'matter')
    mfunc = np.array(
        [ccl.massfunc(cosmo, M, aa, Dmm) for aa, Dmm in zip(a, Dm)]).T
    if selection is not None:
        select = np.array([selection(M, 1. / aa - 1) for aa in a]).T
    else:
        select = 1

    aU, aUU = pau.fourier_profiles(cosmo, k, M, a, squeeze=False, **kwargs)
    if pau.name == pav.name:
        aUV = aUU
    else:
        aV, aVV = pav.fourier_profiles(cosmo, k, M, a, squeeze=False, **kwargs)
        if 'r_corr' in kwargs:
            r = kwargs['r_corr']
        else:
            r = 0

        # aUV = np.sqrt(aUU*aVV)*(1+r)
        aUV = aU * aV * (1 + r)

    bU, bUU = pbu.fourier_profiles(cosmo, k, M, a, squeeze=False, **kwargs)
    if pbu.name == pbv.name:
        bUV = bUU
    else:
        bV, bVV = pbv.fourier_profiles(cosmo, k, M, a, squeeze=False, **kwargs)
        if 'r_corr' in kwargs:
            r = kwargs['r_corr']
        else:
            r = 0

        # bUV = np.sqrt(bUU*bVV)*(1+r)
        bUV = bU * bV * (1 + r)

    t1h = simps((select * mfunc)[:, :, None, None] * aUV[:, :, :, None] *
                bUV[:, :, None, :],
                x=np.log10(M),
                axis=0)

    rhoM = ccl.rho_x(cosmo, a, "matter", is_comoving=True)
    dlM = (logMmax - logMmin) / (mpoints - 1)
    n0_1h = (rhoM - np.dot(M, mfunc) * dlM) / M[0]
    t1h += (n0_1h[:, None, None] * aUV[0, :, :, None] * bUV[0, :, None, :])
    t1h /= (aUnorm * aVnorm * bUnorm * bVnorm)[:, None, None]

    return t1h