CLensPy¶
Welcome to CLensPy, a Python package for cluster gravitational lensing analysis.
Overview¶
CLensPy provides a toolkit for computing weak-lensing observables from dark matter halo profiles: NFW and Einasto density profiles, projected surface density Sigma(R), excess surface density DeltaSigma(R), halo bias, and the two-halo term. It is designed to be:
Modular: each halo profile is a small, self-contained class with the same
density/sigma/deltasigmainterfaceFast: vectorized NumPy/SciPy implementations, with closed-form or series expansions used where available (e.g. the Einasto profile’s projected density)
Validated: cross-checked against independent codes (
pyccl,cluster_toolkit,CLMM) in the test suite
Credits¶
The covariance modules are a refactor and an optimized version of the
method and code of Wu et al. (2019,
arXiv:1907.06611) and Hao-Yi Wu’s
cluster-lensing-cov.
See Covariance for what is theirs and what is new here.
CLensPy is also developed for and validated against the DES cluster
cosmology analysis. We thank the DES cluster team, in particular Tom
McClintock (cluster_toolkit;
McClintock et al. 2019, arXiv:1805.00039)
and the authors of
y3_cluster_cpp. The cluster
number-count and lensing forward model follows Aguena et al. 2023
(arXiv:2309.06593) and the optical
selection-bias and projection-lensing model follows Costanzi et al. 2026
(PhRvD 113, 103508,
arXiv:2604.05833). Full BibTeX is in the
README.
Installation¶
CLensPy is not yet published on PyPI; install it from source:
git clone https://github.com/estevesjh/clenspy.git
cd clenspy
pip install -e .
See Installation for optional dependency groups (docs, compare,
dev).
Quick Start¶
from clenspy.halo import EinastoProfile, NfwProfile
# h-free absolute units: mass in Msun, lengths in Mpc, densities in
# Msun/Mpc^3, wavenumbers in 1/Mpc -- no cosmology object needed, only the
# reference density rho_ref that mass_def is measured against (default:
# the comoving mean matter density, giving M_200m).
m200 = 1e14 # Msun
c200 = 5.0
nfw = NfwProfile(m200=m200, c200=c200)
print(f"r200 = {nfw.r200:.4f} Mpc, rs = {nfw.rs:.4f} Mpc, "
f"rho_s = {nfw.rho_s:.3e} Msun/Mpc^3")
r = np.array([0.1, 0.5, 1.0, 2.0]) # Mpc
print("rho_NFW(r) [Msun/Mpc^3] =", nfw.density(r))
# same r_s as the NFW halo (r_s = r200/c200), rho_0 solved so the enclosed
# mass at r200 matches m200 -- a fair shape-only comparison at fixed mass
# and scale radius. alpha=0.25 is a typical cluster shape (Retana-Montenegro
# et al. 2012 report alpha ~ 0.16-0.25 for clusters).
alpha = 0.25
rho0_unit = EinastoProfile(alpha=alpha, rho_0=1.0, r_s=nfw.rs, tol=1e-4)
rho0 = m200 / rho0_unit.enclosed_mass(nfw.r200)
einasto = EinastoProfile(alpha=alpha, rho_0=rho0, r_s=nfw.rs, tol=1e-4)
print("rho_Einasto(r) [Msun/Mpc^3] =", einasto.density(r))
# fourier() returns rho_tilde(k), the *unnormalized* FT -- units of mass,
# going to M as k -> 0, not the dimensionless mass-normalized u(k|M).
k = np.array([0.1, 1.0, 10.0]) # 1/Mpc
print("rho_tilde_NFW(k) [Msun] =", nfw.fourier(k))
print("rho_tilde_Einasto(k) [Msun] =", einasto.fourier(k))
r200 = 1.4303 Mpc, rs = 0.2861 Mpc, rho_s = 3.547e+14 Msun/Mpc^3
rho_NFW(r) [Msun/Mpc^3] = [5.57109391e+14 2.68756655e+13 5.02012592e+12 7.94381981e+11]
rho_Einasto(r) [Msun/Mpc^3] = [5.83600877e+14 2.77183496e+13 4.86300049e+12 6.13799586e+11]
rho_tilde_NFW(k) [Msun] = [9.98998564e+13 9.05346969e+13 8.91993930e+12]
rho_tilde_Einasto(k) [Msun] = [1.83204136e+14 1.06342641e+14 9.27420738e+12]
This is one section of the same notebook every Theory page’s own example
pulls from — see examples/getting_started.ipynb in the repository for
the full runnable notebook, one section per physical effect, from the
cosmology through the covariance.
API Reference¶
For a detailed breakdown of every class and function, see the API Reference.
Additional Resources¶
Development: see Development for running tests, the optional comparison-test dependencies, and building these docs locally
Theory: the Cosmology toctree caption onward is a physics-first walkthrough of every quantity CLensPy computes — prose, the governing equation, and a runnable snippet, one page per physical effect
Notes: see Einasto Profile: Mathematics and Current Implementation for the Einasto profile’s math - exact anchors, the stable residue-series backend (any
n > 0, with resonance pairing), and theP(k)dispatchSource code: https://github.com/estevesjh/clenspy
Issue tracker: https://github.com/estevesjh/clenspy/issues
Getting Started
Halo profiles
Selection effects
Survey
Cluster observables
Covariance
Reference
Archive (session planning notes, not maintained)