Forward Model¶
The forward model maps stellar parameters to an observer-frame SED and synthetic photometry.
Pipeline¶
(Teff, logg, [M/H]) → SED interpolation (Fortran, Hermite or linear)
→ distance dilution (Fortran, (R/d)²)
→ extinction (Python, optional)
→ bolometric (Fortran)
→ filter convolution (Fortran, per filter)
→ ForwardResult
Extinction is applied after dilution and before filter convolution — physically: star → distance → dust column → telescope → filter.
Two calling conventions¶
Classic¶
from sed_model import run_forward
result = run_forward(
teff=5778.0,
logg=4.44,
meta=0.0,
R=6.957e10, # cm
d=3.086e19, # cm
grid=grid,
filters=filters,
mag_system="Vega", # "AB" (default), "Vega", or "ST"
interp_method="hermite", # "hermite" (default) or "linear"
)
FitParams (used internally by the inverse model)¶
result = run_forward(
fit_params=params, # a FitParams
theta=theta_vec, # only the FREE parameters, canonical order
R=R_sun,
grid=grid,
filters=filters,
)
theta contains only the free parameters in the canonical order teff, logg, meta, a_v, d (skipping fixed ones); fit_params.unpack(theta) fills in the fixed values. If Av or distance are free, they are taken from theta, not from keyword arguments. This is the exact code path the MCMC likelihood uses, so anything you verify in the forward direction holds inside the sampler too. See Parameter Modes.
Interpolation¶
Two schemes operate on the 3D (Teff, logg, [M/H]) flux cube, vectorised over wavelength:
hermite— cubic Hermite tensor interpolation with finite-difference tangents (central differences in the interior, one-sided at grid edges).linear— trilinear interpolation.
If the query point falls outside the grid, both schemes fall back to the nearest grid node and the result is flagged (clamped=True). Interpolated fluxes are floored at a tiny positive value, never negative.
The interp_radius diagnostic (distance in normalised parameter space from the nearest grid node) is computed for every call so you can gauge how far from tabulated models the interpolation reached.
ForwardResult¶
| Field | Description |
|---|---|
wavelengths |
wavelength grid (Å) |
surface_flux |
interpolated surface flux (erg/s/cm²/Å) |
observed_flux |
after (R/d)² dilution and any extinction |
magnitudes |
{filter_name: magnitude} in the requested system |
band_fluxes |
{filter_name: in-band flux} (erg/s/cm²/Å) |
bol_flux, bol_mag |
bolometric flux and magnitude (Mag_bol = -2.5 log10 F_bol, MESA colors convention — no additional zero-point) |
interp_radius, clamped |
interpolation diagnostics |
teff, logg, meta, R, d, a_v |
the parameters that produced this result (self-describing) |
mag_system, extinction_applied |
bookkeeping |
Synthetic photometry¶
For each filter, the transmission is linearly interpolated onto the SED wavelength grid, then the photon-counting in-band flux is computed:
with the zero-point \(F_{zp}\) precomputed per filter and system at load time (Grids and Filters). Failed integrations or non-positive fluxes produce a sentinel magnitude of -99.9 with a non-zero error flag rather than crashing.
Batch evaluation¶
from sed_model import run_forward_batch
import numpy as np
params = np.array([
[5778.0, 4.44, 0.0],
[6200.0, 4.30, -0.2],
])
results = run_forward_batch(params, R=R, d=d, grid=grid, filters=filters)
run_forward_batch accepts an (N, 3) array of (teff, logg, meta) rows (classic convention only) and returns a list of ForwardResult.