The building blocks of tengri’s forward model: star formation history
parameterisations, power spectral density functions, dust attenuation,
stellar population synthesis, and filter handling.
Truncated skew-normal star formation history (Bellstedt+2020).
The most flexible smooth SFH model: a skewed Gaussian kernel multiplied
by a normal CDF truncation factor that smoothly suppresses star formation
at recent times (young lookback times).
Parameters:
t_lookback (array_like, shape (n_age,)) – Lookback time [yr].
log_peak_sfr (float) – log10 of peak SFR [Msun/yr].
where \(w\) is width [yr], \(\gamma\) is skewness [dimensionless],
and \(f_{\rm trunc}\) is the truncation sharpness [dimensionless].
Approximation: The skewness is implemented via the Robotham+2020
formulation (arcsinh-based) rather than the classical Owen’s lambda
transformation. This provides better numerical stability and JAX compatibility.
Double power law with log-peak SFR parameterization (canonical).
Registry-compatible wrapper around the Carnall+2018 double power law.
Uses log10(peak_sfr) instead of linear normalization for consistency
with other parametric SFH models in the registry.
Parameters:
t_lookback (array_like, shape (n_age,)) – Lookback time [yr].
where \(t_{\rm cosmic} = t_{\mathrm{H}} - t_{\rm lookback}\) is cosmic time
since the Big Bang, \(t_{\mathrm{H}}\) is the age of the universe,
\(\tau\) is the turnover timescale, and \(\alpha\), \(\beta\)
are the falling and rising slopes [dimensionless].
In cosmic time: \(\alpha\) controls the declining phase (after peak),
\(\beta\) controls the rising phase (before peak).
In lookback time (as plotted): \(\alpha\) controls the RIGHT side
(early universe, large lookback), \(\beta\) controls the LEFT side
(near present, small lookback).
The mode in log10(age) space is peak_lbt, but the peak in linear
time is shifted: t_peak_linear = peak_lbt * 10^{-w^2 * ln(10)}.
For w=0.3, this is a ~15% shift toward younger ages. peak_lbt is
best interpreted as the median lookback time, not the linear peak.
Parameters:
t_lookback (array_like, shape (n_age,)) – Lookback time [yr].
log_peak_sfr (float) – log10 of peak SFR [Msun/yr].
peak_lbt (float) – Peak lookback time [yr]. Converted to log10 internally.
Triweight burst kernel in log-age space (Zacharegkas+2025).
A compact-support kernel for modeling starburst episodes. The kernel
is smooth, has finite support in log-age space, and is designed for
composition with smooth SFH models via mass-fraction mixing.
Parameters:
t_lookback (array_like, shape (n_age,)) – Lookback time [yr].
log_tpeak_myr (float) – log10 of burst peak time [Myr]. Center of the kernel in log-age space.
log_tmax_myr (float) – log10 of burst duration [Myr]. Controls the kernel half-width.
The kernel has support roughly ±:math:3 imes 10^{log_{mathrm{tmax}}} Myr.
Returns:
Unnormalized burst shape [dimensionless], non-negative. Integrates to ~1.
where \(x\) is the normalized time offset from peak, defined as # noqa: E501
\((\log_{10}(t/\mathrm{Myr}) - \log_{10}(t_{\rm peak}/\mathrm{Myr})) / \log_{10}(t_{\rm max}/\mathrm{Myr})\).
The kernel has compact support (finite extent) and is \(C^{\infty}\) smooth.
It is superior to Gaussian kernels for burst modeling because it avoids
the extended low-level wings that affect neighboring age bins.
Resolve SFH specification to a composed function + params.
Parameters:
mean_sfh_type (str or list[str]) – Model name(s). E.g., "tsnorm" or ["tsnorm","burst","field"].
bin_edges_gyr (array-like, shape (n_bins+1,), optional) – Custom age bin edges [Gyr] for continuity and dirichlet models.
When provided, overrides the default DEFAULT_BIN_EDGES_GYR. Use
make_agebins_from_zred to generate redshift-appropriate edges.
Ignored for non-nonparametric models. Default None (use model default).
where \(\\sigma_{\rm PS}\) is the PSD amplitude [dimensionless],
\(\tau_{\rm PS}\) is the damping timescale [yr], and \(\\omega\)
is the angular frequency [rad/yr].
This is the primary PSD model used in tengri for stochastic SFH modeling.
References
Examples
>>> importjax.numpyasjnp>>> fromtengriimportpsd_drw>>> omega=jnp.linspace(0.0,2e-7,128)# angular frequencies [rad/yr]>>> psd=psd_drw(omega,psd_sigma=1.0,psd_tau_yr=1e8)>>> psd.shape(128,)>>> float(psd[0])# peak power at omega=01e+08
where \(\sigma_{\rm PS}\) is the PSD amplitude, \(\tau_{\rm PS}\)
is the damping timescale [yr], and \(\Delta t\) is the time lag [yr].
Examples
>>> importjax.numpyasjnp>>> fromtengriimportdrw_acf>>> lags=jnp.array([0.0,1e7,1e8,1e9])# time lags [yr]>>> acf=drw_acf(lags,psd_sigma=1.0,psd_tau_yr=1e8)>>> acf.shape(4,)>>> float(acf[0])# variance at zero lag = sigma^2 / 20.5
Pre-compute DRW amplitude operator for log-age grid.
Converts the DRW PSD from physical frequency (rad/yr) to log-age frequency
space (rad/dex) using the Jacobian correction for the change of variables
from linear time \(t\) to log-time \(u = \log_{10} t\).
n_pointsint
Grid size (number of age samples).
d_log_agefloat
Grid spacing in dex [dimensionless].
psd_sigmafloat
DRW PSD amplitude [dimensionless].
psd_tau_yrfloat
DRW damping timescale [yr].
log_age_reffloat, optional
Reference log10(age/yr) for Jacobian correction. Default: 8.0 (100 Myr).
ndarray, shape (n_freq,)
Amplitude operator \(\sqrt{P_u(q) / \Delta u}\) at rfft frequencies
in log-age space [dimensionless].
JIT-compatible: yes — all operations use jnp primitives.
The Jacobian correction for the change of variables from cosmic time
\(t\) (in years) to log-age \(u = \log_{10}(t)\) is:
\(q\) is the angular frequency in log-age space [rad/dex],
and \(P_t\) is the PSD in physical frequency space.
The reference time scales out in the power spectrum but affects the
mapping between physical and log-age frequencies. A typical choice is
the midpoint of the age range (e.g., 100 Myr ~ 8 Gyr cosmic age).
JIT-compatible: yes — uses gp_from_xi and PSD model functions
from the field model registry.
The Gaussian process realization models burstiness via a correlated
random field in log-space. The PSD model (e.g., “drw” for Damped
Random Walk) controls temporal correlations. The lognormal correction
k0_half accounts for the bias introduced when exponentiation is
applied to the Gaussian latents.
(pre-compute with psd_to_sqrt_power()). [dimensionless]
n_pointsint
Number of grid points.
ndarray, shape (n_points,)
GP realization on the log-age grid [dimensionless].
JIT-compatible: yes — uses jax.random.normal and gp_from_xi().
This function is the primary interface for generating mock SFHs with
stochastic variability. The random draw is always independent; for
reproducibility, pass the same PRNGKey.
Each realization is independent with the specified PSD structure.
This function is useful for generating mock catalogs or computing
uncertainties via Monte Carlo sampling.
Deterministic GP realization from standardized latent vector.
Maps a standardized Gaussian random vector to a correlated GP field via
Fourier-space multiplication with a spectral amplitude operator. This
is the core function used during inference and mock generation.
xiarray_like, shape (n_points,)
Standardized latent vector \(\xi \sim \mathcal{N}(0, I)\) under the prior.
The rfft (real FFT) preserves Hermitian symmetry for real-valued output and
ensures correct variance normalization: \(E[|\mathrm{rfft}(\xi)_k|^2] = N\),
so with \(\sqrt{P/\Delta x}\) we recover \(\mathrm{Var}[s] = \int P(f) df\).
This is the primary function called during MCMC inference and mock galaxy generation.
The sampler proposes values of \(\xi\) and this function maps them to
correlated SFH realizations.
This grid is used as the internal representation for age in GP-based SFH models.
The log-space parametrization provides better resolution at young ages and
maps naturally to the logarithmic timescales of stellar evolution.
Two-component dust attenuation following Charlot & Fall (2000) with smooth age transition.
Separates dust into birth-cloud (young stars) and diffuse ISM (all stars) components
with independent optical depths and attenuation curves. Transition between components
uses a smooth sigmoid in log-age, enabling automatic differentiation.
where \(f_{\rm obs}\) is the unattenuated sightline fraction.
Upstream: Implements the Charlot & Fall (2000) two-component framework [1]_ with sigmoid age transition
following tengri’s differentiable design. Birth-cloud + diffuse ISM separation enables realistic modeling
of age-dependent dust geometry in galaxies.
This module provides a generalized two-component dust attenuation framework
(Charlot & Fall 2000) with pluggable attenuation curves and clumpy dust
geometry (f_obscuration, Lower 2022).
JIT-compatible: yes — all operations are jnp primitives.
Uses piecewise polynomials in infrared, optical, UV, and far-UV regimes.
Parameterized by \(x = 1/\lambda\) [μm⁻¹] with \(a(x)\) and \(b(x)\)
coefficients fitted to extinction curves.
JIT-compatible: yes — uses jnp.interp on precomputed curve.
Upstream credit: grain model data from Draine (2003) [1]_,
accessed via the dust-extinction astropy-affiliated package.
Independent implementation in synthesizer (Wilkins et al. 2025 [2]_).
JIT-compatible: yes — uses jnp.interp on precomputed curve.
Upstream credit: grain model data from Hensley & Draine (2023) [1]_,
accessed via the dust-extinction astropy-affiliated package.
Independent implementation in synthesizer (Wilkins et al. 2025 [2]_).
Leitherer et al. (2002) UV starburst attenuation curve.
Far-UV extension of the Calzetti (2000) law, valid 970-1800 Å.
Uses R_V = 4.05 (same as Calzetti). For wavelengths outside the
L02 range, falls back to Calzetti (2000).
Li et al. (2008) analytical dust attenuation/extinction curve.
A flexible 4-parameter analytical model that can reproduce MW, LMC,
SMC, and Calzetti-like curves through a single functional form.
The three terms represent a UV/optical continuum, a far-UV rise,
and the 2175 Angstrom UV bump respectively.
The normalized attenuation is (Li et al. 2008, Eq. 1):
Approximate presets for common curves (Markov et al. 2023, 2025):
MW-like: c1~6.0, c2~4.0, c3~2.0, c4~0.04
SMC-like: c1~5.0, c2~5.5, c3~1.5, c4~0.0
Calzetti-like: c1~3.5, c2~2.5, c3~3.0, c4~0.0
References
Li, A., Liang, S. L., Kann, D. A., et al. 2008, ApJ, 685, 1046
Markov, V., Gallerani, S., Pallottini, A., et al. 2023, A&A, 679, A12
Markov, V., Gallerani, S., Pallottini, A., et al. 2025, A&A (arXiv:2504.12378)
JIT-compatible: yes — all operations are jnp primitives.
When default parameters are used (δ = -0.2, E_b = 1.0), the z-dependent
medians from SIMBA are applied:
\[\begin{split}\delta(z) &\approx -0.2 - 0.1 z \quad \text{(steeper at high z)} \\
E_b(z) &\approx \max(0, 1.0 - 0.15 z) \quad \text{(weaker bump at high z)}\end{split}\]
Noll et al. (2009) modified Calzetti + L02 with UV bump + slope delta.
This is the N09 model from the dust_attenuation package.
Uses Leitherer (2002) for λ < 1500 Å and Calzetti (2000) above.
The modification order is: (base + bump) × power_law.
This differs from kriek_conroy which does NOT use L02 and applies
the bump AFTER the slope: base×power_law+bump.
Normalization follows the dust_attenuation package convention: k(λ) = k’(λ)/R_V
where R_V = 4.05 is fixed. This means k(V) is NOT exactly 1.0 when bump or slope
modifications are applied.
where \(n = -0.7\) produces the standard Charlot & Fall (2000) wavelength
dependence. Negative slopes make dust redder (stronger attenuation at short wavelengths).
Precompute hard young/old masks for fast two-CSP dust decomposition.
Uses a hard threshold at t_birth instead of a smooth sigmoid.
This is the original Charlot & Fall (2000) formulation and enables
a fast path where dust is factored out of the age sum entirely.
Parameters:
age_grid (array_like, shape (n_ages,)) – Stellar population ages. [yr]
young_mask (ndarray, shape (n_ages,)) – 1.0 for young ages (< t_birth), 0.0 for old. [dimensionless]
old_mask (ndarray, shape (n_ages,)) – 1.0 for old ages (≥ t_birth), 0.0 for young. [dimensionless]
Notes
JIT-compatible: yes — all operations are jnp primitives.
The original Charlot & Fall (2000) model uses a hard cutoff instead of a sigmoid.
This returns complementary masks: young_mask + old_mask = 1 everywhere.
Prevot et al. (1984) SMC extinction law for AGN obscuration.
Analytic SMC extinction curve from the UV to near-infrared, used in
AGNfitter for AGN disc reddening. The published Prevot+1984 form
gives \(k_{\rm raw}(\lambda) = A(\lambda)/E(B-V)\) with
\(R_V = 2.72\); this function returns the V-band-normalised
curve \(k(\lambda) = A(\lambda)/A(V) = k_{\rm raw}(\lambda)/k_{\rm raw}(V)\),
matching the convention used by cardelli and the rest of the
components.dust.attenuation registry (k(V)=1).
where \(\lambda_{\mu m}\) is wavelength in micrometres and
\(k_{\rm raw}(0.55) \approx 2.468\).
For wavelengths below 62 Å, reddening is ramped to zero using a smooth
sigmoid (no hard discontinuity) to suppress extinction in the X-ray regime
where dust is ineffective.
Gradient-compatible: yes — enables optimization of extinction parameters.
Decorator that registers the decorated function and returns it unchanged.
Return type:
Callable
Notes
JIT-compatible: no — registration happens at factory time before JIT.
Decorated functions must implement the DustAttenuationLaw protocol:
accept a wavelength array and keyword arguments, returning an attenuation
curve k(λ) [dimensionless].
This is the default attenuation law in DSPS and Zacharegkas+2025
simulations. It combines Calzetti et al. (2000) optical/NIR continuum
with Leitherer et al. (2002) UV extension, plus a variable 2175 Å bump
and power-law tilt.
Salim, Boquien & Lee (2018) modified Calzetti + L02 with UV bump + slope.
This is the SBL18 model from the dust_attenuation package.
Uses Leitherer (2002) for λ < 1500 Å and Calzetti (2000) above.
The modification order is: (base × power_law) + bump.
This differs from noll09 which applies: (base+bump)×power_law.
The SBL18 order is identical to kriek_conroy, but SBL18 additionally
uses L02 in the far-UV.
Applies a single attenuation curve at uniform optical depth to all stellar ages.
Age-independent, enabling factorization out of stellar population integration.
Simpler but less realistic than two-component models; useful for low-precision fits
or high-redshift galaxies where birth-cloud/ISM distinction is unresolved.
where \(k(\lambda)\) is the normalized attenuation curve with \(k(5500 \, \text{\AA}) = 1\),
\(\tau_V\) is the V-band optical depth, and \(f_{\rm obs}\) is the fraction of
unattenuated sightlines (Lower 2022; default 0 = full screen).
Age independence: Unlike two-component models, there is no age-dependence, so this
transmission can be factored out of the stellar population age integration, enabling
faster computation.
Geometry: When \(f_{\rm obs} = 0\), this recovers the standard Beer-Lambert
foreground screen. When \(f_{\rm obs} > 0\), it models a clumpy geometry where
a fraction of photons are unattenuated (Lower 2022).
Single-component dust attenuation broadcast to (n_ages, n_wave).
Computes exp() on the 1-D wavelength grid only, then broadcasts
to (n_ages,n_wave) via jnp.broadcast_to (zero-copy in XLA).
This is the production path used by the SED pipeline.
Three-parameter empirical attenuation with physically motivated
bump-slope correlation from radiative transfer simulations. The
functional form is identical to Kriek & Conroy (2013), but E_b is
derived from delta via a tight relation calibrated on NIHAO-SKIRT.
Two-component dust attenuation following Charlot & Fall (2000) with smooth age transition.
Separates dust into birth-cloud (young stars) and diffuse ISM (all stars) components
with independent optical depths and attenuation curves. Transition between components
uses a smooth sigmoid in log-age, enabling automatic differentiation.
where \(f_{\rm obs}\) is the unattenuated sightline fraction.
Upstream: Implements the Charlot & Fall (2000) two-component framework [1]_ with sigmoid age transition
following tengri’s differentiable design. Birth-cloud + diffuse ISM separation enables realistic modeling
of age-dependent dust geometry in galaxies.
Fast dust attenuation using precomputed age weights.
Avoids recomputing the birth-cloud age sigmoid every call. Used by
both the fused kernel (at effective wavelengths) and the exact path
(at the full wavelength grid).
The output dtype follows the input wavelengths dtype, enabling
mixed-precision: pass float32 arrays to halve memory traffic on the
(n_ages,n_wave) intermediates (~1.6x speedup on CPU).
Parameters:
wavelengths (array_like, shape (n_wave,)) – Evaluation wavelengths (rest-frame). [Å] Can be the full
SSP grid or just the filter effective wavelengths.
dust_age_weights (array_like, shape (n_ages,)) – Pre-computed sigmoid weights from precompute_dust_age_weights.
Computed once at Model init.
Optimized two-component dust attenuation with factorized age-independent term.
Exploits the exponential factorization exp(a + b) = exp(a) · exp(b) to separate
the diffuse ISM component from the age-dependent outer product. The diffuse
exponentiation operates on (n_wave,) instead of (n_ages, n_wave), saving one full-grid
exponential. Accepts pre-resolved law functions to avoid dict lookups in hot code.
dust_age_weights (array_like, shape (n_ages,)) – Pre-computed sigmoid birth-cloud weights from precompute_dust_age_weights.
Computed once at Model init and cached.
JIT-compatible: yes — all operations are jnp primitives.
Gradient-safe: yes — differentiable everywhere.
Performance: Reduces memory traffic by ~40% on (n_ages, n_wave) grids
relative to two_component_dust because the diffuse exponential is computed
on (n_wave,) and broadcast rather than materialized as (n_ages, n_wave).
Significant speedup on CPU; moderate benefit on GPU (memory bandwidth more abundant).
The ISM component is computed once on (n_wave,) and then broadcast with the age-dependent
birth-cloud term, avoiding the full (n_ages, n_wave) grid in intermediate storage.
JIT-compatible: yes — uses jnp.interp on precomputed curve.
Upstream credit: grain model data from Weingartner & Draine (2001) [1]_,
accessed via the dust-extinction astropy-affiliated package.
Independent implementation in synthesizer (Wilkins et al. 2025 [2]_).
Weingartner & Draine (2001) SMC Bar grain model attenuation curve.
Physically motivated dust grain-size + composition distribution for SMC-like
dust: steep UV rise, no 2175 Å bump. Most relevant for high-redshift galaxies.
JIT-compatible: yes — uses jnp.interp on precomputed curve.
Precomputed from dust_extinction.grain_models.WD01("SMCBar") at module
import time. Data cover ~100–107 Å. Values outside the tabulated
range are held constant at boundary values.
Upstream credit: grain model data from Weingartner & Draine (2001) [1]_,
accessed via the dust-extinction astropy-affiliated package.
Independent implementation in synthesizer (Wilkins et al. 2025 [2]_).
Stars and dust are uniformly mixed throughout a slab of total V-band optical depth.
The analytic solution integrates radiative transfer, producing a wavelength-dependent
transmission that is greyer (less wavelength-dependent) than a foreground screen.
Realistic for galaxies with well-mixed ISM (e.g., starburst regions).
where \(k(\lambda)\) is the normalized attenuation curve. This follows the solution
of radiative transfer in a uniform dust-star slab (Natta & Panagia 1984, Section 3.1;
Calzetti et al. 1994).
Limiting behaviour: At low optical depth (\(\tau_V k \ll 1\)), \(T \to 1\)
(transparent). At high optical depth, \(T \approx 1/(\tau_V k)\), producing
a greyer (less wavelength-dependent) effective attenuation than the foreground screen
because stars near the observer-facing side suffer less extinction.
Numerical stability: Uses a Taylor expansion (correct to order \(\tau^3\))
for \(\tau_V k < 10^{-4}\) to avoid division-by-zero, preserving gradients throughout.
Approximation: The analytic solution assumes pure absorption (zero scattering).
Witt & Gordon (2000) Monte Carlo simulations including scattering find the effective
attenuation is slightly greyer still. The analytic form captures the dominant geometric
effect and is widely used in SED fitting codes (e.g., Synthesizer, CIGALE).
Witt & Gordon (2000) DUSTY geometry — clumpy two-phase medium.
The ISM is modelled as n_clumps identical clumps, each with
optical depth tau_clump=tau_V/n_clumps, distributed along
random sightlines (Natta & Panagia 1984; Hobson & Padman 1993).
The probability of a photon traversing N clumps follows a Poisson
distribution, giving the mean transmission.
tau_v (float) – Total V-band optical depth (= n_clumps×tau_clump). [dimensionless]
law (str) – Underlying extinction curve name. Default: “cardelli” (MW).
n_clumps (float) – Mean number of clumps along a sightline. [dimensionless] Default: 10.0.
Higher values approach the homogeneous limit. Typical range: 1–40.
**law_params – Passed to the extinction curve function (e.g., dust_Rv).
where \(\tau_{\rm clump} = \tau_V / n_{\rm clumps}\).
This produces the greyest (least wavelength-dependent) effective attenuation
of the three WG00 geometries because photons preferentially escape through
low-column channels between clumps.
Limiting behaviour:
- \(n_{\rm clumps} \to \infty\) (fixed \(\tau_V\)): recovers the homogeneous slab.
- \(n_{\rm clumps} = 1\): single clump with Poisson averaging.
- \(\tau_V = 0\): T = 1 (transparent), regardless of n_clumps.
This module implements IR re-emission of UV/optical light absorbed by dust.
All models are pure JAX (JIT-compatible, fully differentiable) and follow
the energy-balance constraint: total IR luminosity equals total absorbed
luminosity from the attenuation step.
The "draine_li2007", "dale2014", "draine_li2014",
"astrodust", "bosa", and "themis" models auto-load tabulated
templates from the data/ directory on first use. If templates are not
found, they fall back to analytic approximations with a warning. The
analytic fallbacks are crude (single-Gaussian PAH, hand-tuned temperatures)
and should NOT be used for science.
Casey (2012) modified blackbody + mid-IR power law dust emission.
Combines a modified blackbody (FIR peak from cold/warm dust) with a
mid-IR power law (Wien-side excess from warm dust continuum), joined
by a smooth sigmoid transition function.
When optically_thin=True, the mid-IR power-law component is zeroed,
leaving only the modified blackbody. This variant is useful for cold
dust-dominated galaxies where the power law is unphysical.
Note
The mid-IR power-law contribution is only significant for warm/hot
dust (T ≳ 60 K). For typical cold ISM dust (T = 25–60 K) the Wien
cutoff exp(-hν/kT) kills the power-law component at 8–40 μm (x ≈ 10–51
at those wavelengths), so the model produces less 8–40 μm flux than a
pure MBB normalised to the same L_absorbed. The 8–40 μm advantage
described in Casey (2012) applies to warmer starburst / AGN-heated dust
components where T ≳ 80–100 K.
The implemented model uses the following convention (see code comments):
S(ν) = N_pl * ν^α_mid * f(λ) [mid-IR power law, f→1 at short λ]
+ N_bb * ν^(3+β) / (exp(hν/kT) - 1) * (1 - f(λ)) [FIR MBB, 1-f→1 at long λ]
where the transition function (f→1 selects power law at short λ) is:
f(λ)=1/(1+(λ/λ_0)^2)
Note: Casey (2012, MNRAS 425 3094) Eq. 2 defines the carrier function differently;
the code’s convention has f→1 at short λ (mid-IR) and 1-f→1 at long λ (FIR).
The shapes produced are equivalent; only the labelling of f vs (1-f) differs.
The empirical turnover wavelength is (Eq. 3, with errata):
λ_0=b1+b2*T[μm]
with b1=26.68μm, b2=6.246e-3μm/K.
Both components are normalized so that the total frequency integral
equals L_absorbed.
When redshift>0, the dust temperature is corrected for CMB
heating (da Cunha et al. 2013) and the observed flux is reduced by
the CMB contrast factor.
transmission (array_like, shape (n_wave,)) – Dust transmission fraction in [0, 1]. For age-dependent models
this should be the SFH-weighted effective transmission.
JIT-compatible: yes (returned function is JIT-compiled).
Dispatches to the lazy-loaded DL14 template model. Auto-loads HDF5 templates
on first call. DL14 is the 2014 update to Draine & Li 2007 with additional
alpha (radiation field) dependence.
Two-temperature energy balance with AGN contribution.
Extends simple eta_balance by decomposing IR into warm (SF-heated)
and cold (diffuse ISM) components, plus optional AGN IR contribution.
Parameters:
wavelength_aa (array_like, shape (n_wave,)) – Wavelength grid. [Å] Must be sorted ascending.
L_absorbed_stellar (float) – Total absorbed stellar luminosity. [Lsun]
L_agn_ir (float) – Additional AGN-heated IR luminosity. [Lsun] Default: 0.0.
eta_balance (float) – Energy balance parameter: ratio of re-emitted to absorbed stellar luminosity.
[dimensionless] Default: 1.0 (strict energy balance).
f_cold (float) – Fraction of total IR luminosity in the cold component.
[dimensionless, in [0, 1]] Default: 0.5.
L_absorbed (float) – Total absorbed luminosity. Unit-agnostic: the output L_nu will be
in the same units per Hz (e.g. pass erg/s → get erg/s/Hz; pass
Lsun → get Lsun/Hz). In sed_pipeline.py the pipeline passes
erg/s (from a frequency-integrated trapezoid) and receives erg/s/Hz.
dust_T (float) – Dust temperature in Kelvin. Typical range: 20–60 K. [K]
Smith et al. (2007) PAH Drude profiles dust emission.
A sum of 18 PAH Drude profiles (normalized to Smith+2007 SINGS median
strengths). Runtime evaluation prefers the precomputed lookup from
dust_analytic_precompute; this function
provides a direct full-wavelength evaluation used when precompute is
unavailable.
JIT-compatible: yes — computed via triweight interpolation in precompute
mode; this function is a fallback stub.
Gradient-safe: yes — inherited from precompute lookup.
The PAH template is a pure shape (no free axes). Runtime evaluation uses the
precomputed lookup from dust_analytic_precompute
and skips the full-wavelength evaluation in the hybrid kernel.
Force lazy template loading outside any JAX JIT scope.
Template-based emission models use lazy loaders that fire on first call.
If the first call happens inside a @jax.jit scope, jnp.array()
inside the loader creates DynamicJaxprTracer objects that escape into
closures, causing UnexpectedTracerError on subsequent non-JIT calls.
Call this function at factory time (outside JIT) so templates are loaded
into DUST_EMISSION_MODELS[name] as regular DeviceArray objects.
Dynamic JAX indexing inside JIT then works correctly.
Parameters:
name (str) – Registry name (e.g. "draine_li2007").
Returns:
The loaded (real) emission function — NOT a lazy wrapper.
Return type:
Callable
Notes
JIT-compatible: no — template loading happens at factory time.
Safe to call at SEDModel.__init__ time to prevent tracer leaks
when models are first called inside a @jax.jit scope.
Decorator factory that registers a dust emission model under a name.
Parameters:
name (str) – Registry key (e.g. "dale2014", "draine_li2007").
Returns:
Decorator that registers the decorated function and returns it unchanged.
Return type:
Callable
Notes
JIT-compatible: no — registration happens at factory time before JIT.
Decorated functions must implement the DustEmissionTemplate protocol:
accept a wavelength array, absorbed luminosity, and keyword arguments,
returning an emission SED L_ν [erg/s/Hz].
JIT-compatible: no — registry lookup happens at factory time.
The returned function matches the DustEmissionTemplate protocol and can
be called with wavelengths, absorbed luminosity, and model-specific parameters.
Schreiber et al. (2016) 2-parameter dust emission model.
Mixes dust continuum and PAH emission by a fractional parameter.
The dust continuum is a modified blackbody (modified_blackbody with
beta=1.5). The PAH component is approximated as a sum of Drude profiles
at standard wavelengths.
JIT-compatible: yes (returned function is JIT-compiled).
Dispatches to the lazy-loaded THEMIS/DustEM template model. Auto-loads
HDF5 templates on first call. Uses a-C(:H) aromatic carbon composition
rather than PAH fraction.
Redshift-dependent attenuation priors from cosmological simulations.
Redshift-dependent dust attenuation priors from Narayanan+2018.
Based on cosmological radiative transfer simulations (SIMBA/Narayanan et al.
2018, ApJ, 869, 70), which show systematic trends in attenuation curve shape
and optical depth with redshift and stellar mass:
Higher-z galaxies have steeper curves (more negative delta)
UV bump strength decreases with redshift
Optical depth scales with stellar mass and redshift
These functions return dicts of Gaussian distributions suitable for direct
use in Parameters kwargs.
References
Narayanan, D., et al. (2018). ApJ, 869, 70.
“A Theory for the Variation of Dust Attenuation Laws in Galaxies”
Keys "dust_delta" and "dust_bump_strength", each mapping to a
Gaussian distribution [dimensionless]. Suitable for direct use in
Parameters(...,**narayanan_prior(z)).
Multi-color disc (Shakura-Sunyaev) — physically-motivated standard thin
disc following Kubota & Done (2018), simplified to the key parameters.
Implements the outer standard disc zone only.
Kubota & Done 3-zone disc — full K&D (2018) model with outer standard
disc, warm Comptonization (soft X-ray excess), and hot corona (hard X-ray
power law). Three radially-stratified zones with self-consistent radii.
ADAF + truncated disc — for low-luminosity AGN (L/L_Edd < 0.01).
The inner disc transitions to an advection-dominated accretion flow
(optically thin, radiatively inefficient). Based on Mahadevan (1997)
and Nemmen+2014.
All return specific luminosity L_nu in erg/s/Hz as a function of rest-frame
wavelength. All functions are pure JAX and JIT-compilable.
Physical constants are in CGS. Wavelength inputs are in Angstrom.
Advection-dominated accretion flow (ADAF) plus truncated disc.
Model a low-luminosity AGN in the sub-Eddington regime where the inner
accretion flow transitions from a geometrically thin, optically thick
disc to an advection-dominated accretion flow (ADAF). In an ADAF, most
of the released gravitational energy is advected into the black hole
rather than radiated away, making the flow radiatively inefficient.
The outer disc remains as a Shakura-Sunyaev disc truncated at a transition
radius r_tr.
The total spectrum is the sum of four components:
ADAF synchrotron (radio to millimeter): relativistic electrons
gyrating in a turbulent magnetic field.
ADAF bremsstrahlung (X-ray): thermal bremsstrahlung from
collisions in the hot electron-ion plasma (T_e ~ 10^9–10^11 K).
ADAF inverse Compton (hard X-ray): upscattering of bremsstrahlung
photons by relativistic electrons.
Truncated outer disc (UV/optical): Shakura-Sunyaev multi-color
disc from r_tr outward.
agn_log_lbol (float) – Total AGN bolometric luminosity. [log10(L_sun)]
agn_frac (float, optional) – Fraction of bolometric luminosity emitted by this component.
Default: 0.1. [dimensionless, 0–1]
agn_log_mbh (float, optional) – Black hole mass. Scales the synchrotron peak frequency and
gravitational radius. Default: 8.0. [log10(M_sun)]
agn_log_ledd (float, optional) – Eddington ratio. This model is designed for sub-Eddington
accretion (log(L/L_Edd) < -2). Default: -3.0.
[log10(L / L_Edd)]
agn_r_tr (float, optional) – Truncation radius in units of the gravitational radius
R_g = GM/c^2. This marks the transition between the ADAF
(r < r_tr) and the thin disc (r > r_tr). Typical range: 10–1000 R_g.
Default: 100.0. [dimensionless, ≥ 6]
agn_adaf_beta (float, optional) – Ratio of gas pressure to total pressure in the ADAF.
Controls the magnetic field strength and synchrotron emission.
Range: [0, 1]. Default: 0.5. [dimensionless]
agn_adaf_delta (float, optional) – Fraction of viscously dissipated energy that directly heats electrons
(as opposed to protons). Controls the electron temperature.
Lower δ → hotter electrons. Range: [0, 1]. Default: 0.01.
[dimensionless]
agn_cos_inc (float, optional) – Cosine of the inclination angle (outer disc view angle).
Default: 0.5 (60°). [dimensionless, 0.01–1.0]
n_radii (int, optional) – Number of radial integration points for the outer disc component.
Default: 50.
where \(\dot{m} = L / L_{\rm Edd}\) is the dimensionless accretion rate.
For sub-Eddington rates (\(\dot{m} \lesssim 0.1\)), the radiated luminosity
is highly suppressed. The ADAF component luminosity is estimated from the
fractional contribution determined by the truncation radius.
ADAF electron temperature (Mahadevan 1997, Eq. 40):
The electron temperature is set by the energy-balance equation:
where \(\delta\) is the electron heating fraction and \(\dot{m}\) is the
dimensionless accretion rate. The exponent 1/7 (not 1/2) comes from the coupled
electron-proton heating equations. Clipped to [10^8, 5×10^11] K for physical
plausibility.
Synchrotron component (Mahadevan 1997, Eq. 21, 25):
Electrons in the turbulent ADAF magnetic field produce synchrotron emission with
a characteristic peak frequency:
Below the self-absorption frequency \(\nu_{\rm sa} \approx \nu_{\rm peak}/3\),
the spectrum is optically thick (Rayleigh-Jeans: \(\propto \nu^2\)).
Above \(\nu_{\rm sa}\), it is optically thin with spectral index 2/5:
\(\propto \nu^{2/5}\) (not 1/3). The two regimes join continuously at
\(\nu_{\rm sa}\).
Bremsstrahlung (Mahadevan 1997, Eq. 3):
Thermal bremsstrahlung from the hot electron-ion plasma provides a flat spectrum
(\(\propto \nu^0\)) below the exponential cutoff at \(k_B T_e / h\).
Inverse Compton (Mahadevan 1997, Eq. 34, 35):
Thomson (optically thin) scattering of bremsstrahlung photons by relativistic
electrons. The photon index is:
\[\alpha_c = -\frac{\ln(\tau_{\rm es})}{\ln(A)}\]
where \(\tau_{\rm es}\) is the electron scattering optical depth and
\(A \approx 4 \Theta\) with \(\Theta = k_B T_e / m_e c^2\).
For typical ADAF parameters (\(T_e \sim 10^{10}\) K, \(\tau_{\rm es} \sim 1\)),
this yields \(\alpha_c \sim 0.7–1.0\).
Component weights (Mahadevan 1997, Eq. 26, 29, 35):
The relative contributions of synchrotron, bremsstrahlung, and inverse Compton
are determined by the magnetic field strength (via \(\beta\) = gas pressure
/ total pressure), the optical depth, and the particle distribution. The weights
are not arbitrary: synchrotron dominates at low frequencies, bremsstrahlung at
intermediate frequencies, and inverse Compton at high frequencies. The beta
parameter controls the magnetic energy density.
Truncated outer disc: The standard Shakura-Sunyaev multi-color disc
(see multicolor_disc()) contributes from the truncation radius r_tr
outward. This dominates the UV/optical and provides the warm photons
that seed inverse Compton scattering.
Known limitations:
This implementation is based on Mahadevan (1997) analytic prescriptions and does
not solve the full magnetohydrodynamic ADAF equations.
The inverse Compton calculation uses a simplified approximation; full solutions
would require iterative energy balance with the photon field.
The model has not been extensively validated against 3D ADAF simulations or a
comprehensive sample of observed low-luminosity AGN. Use with caution in
quantitative inference.
This implementation follows Kubota & Done (2018, MNRAS 480 1247, Eq. 6),
which rewrites the Beloborodov (1999) Compton-amplification result as a
power law in the luminosity ratio. The exponent -0.1 encodes the
energy-balance relation between the dissipated power in the corona and
the seed photon luminosity intercepted from the disc. Output is clipped
to [1.4, 3.0] to match the physical range of typical AGN.
The 2500 Å point is a canonical AGN diagnostic wavelength, used to
compute the optical-to-X-ray spectral index (alpha_ox) and as a
benchmark for intrinsic AGN continuum comparisons. Linear interpolation
in wavelength space is sufficient for the optical/UV continuum variability
timescales. The wavelength array need not be pre-sorted; this function
sorts internally before interpolation.
Return a JIT-compatible RELAGN disc SED function from a precomputed grid.
The grid was built with the real RELAGN Python class (Hagen & Done 2023)
using KYCONV (Dovciak, Karas & Yaqoob 2004) per-annulus Kerr ray-tracing.
It stores absolute L_ν (erg/s/Hz) at cos_inc = 0.5; the inclination
correction is applied analytically as 2·cos_inc (valid for the
non-relativistic outer disc; approximate for the GR inner disc).
Parameters:
grid_path (str) – Path to data/relagn_disc_grid.h5.
JIT-compatible: yes — the returned function is pure JAX.
Grid loading is cached via @functools.cache.
Gradient-safe: yes — triweight interpolation is C²-continuous.
Inclination: grid stored at cos_inc = 0.5; scaled by 2·cos_inc.
This is exact for r > 1000 r_g (non-relativistic regime) and approximate
for the GR inner disc where KYCONV applies full Kerr ray-tracing.
Kubota & Done (2018) three-zone accretion disc with self-consistent corona.
Model a physically stratified AGN accretion disc as three radially distinct
zones, each with different physics and electron temperatures. This is the
reference model for intermediate to high accretion rates and is used in
tengri’s default AGN configuration.
The three zones share a single Novikov-Thorne temperature profile but have
different radiation mechanisms:
Outer standard disc (r > R_warm): Optically thick, geometrically thin.
Temperature decreases with radius (∝ r^{-3/4}). Radiates as multi-color
blackbody. Dominates the optical/UV “big blue bump.”
Warm Comptonization zone (R_hot < r < R_warm): Optically thick,
warm electrons (kT_e ~ 0.2 keV, τ ~ 10-20). Inverse Compton-scattered
disc photons plus thermal radiation. Produces the soft X-ray excess.
Computed via precomputed nthcomp Kompaneets templates (when available)
or a simplified modified-blackbody proxy.
Hot corona (R_ISCO < r < R_hot): Optically thin, hot electrons
(kT_e ~ 100 keV, τ ~ 1). Inverse Compton scatters disc seed photons
to produce hard X-ray power-law spectrum with exponential cutoff.
Zone boundaries are determined self-consistently:
R_hot: Solved via bisection from the energy-balance constraint that
the dissipated power in the corona equals f_hard × L_Edd. Uses the
exact analytic Novikov-Thorne integral rather than approximations.
R_warm: Parameterized as a multiple of R_hot (default 2, per K&D).
R_out: Set to the Laor & Netzer (1989) self-gravity (Toomre) radius,
beyond which the disc becomes unstable and fragments.
The hard X-ray photon index Γ_hot is derived self-consistently from the
Beloborodov (1999) energy-balance relation if requested; otherwise uses
the input value.
agn_cos_inc (float, optional) – Cosine of the inclination angle between the disc normal and the
line of sight. Range: [0.01, 1.0]. Used to compute the projected
disc area. Default: 0.5 (60°). [dimensionless]
agn_f_hard (float, optional) – Fraction of Eddington luminosity dissipated in the hot corona.
Controls the corona zone extent R_hot. Typical range: 0.01–0.1.
Default: 0.02. [dimensionless, 0–0.5]
agn_gamma_warm (float, optional) – Photon index of the warm Comptonization zone (nthcomp).
Range: ~1.5–3.5. Default: 2.5. [dimensionless]
agn_kt_warm (float, optional) – Electron temperature in the warm Comptonization zone.
Default: 0.2. [keV]
agn_gamma_hard (float, optional) – Photon index of the hard X-ray power law (hot corona).
Typical range: 1.5–2.5. Default: 1.8.
Ignored if agn_self_consistent_gamma=True. [dimensionless]
agn_kt_hot (float, optional) – Electron temperature in the hot corona.
Default: 100.0. [keV]
agn_r_warm_ratio (float, optional) – Radius ratio R_warm / R_hot. Controls the warm zone extent.
Default: 2.0 (per K&D 2018). [dimensionless, ≥ 1.1]
n_radii (int, optional) – Number of radial integration points per zone.
Default: 50. Higher values increase accuracy at computational cost.
agn_self_consistent_gamma (bool, optional) – If True, compute agn_gamma_hard self-consistently from the
Beloborodov (1999) energy-balance relation:
Γ = 7/3 × (L_diss / L_seed)^{-0.1}
If False, use the input agn_gamma_hard value. Default: False.
where \(T_{\rm in} = (3 G M M_{\rm dot} / 8\pi \sigma_{\rm SB}
r_{\rm ISCO}^3)^{1/4}\), and the inner temperature increases with accretion
rate. The radii are ordered as R_ISCO < R_hot < R_warm < R_out.
Zone luminosity computation:
Each zone is divided into annuli at radii {r_i}, each of which contributes
L_ν from its local Planck function (outer disc), nthcomp prescription
(warm zone), or hot-corona power law (inner zone). All zones are summed
and renormalized to conserve total bolometric energy.
Seed photon calculation (K&D 2018 Eq. 3):
The hot corona inverse-Compton scatters disc seed photons. The seed photon
luminosity is computed from the geometric integral of the warm-zone
blackbody flux intercepted by the corona geometry:
where \(\Theta(r) = \theta_0 - \sin(2\theta_0)/2\) and \(\sin\theta_0
= R_{\rm hot}/r\). This drives the self-consistent Γ_hot via Beloborodov.
Precomputed nthcomp templates: For maximum speed and accuracy, the
warm Comptonization is computed via interpolation in precomputed nthcomp
Kompaneets templates (see scripts/build_nthcomp_templates.py).
These templates span (Γ_warm, kT_e) parameter space and return
(Γ_warm, kT_e, normalisation)-dependent SED at each radius.
If templates are unavailable, a simplified modified-blackbody proxy is used,
which has ~5–10% shape error but allows offline computation.
Approximations and accuracy:
The reference QSOSED/RELAGN codes use non-differentiable operations
(root solvers, C implementations). Tengri’s JAX reimplementation makes
key approximations documented in the code (see
docs/dev/design/agn-kd-model.md):
R_hot: 40-step JAX-compatible bisection (exact to ~10^{-12}).
Warm zone: precomputed nthcomp templates with (Γ_w, kT_e) interpolation
(accuracy: ≲ 2% in flux density).
Shakura-Sunyaev thin accretion disc with multi-color blackbody emission.
Compute the SED of a standard geometrically thin, optically thick accretion
disc via the Shakura-Sunyaev model. The disc is stratified into radial
annuli, each radiating as a blackbody at its local temperature. This is
the outer-disc component of the Kubota & Done (2018) three-zone model
(see kubota_done_disc() for the full model including corona).
where \(T_{\rm in}\) is the inner temperature determined by the
accretion rate and \(r_{\rm ISCO}\) is the innermost stable circular
orbit (radius from Bardeen et al. 1972, depends on spin).
where \(B_\nu(T)\) is the Planck function, \(r_i\) is the ring
radius [cm], \(dr_i\) is the ring width [cm], and \(\cos(i)\) is
the projection factor (inclination).
Key physics:
Radiative efficiency: \(\eta = 1 - \sqrt{1 - 2/(3 r_{\rm ISCO})}\),
computed from Novikov-Thorne theory. For Schwarzschild (a=0): η ≈ 0.057;
for maximally spinning (a→0.998): η ≈ 0.32.
Outer radius: Uses the Laor & Netzer (1989) self-gravity (Toomre)
radius, beyond which the disc fragments. This is an improvement over
fixed approximations (e.g., 1000 r_ISCO) that can err by factors of
a few at extreme masses or accretion rates.
Eddington ratio clamping: The accretion luminosity is capped at
\(L_{\rm Edd}\) (i.e., log(L/L_Edd) is clipped to [0, 1] in linear
space), reflecting the physical limit of radiatively efficient accretion.
Numerical method: Radii are logarithmically spaced to ensure fine
resolution at small radii where the temperature gradient is steep.
Integration uses summation; the trapezoidal rule is applied in log-radius
space via the spacing \(d\log r = \Delta(\log r)\).
Simple power-law accretion disc with exponential UV cutoff.
A phenomenological single-component AGN disc model that approximates the
optical/UV emission as a power law with an exponential cutoff at high
frequencies. This is a faster alternative to multi-color disc models when
fine spectral details are not required.
where \(\alpha\) is the spectral index, \(h\) is Planck’s constant,
\(\nu\) is frequency [Hz], \(k_B\) is Boltzmann’s constant, and
\(T_{\rm max}\) is the cutoff temperature [K].
The normalization constant \(C\) is computed numerically by integrating
the shape over the wavelength grid via the trapezoidal rule, ensuring that
the integral over frequency equals the target luminosity
\(L_{\rm bol} \cdot f_{\rm disc}\).
Approximation: This model is a simplified representation of the true
accretion disc spectrum, which consists of multiple temperature zones
(see multicolor_disc() and kubota_done_disc() for more
realistic models). The power-law form breaks down at low frequencies
(radio/submm) where the SED transitions to a different regime, and does
not capture the soft X-ray excess or hard X-ray corona. Use this model
only when computational speed is prioritized over spectral fidelity.
Broad Line Region (BLR) emission model.
The BLR is dense gas close to the black hole producing broad permitted
emission lines with FWHM ~ 1000-10000 km/s. The BLR is geometrically
compact and lies within the torus, so it is obscured at high
inclinations (Type 2 AGN).
This module provides an analytic BLR template using broad Gaussian
profiles at the wavelengths of the strongest permitted lines, plus
an Fe II pseudo-continuum modeled as a sum of broad Gaussians at key
multiplet wavelength groups (Tsuzuki+2006, Kovacevic+2010).
All functions are pure JAX and JIT-compilable.
References
Vanden Berk et al. 2001, AJ, 122, 549 (SDSS composite quasar spectrum)
BLR emission spectrum: broad permitted lines + Fe II pseudo-continuum.
The BLR receives covering_fraction*L_disc and converts
a fraction into broad emission lines. When agn_fe2_strength>0,
an Fe II pseudo-continuum is added, scaled relative to H-beta
luminosity using the standard R_Fe ratio.
Note: geometric masking by the torus is NOT applied here;
it must be applied by the caller.
JIT-compatible: yes — uses jnp primitives and jax.vmap.
The broad emission lines are modeled as Gaussian profiles at rest-frame
wavelengths (Vanden Berk et al. 2001). Line strengths are calibrated to
typical Type 1 AGN composite spectra. The Fe II pseudo-continuum follows
the Tsuzuki+2006 / Kovacevic+2010 approach: broad Gaussians at UV and
optical multiplet centers, normalized to the standard R_Fe ratio.
Torus geometry: This function returns the “bare” BLR spectrum without
geometric masking by the dusty torus. The caller is responsible for
applying inclination-dependent torus obscuration if using a torus model.
References
Narrow Line Region (NLR) emission model.
The NLR is photoionized gas illuminated by the AGN accretion disc.
It produces nebular-like emission: a power-law continuum plus
forbidden-line emission at key wavelengths.
The NLR emission is isotropic (not masked by the torus) because it
extends on kpc scales beyond the torus opening angle.
For computational efficiency this module uses analytic line profiles
rather than full CLOUDY grids. Each emission line is a Gaussian with
FWHM ~ 500 km/s (narrow lines) placed at the laboratory wavelength.
All functions are pure JAX and JIT-compilable.
References
Groves et al. 2004, ApJS, 153, 75 (NLR photoionization models)
Feltre et al. 2016, MNRAS, 456, 3354 (NLR emission-line diagnostics)
Vijarnwannaluk et al. 2022 (NLR covering fractions)
AGN NLR spectrum using Richardson+2014 Table 3 ‘a42’ line template.
The narrow-line region (NLR) is photoionized gas illuminated by the AGN
accretion disc. This function synthesizes the NLR emission spectrum using
the emission-line template from Richardson et al. (2014), which provides
AGN-specific line ratios derived from the ‘a42’ column of Table 3
(moderate AGN luminosity, intermediate inclination angle).
The NLR receives covering_fraction*L_disc and converts a fraction
into line emission. Each line is modeled as a Gaussian profile at the
rest-frame wavelength.
This function is JIT-compilable (no traced control flow).
The Richardson+2014 ‘a42’ template uses 23 emission lines normalized to
H-beta = 1. The strongest line is [O III] 5007 at 8.53× H-beta.
Implemented via FSPS emission-line indices. Line profiles are Gaussian
with fixed FWHM (narrow lines, ~500 km/s).
Ported from Prospector (Johnson et al. 2021 [1]_), which implements
the same table for AGN NLR modeling.
Combines accretion disc and dust torus models into a single AGN SED.
The disc emission is partly absorbed by the torus (via covering factor)
and re-emitted in the IR.
The component tree and geometric masking design in this module is inspired
by the UnifiedAGN class in the Synthesizer package
(Lovell et al. 2025, Open J. Astrophys., arXiv:2508.03888;
Roper et al. 2025, arXiv:2506.15811; https://github.com/synthesizer-project/synthesizer).
Synthesizer’s model defines:
An accretion disc whose inclination-dependent emission is extracted from
precomputed photoionisation grids (CLOUDY-based).
NLR emission as grid-extracted nebular spectra, not masked by the torus
(isotropic: always visible at all inclinations).
BLR emission as grid-extracted nebular spectra, masked by the torus using a
hard binary condition: inclination+theta_torus>90° → zeroed.
A torus that reprocesses the isotropic disc emission, scaled by
torus_fraction=theta_torus/90° (geometric fraction of sky covered).
tengri adopts the same conceptual decomposition but diverges in several ways
for compatibility with gradient-based inference (VI, HMC):
Analytic disc models, not grids: disc emission uses the closed-form
multicolor/Shakura-Sunyaev or power-law models from disc.py rather
than a photoionisation grid. This makes the disc JIT/grad-compatible.
Analytic NLR/BLR templates, not grids: NLR and BLR use empirically
calibrated Gaussian line templates (Vanden Berk et al. 2001; Groves et al.
2004) rather than CLOUDY-generated photoionisation grids. Grids would
require non-differentiable table look-ups over (U, n_H) axes.
Smooth sigmoid geometric mask, not a hard binary: Synthesizer zeros
the disc/BLR whenever inclination+theta_torus>90°. tengri replaces
this with a smooth sigmoid centred at the critical angle (see
_sigmoid_mask). The sigmoid preserves the gradient through the
inclination parameter, which would otherwise be zero almost everywhere
under the hard mask.
Explicit ``agn_torus_frac`` parameter, not derived from theta_torus:
Synthesizer internally computes torus_fraction=theta_torus/90°,
coupling the torus covering factor to the opening angle. tengri keeps
agn_torus_frac as an independent free parameter. This decoupling is
intentional: deriving the covering factor from cos(theta_torus) in
the forward pass introduces a gradient discontinuity at theta_torus=0
and at theta_torus=90° (see CLAUDE.md gotcha).
Polar dust reddening (SMC law): an optional agn_polar_ebv parameter
applies SMC-law extinction to the disc and BLR for Type 1 sightlines.
This is absent from Synthesizer’s basic UnifiedAGN but present in the
CIGALE skirtor2016 module (Yang et al. 2020, MNRAS, 491, 740).
agn_log_lbol is \(\log_{10}(L_{\rm bol} / L_\odot)\) — the
bolometric luminosity expressed in solar luminosities, not erg/s.
This matches the internal computation in components/agn/_phys.py
(l_bol_erg=10**agn_log_lbol*L_SUN).
Synthesizer’s bolometric_luminosity is in erg/s; convert with
agn_log_lbol=log10(L_bol_erg)-log10(L_SUN_erg),
i.e. subtract \(\approx 33.58\) from synthesizer’s value.
Defaults of agn_log_lbol=44.0 in the function signatures of this module
are inherited from early test fixtures and correspond to
\(L_{\rm bol}\!\approx\!4\times 10^{77}\) erg/s — not a physical AGN
luminosity. They are kept for backward-compatibility with the existing test
suite. Always set this parameter explicitly in production fits; do not rely on
the default.
Usage:
fromtengri.components.agn.unifiedimportunified_agn,resolve_agn_model# Use a named configuration. agn_log_lbol = 11 → L_bol ≈ 4e44 erg/s# (a typical bright Seyfert nucleus).model_fn=resolve_agn_model("simple")l_nu=model_fn(wavelength,agn_log_lbol=11.0,agn_frac=0.1,...)# Or use the generic combiner directly.l_nu=unified_agn(wavelength,agn_log_lbol=11.0,disc_model="powerlaw",...)
ADAF + truncated disc + simple torus for low-luminosity AGN.
At low accretion rates (L/L_Edd < 0.01), the inner disc transitions
to an ADAF. The outer disc remains as a truncated Shakura-Sunyaev disc.
A simple torus re-emits a fraction of the bolometric luminosity in the IR.
6 free parameters (+ agn_frac scaling):
agn_log_mbh: BH mass
agn_log_ledd: Eddington ratio (should be < -2 for ADAF regime)
Full Kubota & Done (2018) 3-zone disc + two-temperature torus.
Extends multicolor_agn with the full K&D 3-zone disc model:
outer standard disc, warm Comptonization (soft X-ray excess), and
hot corona (hard X-ray power law). Combined with a two-temperature dust torus.
Create a Cue-backed NLR emission callable for unified_nlr_blr.
Returns a closure that uses the Cue neural-net emulator (Li et al. 2024
[1]_) to predict NLR emission lines and continuum as a function of
ionising spectrum shape and gas properties. The closure matches the
standard NLR backend interface expected by unified_nlr_blr().
The Cue weights are closed over as static pytree leaves, so the returned
callable is JIT-compatible.
Parameters:
weights (CueWeights) – Pre-loaded Cue network weights from
load_cue_weights().
ionspec_index1..4 (float) – Power-law indices of the ionising spectrum piecewise approximation.
Defaults correspond to a typical Seyfert 1 AGN spectrum.
ionspec_logLratio1..3 (float) – log10(L) ratios between power-law segments. Default 0.0.
gas_logqion (float) – log10(Q_H) — total ionising photon rate [photons/s]. Used for
normalisation. Default 49.1 (typical AGN at log L_bol ~ 44).
JIT/grad compatible when Cue weights are registered as JAX pytrees.
The weights must first be loaded via
tengri.components.nebular.cue.load_cue_weights.
The Cue emulator was trained for AGN-illuminated gas (not stellar HII
regions). It is appropriate for NLR emission; it does NOT model the BLR
(which requires a separate, denser photoionisation model with
n_H ~ 10^10 cm^-3 and no dust).
Standard thin-disc SED with spin-dependent ISCO and Novikov-Thorne
radiative efficiency. This is the outer standard disc only — no warm
Comptonization or hot corona (for the full 3-zone model, see kubota_done_full).
Uses the precomputed RELAGN grid (Hagen & Done 2023) with KYCONV
(Dovciak, Karas & Yaqoob 2004) per-annulus Kerr ray-tracing for the
disc, and a two-temperature modified blackbody for the torus.
The disc luminosity is self-consistent with BH mass and accretion rate;
the torus re-emits agn_torus_frac of the disc bolometric output.
JIT-compatible: yes — disc interpolation is pure JAX triweight kernel.
Gradient-safe: yes — C²-continuous triweight kernel on all grid axes.
Grid required: data/relagn_disc_grid.h5 built by
scripts/build_relagn_disc_grid.py (requires HEASOFT/XSPEC + KYCONV).
Torus normalization: derived by integrating the disc L_ν over the
output wavelength grid via jnp.trapezoid — no separate agn_log_lbol
parameter needed.
Unified AGN SED with NLR/BLR decomposition and geometric masking.
Implements the same conceptual decomposition as the UnifiedAGN class
in Synthesizer (Lovell et al. 2025 [1]_, Roper et al. 2025 [2]_):
an accretion disc, dusty torus, narrow line region (NLR), and broad line
region (BLR), combined with inclination-dependent geometric masking.
Polar dust reddening (SMC law) is additionally adapted from CIGALE’s
skirtor2016 module [3]_.
Correspondence with Synthesizer’s UnifiedAGN
The following table maps tengri parameters to Synthesizer attributes
(synthesizer.components.blackhole.BlackholeComponent):
tengri
Synthesizer
Note
agn_cos_inc
cos(inclination)
Synth uses inclination [deg]
agn_theta_torus
theta_torus [deg]
Same meaning
agn_nlr_cf
covering_fraction_nlr
Identical semantics
agn_blr_cf
covering_fraction_blr
Identical semantics
agn_torus_frac
torus_fraction=theta_torus/90°
Different: independent param
agn_blr_fwhm
velocity_dispersion_blr [km/s]
tengri uses FWHM directly
agn_nlr_fwhm
velocity_dispersion_nlr [km/s]
Same
Deliberate differences from Synthesizer
Analytic disc, not a grid: Synthesizer extracts disc emission from
precomputed CLOUDY photoionisation grids. tengri uses the closed-form
multicolor_disc (Shakura-Sunyaev / Novikov-Thorne) from
disc.py. Rationale: grid look-ups are not JAX-jittable under
gradient tape; analytic models are differentiable by construction.
Analytic NLR/BLR templates, not grids: Synthesizer uses CLOUDY
grids over (logU, log n_H) for both NLR and BLR emission. tengri uses
empirically calibrated Gaussian line templates (Vanden Berk et al.
2001 for BLR; Groves et al. 2004 for NLR). Rationale: same as above.
Smooth sigmoid mask, not a hard binary: Synthesizer zeros the disc
and BLR when inclination+theta_torus>90° — a hard step
function. tengri replaces this with a smooth sigmoid (see
_sigmoid_mask) centred at the same critical angle with a ~2°
transition width. Rationale: the hard mask has zero gradient with
respect to inclination almost everywhere, making gradient-based VI
and HMC blind to inclination information near the critical angle.
``agn_torus_frac`` decoupled from ``theta_torus``: Synthesizer
internally sets torus_fraction=theta_torus/90°, coupling the
reprocessed fraction to the geometric opening angle. tengri keeps
agn_torus_frac as an independent free parameter. Rationale:
auto-deriving from cos(theta_torus) in the forward pass introduces
a gradient discontinuity at the poles (CLAUDE.md gotcha). The coupling
can be enforced at the Parameters level via a fixed/derived param.
Polar dust reddening (SMC law): agn_polar_ebv applies SMC
extinction to the disc and BLR for Type 1 sightlines (mask > 0).
Absent from Synthesizer’s basic UnifiedAGNIntrinsic; adapted from
CIGALE skirtor2016 (Yang et al. 2020 [3]_).
where \(\sigma(i, \theta_t)\) is the smooth sigmoid mask
(1 = visible, 0 = obscured), \(A_{\rm pol,eff}(\lambda) = 1 + \sigma(i, \theta_t) \,
(A_{\rm pol}(\lambda) - 1)\) is the visibility-weighted SMC polar dust transmission
(SMC law; only reddens when disc is visible to the observer), \(f_{\rm NLR/BLR}\)
are the covering fractions, \(\eta_{\rm NLR/BLR}\) are the normalised
line templates, and \(\mathbb{1}_{\rm X-ray/radio}\) are indicator functions
controlling whether X-ray and radio components are included.
agn_log_lbol (float) – \(\log_{10}(L_{\rm bol} / L_\odot)\) — total AGN bolometric
luminosity expressed in solar luminosities (not erg/s).
Convert from synthesizer’s bolometric_luminosity [erg/s] via
agn_log_lbol=log10(L_bol_erg)-log10(L_SUN_erg),
i.e. subtract \(\approx 33.58\). Typical bright Seyfert: 10.5;
bright quasar: 12.5. The default 44.0 is a legacy test fixture
that is not a physical AGN luminosity — set this parameter
explicitly. See module-level “Convention” note. Default 44.0.
agn_theta_torus (float) – Torus half-opening angle [degrees]. Controls the critical inclination
above which the disc and BLR are obscured. Same meaning as
theta_torus in Synthesizer. Default 30.0.
agn_nlr_cf (float) – NLR covering fraction (0 to 1). Fraction of disc luminosity
reprocessed into NLR emission. Synthesizer: covering_fraction_nlr.
Default 0.1.
agn_blr_cf (float) – BLR covering fraction (0 to 1). Fraction of disc luminosity
reprocessed into BLR emission. Synthesizer: covering_fraction_blr.
Default 0.1.
agn_torus_frac (float) – Torus covering factor (fraction of L_bol intercepted by torus).
In Synthesizer this is derived as theta_torus/90°; here it is
an independent free parameter. Default 0.5.
agn_nlr_fwhm (float) – NLR line FWHM [km/s]. Default 500.
agn_polar_ebv (float) – Polar dust E(B-V) applied to disc + BLR for Type 1 views (SMC law).
Adapted from CIGALE skirtor2016 [3]_. Not in Synthesizer’s basic
UnifiedAGN. Default 0.0 (no reddening).
where the return value is L_nu [erg/s/Hz]. Default None uses the
built-in analytic template from nlr_emission().
To use the Cue neural-net emulator, pass the result of
make_cue_nlr_fn().
blr_fn (callable or None) – BLR emission backend. Same signature as nlr_fn. Default None
uses the built-in analytic template from
blr_emission().
include_xray (bool) – If True, include X-ray corona emission. Default False (UV-optical-IR only).
JIT/grad/vmap compatible when nlr_fn and blr_fn are JIT-compatible
(the default analytic templates are; Cue-backed closures are also JIT-safe
since the weights are closed over as static pytree leaves).
X-ray and radio components (when included):
X-ray: Power-law corona emission normalised via the alpha_OX relation
(Tananbaum+1979). Wavelength range: λ < 124 Å (E > ~100 eV). Computed
via xray_agn_corona()[4].
When both include_xray=False and include_radio=False, the function
returns the UV-optical-FIR unified AGN SED (original behaviour). The new
components are additive and do not affect existing parameters or output
ranges.
Nebular line and continuum emission from CLOUDY grids or the Cue neural
network emulator, with optional shock and DIG mixing.
MAPPINGS III + V shock emission line model.
Loads Allen+2008 (ApJS 178 20) MAPPINGS III and Alarie & Morisset 2019
(3MdBs, RMxAA 55 279) MAPPINGS V grids from data/mappings_templates.h5
and interpolates line ratios across the full 4-D grid:
(v_shock, B/√n or B, log_density, abundance)
If the HDF5 file is missing, falls back to the Allen+2008 Table 5
hardcoded arrays (solar, n=1 cm⁻³, 8 velocity points, 10 lines) with a
DeprecationWarning. Build the grid with:
velocity, B-field, log_density : interp_nd_triweight — C²-continuous
triweight kernel (Hearin et al. 2023 / DSPS), jointly interpolated across
all three continuous axes. Bin edges are precomputed at grid load time via
edges_for_grid to avoid rebuilding inside JIT traces.
abundance, component, version : Python string → integer index (static)
MAPPINGS V shock emission backend satisfying the NebularBackend Protocol.
Wraps compute_shock_sed() as an object-oriented backend so that shock
emission can be stored and dispatched using the same interface as other
nebular backends (CueBackend, CloudyGridBackend, etc.).
Static (non-traced) configuration is stored as dataclass fields.
JAX-traced continuous parameters (velocity, density, B-field, Hα luminosity)
are passed as arguments to predict_nebular_sed().
Parameters:
shock_abundance (str) – Abundance set name: "solar", "2xsolar", "lmc", "smc", etc.
shock_component (str) – "shock", "precursor", or "combined".
has_continuum (bool) – Always False — MAPPINGS V provides line emission only.
JIT-compatible: Methods return JAX arrays suitable for JIT compilation.
All computations use pure functions with no side effects.
Attributes: has_continuum is always False — MAPPINGS V provides
shock-associated emission lines only (no underlying continuum).
has_free_params is always True — all parameters (velocity, density,
B-field) are differentiable and suitable for optimization.
JIT-compatible: yes — delegates to compute_shock_sed.
Abundance and component: These are fixed at backend initialization
via shock_abundance and shock_component dataclass fields.
Continuous parameters (velocity, density, B-field, H-alpha luminosity)
are traced and differentiable under jax.jit.
JIT-compatible: yes — all operations use jnp primitives and
calls to _shock_line_arrays and _place_line_profiles.
Line placement: Emission lines are placed as Gaussian profiles
(if line_sigma_aa>0) or delta functions (if line_sigma_aa=0).
Delta functions scatter energy into the nearest pixel, normalized
by pixel width to preserve flux.
Return emission line luminosity ratios relative to Hβ.
Loads the MAPPINGS V (3MdBs) grid from data/mappings_templates.h5.
If the file is missing, falls back to the Allen+2008 Table 5 hardcoded
subset with a DeprecationWarning.
Parameters:
shock_velocity (float) – Shock velocity in km/s. Must be within the grid range
(100–1000 km/s fallback; 200–1000 km/s HDF5). Raises ValueError
if out of range. Continuously interpolated — safe under jax.jit.
shock_log_density (float) – Log10 pre-shock density in cm⁻³ (e.g. 0.0 = 1 cm⁻³).
Must be within [0,3]. Continuously interpolated via triweight
kernel — safe under jax.jit. Raises ValueError if out of range.
shock_b_over_sqrt_n (float) – Absolute B-field strength in μG (3MdBs MAPPINGS V convention).
Must be within [0.0001,10] μG. Continuously interpolated via
triweight kernel — safe under jax.jit. Raises ValueError if
out of range.
shock_abundance (str) – Abundance pattern. Accepted short names:
"solar", "2xsolar" / "twice_solar", "dopita2005",
"lmc", "smc". Full 3MdBs DB names (e.g.
"Allen2008_Solar") also accepted. Raises ValueError for
unknown names.
shock_component (str) – Which emission component to return. One of "shock",
"precursor", "combined" (default). Raises ValueError
for unknown values.
Returns:
PyNeb-format line name → luminosity ratio relative to Hβ
[dimensionless].
ValueError – If any parameter is outside the grid bounds or invalid.
References
Notes
JIT-compatible: yes — continuous parameters (velocity, density,
B-field) are interpolated via interp_nd_triweight, safe under
jax.jit. Discrete parameters (abundance, component) are resolved
at call time and not traced.
Fallback: If the MAPPINGS V HDF5 grid is missing, falls back to
the Allen+2008 Table 5 hardcoded array (solar abundance, n=1 cm⁻³,
8 velocity points) with a DeprecationWarning. To avoid this,
download the grid via scripts/download_mappings_templates.py.
Interpolation: Triweight kernel (C²-continuous) jointly interpolates
velocity, density, and B-field across all three axes. Grid edges are
precomputed at load time to avoid rebuilding inside JIT traces.
Models the mixing of ionizing photon-powered emission from two gas components:
dense HII regions and diffuse ionized gas (DIG). DIG is low-density ionized gas
between HII regions, characterised by lower ionization parameter (log U ~ −4 vs
−2.5 in HII regions). This produces a distinct emission-line signature: enhanced
low-ionization diagnostics ([NII]/Hα, [SII]/Hα, [OI]/Hα).
Observationally, DIG contributes ~30–60% of Hα flux in local star-forming
galaxies (Reynolds 1984; Haffner et al. 2009; Tacchella et al. 2022).
Mixing formula: Returns a weighted average of nebular emission at two
ionization parameters (HII + DIG):
Predict nebular SED with HII region and diffuse ionized gas components.
Computes emission from two ionization regimes (HII + DIG) using any backend,
then combines via mass-weighted mixing. This captures the enhanced low-ionization
emission ([NII], [SII], [OI]) characteristic of warm, ionized ISM.
Parameters:
nebular_backend (NebularBackend (CloudyGridBackend or CueBackend)) – Backend with predict_nebular_sed() method. Called twice (HII, DIG).
JIT-compatible: yes — all operations use jnp primitives, but note
that when neb_dig_frac is a traced JAX value, both HII and DIG forward
passes execute (no short-circuit optimisation).
Mixing model (Haffner et al. 2009, Tacchella et al. 2022):
The diffuse ionized gas (DIG) has a lower ionization parameter than
HII regions, producing a distinct line-ratio signature. We approximate
the total emission as a linear combination:
where log U_DIG = log U_HII + Δ log U, and both components use the
same metallicity, escape fraction, and stellar population weights.
Physical picture:
HII regions: dense, photoionised by young (< 1 Myr) OB stars.
Log U ~ −2.5 to −3. Dominated by recombination lines ([OIII], [SIII],
etc.).
DIG: diffuse, warm (~8000 K), ionised by stellar radiation and
shocks. Log U ~ −3 to −4. Dominated by forbidden lines ([NII], [SII],
[OI]).
Escape fraction:
Both HII and DIG share the same f_esc (stellar-population-level escape).
This is a simplification; physically, dust might preferentially shield
DIG, but we do not model this spatial variation.
Pitfall: When neb_dig_frac is a JAX-traced (differentiable) value,
both forward passes (HII + DIG) execute and contribute to gradients, even
if neb_dig_frac = 0 at runtime. Pre-compute DIG mixing only when needed.
Photometry, spectroscopy, calibration, and emission line marginalization.
Spectrophotometric calibration polynomials.
When fitting spectra, the observed spectrum has wavelength-dependent
calibration errors from flux calibration, slit losses, and telluric
residuals. A low-order Chebyshev polynomial corrects this multiplicatively:
where C(lambda) = 1 + sum_{n=1}^{order} a_n * T_n(x) and
x = 2*(lambda - lambda_min)/(lambda_max - lambda_min) - 1 maps wavelengths
to [-1, 1]. The constant term is unity by convention (overall normalization
is handled elsewhere); the fitted coefficients represent deviations from
a flat calibration.
Coefficients a_n have a Gaussian(0, sigma) prior that regularizes the
polynomial toward unity, preventing overfitting of broad spectral features.
To add calibration coefficients as free parameters:
fromtengri.parameters.priorsimportGaussianspec=Parameters(...,# 3rd-order calibration polynomial (3 free coefficients)cal_c1=Gaussian(0.0,0.1),cal_c2=Gaussian(0.0,0.1),cal_c3=Gaussian(0.0,0.05),)# In the forward model, pack coefficients and apply:coeffs=jnp.array([params["cal_c1"],params["cal_c2"],params["cal_c3"]])model_spec=apply_calibration(physical_spec,wave_obs,coeffs,wave_min,wave_max)
References
Johnson et al. (2021) — Prospector calibration model.
Piecewise calibration: independent Chebyshev polynomials for blue and red halves.
For two-arm spectrographs (e.g. X-SHOOTER, DEIMOS) where a detector
gap or dichroic split causes a calibration discontinuity, fitting a
single polynomial across the full range can bias the result. This
function applies separate polynomials to each half, matched to their
local wavelength range.
Parameters:
wavelength (array, shape (n_wave,)) – Wavelength grid [Angstrom], must be sorted.
coeffs_blue (array, shape (order_blue,)) – Chebyshev coefficients for the blue arm (wavelength < wave_split).
coeffs_red (array, shape (order_red,)) – Chebyshev coefficients for the red arm (wavelength >= wave_split).
wave_split (float) – Wavelength boundary between blue and red arms [Angstrom].
Analytically marginalize over calibration polynomial coefficients.
Given a model SED m(lambda) and observed spectrum d(lambda) with noise
sigma(lambda), the calibrated model is C(lambda)*m(lambda) where C is
a Chebyshev polynomial. With a Gaussian prior on the polynomial
coefficients c ~ N(0, prior_sigma^2 I), the optimal coefficients and
marginalized log-likelihood are computed in closed form.
This follows the Prospector approach: the calibration polynomial is
treated as a nuisance and integrated out analytically at each likelihood
evaluation, reducing the dimensionality of the sampling problem.
n_poly (int, optional) – Number of Chebyshev polynomial coefficients (order 1 through
n_poly). The constant term (T_0 = 1) is implicit and fixed.
Default 3.
prior_sigma (float, optional) – Standard deviation of the Gaussian prior on each coefficient.
Default 1.0.
Returns:
log_likelihood_marginal (scalar) – Marginalized log-likelihood with calibration polynomial
integrated out.
c_hat_err (ndarray, shape (n_poly,)) – Posterior standard deviations of the coefficients.
Notes
JIT-compatible: yes — n_poly is a static argument.
Gradient-safe: no — uses matrix inversion (not safe for gradient).
The marginalized log-likelihood integrates the Gaussian likelihood and
Gaussian prior on the polynomial coefficients in closed form via the
matrix determinant lemma.
Holds wavelength grid, flux templates, and metadata (age/metallicity grids)
needed by the CSP integration engine. Typically loaded once from disk and
reused across many forward-model evaluations.
ssp_flux (array, shape (n_met, n_age, n_wave)) – Spectral luminosity density of simple stellar populations (SSPs)
per unit stellar mass [erg/s/Hz/Msun].
Origin: BC03, BPASS, FSPS, ProGeny, or other DSPS-compatible library.
ssp_lg_age_gyr (array, shape (n_age,)) – Age grid in log10 space [log10(Gyr)].
ssp_lgmet (array, shape (n_met,)) – Metallicity grid (absolute, NOT solar-relative) [log10(Z)].
Offset: log10(Z_sun) ≈ −1.848 (Asplund+2009).
Do NOT confuse with user-facing log10(Z/Z_sun).
ssp_mass_remaining (array, shape (n_met, n_age), optional) – Fraction of initial stellar mass still present (living stars + remnants)
at each (age, metallicity) [dimensionless, ∈ [0, 1]].
Used for stellar mass normalization in CSP integral. Depends on IMF
and isochrone library; None if unavailable.
ssp_alpha_fe (array, optional) – Alpha enhancement grid (for future use). Currently None.
When implemented: ssp_flux will be (n_met, n_alpha, n_age, n_wave).
Notes
Metallicity convention: ssp_lgmet is absolute log10(Z), NOT relative
to solar. To convert user-supplied log10(Z/Z_sun) to grid coordinates,
add LOG10_ZSUN ≈ −1.848.
Future extension: ssp_alpha_fe support for alpha-element abundance
variations (Vazdekis+2015, MIST, etc.) is planned. Currently, metallicity
is the only dimension; alpha is fixed (typically solar, α = 0).
Survival mass: ssp_mass_remaining encodes stellar mass loss due to
stellar evolution (main-sequence turnoff, white dwarf cooling, etc.).
It is essential for mass-based inferences but may not be present in
older SSP libraries.
Convert [Fe/H] + [alpha/Fe] to effective total metallicity.
Approximates the effect of alpha-element enhancement on the SED as
a shift in the total metallicity used for SSP interpolation. Used
when SSP templates are computed at fixed solar abundance ratios and
cannot vary [alpha/Fe] at runtime.
Parameters:
log_z_fe (float) – Iron abundance [Fe/H] (equivalently, log10(Z/Zsun) when
alpha_fe=0). [dex]
JIT-compatible: yes — pure arithmetic; decorated with @jax.jit.
Gradient-safe: yes.
Approximation (Thomas, Maraston & Bender 2003 [1]_):
only valid for SSP grids that lack an explicit [alpha/Fe] axis. When
the grid does include one, prefer bilinear (Z, [alpha/Fe]) interpolation;
use has_alpha_grid() to test the SSP container at construction.
The coefficient 0.75 (_ALPHA_TO_Z_COEFF) is the empirical
enhancement-to-metallicity scaling adopted by the Vazdekis et al.
2015 [2]_ MILES library for E-MILES alpha-enhanced SSPs.