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.

Radiative transfer (RTM) stack — parallel track

The RTM is the observation operator Hobs:c(x,t)→yradiance\mathbf{H}_\text{obs} : c(\mathbf{x},t) \to \mathbf{y}_\text{radiance}. It connects Tiers II–IV to actual satellite measurements. Independent of transport tier — can be developed in parallel by a different person without coordination.

If you’re working with Level-2 XCH₄ products (e.g. TROPOMI official retrieval; [s5p_tropomi]), the entire RTM stack collapses to just the averaging-kernel operator; this whole page becomes “use the published L2.” This page assumes Level-1 (radiance) work, where you build the retrieval yourself.


(1) Simple model — line-by-line via HAPI

HAPI (HITRAN Application Programming Interface) ([gordon2022hitran,kochanov2016hapi]) provides absorption cross-sections σ(ν,T,p)\sigma(\nu, T, p) from the HITRAN database. All operational satellites for methane retrieval are SWIR — solar reflection, not thermal emission. The two-way path matters and so does scattering; a pure clear-sky Beer–Lambert model is biased by 10–30% on aerosol-loaded scenes.

Clear-sky two-way Beer–Lambert (SWIR scope)

L(ν)  =  Fsolar(ν)π Asurf(ν) cos⁡(SZA) exp⁡ ⁣(−τtotal(ν))L(\nu) \;=\; \frac{F_\text{solar}(\nu)}{\pi}\, A_\text{surf}(\nu)\, \cos(\text{SZA})\, \exp\!\bigl(-\tau_\text{total}(\nu)\bigr)
τtotal(ν)  =  τ(ν)cos⁡(SZA)  +  τ(ν)cos⁡(VZA)\tau_\text{total}(\nu) \;=\; \frac{\tau(\nu)}{\cos(\text{SZA})} \;+\; \frac{\tau(\nu)}{\cos(\text{VZA})}
τ(ν)  =  ∫σ ⁣(ν,T(z),p(z)) ρCH4(z) dz\tau(\nu) \;=\; \int \sigma\!\bigl(\nu, T(z), p(z)\bigr)\, \rho_{\text{CH}_4}(z)\, \mathrm{d}z

Thermal-IR addendum

For TIR work (legacy / portability), the surface term is emission, not solar reflection:

LTIR(ν)  =  εsurf(ν) B(Tsurf,ν) exp⁡ ⁣(−τ(ν))  +  ∫B(ν,T(z)) d ⁣exp⁡ ⁣(−τ(ν,z))L_\text{TIR}(\nu) \;=\; \varepsilon_\text{surf}(\nu)\, B(T_\text{surf}, \nu)\, \exp\!\bigl(-\tau(\nu)\bigr) \;+\; \int B(\nu, T(z))\, \mathrm{d}\!\exp\!\bigl(-\tau(\nu, z)\bigr)

Different physics, different priors (εsurf\varepsilon_\text{surf} instead of AsurfA_\text{surf}, TsurfT_\text{surf} instead of FsolarF_\text{solar}). Don’t conflate the two surface models in code — split per spectral regime.

Scattering — out-of-scope for v1, planned for v2

SWIR aerosol scattering is the leading systematic for methane retrievals over bright/aerosol-loaded scenes. v1 commits to clear-sky direct-beam with explicit AOD-based screening (reject pixels with AOD>0.2\text{AOD} > 0.2); v2 couples to LIDORT / DISORT / 6S for multiple-scattering Jacobians. Validation against operational L2 in Step 4 must stratify by AOD to expose the v1 limit.

Line shape and continuum

HAPI traceability


(2) Model-based inference

Joint state vector

Operational SWIR retrievals do not retrieve XCH₄ alone. The state vector is jointly:

x  =  (profileCH4,  profileH2O,  Asurf,  AOD,  psurf,offset)\mathbf{x} \;=\; (\text{profile}_{\text{CH}_4},\; \text{profile}_{\text{H}_2\text{O}},\; A_\text{surf},\; \text{AOD},\; p_\text{surf,offset})

Prior Sa\mathbf{S}_a

Prior structure for the joint RTM state vector.

ElementFormNotes
profileCH4\text{profile}_{\text{CH}_4}climatological covariance + AR(1) in verticalsmoothness prior; covariance from CAMS reanalysis
profileH2O\text{profile}_{\text{H}_2\text{O}}same structurefrom ECMWF or in-situ profile climatology
AsurfA_\text{surf}per-band Gaussian around L1 prior or MODIS climatology
AOD\text{AOD}LogNormal⁡(μAOD,σ2)\operatorname{LogNormal}(\mu_\text{AOD}, \sigma^2)non-negative, heavy-tail
psurf,offsetp_\text{surf,offset}tight Gaussian around DEMsub-pixel terrain uncertainty

Iterative Gauss–Newton

The closed-form formula in the prior version is the first update. The converged retrieval iterates ([rodgers2000]):

xk+1  =  xa+Gk (y−F(xk)+Kk(xk−xa))\mathbf{x}^{k+1} \;=\; \mathbf{x}_a + \mathbf{G}_k\, \bigl(\mathbf{y} - F(\mathbf{x}^k) + \mathbf{K}_k (\mathbf{x}^k - \mathbf{x}_a)\bigr)
Gk  =  (Kk⊤ Sε−1 Kk+Sa−1)−1 Kk⊤ Sε−1,Kk  =  ∂F∂x∣xk\mathbf{G}_k \;=\; (\mathbf{K}_k^{\top}\, \mathbf{S}_\varepsilon^{-1}\, \mathbf{K}_k + \mathbf{S}_a^{-1})^{-1}\, \mathbf{K}_k^{\top}\, \mathbf{S}_\varepsilon^{-1}, \qquad \mathbf{K}_k \;=\; \frac{\partial F}{\partial \mathbf{x}}\bigg|_{\mathbf{x}^k}

Convergence criterion ([rodgers2000] §5.7):

δχk2  =  (xk+1−xk)⊤ (S∗)−1 (xk+1−xk)  <  0.5⋅DOFs\delta \chi^{2}_{k} \;=\; (\mathbf{x}^{k+1} - \mathbf{x}^{k})^{\top}\, (\mathbf{S}^{*})^{-1}\, (\mathbf{x}^{k+1} - \mathbf{x}^{k}) \;<\; 0.5 \cdot \text{DOFs}

Cap at kmax=10k_\text{max} = 10. Pixels that fail to converge get a quality flag.

Posterior covariance and information content

Standard outputs of optimal estimation — should appear on every retrieved pixel:

S∗  =  (K⊤ Sε−1 K+Sa−1)−1\mathbf{S}^{*} \;=\; (\mathbf{K}^{\top}\, \mathbf{S}_\varepsilon^{-1}\, \mathbf{K} + \mathbf{S}_a^{-1})^{-1}
A  =  G K,DOFs  =  tr⁡(A)\mathbf{A} \;=\; \mathbf{G}\, \mathbf{K}, \qquad \text{DOFs} \;=\; \operatorname{tr}(\mathbf{A})
H  =  12log⁡det⁡(Sa)−12log⁡det⁡(S∗),ΔS  =  tr⁡(Sa)−tr⁡(S∗)H \;=\; \tfrac{1}{2} \log \det(\mathbf{S}_a) - \tfrac{1}{2} \log \det(\mathbf{S}^{*}), \qquad \Delta \mathbf{S} \;=\; \operatorname{tr}(\mathbf{S}_a) - \operatorname{tr}(\mathbf{S}^{*})

These are load-bearing for instrument-design questions (EMIT vs Tanager vs TROPOMI comparisons) and for the cross-tier UQ pipeline that Tier IV assembles. Currently absent from the doc — must appear in the retrieved-product schema.

Quality flags

Each retrieval emits a flag bitmask:


(3) Model emulator — two levels

Level A — factorised LUT RTM

A dense LUT over (T,p,qCH4,Asurf,SZA,VZA,RAA,AOD)(T, p, q_{\text{CH}_4}, A_\text{surf}, \text{SZA}, \text{VZA}, \text{RAA}, \text{AOD}) has ∼4×1013\sim 4 \times 10^{13} cells — untrainable. Operational practice: factorise.

Decompose the radiance into multiplicative / additive components on lower-dimensional sub-LUTs:

L(ν)  =  Tgas ⁣(ν ∣ T(z),p(z),qCH4(z))⏟sub-LUT 1: gas transmittance  ×  Rsurf ⁣(ν ∣ Asurf,SZA,VZA,RAA)⏟sub-LUT 2: surface BRDF kernel  +  Sscatt ⁣(ν ∣ AOD,SZA,VZA,RAA)⏟sub-LUT 3 (v2): scattering source termL(\nu) \;=\; \underbrace{T_\text{gas}\!\bigl(\nu \,\big|\, T(z), p(z), q_{\text{CH}_4}(z)\bigr)}_{\text{sub-LUT 1: gas transmittance}} \;\times\; \underbrace{R_\text{surf}\!\bigl(\nu \,\big|\, A_\text{surf}, \text{SZA}, \text{VZA}, \text{RAA}\bigr)}_{\text{sub-LUT 2: surface BRDF kernel}} \;+\; \underbrace{S_\text{scatt}\!\bigl(\nu \,\big|\, \text{AOD}, \text{SZA}, \text{VZA}, \text{RAA}\bigr)}_{\text{sub-LUT 3 (v2): scattering source term}}

Sub-LUT sizes are tractable (~106 cells each). Combine analytically at runtime. This is the only viable path for high-dimensional SWIR retrieval — without factorisation, LUTs don’t fit.

Level B — Neural RTM

MLP / Fourier-feature network mapping (profile,geometry,Asurf,AOD)→L(ν)(\text{profile}, \text{geometry}, A_\text{surf}, \text{AOD}) \to L(\nu). Train on factorised LUT or directly on HAPI outputs.

Neural-Jacobian calibration is mandatory

Backprop through a trained neural RTM gives some gradient — whether it matches HAPI’s K\mathbf{K} is an empirical question, and the entire Step-4 retrieval depends on it.


(4) Emulator-based inference

Replace HAPI with the neural RTM in the optimal-estimation loop. The entire retrieval becomes differentiable end-to-end:

∇xJ  =  jax.grad ⁣(∥NeuralRTM(x)−y∥2)\nabla_{\mathbf{x}} J \;=\; \texttt{jax.grad}\!\Bigl(\bigl\lVert \texttt{NeuralRTM}(\mathbf{x}) - \mathbf{y}\bigr\rVert^{2}\Bigr)

Same Gauss–Newton iteration, ~1000× faster per step, gradients trivially available.


(5) Amortized inference (predictor)

fθ:(yradiance, geometry, prioratm, instrument_id)  ⟼  p(profileCH4, Asurf, AOD∣y)f_\theta : (\mathbf{y}_\text{radiance},\, \text{geometry},\, \text{prior}_\text{atm},\, \text{instrument\_id}) \;\longmapsto\; p(\text{profile}_{\text{CH}_4},\, A_\text{surf},\, \text{AOD} \mid \mathbf{y})

Output the joint posterior

Collapsing to p(XCH4∣y)p(\text{XCH}_4 \mid \mathbf{y}) throws away information Tier IV wants — the joint (profile,albedo,AOD)(\text{profile}, \text{albedo}, \text{AOD}) is the right output. Collapse to XCH₄ at the consumer side, not in the predictor.

Per-instrument heads

Different spectral resolutions (TROPOMI ~1000 ch [s5p_tropomi], EMIT ~285 ch [emit], GHGSat hyperspectral [ghgsat], Tanager hyperspectral [carbon_mapper]) → per-instrument predictor heads dispatched by instrument_id. Same pattern as Tiers II/III.

Context conditioning

prioratm=(T(z),p(z),qH2O(z))\text{prior}_\text{atm} = (T(z), p(z), q_{\text{H}_2\text{O}}(z)) from the met field and geometry=(SZA,VZA,RAA)\text{geometry} = (\text{SZA}, \text{VZA}, \text{RAA}) from L1 metadata. Wire in via FiLM / hypernet primitives in pyrox.nn — same pattern as Tiers I/II/III.

Posterior over the spatial profile

Conditional flow over the vertical profile (1D — gauss_flows handles this natively, no 2D extension needed) for profileCH4\text{profile}_{\text{CH}_4} and joint Gaussian for (Asurf,AOD)(A_\text{surf}, \text{AOD}) is the simplest split. Validate via SBC against HAPI-based optimal-estimation posteriors on synthetic data, stratified by SNR / SZA / AOD.

Uncertainty calibration

SBC is necessary but not sufficient — the specific requirement is that the predictor’s standard deviation matches the empirical RMSE on a held-out set, stratified by SNR / SZA / AOD. Without stratification, calibration on the easy regime hides miscalibration on the hard regime.


(6) Improve


Module layout

RTM stack module layout — step, concern, target module, status.

StepConcernModuleStatus
1HAPI Beer-Lambert (clear-sky, two-way)hapi_lut/beers.py✓ — two-way path consistency test tracked in #99
1LUT generatorhapi_lut/generator.py✓
1LUT confighapi_lut/config.py✓
1Multi-gas LUThapi_lut/multi.py✓
1Factorised LUT (gas × surf × scatt)plumax.hapi_lut.factorised☐ #99
1Forward RTMradtran/forward.py🚧
1Spectral response (SRF)radtran/srf.py✓
1Instrument modelradtran/instrument.py✓
1Background atmosphereradtran/background.py✓
1Target gas specradtran/target.py✓
1Surface model — SWIR (albedo / BRDF)plumax.radtran.surface_swir☐ #98
1Surface model — TIR (emissivity)plumax.radtran.surface_tir☐ #98
1Aerosol / scattering coupling (v2)plumax.radtran.scattering☐
—Matched filter (detection)radtran/matched_filter.py, matched_filter/✓
—gaussx-based linear solveradtran/gaussx_solve.py✓
2Optimal-estimation iterative loopplumax.radtran.retrieval (gaussx_solve.py stays the one-shot linear matched-filter path)☐ #96
2Quality flags + screeningplumax.radtran.quality☐ #97
2Information-content diagnosticsplumax.radtran.diagnostics☐ #97
2Posterior export → Tier IVOEResult consumed by the coupled inversion☐ #102
3Neural RTM (per scene class)plumax.radtran.neural_rtm☐ #100
3Neural-Jacobian calibration harnessplumax.radtran.neural_jacobian_test☐ #100
5Direct retrieval predictor (per instrument)plumax.radtran.predictor☐

Validation strategy


Open questions