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.

CH4 absorption cross-section LUT

Building a single-gas absorption LUT — CH4_4

This notebook exercises the end-to-end single-gas pipeline in plumax.hapi_lut. We fetch HITRAN line parameters for methane, evaluate the Voigt-profile absorption cross-section σ(ν;T,p)\sigma(\nu; T, p) on a coarse (T,p)(T, p) grid, and inspect how the cross-section changes with temperature and pressure. The physics is derived in 00_hapi_lut_derivation.md; here we focus on the pipeline + visual sanity checks.

The LUT grid is intentionally small — 3 temperatures × 3 pressures over a 500-cm⁻¹ window at 0.05-cm⁻¹ spectral resolution. That’s enough to recover the pressure-broadening signature and the Boltzmann redistribution of line strength with TT without the ~30 min runtime of an operational grid (7 × 6 × ~0.01 cm⁻¹).

Dependencies: hitran-api (HAPI), xarray, matplotlib. All covered by the hapi extra (uv sync --extra hapi). HITRAN line parameters are fetched on first run and cached under ~/.cache/plumax/hitran/ (outside the repository).

Cache dir: /root/.cache/plumax/hitran
LUT out:   /root/.cache/plumax/hapi_lut

1. Gas and grid configuration

ATMOSPHERIC_GASES carries a curated registry of the SWIR/NIR species most relevant to methane / CO2_2 remote sensing. We pull the CH4_4 entry and narrow the spectral window to the 4000–4500 cm⁻¹ fundamental ν3\nu_3 stretch — broad enough to see the rotational envelope, narrow enough to keep the LUT at ~10⁵ cells.

The default LUTGridConfig covers 200–320 K and 0.1–1.0 atm; for this tutorial we use coarse 3×3 knots so the HAPI calls take under two minutes on a laptop.

GasConfig(CH4, M6, I1)
grid: T=[220.0, 260.0, 300.0] K, P=[0.3, 0.6, 1.0] atm
expected σ LUT shape: (10000, 3, 3)

2. Fetch HITRAN line parameters

On first run this downloads the line list from hitran.org and caches two files (CH4.data, CH4.header) under CACHE_DIR. Subsequent runs reuse the cache.

HAPI version: 1.3.0.0
To get the most up-to-date version please check http://hitran.org/hapi
ATTENTION: Python versions of partition sums from TIPS-2021 are now available in HAPI code

           MIT license: Copyright 2021 HITRAN team, see more at http://hitran.org. 

           If you use HAPI in your research or software development,
           please cite it using the following reference:
           R.V. Kochanov, I.E. Gordon, L.S. Rothman, P. Wcislo, C. Hill, J.S. Wilzewski,
           HITRAN Application Programming Interface (HAPI): A comprehensive approach
           to working with spectroscopic data, J. Quant. Spectrosc. Radiat. Transfer 177, 15-30 (2016)
           DOI: 10.1016/j.jqsrt.2016.03.005

           ATTENTION: This is the core version of the HITRAN Application Programming Interface.
                      For more efficient implementation of the absorption coefficient routine, 
                      as well as for new profiles, parameters and other functional,
                      please consider using HAPI2 extension library.
                      HAPI2 package is available at http://github.com/hitranonline/hapi2

Using /root/.cache/plumax/hitran

CH4
                     Lines parsed: 39817

Data is fetched from http://hitran.org

BEGIN DOWNLOAD: CH4
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
  65536 bytes written to /root/.cache/plumax/hitran/CH4.data
Header written to /root/.cache/plumax/hitran/CH4.header
END DOWNLOAD
                     Lines parsed: 39817
PROCESSED
PosixPath('/root/.cache/plumax/hitran')

3. Compute σ(ν;T,p)\sigma(\nu; T, p) on the LUT grid

For each (T,p)(T, p) knot HAPI performs the line-by-line Voigt sum (§2 of the derivation note) and returns a cross-section array of shape (n_nu,). Runtime is dominated by the convolution inside HAPI — typically a few seconds per knot on a warm cache, so our 3 × 3 grid is a ~1-minute job.

Using /root/.cache/plumax/hitran

CH4
                     Lines parsed: 39817
{'air': 0.999998, 'self': 2e-06}
14.540211 seconds elapsed for abscoef; nlines = 39817
{'air': 0.999998, 'self': 2e-06}
14.139914 seconds elapsed for abscoef; nlines = 39817
{'air': 0.999998, 'self': 2e-06}
14.203306 seconds elapsed for abscoef; nlines = 39817
{'air': 0.999998, 'self': 2e-06}
14.818915 seconds elapsed for abscoef; nlines = 39817
{'air': 0.999998, 'self': 2e-06}
13.883416 seconds elapsed for abscoef; nlines = 39817
{'air': 0.999998, 'self': 2e-06}
13.914742 seconds elapsed for abscoef; nlines = 39817
{'air': 0.999998, 'self': 2e-06}
14.360457 seconds elapsed for abscoef; nlines = 39817
{'air': 0.999998, 'self': 2e-06}
14.599542 seconds elapsed for abscoef; nlines = 39817
{'air': 0.999998, 'self': 2e-06}
14.512946 seconds elapsed for abscoef; nlines = 39817
σ LUT shape: (10000, 3, 3)  [n_nu, n_T, n_P]
σ range: [4.41e-25, 1.03e-19] cm²/molecule
ν range: [4000.0, 4500.0] cm⁻¹ = [2222.2, 2500.0] nm

Wrap in the CF-conformant xarray.Dataset:

Loading...

4. Visual sanity checks

4a. Cross-section at one reference state

At T=260T = 260 K, p=0.6p = 0.6 atm (a mid-troposphere state) the methane ν3\nu_3 band structure is clearly visible — a forest of sharp Voigt lines between ∼4150\sim 4150 and ∼4450\sim 4450 cm⁻¹ (2250–2410 nm).

<Figure size 1000x350 with 1 Axes>

4b. Temperature dependence at fixed pressure

The Boltzmann factor in Si(T)S_i(T) rearranges line strength between low-E′′E'' and high-E′′E'' transitions as TT changes. At higher TT the thermal population of excited rovibrational levels rises, so lines from those levels gain strength. We visualise this with a zoom into a single Q-branch feature.

<Figure size 1000x400 with 1 Axes>

4c. Pressure dependence at fixed temperature

Pressure broadening widens the Lorentzian half-width γL∝p\gamma_L \propto p, which lowers peak amplitude and raises the absorption between lines (line wings overlap more). The same 10-cm⁻¹ zoom makes the effect obvious.

<Figure size 1000x400 with 1 Axes>

Reading the plot. Going from 0.3 atm (blue) to 1.0 atm (green):

  • Peak cross-sections drop by roughly 2–3× (Lorentzian area-preserving broadening).

  • Valleys between lines rise, sometimes by more than 10× — the “line-wing blending” that makes high-pressure cross-sections look smoother.

  • The shift in peak position is sub-bin (we’d need Δν≪0.05\Delta\nu \ll 0.05 cm⁻¹ to resolve pressure-induced line shifts).

5. Save the LUT

The generated NetCDF is git-ignored by design — each user regenerates it locally. Downstream notebooks expect it at the canonical path below.

wrote /root/.cache/plumax/hapi_lut/ch4_absorption_lut.nc  (0.47 MB)

6. Summary

  • HAPI’s absorptionCoefficient_Voigt gives us the line-by-line cross-section per molecule at any (T,p)(T, p) — we stitched 9 such calls into a 3D xarray.Dataset.

  • The cross-section dependence on TT (Boltzmann redistribution) and pp (pressure broadening) is directly observable in a 10-cm⁻¹ zoom of the CH4_4 ν3\nu_3 band.

  • This LUT is the offline artefact for every downstream Beer–Lambert forward model — see Multi-gas absorption LUT for multi-gas LUTs and Differential Beer-Lambert plume retrieval from the LUT for the plume-enhancement retrieval.