def lens_efficiency(sourcedist, dcomov, dcomov_lim, prec=12): """ Signature: lens_efficiency(sourcedist, dcomov, dcomov_lim) Description: Computes the lens efficiency function q (see e.g. equation (24)the review article by Martin Kilbinger "Cosmology with cosmic shear observations: a review", July 21, 2015, arXiv:1411.0115v2), given a source distribution function n and two comoving distances. Input types: sourcedist - np.ndarray dcomov - float (or int) or np.ndarray dcomov_lim - float Output types: float (or np.ndarray if type(dcomov)=np.ndarray) """ # interpolate the source distribution function nfunc = _CubicSpline(_np.log10(sourcedist['chi']), _np.log10(sourcedist['n'])) result = [] if isinstance(dcomov, _np.ndarray): for distance in dcomov: chi = _np.linspace(distance, dcomov_lim, 2**prec + 1) sourcedistribution = 10**nfunc(_np.log10(chi)) integrand = sourcedistribution * (1 - distance / chi) result.append(_romb(integrand, chi[1] - chi[0])) return _np.asarray(result) elif isinstance(dcomov, (float, int)): chi = _np.linspace(dcomov, dcomov_lim, 2**prec + 1) sourcedistribution = 10**nfunc(_np.log10(chi)) integrand = sourcedistribution * (1 - dcomov / chi) return _romb(integrand, chi[1] - chi[0]) else: raise (TypeError, "The second argument 'dcomov' must be either a float,\ an integer or a np.ndarray.\n")
def dist_comov(emu_pars_dict, z1, z2, prec=12): """ Signature: dist_comov(emu_pars_dict, z1, z2, prec=12) Description: Computes the comoving distance (in units of Mpc/h) between objects at redshifts z1 and z2 for a cosmology specified by the parameters Om_m (matter density parameter), Om_rad (radiation density parameter) and Om_DE (dark energy density parameter), the Hubble parameter H0, and the dark energy equation of state parameters w0 and wa. Input type: python dictionary (containing the 6 LCDM parameters) floats or np.ndarrays Output type: float or np.ndarray REMARK 1: If the redshifts z1 and z2 are passed as vectors (1-dimen- sional np.ndarrays) then the comoving distances will be com- puted between the pairs of redshift (z1_1, z2_1), (z1_2,z2_2), (z1_3, z2_3) etc. Hence, if the vectors have length n, the resulting vector of d_comov will also be of length n (and not n(n-1)). We do NOT compute the d_comov for all possible red- shift combinations. REMARK 2: The geometry of the Universe is fixed to be flat (i.e. Omega_curvature = 1) and the radiation energy density is set to Om_rad = 4.183709411969527e-5/(h*h). These values were assumed in the construction process of EuclidEmulator and hence must be used whenever one is working with it. """ if isinstance(z1, (float, int)) and isinstance(z2, (float, int)): z1 = _np.array([z1]) z2 = np.array([z2]) a1_vec = _cc.z_to_a(z1) a2_vec = _cc.z_to_a(z2) d_comov = [] for a1, a2 in zip(a1_vec, a2_vec): if a1 > a2: a1, a2 = a2, a1 # swap values avec = _np.linspace(a1, a2, 2**prec + 1) delta_a = avec[1] - avec[0] H = _cc.a_to_hubble(emu_pars_dict, avec) d_comov.append(_romb(1. / (avec * avec * H), dx=delta_a)) chi = _np.array( d_comov) # here the comoving distances have units of Mpc/(km/s) # return result in units of Mpc/h return SPEED_OF_LIGHT_IN_KILOMETERS_PER_SECOND * chi * emu_pars_dict['h']
def get_pconv(emu_pars_dict, sourcedist_func, prec=7): """ Signature: get_pconv(emu_pars_dict, sourcedist_func, prec=12) Description: Converts a matter power spectrum into a convergence power spectrum via the Limber equation (conversion is based on equation (29) of the review article by Martin Kilbinger "Cosmology with cosmic shear observations: a review", July 21, 2015,arXiv:1411.0115v2). REMARK: The g in that equation is a typo and should be q which is defined in equation (24). The input variable emu_pars_dict is a dictionary contai- ning the cosmological parameters and sourcedist is a dictionary of the format {'chi': ..., 'n': ...} containing the a vector of comoving distances ("chi") together with the number counts of source galaxies at these distances or redshifts, respectively. The precision parameter prec is an integer which defines at how many redshifts the matter power spectrum is emula- ted for integration in the Limber equation. The relation between the number of redshifts len_redshifts and the parameter prec is given by len_redshifts = 2^prec + 1 REMARK: The 'chi' vector in the sourcedist dictionary should span the range from 0 to chi(z=5). Input type: emu_pars_dict - dictionary sourcedist - function object prec - int Ouput type: dictionary of the form {'l': ..., 'Cl': ...} """ def limber_prefactor(emu_pars_dict): """ * NESTED FUNCTION * (defined inside get_pconv) Signature: LimberPrefactor(emu_pars_dict) Description: Computes the cosmology dependend prefactor of the integral in the Limber approximation. Input type: emu_pars_dict - dictionary Output type: float """ c_inv = 1. / _bg.SPEED_OF_LIGHT_IN_KILOMETERS_PER_SECOND h = emu_pars_dict['h'] H0 = 100 * h Om_m = emu_pars_dict['om_m'] / (h * h) # compute prefactor of limber equation integral # --> in units of [Mpc^4] prefac = 2.25 * Om_m * Om_m * H0 * H0 * H0 * H0 * c_inv * c_inv * c_inv * c_inv # convert prefactor units to [(Mpc/h)^4] prefac *= h * h * h * h return prefac def eval_lensingefficiency(emu_pars_dict, sd_func, z_vec): """ * NESTED FUNCTION * (defined inside get_pconv) Signature: eval_lensingefficiency(emu_pars_dict, sd_func, z_vec) Descrition: Evaluates the lensing efficiency function for a given cosmology and source galaxy distribution function at a number of different comoving distances (corresponding to different redshifts). Input types: emu_pars_dict - dictionary sd_func - function object z_vec - numpy.ndarray Output types: numpy.ndarray numpy.ndarray """ chi_lim = _bg.dist_comov(emu_pars_dict, 1e-12, 5.0) # in Mpc/h chi_vec = _bg.dist_comov(emu_pars_dict, _np.zeros_like(z_vec), z_vec) source_dict = {'chi': chi_vec, 'n': sd_func(z_vec)} lenseff = _lens.lens_efficiency(source_dict, chi_vec, chi_lim) return (chi_vec, lenseff) def get_pnonlin_of_l_and_z(emu_pars_dict, z_vec, l_vec): """ * NESTED FUNCTION * (defined inside get_pconv) Signature: get_P_of_l_and_z(emu_pars_dict, z_vec, l_vec) Description: This function computes the different k ranges for the given cosmology at all different redshifts and computes the power spectrum for these redshifts at these k modes. Input types: emu_pars_dict - dictionary z_vec - numpy.ndarray l_vec - numpy.ndarray Output type: numpy.ndarray """ P = get_pnonlin(emu_pars_dict, z_vec) # call EuclidEmulator pnonlin_array = [] for i, z in enumerate(z_vec): func = _CubicSpline(_np.log10(P['k']), _np.log10(P['P_nonlin']['z' + str(i)])) k = _cc.l_to_k(emu_pars_dict, l_vec, z) # needs to be called # inside loop because # different z-values # lead to different # results # evaluate the interpolating function of Pnl for all k in the # range allowed by EuclidEmulator (this range is given by # P['k']) pmatternl = [ 10.0**func(_np.log10(kk)) for kk in k if kk >= P['k'].min() and kk <= P['k'].max() ] # for k values below the lower bound or above the upper bound # of this k range, set the contributions to 0.0 p_toosmall = [0.0 for kk in k if kk < P['k'].min()] p_toobig = [0.0 for kk in k if kk > P['k'].max()] pnonlin_array.append( _np.array(p_toosmall + pmatternl + p_toobig)) # get the non-linear matter power spectrum in units of [(Mpc/h)^3] return _np.asarray(pnonlin_array).transpose() # ===================================== if _Class.__module__ not in _sys.modules: print "You have not imported neither classee nor classy.\n \ Emulating convergence power spectrum is hence not\n \ possible." return None z_vec = _np.logspace(_np.log10(5e-2), _np.log10(4.999999), 2**prec + 1) a_inv_vec = 1. + z_vec len_l_vec = int(1e4) l_vec = _np.linspace(1e1, 2e3, len_l_vec) # get the lensing efficiency chi_vec, q_vec = eval_lensingefficiency(emu_pars_dict, sourcedist_func, z_vec) assert len(z_vec) == len(chi_vec) # get the matter power spectrum at the correct k modes pnonlin_array = get_pnonlin_of_l_and_z(emu_pars_dict, z_vec, l_vec) assert all([ len(chi_vec) == len(pnonlin_array[i]) for i in range(len(pnonlin_array)) ]) # Compose integrand integrand = _np.array([ q_vec * q_vec * a_inv_vec * a_inv_vec * pnonlin_array[i] for i in range(len_l_vec) ]) assert integrand.shape == pnonlin_array.shape # perform integral (bear in mind that only the product of the # integral and the prefac is truely dimensionless) and return return { 'l': l_vec, 'Cl': limber_prefactor(emu_pars_dict) * _romb(integrand, chi_vec[1] - chi_vec[0]) }