HOD galaxy clustering and weak lensing prediction and fitting
Project description
hod_mod
JAX-accelerated HOD galaxy clustering, weak lensing, and gas cross-correlation predictions and fitting.
Overview
hod_mod is a Python 3.11+ package for forward-modelling galaxy clustering (w_p),
weak gravitational lensing (ΔΣ), and galaxy × gas cross-correlations (tSZ Compton-y,
soft X-ray) from Halo Occupation Distribution (HOD) and inverse-SHMR (iHOD) models.
All numerical code is JAX-native, enabling automatic differentiation and JIT
compilation for efficient MCMC inference.
Install
Available on PyPI:
pip install hod-mod
For development, create and activate the conda environment then install in editable mode:
# Download the installer (Linux x86_64)
wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh
# Run the installer (follow prompts, accept defaults)
bash Miniforge3-Linux-x86_64.sh
# Reload shell
source ~/.bashrc
mamba env create -f environment.yml
mamba activate hod_mod
pip install -e .
pre-commit install # optional: blocks committing large files / results/
Data and benchmark results
Small reference data needed to run the models ships inside the package. Large inputs and the curated benchmark results (final MCMC chains, headline figures) are archived on Zenodo and fetched on demand — the git repository stays lean.
- Dataset: 10.5281/zenodo.21078473 (concept DOI — always resolves to the latest version)
- Downloads are checksum-verified and cached locally with
pooch(a dependency, installed automatically).
from hod_mod.data_io import fetch
# downloads from Zenodo + verifies the checksum on first call; cache hit afterwards
chain = fetch("results/benchmarks/more2015_logM11_12/flatchain.npz")
See docs/data_hosting.rst for the full strategy and the upload/registry workflow.
Environment variables
All filesystem locations are resolved through hod_mod.paths
— there are no hardcoded paths in the code. Each helper reads an env var and
falls back to a sensible default, so a fresh checkout runs without configuration,
and your machine's layout is set once in ~/.bashrc.
| Variable | Helper | Points to | Default |
|---|---|---|---|
HOD_MOD_REPO |
repo_root() |
code repository (configs/, in-repo data/) |
auto-detected from the package |
HOD_MOD_DATA_DIR |
data_root() |
the data repository (external inputs: zenodo/, erosita/, legacysurvey/, st_mod_data/, xray_bands/) |
hod_mod/data |
HOD_MOD_SUMSTAT |
sum_stat_root() |
sum_stat measurement products |
~/software/sum_stat/data |
HOD_MOD_RESULTS |
results_root() |
generated outputs (chains, figures) — never in the repo | ~/.local/share/hod_mod/results |
HOD_MOD_CACHE |
cache_root() |
JAX/XLA compilation caches | OS user-cache dir |
HOD_MOD_DATA_DOI |
— | pin a specific Zenodo version (default: pinned in code) | concept DOI |
Recommended ~/.bashrc setup:
export HOD_MOD_REPO="$HOME/software/hod_mod"
export HOD_MOD_DATA_DIR="$HOME/data"
export HOD_MOD_SUMSTAT="$HOME/software/sum_stat/data"
export HOD_MOD_RESULTS="$HOME/data/hod_mod_results"
from hod_mod.paths import repo_root, data_root, sum_stat_root, results_root
print(repo_root(), data_root(), sum_stat_root(), results_root())
Tests
pytest # run all tests
pytest tests/test_cosmology.py # single module
pytest -x # stop on first failure
pytest -v # verbose output
pytest --tb=short # compact tracebacks
The test suite covers cosmology, HOD models, gas profiles, clustering predictions,
cross-spectra, data I/O, and fitting. Tests that require optional backends
(camb, colossus) are skipped automatically if those packages are absent.
Supported HOD models
| Class | Reference |
|---|---|
HODModel |
Zheng et al. 2007 |
MoreHODModel |
More et al. 2015 (BOSS CMASS) |
Kravtsov04HODModel |
Kravtsov et al. 2004 |
Guo18ICSMFModel |
Guo et al. 2018 |
Guo19ICSMFModel |
Guo et al. 2019 (eBOSS ELGs) |
Zacharegkas25HODModel |
Zacharegkas et al. 2025 |
VanUitert16CSMFModel |
van Uitert et al. 2016 |
ZuMandelbaum15HODModel |
Zu & Mandelbaum 2015 (iHOD) |
ZuMandelbaum16QuenchingModel |
Zu & Mandelbaum 2016 |
Leauthaud12HODModel |
Leauthaud et al. 2012 |
All clustering HOD classes subclass HODBase (ABC) and implement nc_ns() and
default_params().
Gas profiles and cross-correlations
hod_mod predicts galaxy × gas cross-correlations using parametric electron
pressure and density profiles embedded in the same halo model framework.
Gas profile classes (hod_mod.gas):
| Class | Physical profile | Reference |
|---|---|---|
PressureProfileA10 |
electron pressure P_e(r|M,z) → tSZ Compton-y | Arnaud et al. 2010 |
GasDensityDPM (model=1,2,3) |
electron density n_e(r|M,z) → soft X-ray ε | Oppenheimer et al. 2025 |
m200_to_m500c |
NFW bisection: M₂₀₀ → M₅₀₀c, R₅₀₀c | — |
Cross-spectrum observables (hod_mod.observables.cross_spectra):
| Method | Observable | Units |
|---|---|---|
_pk_tables_gy |
P_{g,y}(k), P_{m,y}(k), 1h+2h | (Mpc/h)² |
_pk_tables_gX |
P_{g,X}(k), 1h+2h | (Mpc/h)³ cm⁻⁶ |
projected_gy |
Σ_y(r_p) stacked tSZ profile | dimensionless Compton-y |
projected_gX |
w_{g,X}(r_p) stacked X-ray profile | (Mpc/h) cm⁻⁶ |
angular_cl_gy |
C_ℓ^{g,y} via Limber approximation | (Mpc/h)² |
angular_cl_gX |
C_ℓ^{g,X} via Limber approximation | (Mpc/h) cm⁻⁶ |
from hod_mod.gas import PressureProfileA10, GasDensityDPM
from hod_mod.observables.cross_spectra import HaloModelCrossSpectra
pp = PressureProfileA10(r_max_over_r500c=5.0, n_gl=200) # Arnaud+2010
dp = GasDensityDPM(model=2, r_max_over_r200=3.0, n_gl=200) # Oppenheimer+2025
cross = HaloModelCrossSpectra(fhmp, pressure_profile=pp, density_profile=dp)
sigma_y = cross.projected_gy(rp, z=0.5, theta_cosmo=theta, hod_params=params)
cl_gy = cross.angular_cl_gy(ell, z_arr, nz_g, theta, params)
wgX = cross.projected_gX(rp, z=0.5, theta_cosmo=theta, hod_params=params)
Benchmark data for Comparat et al. 2025
(galaxy × eROSITA 0.5–2 keV, 7 stellar-mass-selected samples, LS DR10 × eRASS:5)
is included in hod_mod/data/benchmarks/xray/.
Quick start — clustering and lensing
from hod_mod import (
LinearPowerSpectrum, make_hmf, HaloProfile,
MoreHODModel, FullHaloModelPrediction,
)
import jax.numpy as jnp
pk_lin = LinearPowerSpectrum()
theta = pk_lin.default_cosmology()
hmf = make_hmf("tinker08", pk_func=pk_lin.pk_linear)
colossus_cosmo = dict(flat=True, H0=67.36, Om0=0.31, Ob0=0.0493, sigma8=0.811, ns=0.965)
hp = HaloProfile(colossus_cosmo, cm_relation="diemer19")
hod = MoreHODModel(hmf, hmf.bias)
pred = FullHaloModelPrediction(pk_lin, hod, hp, profile="nfw")
rp = jnp.logspace(-1, 1.5, 20)
params = MoreHODModel.default_params()
wp = pred.wp(rp, pi_max=60.0, z=0.5, theta_cosmo=theta, hod_params=params)
"tinker08" is the library's dependency-free default HMF backend. The
fitting pipelines under hod_mod/scripts/fitting/ instead use
make_hmf("csst") (CSSTEMU) as their baseline — see
docs/cosmology.rst for details.
HOD fitting
Run from the repository root (paths in configs are resolved relative to it):
from hod_mod.fitting import load_config, WpFitter
cfg = load_config("configs/hod_fit_more2015_cmass.yml")
fitter = WpFitter(cfg)
result = fitter.map_fit() # Nelder-Mead MAP → dict
sampler = fitter.sample() # emcee MCMC → EnsembleSampler
chain = sampler.get_chain(flat=True) # shape (n_steps * n_walkers, n_free)
The sample data file data/more2015_boss_cmass/wp_cmass_z052.csv is included in
the repository (More+2015, arXiv:1407.1856, Figure 2).
Reproducing published results
Each benchmark paper has a dedicated validation script. Run any script from the repository root:
| Paper | Script | Observable |
|---|---|---|
| More et al. 2015 | run_benchmark.py --model more2015 |
w_p(r_p) BOSS CMASS |
| Lange et al. 2025 | run_benchmark.py --model lange2025_bgs3_bwpd_hsc |
w_p + ΔΣ DESI BGS |
| Arnaud et al. 2010 | validate_arnaud2010.py |
A10 pressure profile |
| Oppenheimer et al. 2025 | validate_oppenheimer2025.py |
DPM density profile |
| Amodeo et al. 2021 | validate_amodeo2021.py |
Σ_y(r_p) BOSS CMASS tSZ |
| Pandey et al. 2025 | validate_pandey2025.py |
C_ℓ^{g,y} DES × ACT |
| Comparat et al. 2025 | validate_comparat2025.py |
w_θ(θ) LS DR10 × eROSITA |
Run clustering/lensing benchmarks:
# from repo root
python hod_mod/scripts/benchmarks/run_benchmark.py --model more2015 --plot
python hod_mod/scripts/benchmarks/run_all_benchmarks.py --plot
Run gas/cross-correlation validation scripts:
python -m hod_mod.scripts.validate_arnaud2010
python -m hod_mod.scripts.validate_oppenheimer2025
python -m hod_mod.scripts.validate_sz_xray
python -m hod_mod.scripts.validate_amodeo2021
python -m hod_mod.scripts.validate_pandey2025
python -m hod_mod.scripts.validate_comparat2025
Figures are saved to hod_mod/scripts/figures/.
Citation
If you use hod_mod in published work, cite:
Comparat et al. 2025, A&A 697, A173 https://ui.adsabs.harvard.edu/abs/2025A%26A...697A.173C
and this repository URL. Depending on the model used, additionally cite the relevant HOD or gas profile paper(s) from the tables above.
If you use the archived benchmark data or curated results, also cite the dataset: 10.5281/zenodo.21078473.
License
MIT — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hod_mod-0.1.5.tar.gz.
File metadata
- Download URL: hod_mod-0.1.5.tar.gz
- Upload date:
- Size: 604.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
692ad5c0f606a5c3dd0cde3cd77078a589a17a408f53f4f2029b4f92368d50a9
|
|
| MD5 |
4c0822aa37e333375fe1137dfced615d
|
|
| BLAKE2b-256 |
c66145a97c5606db47af75d89cf26107c64da4666929653f09ca9c9dc0b5f3c9
|
File details
Details for the file hod_mod-0.1.5-py3-none-any.whl.
File metadata
- Download URL: hod_mod-0.1.5-py3-none-any.whl
- Upload date:
- Size: 640.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21b6badc9e4242777fbb5ab6b47f741d9060ce3a259b53be343ab381f6fd6fb9
|
|
| MD5 |
81789aadd1cc7f05e75ad46f16a35694
|
|
| BLAKE2b-256 |
e10ec9be5050de44debf6c76cdc78ae04820f4e998451f462fbe5cad9e1c0bcc
|