Skip to content

Predicting

One call does everything: reg.predict(property, gravity, redshift, theta, **kw).

import os; os.environ.setdefault("JAX_PLATFORMS", "cpu")
import numpy as np
from haloemu import get_registry
reg = get_registry()

th  = [0.31, 0.677, 0.967, 0.83]          # LCDM
th5 = [0.31, 0.677, 0.967, 0.83, -5.0]    # fRn1

One-liner per property

n   = reg.predict("hmf",   "LCDM", 0.25, th)    # (1, 23)  n(>M), (Mpc/h)^-3
b   = reg.predict("b_cum", "LCDM", 0.25, th)    # (1, 30)  b(>M)   (fRn1: 31)
pk  = reg.predict("pk_mm", "LCDM", 0.25, th)    # (1, 147) P(k), (Mpc/h)^3
xi  = reg.predict("xi_mm", "LCDM", 0.25, th)    # (1, 113) xi(r), SIGNED
rab = reg.predict("r_ab",  "LCDM", 0.25, th)    # (1, 30, 30) threshold-pair matrix
m10 = reg.predict("vel_m10", "LCDM", 0.25, th)  # (1, 105, 57) mass-pair x r surface
vb  = reg.predict("vel_binned", "LCDM", 0.25, th,
                  mass_edges=[12.5, 13.0, 13.5]) # dict: {moment: (Nbin, Nbin, 57)}
bd  = reg.predict("b_diff", "LCDM", 0.25, th)   # dict: x_grid, b_diff, b_err, cov, checks
xhh = reg.predict("xi_hh", "LCDM", 0.25, th)    # dict, see below

Same calls with "fRn1" and a 5-parameter θ; all eight velocity moments, including vel_c12, are registered for both gravities.

Coordinates, variance, and surfaces

art = reg.load(prop, gravity, z)
art.coord                                   # 1-D grid (log10M edges / k / r)
reg.predict(prop, gravity, z, th, return_var=True)   # (mean, variance) for trained emulators

# surface emulators carry extra axes:
reg.load("r_ab",   gravity, z).thresholds   # both matrix axes
reg.load("vel_m10", gravity, z).pair_keys   # mass-bin pairs
reg.load("vel_m10", gravity, z).r           # radial grid

xi_hh — custom bins and routes

res = reg.predict("xi_hh", "LCDM", 0.25, th,
                  edges=np.array([13.0, 13.3, 13.6]),  # your log10M bin edges
                  r=np.geomspace(3, 90, 40),           # custom radii -> exact route
                  route="auto")                        # auto | nbar | exact | bbar
res["xi_hh"]     # (Nbin, Nbin, Nr)
res["validity"]  # per-gravity evidence + route_selection — READ IT
  • route="nbar" (the default via auto since 2026-08-20, for requests inside its contract): the released fixed-number-density chain relabelled into mass coordinates — exact abundances, no emulated-HMF weighting error, every bin pair physical. Contract: edges inside [12.8, 14.2] for auto (the full per-cosmology mass span, ≈[12.0–12.8, 14.3–14.9], with explicit route="nbar" — above the f(R) trained cap), radii on the native 0.051-dex measurement bin centres with r ≥ 0.5 (bin estimates, no interpolation, no r_edges). Anything else falls back to exact with the reason in validity["route_selection"].
  • route="exact" (the fallback, and the route for everything below): validated r ∈ [0.5, 100] with per-pair trained-support floors validity["r_valid_bin"][i, j]; below them the value is the labelled halo-exclusion reconstruction (never NaN): the boundary prediction continued along the emulated matter shape times a calibrated suppression, reaching ξ = −1 (zero pair density) below validity["r_zero_bin"][i, j]. validity["xi_mode"] labels each value: 0 trained, 1 exclusion model, 2 zero-pair. The floors are data edges, not physical exclusion radii — pairs remain abundant below them, so never zero out the sub-floor region yourself.
  • Mass bins with edges on the 0.05-dex grid get the bin-level small-r route: floors reach 0.56–1.6 Mpc/h (ΛCDM; ≳0.97 for f(R)) instead of the threshold-corner ~2.0–2.4. validity["bin_smallr_served"] marks the pairs, validity["r_valid_bin_threshold"] keeps the off-grid floors.
  • route="bbar": factorization, only good r ∈ [20, 70].
  • r above the xi_mm support (124.8) raises; arbitrarily small r is always accepted (the model region and its zero-pair core are served with labels).

b_cum at arbitrary masses

art = reg.load("b_cum", "LCDM", 0.25)
b = art.predict_mass(th, np.array([13.2, 14.3]))   # empirical LCDM tail above 14

For modified gravity, predict_mass stops at the artifact's trained edge; there is no public high-mass continuation without independent screening data.

CLI equivalent

micromamba run -n cosemu python3 -m haloemu.cli predict xi_mm \
    --gravity fRn1 --redshift 0.25 --theta 0.31,0.677,0.967,0.83,-5
micromamba run -n cosemu python3 -m haloemu.cli predict b_diff \
    --theta 0.31,0.677,0.967,0.83 --out b_diff.hdf5

Checklist before you trust a number

  1. θ in the right order, with S_8 not σ_8 (conventions).
  2. θ inside the design ranges.
  3. Redshift registered (z = 0.25 everywhere; z = 0 for the matter sector only).
  4. For ξ/ξ_hh: respect the masks and validity windows; mind the frozen-seed offset.