Overview ======== ``hod_mod`` is a JAX-accelerated Python framework for modelling the galaxy–halo connection (see reviews from [CooraySheth2002]_, [Asgari2023]_). Starting from a set of cosmological parameters and a galaxy–halo occupation model, it predicts: the observed projected galaxy autocorrelation function :math:`w_p(r_p)` and the observed galaxy–matter cross-correlation (excess surface density) :math:`\Delta\Sigma(R)`. The forward model chain ----------------------- The pipeline proceeds through six sequential steps: .. code-block:: text Cosmological parameters θ │ ▼ 1. Linear matter power spectrum P_lin(k, z; θ) │ ▼ 2. Halo mass function dn/dM(M, z; θ) Halo bias b(M, z; θ) │ ▼ 3. Halo profiles u(k|M) [NFW or Einasto], c-M │ ▼ 4. Galaxy occupation ⟨N_cen⟩, ⟨N_sat⟩(M; p_HOD) [HOD / ICSMF / iHOD models] │ ▼ 5. Power spectra P_gg(k), P_gm(k) ├── Galaxy clustering w_p(r_p; π_max) └── Galaxy-mass lensing ΔΣ(R) Step 1 is the computational bottleneck (CAMB takes ~30 s). In MCMC mode a caching layer (``CachedPkLinear``) interpolates on a pre-computed grid, reducing per-step cost to < 1 s. --- Installation ------------ Requires Python ≥ 3.11, JAX ≥ 0.4, and CAMB. The package is available on `PyPI `_: .. code-block:: bash pip install hod-mod For development, create and activate the conda/mamba environment, then install in editable mode: .. code-block:: bash mamba env create -f environment.yml mamba activate hod_mod pip install -e . --- Quick start ----------- Compute the projected correlation function :math:`w_p(r_p)` with a the HOD model from [More2015]_: .. code-block:: python import jax.numpy as jnp from hod_mod.core.power_spectrum import LinearPowerSpectrum from hod_mod.core.halo_mass_function import make_hmf from hod_mod.core.halo_profiles import HaloProfile from hod_mod.connection import MoreHODModel from hod_mod.observables import FullHaloModelPrediction pk_lin = LinearPowerSpectrum() theta = pk_lin.default_cosmology() # Planck 2018 best-fit 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, used above for the quickstart. The project's fitting pipelines instead use ``make_hmf("csst")`` (CSSTEMU) as their baseline — see :doc:`cosmology` for the full list of backends and why. --- Coordinate and unit conventions --------------------------------- All spatial quantities are in **h-units** throughout the pipeline: =========================== ====================== ======================= Quantity Symbol Unit =========================== ====================== ======================= Comoving separation :math:`r, r_p` Mpc/h Halo mass :math:`M` :math:`M_\odot/h` Power spectrum :math:`P(k)` :math:`({\rm Mpc}/h)^3` Wavenumber :math:`k` :math:`h\,{\rm Mpc}^{-1}` Galaxy number density :math:`n_g` :math:`({\rm Mpc}/h)^{-3}` Stellar Mass Function :math:`\Phi` :math:`({\rm Mpc}/h)^{-3}\,{\rm dex}^{-1}` =========================== ====================== ======================= --- Cosmological parameter dictionary ---------------------------------- All functions that require cosmological parameters expect a Python ``dict`` with these keys (produced by ``LinearPowerSpectrum.default_cosmology()``): .. code-block:: python theta = { "h": 0.6736, # H₀ / (100 km/s/Mpc) "Omega_b": 0.0493, # baryon density parameter "Omega_cdm": 0.2644, # cold dark matter density "Omega_m": 0.3137, # total matter = Omega_b + Omega_cdm "n_s": 0.9649, # scalar spectral index "ln10^{10}A_s": 3.044, # log amplitude of primordial spectrum } These are the Planck 2018 TT,TE,EE+lowE+lensing best-fit values (`Planck Collaboration 2020 `_, Table 2) [PlanckCollaboration2018]_. --- JAX conventions --------------- The package follows JAX idioms to enable gradient-based inference: * Use ``jnp.*`` everywhere inside hot functions; only use numpy ``np.*`` at I/O boundaries. * Pure functions are decorated with ``@jax.jit``; class methods use ``@partial(jax.jit, static_argnums=(0,))``. * Avoid Python-level ``if``/``for`` inside JIT-compiled code; use ``jax.lax.cond`` and ``jax.lax.scan``. * Never mutate arrays in-place (JAX arrays are immutable). Non-JAX libraries (CAMB, colossus, aemulusnu) are called at explicit **boundaries**; their outputs are wrapped with ``jnp.asarray()`` before entering the JAX computation graph. --- Repository structure -------------------- .. code-block:: text hod_mod/ organised by observable pipeline over a shared core ├── core/ P(k), HMF, halo profiles, distances, concentration, BNL ├── connection/ galaxy–halo occupation: hod/ (per-family), CLF, SHAM ├── gas/ hot-gas fields: pressure, density, cooling, metallicity, │ conversions, eROSITA response (X-ray + tSZ ingredients) ├── agn/ AGN X-ray models: xray, ham, hod, duty_cycle ├── observables/ the pipelines: clustering (wp, ΔΣ), cross_spectra │ (g×y tSZ + g×X engine), cross_clustering, IA, baryon frac. ├── fitting/ models, config, fitters (MAP + emcee), Planck prior ├── cli/ unified ``hod-mod`` command (python -m hod_mod) └── data_io/ SumStatReader (HDF5 + FITS), wp/ΔΣ CSV loaders hod_mod/scripts/ ├── cosmology/ demo scripts (P(k), HMF, profiles) ├── galaxies/ demo + AGN/gas plotting scripts ├── benchmarks/ literature benchmark runner └── fitting/ ├── bgs_ls10/ BGS/LS10 fitting campaign ├── mocks/ Uchuu mock fitting campaign └── paper_reproductions/ configs/ YAML configurations for WpFitter results/ output directory (not tracked by git) tests/ pytest test suite data/ data sets for testing --- .. _acronyms: Acronym glossary ----------------- .. list-table:: :header-rows: 1 :widths: 15 85 * - Acronym - Expansion * - **1h / 2h** - 1-halo / 2-halo term — pairs of galaxies within the same halo vs. different halos * - **AGN** - Active Galactic Nucleus * - **BOSS** - Baryon Oscillation Spectroscopic Survey (SDSS-III) * - **CAMB** - Code for Anisotropies in the Microwave Background * - **CDM** - Cold Dark Matter * - **CSMF** - Conditional Stellar Mass Function — P(M\ :sub:`*` | M\ :sub:`h`) * - **DES** - Dark Energy Survey * - **eBOSS** - Extended Baryon Oscillation Spectroscopic Survey (SDSS-IV) * - **EH98** - Eisenstein & Hu 1998 — analytical transfer function / power spectrum * - **ELG** - Emission Line Galaxy * - **eRASS** - eROSITA All-Sky Survey * - **GAMA** - Galaxy And Mass Assembly survey * - **GP** - Gaussian Process emulator * - **HMC** - Hamiltonian Monte Carlo * - **HMF** - Halo Mass Function — dn/dM or dn/d ln M * - **HOD** - Halo Occupation Distribution — P(N | M) * - **ICSMF** - Inverse Conditional Stellar Mass Function * - **iHOD** - Inverse HOD — galaxy assignment derived by inverting the SHMR (Zu & Mandelbaum 2015) * - **JAX** - Google's library for high-performance numerical computing with autodiff and JIT * - **JIT** - Just-In-Time compilation (via XLA, used by JAX) * - **ΛCDM** - Lambda Cold Dark Matter — the standard cosmological model * - **LRG** - Luminous Red Galaxy * - **MAP** - Maximum A Posteriori estimate * - **MCMC** - Markov Chain Monte Carlo * - **NFW** - Navarro-Frenk-White (1997) dark matter halo density profile * - **NUTS** - No-U-Turn Sampler — gradient-based MCMC implemented in numpyro * - **P(k)** - Matter power spectrum * - **SDSS** - Sloan Digital Sky Survey * - **SHAM** - Sub-Halo Abundance Matching * - **SHMR** - Stellar-to-Halo Mass Relation * - **SMF** - Stellar Mass Function — Φ(M\ :sub:`*`) * - **XLA** - Accelerated Linear Algebra — the compiler backend used by JAX * - **ΔΣ(R)** - Excess Surface Density — a weak gravitational lensing observable * - **w\ :sub:`p`\ (r\ :sub:`p`\ )** - Projected galaxy two-point correlation function — the clustering observable --- Citing this work ----------------- If you use ``hod_mod`` in published research, please cite: `Comparat et al. 2025 `_ (A&A 697, A173) ---