Skip to content

EM Cascades

EM_Cascade

EM_Cascade()

Electromagnetic cascade light yield calculator.

Calculates Cherenkov light production from electromagnetic showers using the Aachen parametrization. Handles electron, positron, and photon-initiated cascades with longitudinal development profiles.

Attributes:

Name Type Description
_medium dict

Medium properties dictionary

_n float

Refractive index

_radlength float

Radiation length in g/cm²

_Lrad float

Radiation length in cm

_params dict

Parametrization coefficients

cherenkov_angle_distro Callable

Angular distribution calculator

track_lengths Callable

Track length calculator

long_profile Callable

Longitudinal profile calculator

Examples:

>>> from fennel.em_cascades import EM_Cascade
>>> em = EM_Cascade()
>>> track_len, track_dev = em.track_lengths(100.0, particle=11)
>>> z_grid = np.linspace(0, 1000, 100)
>>> profile = em.long_profile(100.0, z_grid, particle=11)
Notes
  • Parametrization based on GEANT4 simulations
  • Accounts for shower fluctuations
  • Supports both NumPy and JAX backends

Initialize the EM cascade calculator.

Loads parametrization data and configures calculation methods based on JAX availability.

Raises:

Type Description
ValueError

If parametrization is not implemented

ImportError

If JAX mode enabled but not installed

Source code in fennel/em_cascades.py
def __init__(self) -> None:
    """
    Initialize the EM cascade calculator.

    Loads parametrization data and configures calculation methods
    based on JAX availability.

    Raises
    ------
    ValueError
        If parametrization is not implemented
    ImportError
        If JAX mode enabled but not installed
    """
    if not config["general"]["enable logging"]:
        _log.disabled = True
    _log.debug("Constructing an em cascade object")
    self._medium = config["mediums"][config["scenario"]["medium"]]
    self._n = self._medium["refractive index"]
    self._radlength = self._medium["radiation length"]
    self._Lrad = self._radlength / self._medium["density"]
    if config["scenario"]["parametrization"] == "aachen":
        _log.info("Loading the aachen parametrization")
        param_file = pkgutil.get_data(
            __name__, "data/%s.pkl" % config["scenario"]["parametrization"]
        )
        self._params = pickle.loads(param_file)["em cascade"]
    else:
        raise ValueError(
            "EM parametrization "
            + config["scenario"]["parametrization"]
            + " not implemented!"
        )
    if config["general"]["jax"]:
        _log.info("Running with JAX functions")
        self.cherenkov_angle_distro = self._symmetric_angle_distro_jax
        self.track_lengths = self._track_lengths_fetcher_jax
        self.long_profile = self._log_profile_func_fetcher_jax
    else:
        _log.info("Running with basic functions")
        self.cherenkov_angle_distro = self._symmetric_angle_distro
        self.track_lengths = self._track_lengths_fetcher
        self.long_profile = self._log_profile_func_fetcher