def check_background_nu(cosmo): """ Check that background functions can be run and that the growth functions exit gracefully in functions with massive neutrinos (not implemented yet). """ # Types of scale factor input (scalar, list, array) a_scl = 0.5 a_lst = [0.2, 0.4, 0.6, 0.8, 1.] a_arr = np.linspace(0.2, 1., 5) # growth_factor assert_raises(CCLError, ccl.growth_factor, cosmo, a_scl) assert_raises(CCLError, ccl.growth_factor, cosmo, a_lst) assert_raises(CCLError, ccl.growth_factor, cosmo, a_arr) # growth_factor_unnorm assert_raises(CCLError, ccl.growth_factor_unnorm, cosmo, a_scl) assert_raises(CCLError, ccl.growth_factor_unnorm, cosmo, a_lst) assert_raises(CCLError, ccl.growth_factor_unnorm, cosmo, a_arr) # growth_rate assert_raises(CCLError, ccl.growth_rate, cosmo, a_scl) assert_raises(CCLError, ccl.growth_rate, cosmo, a_lst) assert_raises(CCLError, 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))) # 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')))
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 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)) ) # 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')) )
def r_Delta(cosmo, halo_mass, a, Delta=200, is_matter=False): """ Calculate the reference radius of a halo. .. note:: this is R=(3M/(4*pi*rho_c(a)*Delta))^(1/3), where rho_c is the critical matter density Arguments --------- cosmo : ``pyccl.Cosmology`` object Cosmological parameters. halo_mass : float or array_like Halo mass [Msun]. a : float Scale factor Delta : float Overdensity parameter. Returns ------- float or array_like : The halo reference radius in `Mpc`. """ omega_factor = 1. if is_matter: omega_factor = ccl.omega_x(cosmo, a, 'matter') prefac = Delta * omega_factor * 1.16217766E12 * ( cosmo['h'] * ccl.h_over_h0(cosmo, a))**2 return (halo_mass / prefac)**(1. / 3.)
def Tb(self, z): Ez = ccl.h_over_h0(self.C, 1. / (1. + z)) # Note potentially misleading notation: # Ohi = (comoving density at z) / (critical density at z=0) Ohi = 4e-4 * (1 + z)**0.6 Tb = 188e-3 * self.C['h'] / Ez * Ohi * (1 + z)**2 return Tb
def cutWedge(self, noise, kperp, kpar, z, NW=3.0): r = ccl.comoving_radial_distance(self.C, 1 / (1. + z)) H = self.C['H0'] * ccl.h_over_h0(self.C, 1. / (1. + z)) slope = r * H / 3e5 * 1.22 * 0.21 / self.D * NW / 2.0 noiseout = np.copy(noise) noiseout[np.where(kpar < kperp * slope)] = 1e30 return noiseout
def signal_power(zc, k, mu, cosmo, params): """ Return the signal auto- and cross-power spectra. """ # Scale factor at central redshift a = 1. / (1. + zc) # Get matter power spectrum pk = ccl.linear_matter_power(cosmo, k, a) # Get redshift-dep. functions b = bias(zc, params) rg = corrfac(zc, params) f = params['x_f'] * ccl.growth_rate(cosmo, a) beta = f / b H = params['x_H'] * ccl.h_over_h0(cosmo, a) * 100. * cosmo['h'] # km/s/Mpc # Redshift-space suppression factors D_g = 1. / np.sqrt(1. + 0.5 * (k * mu * sigma_g(zc, params))**2.) D_u = np.sinc(k * sigma_u(zc, params)) # galaxy-galaxy (dimensionless) pk_gg = b**2. * (1. + 2. * rg * beta * mu**2. + beta**2. * mu**4.) * D_g**2. * pk # galaxy-velocity (units: km/s) pk_gv = 1.j * a * H * f * b * mu * (rg + beta * mu**2.) * D_g * D_u / k * pk #pk_vg = -1. * pk_gv # Complex conjugate # velocity-velocity (units: [km/s]^2) pk_vv = (a * H * f * mu)**2. * (D_u / k)**2. * pk # Multiply all elements by P(k) and return return pk_gg, pk_gv, pk_vv
def test_tracer_nz_support(): z_max = 1.0 a = np.linspace(1 / (1 + z_max), 1.0, 100) background_def = { "a": a, "chi": ccl.comoving_radial_distance(COSMO, a), "h_over_h0": ccl.h_over_h0(COSMO, a) } calculator_cosmo = ccl.CosmologyCalculator(Omega_c=0.27, Omega_b=0.045, h=0.67, sigma8=0.8, n_s=0.96, background=background_def) z = np.linspace(0., 2., 2000) n = dndz(z) with pytest.raises(ValueError): _ = ccl.WeakLensingTracer(calculator_cosmo, (z, n)) with pytest.raises(ValueError): _ = ccl.NumberCountsTracer(calculator_cosmo, has_rsd=False, dndz=(z, n), bias=(z, np.ones_like(z))) with pytest.raises(ValueError): _ = ccl.CMBLensingTracer(calculator_cosmo, z_source=2.0)
def redshift_space_density(self, delta_x=None, velocity_z=None, sigma_nl=0., method='linear'): """ Remap the real-space density field to redshift-space using the line-of- sight velocity field. Parameters: delta_x (array_like, optional): Real-space density field. velocity_z (array_like, optional): Velocity in the z (line-of-sight) direction (km/s). sigma_nl (float, optional): Optionally, add random small-scale incoherent velocities along the LOS (uncorrelated Gaussian; km/s). method (str, optional): Interpolation method to use when performing remapping, using the `scipy.interpolate.griddata` function. Default: 'linear'. """ # Expansion rate (km/s/Mpc) Hz = 100. * self.cosmo['h'] * ccl.h_over_h0(self.cosmo, self.scale_factor) # Empty redshift-space array delta_s = np.zeros_like(delta_x) - 1. # Default value is -1 (void) # Loop over x and y pixels for i in range(delta_x.shape[0]): for j in range(delta_x.shape[1]): # Realisation of uncorrelated non-linear velocities vel_nl = 0. if sigma_nl > 0.: vel_nl = sigma_nl * np.random.normal(0., 1., self.z.size) # Redshift-space z coordinate (negative sign as we will map # from real coord to redshift-space coord) s = self.z - (velocity_z[i, j, :] + vel_nl) / Hz # Apply periodic boundary conditions length_z = np.max(self.z) - np.min(self.z) s = (s - np.min(self.z)) % (length_z) + np.min(self.z) # Use average value of endpoints as fill value fill_value = 0.5 * (delta_x[i, j, 0] + delta_x[i, j, -1]) # Remap to redshift-space (on regular grid in redshift-space # with same grid points as in 'z' array) delta_s[i, j, :] = griddata(points=(s, ), values=delta_x[i, j, :], xi=(self.z), method=method, fill_value=fill_value) return delta_s
def _func(m, a): abs_dzda = 1 / a / a dc = ccl.comoving_angular_distance(cosmo, a) ez = ccl.h_over_h0(cosmo, a) dh = ccl.physical_constants.CLIGHT_HMPC / cosmo['h'] dvdz = dh * dc**2 / ez dvda = dvdz * abs_dzda val = hmf.get_mass_function(cosmo, 10**m, a, mdef_other=mdef) val *= sel(10**m, a) return val[0, 0] * dvda
def PNoise(self, z, kperp): """Thermal noise power spectrum. Parameters ---------- z : float Redshift. kperp : float or array kperp value(s), in Mpc^-1. Returns ------- Pn : float or array Thermal noise power spectrum, in K^2 Mpc^3. """ # Observed wavelength lam = 0.21 * (1 + z) # m # Comoving radial distance to redshift z r = ccl.comoving_radial_distance(self.C, 1 / (1. + z)) # Mpc # Conversion between kperp and uv-plane (vector norm) u u = np.asarray(kperp) * r / (2 * np.pi) # Baseline length corresponding to u l = u * lam # m # Number density of baselines in uv plane Nu = self.nofl(l) * lam**2 # Inaccurate approximation for uv-plane baseline density #umax=self.Dmax/lam #Nu=self.Nd**2/(2*np.pi*umax**2) # Field of view of single dish FOV = (lam / self.Deff)**2 # sr # Hubble parameter H(z) Hz = self.C['H0'] * ccl.h_over_h0(self.C, 1. / (1. + z)) # km s^-1 Mpc^-1 # Conversion factor from frequency to physical space y = 3e5 * (1 + z)**2 / (1420e6 * Hz) # Mpc s # System temperature (sum of telescope and sky temperatures) Tsys = self.Tsky(1420. / (1 + z)) + self.Tscope # K # 21cm noise power spectrum (Eq. D4 of paper). # Hard-codes 2 polarizations Pn = Tsys**2 * r**2 * y * (lam**4 / self.Ae**2) * 1 / ( 2 * Nu * self.ttotal) * (self.Sarea / FOV) # K^2 Mpc^3 # Catastrophically fail if we've gotten negative power spectrum values if np.any(Pn < 0): print(Nu, Pn, l, self.nofl(l), self.nofl(l / 2)) stop() return Pn
def __init__(self, cosmo, z_max=6., n_chi=1024): self.chi_max = ccl.comoving_radial_distance(cosmo, 1. / (1 + z_max)) chi = np.linspace(0, self.chi_max, n_chi) a_arr = ccl.scale_factor_of_chi(cosmo, chi) H0 = cosmo['h'] / ccl.physical_constants.CLIGHT_HMPC OM = cosmo['Omega_c'] + cosmo['Omega_b'] Ez = ccl.h_over_h0(cosmo, a_arr) fz = ccl.growth_rate(cosmo, a_arr) w_arr = 3 * cosmo['T_CMB'] * H0**3 * OM * Ez * chi**2 * (1 - fz) self._trc = [] self.add_tracer(cosmo, kernel=(chi, w_arr), der_bessel=-1)
def thermal_n(kperp, zz, D=6.0, Ns=256, hex=True): """The thermal noise for PUMA -- note noise rescaling from 5->5/4 yr.""" # Some constants. etaA = 0.7 # Aperture efficiency. Aeff = etaA * np.pi * (D / 2)**2 # m^2 lam21 = 0.21 * (1 + zz) # m nuobs = 1420 / (1 + zz) # MHz # The cosmology-dependent factors. hub = C['h'] Ez = ccl.h_over_h0(C, 1. / (1. + zz)) chi = ccl.comoving_radial_distance(C, 1 / (1. + zz)) * hub # Mpc/h. #hub = cc.H(0).value / 100.0 #Ez = cc.H(zz).value / cc.H(0).value #chi = cc.comoving_distance(zz).value * hub # Mpc/h. OmHI = 4e-4 * (1 + zz)**0.6 / Ez**2 Tbar = 0.188 * hub * (1 + zz)**2 * Ez * OmHI # K # Eq. (3.3) of Chen++19 d2V = chi**2 * 2997.925 / Ez * (1 + zz)**2 # Eq. (3.5) of Chen++19 if hex: # Hexagonal array of Ns^2 elements. n0, c1, c2, c3, c4, c5 = ( Ns / D)**2, 0.5698, -0.5274, 0.8358, 1.6635, 7.3177 uu = kperp * chi / (2 * np.pi) xx = uu * lam21 / Ns / D # Dimensionless. nbase = n0 * (c1 + c2 * xx) / ( 1 + c3 * xx**c4) * np.exp(-xx**c5) * lam21**2 + 1e-30 #nbase[uu< D/lam21 ]=1e-30 nbase[uu > Ns * D / lam21 * 1.3] = 1e-30 else: # Square array of Ns^2 elements. n0, c1, c2, c3, c4, c5 = (Ns / D)**2, 0.4847, -0.33, 1.3157, 1.5974, 6.8390 uu = kperp * chi / (2 * np.pi) xx = uu * lam21 / Ns / D # Dimensionless. nbase = n0 * (c1 + c2 * xx) / ( 1 + c3 * xx**c4) * np.exp(-xx**c5) * lam21**2 + 1e-30 #nbase[uu< D/lam21 ]=1e-30 nbase[uu > Ns * D / lam21 * 1.4] = 1e-30 # Eq. (3.2) of Chen++19 npol = 2 fsky = 0.5 tobs = 5. * 365.25 * 24. * 3600. # sec. tobs /= 4.0 # Scale to 1/2-filled array. Tamp = 62.0 # K Tgnd = 33.0 # K Tsky = 2.7 + 25 * (400. / nuobs)**2.75 # K Tsys = Tamp + Tsky + Tgnd Omp = (lam21 / D)**2 / etaA # Return Pth in "cosmological units", with the Tbar divided out. Pth = (Tsys/Tbar)**2*(lam21**2/Aeff)**2 *\ 4*np.pi*fsky/Omp/(npol*1420e6*tobs*nbase) * d2V return (Pth)
def LSSTSpecParams(C): biasfunc = lambda z: 0.95 / ccl.growth_factor(C, 1 / (1 + z)) ndens = 49 ## per /arcmin^2, LSST SRD, page 47 dndz = lambda z: z**2 * np.exp(-(z / 0.28)**0.94) ## LSST SRD, page 47 arcminfsky = 1 / (4 * np.pi / (np.pi / (180 * 60))**2) ## volume between z=3 zmax = 3 V = 4 * np.pi**3 / 3 * ccl.comoving_radial_distance(C, 1 / (1 + zmax))**3 dVdz = lambda z: 3e3 / C['h'] * 1 / ccl.h_over_h0(C, 1 / ( 1 + z)) * 4 * np.pi * ccl.comoving_radial_distance(C, 1 / (1 + z))**2 norm = ndens / (quad(dndz, 0, zmax)[0] * arcminfsky) nbarofz = lambda z: norm * dndz(z) / dVdz(z) return biasfunc, nbarofz, 0, 3, None
def get_battaglia(m,z,delta) : """Sets all parameters needed to compute the Battaglia et al. profile.""" fb=cosmo.cosmo.params.Omega_b/cosmo.cosmo.params.Omega_m ez2=(ccl.h_over_h0(cosmo,1/(1+z)))**2 h=cosmo.cosmo.params.h mr=m*1E-14 p0=18.1*mr**0.154*(1+z)**(-0.758) rDelta=R_Delta(cosmo,m,1./(1+z),Delta=delta)*(1+z) dic={'ups0':0.518*p0*2.52200528E-19*delta*m*h**2*ez2*fb*(1+z)/rDelta, 'rDelta':rDelta, 'xc':0.497*(mr**(-0.00865))*((1+z)**0.731), 'beta':4.35*(mr**0.0393)*((1+z)**0.415)} return dic
def Ntot(z, mhmin, fsky=1.): """ Calculate the total number of dark matter halos above a given mass threshold, as a function of maximum redshift and sky fraction. """ # Calculate cumulative number density n(>M_min) as a fn of M_min and redshift ndens = nm(z, mhmin=mhmin) # Integrate over comoving volume of lightcone r = ccl.comoving_radial_distance(cosmo, a) # Comoving distance, r H = 100. * cosmo['h'] * ccl.h_over_h0(cosmo, a) # H(z) in km/s/Mpc Ntot = integrate.cumtrapz(ndens * r**2. / H, z, initial=0.) Ntot *= 4. * np.pi * fsky * C_kms return Ntot
def _norm(self, cosmo, M, a, b): """Computes the normalisation factor of the Arnaud profile. .. note:: Normalisation factor is given in units of ``eV/cm^3``. \ (Arnaud et al., 2009) """ aP = 0.12 # Arnaud et al. h70 = cosmo["h"] / 0.7 P0 = 6.41 # reference pressure K = 1.65 * h70**2 * P0 * (h70 / 3e14)**(2 / 3 + aP) # prefactor PM = (M * (1 - b))**(2 / 3 + aP) # mass dependence Pz = ccl.h_over_h0(cosmo, a)**(8 / 3) # scale factor (z) dependence P = K * PM * Pz return P
def kernel(self, cosmo, a, **kwargs): """The galaxy number overdensity window function.""" unit_norm = 3.3356409519815204e-04 # 1/c Hz = ccl.h_over_h0(cosmo, a) * cosmo["h"] z = 1 / a - 1 w = kwargs["width"] nz_new = self.nzf(self.z_avg + (1 / w) * (self.z - self.z_avg)) nz_new /= simps(nz_new, x=self.z) nzf_new = interp1d(self.z, nz_new, kind="cubic", bounds_error=False, fill_value=0) return Hz * unit_norm * nzf_new(z)
def test_iswcl(): # Cosmology Ob = 0.05 Oc = 0.25 h = 0.7 COSMO = ccl.Cosmology(Omega_b=Ob, Omega_c=Oc, h=h, n_s=0.96, sigma8=0.8, transfer_function='bbks') # CCL calculation ls = np.arange(2, 100) zs = np.linspace(0, 0.6, 256) nz = np.exp(-0.5 * ((zs - 0.3) / 0.05)**2) bz = np.ones_like(zs) tr_n = ccl.NumberCountsTracer(COSMO, has_rsd=False, dndz=(zs, nz), bias=(zs, bz)) tr_i = ccl.ISWTracer(COSMO) cl = ccl.angular_cl(COSMO, tr_n, tr_i, ls) # Benchmark from Eq. 6 in 1710.03238 pz = nz / simps(nz, x=zs) H0 = h / ccl.physical_constants.CLIGHT_HMPC # Prefactor prefac = 3 * COSMO['T_CMB'] * (Oc + Ob) * H0**3 / (ls + 0.5)**2 # H(z)/H0 ez = ccl.h_over_h0(COSMO, 1. / (1 + zs)) # Linear growth and derivative dz = ccl.growth_factor(COSMO, 1. / (1 + zs)) gz = np.gradient(dz * (1 + zs), zs[1] - zs[0]) / dz # Comoving distance chi = ccl.comoving_radial_distance(COSMO, 1 / (1 + zs)) # P(k) pks = np.array([ ccl.nonlin_matter_power(COSMO, (ls + 0.5) / (c + 1E-6), 1. / (1 + z)) for c, z in zip(chi, zs) ]).T # Limber integral cl_int = pks[:, :] * (pz * ez * gz)[None, :] clbb = simps(cl_int, x=zs) clbb *= prefac assert np.all(np.fabs(cl / clbb - 1) < 1E-3)
def signal_covariance(zc, cosmo, params): """ Signal power spectrum matrix, containing (cross-)spectra for gg, gv, vv. These are simply the galaxy auto-, galaxy-velocity cross-, and velocity auto-spectra. """ # Scale factor at central redshift a = 1. / (1. + zc) # Grid of Fourier wavenumbers k = np.logspace(KMIN, KMAX, NK) mu = np.linspace(-1., 1., NMU) K, MU = np.meshgrid(k, mu) # Get matter power spectrum pk = ccl.linear_matter_power(cosmo, k, a=1.) # Get redshift-dep. functions b = bias(zc, params) rg = corrfac(zc, params) f = params['x_f'] * ccl.growth_rate(cosmo, a) beta = f / b H = params['x_H'] * ccl.h_over_h0(cosmo, a) * 100. * cosmo['h'] # km/s/Mpc # Redshift-space suppression factors D_g = 1. / np.sqrt(1. + 0.5 * (K * MU * sigma_g(zc, params))**2.) D_u = np.sinc(K * sigma_u(zc, params)) # Build 2x2 matrix of mu- and k-dependent pre-factors of P(k) fac = np.zeros((2, 2, mu.size, k.size)).astype(complex) # galaxy-galaxy (dimensionless) fac[0, 0] = b**2. * (1. + 2. * rg * beta * MU**2. + beta**2. * MU**4.) * D_g**2. # galaxy-velocity (units: km/s) fac[0, 1] = 1.j * a * H * f * b * MU * (rg + beta * MU**2.) * D_g * D_u / K fac[1, 0] = -1. * fac[0, 1] # Complex conjugate # velocity-velocity (units: [km/s]^2) fac[1, 1] = (a * H * f * MU)**2. * (D_u / K)**2. # Multiply all elements by P(k) and return return fac * pk[np.newaxis, np.newaxis, np.newaxis, :]
def PNoise(self, z, kperp): """ Thermal noise power in Mpc^3 """ lam = 0.21 * (1 + z) r = ccl.comoving_radial_distance(self.C, 1 / (1. + z)) u = kperp * r / (2 * np.pi) l = u * lam Nu = self.nofl(l) * lam**2 #umax=self.Dmax/lam #Nu=self.Nd**2/(2*np.pi*umax**2) FOV = (lam / self.Deff)**2 Hz = self.C['H0'] * ccl.h_over_h0(self.C, 1. / (1. + z)) y = 3e5 * (1 + z)**2 / (1420e6 * Hz) Tsys = self.Tsky(1420. / (1 + z)) + self.Tscope Pn = Tsys**2 * r**2 * y * (lam**4 / self.Ae**2) * 1 / ( 2 * Nu * self.ttotal) * (self.Sarea / FOV) if np.any(Pn < 0): print(Nu, Pn, l, self.nofl(l), self.nofl(l / 2)) stop() return Pn
def R_Delta(cosmo, M, a, Delta=500, is_matter=False, squeeze=True, **kwargs): """ Calculate the reference radius of a halo. .. note:: This is ``R = (3M/(4*pi*rho_c(a)*Delta))^(1/3)``, where rho_c is the critical matter density at scale factor ``a``. Arguments --------- cosmo: ~pyccl.core.Cosmology Cosmology object. M : float or array_like Halo mass [Msun]. a : float or array_like Scale factor Delta : float Overdensity parameter. is_matter : bool True when R_Delta is calculated using the average matter density. False when R_Delta is calculated using the critical density. squeeze : bool Whether to squeeze extra dimensions. **kwargs : dict Parametrisation of the profiles and cosmology. Returns ------- float or array_like : The halo reference radius in `Mpc`. """ # Input handling M, a = np.atleast_1d(M, a) if is_matter: omega_factor = ccl.omega_x(cosmo, a, "matter") else: omega_factor = 1 c1 = (cosmo["h"] * ccl.h_over_h0(cosmo, a))**2 prefac = 1.16217766e12 * Delta * omega_factor * c1 R = (M[..., None] / prefac)**(1 / 3) return R.squeeze() if squeeze else R
def _norm(self, cosmo, M, a, b): """Computes the normalisation factor of the Arnaud profile. .. note:: Normalisation factor is given in units of ``eV/cm^3``. \ (Arnaud et al., 2009) """ aP = 0.12 # Arnaud et al. h70 = cosmo["h"] / 0.7 # Value from Planck 2013 (Planck intermediate results: V.Pressure profiles of galaxy clusters from # the Sunyaev - Zeldovich effect P0 = 6.41 # reference pressure # Values from Arnaud et al., 2010 # P0 = 8.403*h70**(-3./2) K = 1.65 * h70**2 * P0 * (h70 / 3e14)**(2 / 3 + aP) # prefactor PM = (M * (1 - b))**(2 / 3 + aP) # mass dependence Pz = ccl.h_over_h0(cosmo, a)**(8 / 3) # scale factor (z) dependence P = K * PM * Pz return P
def norm(self, cosmo, M, a, b, squeeze=True): """Computes the normalisation factor of the Arnaud profile. .. note:: Normalisation factor is given in units of ``eV/cm^3``. \ (Arnaud et al., 2009) """ # Input handling M, a = np.atleast_1d(M), np.atleast_1d(a) aP = 0.12 # Arnaud et al. h70 = cosmo["h"] / 0.7 P0 = 6.41 # reference pressure K = 1.65 * h70 * P0 * (h70 / 3e14)**(2 / 3 + aP) # prefactor PM = (M * (1 - b))**(2 / 3 + aP) # mass dependence Pz = ccl.h_over_h0(cosmo, a)**(8 / 3) # scale factor (z) dependence P = K * PM[..., None] * Pz return P.squeeze() if squeeze else P
def freq_array(self, redshift=None): """ Return frequency array coordinates (in the z direction of the box). This approximates the frequency channel width to be constant across the box, which is only a good approximation in the distant observer approximation. Parameters: redshift (float, optional): Redshift to evaluate the centre of the box at. Default: Same value as ``self.redshift``. Returns: freqs (array_like): Frequencies, in MHz. Frequency decreases as z coordinate increases. """ # Check redshift if redshift is None: redshift = self.redshift a = 1. / (1. + redshift) # Calculate central frequency of box freq_centre = a * self.line_freq # Comoving voxel size dx = self.Lz / self.N # Convert comoving voxel size to frequency channel size # df / dr = df / da * (dr / da)^-1 = f0 * (a^2 H) / c Hz = 100. * self.cosmo['h'] * ccl.h_over_h0(self.cosmo, a) # km/s/Mpc df = dx * self.line_freq * (a**2. * Hz) / (C / 1e3 ) # Same units as line_freq # Comoving units in z direction: place origin in centre of box freqs = freq_centre \ + df * (np.arange(self.N) - 0.5*(self.N - 1.)) # Frequency is decreasing with increasing z coordinate return freqs[::-1]
def signal_amplitude(self, redshift=None, formula='powerlaw'): """ Brightness temperature Tb(z), in mK. Several different expressions for the 21cm line brightness temperature are available: Parameters: redshift (float, optional): Central redshift to evaluate the signal amplitude at. If not specified, uses `self.box.redshift`. formula (str, optional): Which fitting formula to use for the brightness temperature. Some of the options are a function of Omega_HI(z) - ``powerlaw``: Simple power-law fit to Mario's updated data (powerlaw M_HI function with alpha=0.6) (Default) - ``hall``: From Hall, Bonvin, and Challinor. """ if redshift is None: redshift = self.box.redshift z = redshift # Calculate OmegaHI(z) omegaHI = self.Omega_HI(redshift=redshift) # Select which formula to use if formula == 'powerlaw': # Mario Santos' fit, used in Bull et al. (2015) Tb = 5.5919e-02 + 2.3242e-01 * z - 2.4136e-02 * z**2. elif formula == 'hall': # From Hall et al. E = ccl.h_over_h0(self.box.cosmo, 1. / (1. + z)) Tb = 188. * self.box.cosmo['h'] * omegaHI * (1. + z)**2. / E else: raise ValueError("No formula found with name '%s'" % formula) return Tb
def Tb(self, z): """Approximation for mean 21cm brightness temperature. This is reasonably up-to-date, and comes from Eq. B1 in the CV 21cm paper. Parameters ---------- z : float or array Redshift(s). Returns ------- Tb : float or array Temperature value(s), in K. """ z = np.asarray(z) Ez = ccl.h_over_h0(self.C, 1. / (1. + z)) # Note potentially misleading notation: # Ohi = (comoving density at z) / (critical density at z=0) Ohi = 4e-4 * (1 + z)**0.6 Tb = 188e-3 * self.C['h'] / Ez * Ohi * (1 + z)**2 return Tb
def cutWedge(self, noise, kperp, kpar, z, NW=3.0): """Cut the foreground wedge from a 2d noise power spectrum. Parameters ---------- noise : array[nkpar,nkperp] 2d noise power spectrum. kperp : array[nkpar,nkperp] 2d array where columns are kperp values (in Mpc^-1) and rows are identical. kpar : array[nkpar,nkperp] 2d array where rows are kpar values (in Mpc^-1) and columns are identical. z : float Redshift. NW : float, optional Multiplier defining wedge in terms of primary beam. (default = 3) Returns ------- Pn : array[nkpar,nkperp] 2d noise power spectrum where modes within wedge have noise set to large value. """ # Comoving radial distance to redshift z r = ccl.comoving_radial_distance(self.C, 1 / (1. + z)) # Mpc # Hubble parameter H(z) H = self.C['H0'] * ccl.h_over_h0(self.C, 1. / (1. + z)) # km s^-1 Mpc^-1 # Slope that defines wedge as kpar < kperp * slope. # See Eq. C1 from the CV 21cm paper. slope = r * H / 3e5 * 1.22 * 0.21 / self.D * NW / 2.0 # dimensionless # Boost noise for modes within wedge noiseout = np.copy(noise) noiseout[np.where(kpar < kperp * slope)] = 1e30 return noiseout
def get_E2Omega_m(self, z): a = 1.0/(1.0+z) return ccl.omega_x(self.be_cosmo, a, "matter")*(ccl.h_over_h0(self.be_cosmo, a))**2
def rDelta(m, zz, Delta): """Returns r_Delta """ hn = ccl.h_over_h0(cosmo, 1. / (1 + zz)) rhoc = RHOCRIT0 * hn * hn return (3 * m / (4 * np.pi * Delta * rhoc))**0.333333333 * (1 + zz)
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)))