Integrated Effects

Integrated contributions arise from line-of-sight integrals between the observer and source, including lensing convergence, the integrated Sachs-Wolfe (ISW) effect, and time delay. These are important for unbiased \(f_\mathrm{NL}\) constraints – neglecting them can bias \(f_\mathrm{NL}\) by several sigma.

Integration Methods

CosmoWAP provides two underlying integration routines (in integrated.BaseInt) for evaluating line-of-sight integrals:

BaseInt.single_int(func, \*args, n=128, remove_div=True, source_func=None)

Gauss-Legendre quadrature over a single line-of-sight integral \(\int_0^{1} f(y)\, dy\), where \(y = \chi/d\) is the normalised radial distance. Used for RSD x Integrated terms.

Parameters:
  • n (int) – Number of quadrature nodes

  • remove_div (bool) – Excise numerical divergence near the source (default: True)

  • source_func – Optional function returning the integrand value at the source, used for interpolation near the divergence

BaseInt.double_int(func, \*args, n=128, n2=None, fast=True)

Gauss-Legendre quadrature over a double line-of-sight integral \(\int_0^{1}\!\int_0^{1} f(y_1, y_2)\, dy_1\, dy_2\), where \(y_i = \chi_i/d\). Used for Integrated x Integrated terms. Exploits symmetry \(f(y_1, y_2) = f(y_2, y_1)\) when fast=True to reduce memory and computation.

Parameters:
  • n (int) – Number of quadrature nodes for first integral

  • n2 (int) – Nodes for second integral (default: same as n)

  • fast (bool) – Sum directly rather than building the full 2D grid (default: True)

Numerical \(\mu\) Pipeline

pk_int.get_multipole provides an alternative numerical approach for computing power spectrum multipoles. Rather than using the analytically-derived multipole expressions (e.g. pk.NPP.l0), it constructs the full \(P(k,\mu)\) from first-order field kernels (defined in lib/kernels.py) and numerically projects onto Legendre multipoles. This handles any combination of standard and integrated kernels with a single interface.

pk_int.get_multipole(kernel1, kernel2, l, cosmo_funcs, kk, zz, sigma=None, n=32, n_mu=256, nr=2000, deg=8, delta=0.1, GL=False)

Compute the l-th multipole of the power spectrum for a given pair of kernels.

Parameters:
  • kernel1 (list) – Kernel(s) for field 1 (e.g. ['N'], ['N', 'LP'], ['I'])

  • kernel2 (list) – Kernel(s) for field 2

  • l (int) – Multipole order

  • cosmo_funcsClassWAP instance

  • kk (array) – Wavevectors [h/Mpc]

  • zz (float) – Redshift

  • sigma (float) – FoG damping

  • n (int) – Number of Gauss-Legendre nodes for the line-of-sight integral

  • n_mu (int) – Number of \(\mu\) integration points

  • nr (int) – Number of radial points for the kernel integration

  • deg (int) – Polynomial degree for Filon integration

  • delta (float) – Width of the central region for non-uniform \(\mu\) grid

  • GL (bool) – Use Gauss-Legendre for \(\mu\) integration (default: non-uniform grid)

Returns:

Power spectrum multipole [(Mpc/h)^3]

Available Kernels

The kernels are defined in lib/kernels.py (class K1). Each kernel represents a first-order field contribution to the observed galaxy overdensity.

Standard (evaluated at source):

  • 'N' – Newtonian (Kaiser RSD): \(D(z)[b_1 + f\mu^2]\)

  • 'LP' – Local projection effects (relativistic): \(D(z)[i\mu\,\beta_1/k + \beta_2/k^2]\)

Integrated (line-of-sight):

  • 'I' – All integrated effects combined (L + TD + ISW)

  • 'L' – Lensing convergence

  • 'TD' – Time delay

  • 'ISW' – Integrated Sachs-Wolfe

The power spectrum for any pair of kernels is \(P_\ell(k) = \frac{2\ell+1}{2}\int_{-1}^{1} K_1 K_2^* P(k)\, \mathcal{L}_\ell(\mu)\, d\mu\), where the line-of-sight integrals for integrated kernels are handled internally.

Usage

import numpy as np
import cosmo_wap as cw
from cosmo_wap.pk import pk_int
from cosmo_wap.lib import utils

cosmo = utils.get_cosmo()
survey = cw.SurveyParams.Euclid(cosmo)
cosmo_funcs = cw.ClassWAP(cosmo, survey)

k = np.linspace(0.01, 0.3, 100)
z = 1.0

# Standard Newtonian (Kaiser x Kaiser) -- equivalent to pk.NPP
P0_NPP = pk_int.get_multipole(['N'], ['N'], 0, cosmo_funcs, k, z)

# Newtonian + local projection (Kaiser + GR)
P0_full = pk_int.get_multipole(['N', 'LP'], ['N', 'LP'], 0, cosmo_funcs, k, z)

# Integrated x NPP (lensing + ISW + TD crossed with Kaiser)
P0_IntNPP = pk_int.get_multipole(['I'], ['N'], 0, cosmo_funcs, k, z)
P2_IntNPP = pk_int.get_multipole(['I'], ['N'], 2, cosmo_funcs, k, z)

# Integrated x Integrated
P0_IntInt = pk_int.get_multipole(['I'], ['I'], 0, cosmo_funcs, k, z)

# Individual components (e.g. Lensing x NPP only)
P0_LxNPP = pk_int.get_multipole(['L'], ['N'], 0, cosmo_funcs, k, z)

Analytic Multipole Classes

Analytically-derived multipole expressions are also available in pk.int and pk.int_components. These are computed in Mathematica and exported, with the line-of-sight integrals evaluated via Gauss-Legendre quadrature.

class pk.int.IntNPP

RSD x Integrated (single line-of-sight integral).

l0(cosmo_funcs, k1, zz=0, t=0, sigma=None, n=128)
l1(cosmo_funcs, k1, zz=0, t=0, sigma=None, n=128)
l2(cosmo_funcs, k1, zz=0, t=0, sigma=None, n=128)
l3(cosmo_funcs, k1, zz=0, t=0, sigma=None, n=128)
l4(cosmo_funcs, k1, zz=0, t=0, sigma=None, n=128)
l(l, cosmo_funcs, k1, zz=0, t=0, sigma=None, n=128, n_mu=16)

Generic l-th multipole via numeric \(\mu\) integration.

mu(mu, cosmo_funcs, k1, zz=0, t=0, sigma=None, n=128)

Full \(P(k, \mu)\).

class pk.int.IntInt

Integrated x Integrated (double line-of-sight integral).

l0(cosmo_funcs, k1, zz=0, t=0.5, sigma=None, n=128, fast=True)
l1(cosmo_funcs, k1, zz=0, t=0.5, sigma=None, n=128, fast=True)
l2(cosmo_funcs, k1, zz=0, t=0.5, sigma=None, n=128, fast=True)
l3(cosmo_funcs, k1, zz=0, t=0.5, sigma=None, n=128, fast=True)
l4(cosmo_funcs, k1, zz=0, t=0.5, sigma=None, n=128, fast=True)
l(l, cosmo_funcs, k1, zz=0, t=0.5, sigma=None, n=128, n_mu=16)

Generic l-th multipole via numeric \(\mu\) integration.

mu(mu, cosmo_funcs, k1, zz=0, t=0.5, sigma=None, n=128)

Full \(P(k, \mu)\).

Individual integrated component classes are also available in pk.int_components:

  • LxL, LxTD, LxISW, TDxTD, ISWxISW, TDxISW

Each provides l0 through l4 multipoles with the same interface as IntInt.