Source code for firecrown.models.cluster.kernel

"""The cluster kernel module.

This module holds the classes that define the kernels that can be included
in the cluster abundance integrand.
"""

from typing import Optional
from enum import Enum
import numpy.typing as npt
import numpy as np

from firecrown import parameters
from firecrown.updatable import Updatable

REDMAPPER_DEFAULT_AC_NC = 0.38
REDMAPPER_DEFAULT_BC_NC = 1.2634
REDMAPPER_DEFAULT_AC_MC = 13.31
REDMAPPER_DEFAULT_BC_MC = 0.2025


[docs] class KernelType(Enum): """The kernels that can be included in the cluster abundance integrand.""" MASS = 1 Z = 2 MASS_PROXY = 3 Z_PROXY = 4 COMPLETENESS = 5 PURITY = 6
[docs] class Completeness(Updatable): """The completeness kernel for the numcosmo simulated survey. This kernel will affect the integrand by accounting for the incompleteness of a cluster selection. """ def __init__( self, ): super().__init__() # Updatable parameters self.ac_nc = parameters.register_new_updatable_parameter( default_value=REDMAPPER_DEFAULT_AC_NC ) self.bc_nc = parameters.register_new_updatable_parameter( default_value=REDMAPPER_DEFAULT_BC_NC ) self.ac_mc = parameters.register_new_updatable_parameter( default_value=REDMAPPER_DEFAULT_AC_MC ) self.bc_mc = parameters.register_new_updatable_parameter( default_value=REDMAPPER_DEFAULT_BC_MC ) def _mc(self, z: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: ac_mc = self.ac_mc bc_mc = self.bc_mc log_mc = ac_mc + bc_mc * (1.0 + z) mc = 10.0**log_mc return mc.astype(np.float64) def _nc(self, z: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: ac_nc = self.ac_nc bc_nc = self.bc_nc nc = ac_nc + bc_nc * (1.0 + z) assert isinstance(nc, np.ndarray) return nc
[docs] def distribution( self, log_mass: npt.NDArray[np.float64], z: npt.NDArray[np.float64], ) -> npt.NDArray[np.float64]: """Evaluates and returns the completeness contribution to the integrand.""" mc = self._mc(z) mass = 10.0**log_mass nc = self._nc(z) completeness = (mass / mc) ** nc / ((mass / mc) ** nc + 1.0) assert isinstance(completeness, np.ndarray) return completeness
REDMAPPER_DEFAULT_AP_NC = 3.9193 REDMAPPER_DEFAULT_BP_NC = -0.3323 REDMAPPER_DEFAULT_AP_RC = 1.1839 REDMAPPER_DEFAULT_BP_RC = -0.4077
[docs] class Purity(Updatable): """The purity kernel for the numcosmo simulated survey. This kernel will affect the integrand by accounting for the purity of a cluster selection. """ def __init__(self): super().__init__() self.ap_nc = parameters.register_new_updatable_parameter( default_value=REDMAPPER_DEFAULT_AP_NC ) self.bp_nc = parameters.register_new_updatable_parameter( default_value=REDMAPPER_DEFAULT_BP_NC ) self.ap_rc = parameters.register_new_updatable_parameter( default_value=REDMAPPER_DEFAULT_AP_RC ) self.bp_rc = parameters.register_new_updatable_parameter( default_value=REDMAPPER_DEFAULT_BP_RC ) def _rc(self, z: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: ap_rc = self.ap_rc bp_rc = self.bp_rc log_rc = ap_rc + bp_rc * (1.0 + z) rc = 10**log_rc return rc.astype(np.float64) def _nc(self, z: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: bp_nc = self.bp_nc ap_nc = self.ap_nc nc = ap_nc + bp_nc * (1.0 + z) assert isinstance(nc, np.ndarray) return nc
[docs] def distribution( self, z: npt.NDArray[np.float64], mass_proxy: npt.NDArray[np.float64], mass_proxy_limits: Optional[tuple[float, float]] = None, ) -> npt.NDArray[np.float64]: """Evaluates and returns the purity contribution to the integrand.""" if all(mass_proxy == -1.0): if mass_proxy_limits is None: raise ValueError( "mass_proxy_limits must be provided when mass_proxy == -1" ) mean_mass = (mass_proxy_limits[0] + mass_proxy_limits[1]) / 2 r = np.array([np.power(10.0, mean_mass)], dtype=np.float64) else: r = np.array([np.power(10.0, mass_proxy)], dtype=np.float64) r_over_rc = r / self._rc(z) purity = (r_over_rc) ** self._nc(z) / (r_over_rc ** self._nc(z) + 1.0) assert isinstance(purity, np.ndarray) return purity
[docs] class TrueMass: """The true mass kernel. Assuming we measure the true mass, this will always be 1. """
[docs] def distribution(self) -> npt.NDArray[np.float64]: """Evaluates and returns the mass distribution contribution to the integrand. We have set this to 1.0 (i.e. it does not affect the mass distribution) """ return np.atleast_1d(1.0)
[docs] class SpectroscopicRedshift: """The spec-z kernel. Assuming the spectroscopic redshift has no uncertainties, this is akin to multiplying by 1. """
[docs] def distribution(self) -> npt.NDArray[np.float64]: """Evaluates and returns the z distribution contribution to the integrand. We have set this to 1.0 (i.e. it does not affect the redshift distribution) """ return np.atleast_1d(1.0)