def get_r200(self, comoving=True): """ Returns R200mean of each halo Args: comoving: (optional) if True convert to comoving distance Returns: array of R200mean [Mpc/h] """ cosmo = Cosmology(par.h0, par.OmegaM, par.OmegaL) rho_mean = cosmo.mean_density(self.get("zcos")) r200 = (3./(800*np.pi) * self.get("mass") / rho_mean)**(1./3) if comoving: return r200 * (1.+self.get("zcos")) else: return r200
class PowerSpec(object): """ Class containing the linear power spectrum and useful methods Args: filename: Tabulated file of linear P(k) at z=0 h0: Hubble parameter at z=0, in units [100 km/s/Mpc] OmegaM: Omega matter at z=0 """ def __init__(self, filename, h0, OmegaM): self.k, self.P = np.loadtxt(filename, unpack=True) self.cosmo = Cosmology(h0, OmegaM) self.tck = self.__get_sigma_spline() #spline fit to sigma(M,z=0) def P_lin(self, k, z): """ Returns the linear power spectrum at redshift z Args: k: array of k in units [h/Mpc] z: array of z Returns: array of linear power spectrum in units [Mpc/h]^-3 """ tck = splrep(np.log10(self.k), np.log10(self.P)) P0 = 10**splev(np.log10(k), tck) return P0 * self.cosmo.growth_factor(z)**2 def Delta2_lin(self, k, z): """ Returns the dimensionless linear power spectrum at redshift z, defined as Delta^2(k) = 4pi * (k/2pi)^3 * P(k) Args: k: array of k in units [h/Mpc] z: array of z Returns: array of dimensionless linear power spectrum """ return self.P_lin(k, z) * k**3 / (2 * np.pi**2) def W(self, k, R): """ Window function in k-space (Fourier transform of top hat window) Args: k: array of k in units [h/Mpc] z: array of R in units [Mpc/h] Returns: window function """ return 3 * (np.sin(k * R) - k * R * np.cos(k * R)) / (k * R)**3 def R_to_M(self, R): """ Average mass enclosed by a sphere of comoving radius R Args: R: array of comoving radius in units [Mpc/h] Returns: array of mass in units [Msun/h] """ return 4. / 3 * np.pi * R**3 * self.cosmo.mean_density(0) def M_to_R(self, M): """ Comoving radius of a sphere which encloses on average mass M Args: M: array of mass in units [Msun/h] Returns: array of comoving radius in units [Mpc/h] """ return (3 * M / (4 * np.pi * self.cosmo.mean_density(0)))**(1. / 3) def __func(self, k, R): # function to integrate to get sigma(M) return self.k**2 * self.P * self.W(k, R)**2 def __get_sigma_spline(self): # spline fit to sigma(R) at z=0 logR = np.arange(-2, 2, 0.01) sigma = np.zeros(len(logR)) R = 10**logR for i in range(len(R)): sigma[i] = simps(self.__func(self.k, R[i]), self.k) sigma = sigma / (2 * np.pi**2) sigma = np.sqrt(sigma) return splrep(logR, np.log10(sigma)) def sigmaR_z0(self, R): """ Returns sigma(R), the rms mass fluctuation in spheres of radius R, at redshift 0 Args: R: array of comoving distance in units [Mpc/h] Returns: array of sigma """ return 10**splev(np.log10(R), self.tck) def sigmaR(self, R, z): """ Returns sigma(R,z), the rms mass fluctuation in spheres of radius R, at redshift z Args: R: array of comoving distance in units [Mpc/h] z: array of redshift Returns: array of sigma """ return self.sigmaR_z0(R) * self.delta_c(0) / self.delta_c(z) def sigma_z0(self, M): """ Returns sigma(M), the rms mass fluctuation in spheres of mass M, at redshift 0 Args: M: array of mass in units [Msun/h] Returns: array of sigma """ R = self.M_to_R(M) return self.sigmaR_z0(R) def sigma(self, M, z): """ Returns sigma(M), the rms mass fluctuation in spheres of mass M, at redshift z Args: M: array of mass in units [Msun/h] z: array of redshift Returns: array of sigma """ return self.sigma_z0(M) * self.delta_c(0) / self.delta_c(z) def nu(self, M, z): """ Returns nu = delta_c(z=0) / (sigma(M,z=0) * D(z)) Args: M: array of mass in units [Msun/h] z: array of redshift Returns: array of nu """ return self.delta_c(z) / self.sigma_z0(M) def f_ST(self, nu): """ Returns Sheth-Tormen mass function Args: nu: array of nu Returns: array of mass function """ A = 0.216 q = 0.707 p = 0.3 x = q * nu**2 return A * (1. + 1. / x**p) * np.exp(-x / 2.) def mass_function(self, M, z): """ Returns number density of haloes predicted by the Sheth-Tormen mass function Args: M: array of mass in units [Msun/h] z: array of redshift Returns: array of number density in units [Mpc/h]^-3 """ nu = self.nu(M, z) f = self.f_ST(nu) return f * nu * -self.alpha(M,z) * np.log(10) * \ self.cosmo.mean_density(0) / M def b(self, nu, z): """ Returns Sheth-Tormen halo bias, where the values of the parameters have been modified to reproduce the halo bias measured from the OuterRim simulation, in which haloes are defined as friends-of-friends groups with linking length b=0.168 Args: nu: array of nu z: array of redshift Returns: array of halo bias """ # bias (peak background split) dc = self.delta_c(0) a = 0.707 * 1.15 p = 0.15 x = a * nu**2 A = (x - 1.) / dc B = 2 * p / (dc * (1. + x**p)) return 1. + A + B def bM(self, M, z): """ Returns Sheth-Tormen halo bias, as a function of mass, where the values of the parameters have been modified to reproduce the halo bias measured from the OuterRim simulation, in which haloes are defined as friends-of-friends groups with linking length b=0.168 Args: M: array of mass in units [Msun/h] z: array of redshift Returns: array of halo bias """ nu = self.nu(M, z) return self.b(nu, z) def __f_int1(self, M, z): #function to integrate when calculating b_eff nu = self.nu(M, z) x = self.b(nu, z) * self.f_ST(nu) / M return x def __f_int2(self, M, z): #function to integrate when calculating b_eff nu = self.nu(M, z) return self.f_ST(nu) / M def b_eff(self, Mmin, Mmax, z): """ Returns the effective bias of haloes in the mass range Mmin < M < Mmax at redshift z Args: Mmin: minimum halo mass in units [Msun/h] Mmax: maximum halo mass in units [Msun/h] z: redshift Returns: effective halo bias """ A = quad(self.__f_int1, Mmin, Mmax, args=z)[0] B = quad(self.__f_int2, Mmin, Mmax, args=z)[0] return A / B def R_nl(self, z): """ Returns the non-linear scale, defined as the value of R where sigma(R,z) = 1 Args: z: redshift Returns: non-linear scale in units [Mpc/h] """ def func(logM, z): return np.log10(self.sigma(10**logM, z))**2 M = 10**minimize(func, x0=12, args=(z, ))['x'] R = self.M_to_R(M) return R def var_f(self, Rnl, Lbox, z): """ Returns the expected variance of the the smoothed displacement field Args: Rnl: non-linear smoothing scale in units [Mpc/h] Lbox: simulation box size in units [Mpc/h] z: redshift Returns: variance of the displacement field """ def func(k, Rnl, z): return np.exp(-(k**2*Rnl**2)) * \ self.Delta2_lin(k,z) / k**2 kbox = 2 * np.pi / Lbox lnk = np.arange(np.log(kbox), 10, 0.001) k = np.exp(lnk) f = func(k, Rnl, z) return np.sum(f) * 0.001 def delta_c(self, z): """ Returns delta_c, the linear density threshold for collapse, at redshift z Args: z: redshift Returns: delta_c """ return 1.686 / self.cosmo.growth_factor(z)