Testing the halo model

A different approach to compute the non-linear matter power spectrum is provided by the halo model, which became popular at the beginning of the 2000. This code implements all the useful functions for this purpose, using the Sheth-Tormen mass function. Despite it returns a poor description of matter clustering, it can be easily expanded to account for galaxies and/or qualitatively predicting covariance matrices for cosmological observables (for a review see arXiv:0206508 ).

Matter power spectrum

Let us start defining a colibri.halo.halo() instance:

import colibri.cosmology as cc
import colibri.halo as hc

# Define a halo instance
H = hc.halo(z = [0., 1., 2.],              # 3 redshifts
            k = np.logspace(-4., 1., 201), # Scales in h/Mpc
            code = 'camb',                 # Boltzmann code with which to compute linear P(k)
            BAO_smearing = False,          # Smooth BAO due to non-linearities
            cosmology = cc.cosmo())        # ``cosmo`` instance

The halo power spectrum is then computed with the following lines

# Load power spectrum according to the halo model
H.halo_Pk(kwargs_mass_function = {'a': 0.707, 'p': 0.3},   # arguments to pass to the Sheth-Tormen mass function
          kwargs_concentration = {'c0': 9., 'b': 0.13})    # arguments to pass to the concentration parameter c0*(M/Mstar)**(-b)

# Store 1-halo, 2-halo and total terms
oneh = H.Pk['matter']['1-halo']       # array of shape (len(z),len(k))
twoh = H.Pk['matter']['2-halo']       # array of shape (len(z),len(k))
tot  = H.Pk['matter']['total halo']   # array of shape (len(z),len(k))

The comparison with CAMB Halofit (for our 3 different redshifts) is the following:

../../_images/halo_spectrum.png

Galaxy power spectrum: real space

The galaxy power spectrum in real space is computed using the Halo Occupation Distribution (HOD) method. In this pictures, halos are populated of galaxies depending exclusively on their mass. Galaxies are divided into central (max. 1 per halo) and satellites (from 0 to infinity): the 1-halo and 2-halo terms are computed by counting pairs of galaxies in the same and different halos, respectively.

To compute the power spectrum, one must provide the average amount of galaxies per halo. This is done in a few steps here. First, we define a colibri.galaxy.galaxy() instance:

import colibri.cosmology as cc
import colibri.galaxy as gc

# Define a halo instance
G = gc.galaxy(z = [0., 1., 2.],              # 3 redshifts
              k = np.logspace(-4., 2., 201), # Scales in h/Mpc
              code = 'camb',                 # Boltzmann code with which to compute linear P(k)
              BAO_smearing = False,          # Smooth BAO due to non-linearities
              cosmology = cc.cosmo())        # ``cosmo`` instance

Second, we give to the code the ‘ingredients’ for the HOD. This is done through the function colibri.galaxy.galaxy.load_HOD()

G.load_HOD(kind_satellite   = G.power_law,
           kwargs_satellite = {'log_Mcut':[13., 12.5, 12.3], 'log_M1': [13., 13.4, 13.], 'alpha': [1., 1.5, 1.]},
           kind_central     = G.logistic_function,
           kwargs_central   = {'log_Mmin': [13., 12.4, 11.4], 'sigma_logM': [0.8, 0.5, 0.6]})

The arguments kind_satellite and kind_central are callable functions whose first argument must be the halo mass in units of \(M_\odot/h\). In this case we have used the functions colibri.galaxy.galaxy.power_law() and colibri.galaxy.galaxy.logistic_function(). The arguments kwargs_satellite and kwargs_central are dictionaries that contain all the remaining arguments to pass to the above functions. Each value of each key must be a list of same size of the redshifts required, otherwise the code will return an AssertionError.

The last step consists of the actual computation of the galaxy power spectrum, which is done like in the halo case:

G.galaxy_Pk(kwargs_mass_function = {'a': 0.707, 'p': 0.3},
            kwargs_concentration = {'c0': 9., 'b': 0.13})

pg1 = G.Pk['galaxies']['real space']['1-halo']
pg2 = G.Pk['galaxies']['real space']['2-halo']
pgt = G.Pk['galaxies']['real space']['total halo']

Note

The last two steps can be combined together. In fact, when the function colibri.galaxy.galaxy.galaxy_Pk() is called, it will search the quantities self.Ncen and self.Nsat which are generated only after the call of colibri.galaxy.galaxy.load_HOD(). If these are not found, the code will try to compute them on the fly, provided that the arguments of colibri.galaxy.galaxy.load_HOD() are given. In other words, the last two steps can be gathered in:

G.galaxy_Pk(kind_satellite       = G.power_law,
            kwargs_satellite     = {'log_Mcut':[13., 12.5, 12.3], 'log_M1': [13., 13.4, 13.], 'alpha': [1., 1.5, 1.]},
            kind_central         = G.logistic_function,
            kwargs_central       = {'log_Mmin': [13., 12.4, 11.4], 'sigma_logM': [0.8, 0.5, 0.6]},
            kwargs_mass_function = {'a': 0.707, 'p': 0.3},
            kwargs_concentration = {'c0': 9., 'b': 0.13})
../../_images/galaxy_spectrum.png

Galaxy power spectrum: redshift space

Galaxies in surveys are observed in redshift-space due to the fact that we only measure the recession velocity along the line-of-sight. The class colibri.RSD.RSD() provides routines able to compute the power spectrum in redshift-space using different configurations of independent variables:

  • in \((k,\mu)\) space

  • in multipole space, using the Legendre expansion

  • in \((k_\parallel,k_\perp)\) space

The RSD instance is called as follows:

import colibri.cosmology as cc
import colibri.RSD as rsd

Z = rsd.RSD(z            = [0., 1., 2.],                    # Redshifts
            k            = np.geomspace(0.0005, 10., 101),  # Scales in h/Mpc
            mu           = np.linspace(0., 1., 31),         # Cosine of angles with LOS
            k_par        = np.linspace(0.01, 1., 51),       # Scales parallel in h/Mpc
            k_perp       = np.linspace(0.01, 1., 31),       # Scales perpendicular in h/Mpc
            BAO_smearing = True,                            # Smooth BAO feature in non-linearities
            cosmology    = cc.cosmo())                      # Cosmology

With our 3 redshifts, we define the following useful quantities

# Galaxy biases
bb = [1.30, 2.60, 3.34]    # Galaxy biases
# Growth rates
ff = C.Omega_m_z(zz)**0.55
# Velocity dispersions (in km/s)
sv = [200., 200., 200.]
# HOD functions (like in ``galaxy``)
HOD_central_kind, HOD_satellite_kind = Z.logistic_function, Z.power_law
HOD_central_parameters   = {'log_Mmin': [12., 12.5, 12.], 'sigma_logM': [0.8, 0.5, 0.2]}
HOD_satellite_parameters = {'log_Mcut': [13., 12.5, 12.], 'log_M1': [14., 13.2, 13.4], 'alpha': [1., 1.25, 1.5]}
# Kind of damping functions for fingers-of-god effect
FoG_damping = 'Lorentzian' # Kind of damping due to fingers-of-God (choose between 'Lorentzian' and 'Gaussian')
# Base power spectrum is the non-linear matter one (computed with Halofit) (choose among 'linear', 'nonlinear', 'HOD', 'halo model')
RSD_model = 'nonlinear'

At this point the galaxy redshift-space power spectrum can be computed in 3 ways:

  • in \((k,\mu)\) space

Z.galaxy_RSD_Pk(bias                 = bb,                        # Galaxy bias (used only if model = 'HOD' or 'halo model')
                growth_rate          = ff,                        # Growth rate f = dln(D)/dln(a)
                velocity_dispersion  = sv,                        # Average velocity dispersion of galaxies in halos
                model                = RSD_model,                 # Model to compute RSD
                kwargs_mass_function = {'a': 0.707, 'p': 0.3},    # Parameters to compute halo mass function (used only if model = 'HOD' or 'halo model')
                kwargs_concentration = {'c0': 9., 'b': 0.13},     # Parameters to compute concentration parameter (used only if model = 'HOD' or 'halo model')
                fingers_of_god       = FoG_damping,               # Kind of damping ('Lorentzian' or 'Gaussian', used only if model != 'halo model')
                kind_central         = HOD_central_kind,          # Function to compute central galaxies (1st arguments must be mass in Msun/h)
                kwargs_central       = HOD_central_parameters,    # Remaining arguments to pass to kind_central
                kind_satellite       = HOD_satellite_kind,        # Function to compute satellite galaxies (1st arguments must be mass in Msun/h)
                kwargs_satellite     = HOD_satellite_parameters)  # Remaining arguments to pass to kind_satellite
  • in multipole space, using the Legendre expansion

Z.galaxy_RSD_Pk_multipoles(l                    = [0,2,4]                     # Multipoles to compute (monopole, quadrupole, hexadecapole)
                           bias                 = bb,                         # Galaxy bias (used only if model = 'HOD' or 'halo model')
                           growth_rate          = ff,                         # Growth rate f = dln(D)/dln(a)
                           velocity_dispersion  = sv,                         # Average velocity dispersion of galaxies in halos
                           model                = RSD_model,                  # Model to compute RSD
                           kwargs_mass_function = {'a': 0.707, 'p': 0.3},     # Parameters to compute halo mass function (used only if model = 'HOD' or 'halo model')
                           kwargs_concentration = {'c0': 9., 'b': 0.13},      # Parameters to compute concentration parameter (used only if model = 'HOD' or 'halo model')
                           fingers_of_god       = FoG_damping,                # Kind of damping ('Lorentzian' or 'Gaussian', used only if model != 'halo model')
                           kind_central         = HOD_central_kind,           # Function to compute central galaxies (1st arguments must be mass in Msun/h)
                           kwargs_central       = HOD_central_parameters,     # Remaining arguments to pass to kind_central
                           kind_satellite       = HOD_satellite_kind,         # Function to compute satellite galaxies (1st arguments must be mass in Msun/h)
                           kwargs_satellite     = HOD_satellite_parameters)   # Remaining arguments to pass to kind_satellite
  • in \((k_\parallel,k_\perp)\) space

Z.galaxy_RSD_Pk_2D(bias                 = bb,                        # Galaxy bias (used only if model = 'HOD' or 'halo model')
                   growth_rate          = ff,                        # Growth rate f = dln(D)/dln(a)
                   velocity_dispersion  = sv,                        # Average velocity dispersion of galaxies in halos
                   model                = RSD_model,                 # Model to compute RSD
                   kwargs_mass_function = {'a': 0.707, 'p': 0.3},    # Parameters to compute halo mass function (used only if model = 'HOD' or 'halo model')
                   kwargs_concentration = {'c0': 9., 'b': 0.13},     # Parameters to compute concentration parameter (used only if model = 'HOD' or 'halo model')
                   fingers_of_god       = FoG_damping,               # Kind of damping ('Lorentzian' or 'Gaussian', used only if model != 'halo model')
                   kind_central         = HOD_central_kind,          # Function to compute central galaxies (1st arguments must be mass in Msun/h)
                   kwargs_central       = HOD_central_parameters,    # Remaining arguments to pass to kind_central
                   kind_satellite       = HOD_satellite_kind,        # Function to compute satellite galaxies (1st arguments must be mass in Msun/h)
                   kwargs_satellite     = HOD_satellite_parameters)  # Remaining arguments to pass to kind_satellite

The result should be the following:

../../_images/rsd_spectrum.png