def get_combined_shear_ia_spline(self, block, kernel_name, sample_name, i, z): # Get basic W spline that this thing starts from. # Might have it already or need to make it fresh (and store it) W_kernel_name = "W_" + kernel_name[2:] W_dict = self.kernels_A[W_kernel_name] W = W_dict.get(i) if W is None: print(sample_name, i + 1) W = limber.get_named_w_spline(block, sample_name, i + 1, z, self.chi_max, self.a_of_chi) if W is None: raise ValueError( "Could not load the W(z) splines needed for limber integral (fast shear+IA, name={} bin={})" .format(sample_name, i + 1)) W_dict[i] = W # This one is quick to calculate so I won't mess around caching it N = limber.get_named_nchi_spline(block, sample_name, i + 1, z, self.a_of_chi, self.chi_of_z) # Check that the P_II(k,z) does not z1, k1, P_II = block.get_grid(names.intrinsic_power, "z", "k_h", "p_k") z2, k2, P_GI = block.get_grid(names.matter_intrinsic_power, "z", "k_h", "p_k") assert np.allclose( k1, k2 ), "Non-matching PII and PGI in the Fast Shear+IA C_ell calculator" assert np.allclose( z1, z2 ), "Non-matching PII and PGI in the Fast Shear+IA C_ell calculator" chi = self.chi_of_z(z) chi1 = self.chi_of_z(z1) if (P_GI[:, 0] == 0).all(): # If there are no intrinsic alignments we can just use W kernel = W else: F1 = P_II[:, 0] / P_GI[:, 0] F_test = P_II[:, -1] / P_GI[:, -1] assert np.allclose( F1, F_test ), "Scale dependent IA cannot be used with Fast Shear+IA C_ell calculator" F = GSLSpline(chi1, F1) Q = W(chi) + F(chi) * N(chi) / lensing_prefactor(block) kernel = GSLSpline(chi, Q) return kernel
def growth_from_power(chi, k, p, k_growth): "Get D(chi) from power spectrum" growth_ind = np.where(k > k_growth)[0][0] growth_array = np.sqrt( np.divide(p[:, growth_ind], p[0, growth_ind], out=np.zeros_like(p[:, growth_ind]), where=p[:, growth_ind] != 0.)) return GSLSpline(chi, growth_array)
def limber(WX, WY, P, xlog, ylog, ell, prefactor): config = c_limber_config() config.xlog = xlog config.ylog = ylog config.n_ell = len(ell) config.ell = np.ctypeslib.as_ctypes(ell) config.prefactor = prefactor spline = GSLSpline(lib.limber_integral( ct.byref(config), WX, WY, P), xlog=xlog, ylog=ylog) return spline
def get_tSZ_kernel(chi_max, a_of_chi, h): n = 500 chi = np.linspace(0, chi_max, n, endpoint=True) a = a_of_chi(chi) y_fac = 8.125561e-16 # sigma_T/m_e*c^2 in SI mpc = 3.086e22 # m/Mpc eV = 1.60218e-19 # Electronvolt in Joules cm = 0.01 # Centimetre in metres y_kernel_const = y_fac * mpc * eV * cm**-3 / h return GSLSpline(chi, y_kernel_const / a**2)
def load_distance_splines(self, block): # Extract some useful distance splines # have to copy these to get into C ordering (because we reverse them) z_distance = block[names.distances, 'z'] a_distance = block[names.distances, 'a'] chi_distance = block[names.distances, 'd_m'] if z_distance[1] < z_distance[0]: z_distance = z_distance[::-1].copy() a_distance = a_distance[::-1].copy() chi_distance = chi_distance[::-1].copy() h0 = block[names.cosmological_parameters, "h0"] # convert Mpc to Mpc/h chi_distance *= h0 if block.has_value(names.distances, 'CHISTAR'): self.chi_star = block[names.distances, 'CHISTAR'] * h0 else: self.chi_star = None self.chi_max = chi_distance.max() self.a_of_chi = GSLSpline(chi_distance, a_distance) self.chi_of_z = GSLSpline(z_distance, chi_distance)
def growth_from_power(chi, k, p, k_growth): "Get D(chi) from power spectrum" growth_ind = np.where(k > k_growth)[0][0] p_0 = p[0, growth_ind] # The power spectrum might not be defined at z=0. Set growth to 1 in that # case, since it gets only used in get_reduced_kernel. if np.isclose(p_0, 0.0): p_0 = 1.0 growth_array = np.sqrt( np.divide(p[:, growth_ind], p_0, out=np.zeros_like(p[:, growth_ind]), where=p[:, growth_ind] != 0.)) return GSLSpline(chi, growth_array)
def limber(WX, WY, P, xlog, ylog, ell, prefactor, rel_tol=1e-3, abs_tol=1e-5): config = c_limber_config() config.xlog = xlog config.ylog = ylog config.n_ell = len(ell) config.ell = np.ctypeslib.as_ctypes(ell) config.prefactor = prefactor config.status = 0 config.absolute_tolerance = abs_tol config.relative_tolerance = rel_tol spline_ptr = lib.limber_integral(ct.byref(config), WX, WY, P) if config.status == LIMBER_STATUS_ERROR: raise ValueError("Error running Limber integral. More info above.") elif config.status == LIMBER_STATUS_ZERO: ylog = False elif config.status == LIMBER_STATUS_NEGATIVE: ylog = False spline = GSLSpline(spline_ptr, xlog=xlog, ylog=ylog) return spline
def get_cmb_kappa_spline(chi_max, chi_star, a_of_chi): "Compute the CMB WL kernel W_cmb(chi) spline" return GSLSpline(lib.cmb_wl_kappa_kernel(chi_max, chi_star, a_of_chi))
def get_named_w_spline(block, section, bin, z, chi_max, a_of_chi): "Compute a shear kernel W(chi) spline" return GSLSpline(lib.get_named_w_spline(block._ptr, section.encode('ascii'), bin, z, chi_max, a_of_chi))
def get_named_nchi_spline(block, section, nbin, z, a_of_chi, chi_of_z): return GSLSpline(lib.get_named_nchi_spline(block._ptr, section.encode('ascii'), nbin, z, a_of_chi, chi_of_z))
def get_reduced_kernel(orig_kernel, d_of_chi): return GSLSpline(lib.get_reduced_kernel(orig_kernel, d_of_chi))