clenspy.selection.richness_kernel.EmgParams

class clenspy.selection.richness_kernel.EmgParams(delta_mu, sigma, f_prj, tau, mu_slope=1.0)[source]

Bases: object

The four kernel parameters as functions of \((\lambda^{\rm tr}, z)\).

Holds \(\Delta\mu\), \(\sigma\), \(f^{\rm prj}\) and \(\tau\), each either a constant or a callable f(lambda_true, z). Constructing this rather than passing four loose arrays keeps the set together: they are calibrated jointly and mixing one study’s \(f^{\rm prj}\) with another’s \(\tau\) is not a kernel anybody fitted.

NOTE: units – delta_mu and sigma in richness, tau in inverse richness, f_prj dimensionless in \([0,1]\).

NOTE: \(\mu = \lambda^{\rm tr} + \Delta\mu\), and \(\Delta\mu < 0\) typically – redMaPPer’s global background subtraction biases \(\lambda^{\rm ob}\) low. The sign is the caller’s to supply; nothing here enforces it.

NOTE: \(f^{\rm prj} = 0\) recovers the pure-Gaussian “BKG” model of Costanzi et al. (2021) exactly, which is the check richness_bin_probability uses to show the two limits agree.

NOTE: \(\mu = b_\mu\lambda^{\rm tr} + \Delta\mu\), and mu_slope is \(b_\mu\). It defaults to 1, which is the form the Costanzi papers write, but the DES Y3 fit leaves it free and it runs 0.984 to 1.172 across the tabulated redshifts – up to 17% off unity. Hardcoding 1 therefore misrepresents the production kernel, which is why the slope is a parameter rather than an assumption.

Parameters:
  • delta_mu (float or callable) – Each either a scalar or f(lambda_true, z) -> array.

  • sigma (float or callable) – Each either a scalar or f(lambda_true, z) -> array.

  • f_prj (float or callable) – Each either a scalar or f(lambda_true, z) -> array.

  • tau (float or callable) – Each either a scalar or f(lambda_true, z) -> array.

  • mu_slope (float or callable, optional) – \(b_\mu\) (default 1.0).

__init__(delta_mu, sigma, f_prj, tau, mu_slope=1.0)[source]

Methods

__init__(delta_mu, sigma, f_prj, tau[, mu_slope])

at(lambda_true, z)

(mu, sigma, tau, f_prj) at \((\lambda^{\rm tr}, z)\).

from_y3_table([path])

The DES Y3 lss_lin_dep production kernel, from the table.

classmethod from_y3_table(path=None)[source]

The DES Y3 lss_lin_dep production kernel, from the table.

Ten coefficients on 15 redshift nodes over \([0.10, 0.80]\), linearly interpolated, giving

\[\mu = a_\mu + b_\mu\lambda^{\rm tr}, \qquad \sigma = b_\sigma\,(\lambda^{\rm tr})^{a_\sigma},\]
\[\tau = \frac{b_\tau}{(\lambda^{\rm tr})^{a_\tau}}, \qquad f^{\rm prj} = \min\!\left[1,\; \frac{b_f}{\left(1 + e^{-\lambda^{\rm tr}}\right)^{a_f}} \right]\]

NOTE: \(b_\mu\) is not 1. It runs 0.984 to 1.172 across the table, so the slope-1 form the papers write is an approximation to this fit at the 2-17% level in \(\mu\). That is why EmgParams carries mu_slope at all.

NOTE: \(f^{\rm prj}\) is clipped at 1, in the fit itself – \(b_f\) reaches 0.998 and the sigmoid can push the raw value past unity. The clip is part of the calibrated model, not a safety net, so it is applied here rather than left to at.

NOTE: afmsk and bfmsk are read and discarded. They parametrise a masking fraction the production kernel does not apply. Discarding them explicitly, rather than slicing the first eight columns, is what makes their absence visible.

NOTE: linear interpolation with constant extrapolation outside \([0.10, 0.80]\), matching the production spline. Beyond the table the kernel is frozen at the endpoint, not extrapolated – a higher-order spline would give negative \(\sigma\).

Parameters:

path (str or pathlib.Path, optional) – Defaults to Y3_PRJ_PARAMS_FILE.

Returns:

EmgParams – With all five parameters as callables of \((\lambda^{\rm tr}, z)\).

at(lambda_true, z)[source]

(mu, sigma, tau, f_prj) at \((\lambda^{\rm tr}, z)\).

Returns \(\mu\), not \(\Delta\mu\) – the shift is applied here, once, so no caller can forget it.