Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Prerequisites — Cross-tier infrastructure

Before any dispersion model, you need three things that every tier shares: meteorological forcing (winds, turbulence, PBL), static surface fields (orography, roughness, land-use), and the observation-side glue (L1/L2 ingest, averaging kernels). These are not models — they are the data interfaces all tiers read from. Getting them right early pays off because all four tiers will read from the same APIs; getting them wrong forces parallel ports of every tier later.

The page is grouped into:

  1. Forcing — meteorology (dynamic 3D fields)

  2. Static surface fields (orography, land-use, roughness)

  3. Geometry (coordinate frames and time)

  4. Inversion priors (background emission inventory)

  5. Observation side (L1/L2 ingest + averaging kernel)

The fixed forward interface is the contract that ties them together.


1 · Forcing — meteorology

Reanalysis-agnostic met reader

Met forcing has a many-to-one interface. WRF is the highest-fidelity option (you control resolution, microphysics, nesting) and is the industry baseline, but ERA5 / MERRA-2 / HRRR / GEOS-FP are all valid forcing sources. The MetField PyTree is the abstraction; the WRF reader is one concrete loader.

Planetary boundary layer (PBL) height

PBL height is not optional — Tier I plume rise, Tier II trajectory reflection, and Tier IV column partitioning all depend on it. WRF emits it as a diagnostic (PBLH); ERA5 has blh. Carry it as a first-class field on MetField, not buried inside a derived helper.

Pasquill–Gifford stability classifier

Maps surface observations (wind speed, cloud cover, time-of-day, solar elevation) to PG stability class A–F. Used by Gaussian-tier σy\sigma_y, σz\sigma_z parameterizations.

Monin–Obukhov similarity

Surface-layer wind and turbulence profiles. Provides σy(x)\sigma_y(x) and σz(x)\sigma_z(x) as functions of downwind distance, friction velocity u∗u_*, Obukhov length LL, and surface roughness z0z_0.


2 · Static surface fields

These are time-invariant geophysical fields. Distinct enough from dynamic met to deserve their own loader, but they live alongside MetField (typically broadcast against the time axis).

Surface roughness z0z_0 and land-use

Orography / terrain


3 · Geometry

Coordinate transforms

Time and calendar

UTC throughout — but enforce it. A small Timestamp PyTree (epoch_seconds: int64, tz: Literal["UTC"]) makes the invariant load-bearing instead of aspirational. Document leap-year / leap-second handling at the boundary (most projects botch this once and never again).


4 · Inversion priors

Background emission inventory qaq_a

Every Bayesian inversion (Tiers I–IV, Step 2) uses a prior qaq_a over the source field. Naming a single source matters because results are sensitive to it.


5 · Observation side

L1 / L2 ingest

Symmetric to the met reader. Parses raw satellite products into the shared Observations PyTree.

Averaging-kernel operator

Applies the satellite averaging kernel to a model column:

y^  =  A ⁣(h⊤x + (1−h⊤) xa)\hat{y} \;=\; \mathbf{A}\!\left(\mathbf{h}^{\top} \mathbf{x} \,+\, (1 - \mathbf{h}^{\top})\, \mathbf{x}_a\right)

where x\mathbf{x} is the model state (CH₄ mixing-ratio profile), xa\mathbf{x}_a is the prior used in the L2 retrieval, h\mathbf{h} is the column-averaging weighting, and A\mathbf{A} is the satellite-product averaging kernel matrix. The construction follows the optimal-estimation framework of [rodgers2000]. Needed by Tiers II–IV when comparing to L2 XCH₄ products instead of L1 radiances.


Fixed forward interface

All four tiers implement the same shape:

def forward(params: Params, met: MetField) -> Observations:
    """Map source/state parameters + met forcing → simulated observations.

    Each tier provides its own concrete `Params` PyTree, but the call
    signature, return type, and JAX traceability are identical, so any
    inference loop (NumPyro, vardaX, filterax) takes any tier as a drop-in.
    """

MetField schema

The single most-shared object in plumax. Concrete fields, units, and conventions:

MetField PyTree fields, shapes, units, and provenance.

FieldShapedtypeUnitsSourceNotes
u, v, w(T, Z, Y, X)f32m/sdynamicwind components, cell-centred
T(T, Z, Y, X)f32Kdynamictemperature
p(T, Z, Y, X)f32Padynamicpressure
q(T, Z, Y, X)f32kg/kgdynamicwater vapour mixing ratio
tke(T, Z, Y, X)f32m²/s²dynamicturbulent KE (optional; some loaders provide)
pblh(T, Y, X)f32mdynamicPBL height
z0(Y, X)f32mstaticsurface roughness
lu(Y, X)i8—staticland-use class (IGBP)
hgt(Y, X)f32mstaticterrain elevation
frame—static metadata—staticLocalFrame (pyproj-built, non-traced)
time(T,)i64UTC secondsstatic metadataTimestamp PyTree
ensemble_dimscalarint—static metadata0 for deterministic; >0 carries an outer ensemble axis on dynamic fields

Conventions:

Params and Observations

This contract is what makes Step 6 (“upgrade any component”) tractable: replace forward with an emulator, the inference loop doesn’t notice.


Module layout

Module-level breakdown — concern, target module, status, downstream blockers.

ConcernModuleStatusBlocks
Met loader (WRF)met/wrf.py (load_wrf) + met/field.py (MetField, to_prescribed_wind)✓ v1 — destagger, η→z per column, bilinear onto the C-grid stagger, piecewise-linear in time; origin places the grid until frames land (#79)Tier II, III
Met loader (ERA5)plumax.met.era5☐ #77global Tier II/III
PBL diagnosticsplumax.met.pbl☐ #78Tier II reflection, Tier IV partitioning
Static fields (z0z_0, LU, terrain)plumax.met.static☐ #78MO similarity, Tier III BCs
PG stabilityplumax.gauss_plume.dispersion🚧 partialTier I (only)
MO similarityplumax.met.surface_layer☐ #78Tier II turbulence, Tier III diffusivity
Coord transformsplumax.met.frames☐ #79all tiers
Time / Timestampplumax.met.time☐ #79all tiers
Emission inventory loaderplumax.priors.inventory☐ #81Tier I–IV inversion priors
L1/L2 ingestplumax.obs.ingest☐ #80Tier IV (and any real-data work)
AK operatorplumax.assimilation.obs_operator (radiance model) + coupled.Instrument (AK payload)🚧 — shared column + AK pipeline #83; L2 ingest builds Instruments #80Tier IV column-space comparison

plumax.met now exists (the MetField container and the WRF loader); the remaining met concerns land beside them. plumax.priors and plumax.obs are still proposed. All eleven concerns are tracked under the Tier 0 epic #69.


Validation strategy


Open questions