How to Select and Use Molecular and Atomic Databases (ExoMol, HITRAN, VALD) in ExoJAX

ExoJAX provides specialized database classes—MdbExomol, MdbHitran, MdbHitemp, AdbVald, and AdbSepVald—that download, filter, and convert spectroscopic line lists into JAX-compatible arrays for radiative transfer calculations.

ExoJAX stores spectroscopic line-list data in database (MDB) objects that handle everything from file parsing to GPU memory management. Whether you are modeling high-temperature exoplanet atmospheres with ExoMol, Earth-like conditions with HITRAN, or stellar abundances with VALD atomic data, the library provides a unified interface to select and use molecular and atomic databases in ExoJAX.

Database Class Overview

ExoJAX organizes spectroscopic data into three families of database classes, each located in specific submodules under src/exojax/database/.

Molecular Databases

Atomic Databases

  • VALD: Use AdbVald from src/exojax/database/vald/api.py for combined atomic line lists (e.g., Fe I, Fe II). For species-separated views, use AdbSepVald, which reshapes the combined object into separate axes per atomic/ionic species.

All classes share a common constructor signature that controls data location, spectral range, line filtering, and memory layout.

Instantiating Molecular Databases

Each molecular database class accepts parameters to define the local data directory (path or molecule_path), select a wavenumber region with nurange=[νmin, νmax] (in cm⁻¹), and apply a line-strength cut (crit) based on a typical temperature (Ttyp). You can also control memory layout with gpu_transfer=True/False, select the I/O engine ("vaex" or "pytables"), and choose whether to automatically activate the database (activation=True).

Under the hood, these classes inherit from a thin Radis wrapper (*_DatabaseManager) and the ExoJAX base MdbCommonHitempHitran. The base handles downloading missing files via download_and_parse, loading data into lazy-IO dataframes (Vaex or Pandas), and applying a load mask that enforces the wavenumber range, line-strength cut, and optional elower_max.

ExoMol Example

from exojax.database.exomol.api import MdbExomol

mdb_co = MdbExomol(
    path=".database/CO/12C-16O/Li2015",  # Unpacked ExoMol folder structure

    nurange=[2000.0, 2500.0],            # Wavenumber range in cm⁻¹

    crit=1e-30,                          # Keep only lines stronger than this

    Ttyp=1500.0,                         # Temperature for crit evaluation

    gpu_transfer=True,                   # Store arrays on GPU if available

)

print(mdb_co.dev_nu_lines.shape)   # JAX DeviceArray shape, e.g., (123456,)

print(mdb_co.logsij0[:5])           # First five log line strengths

HITRAN Example

from exojax.database.hitran.api import MdbHitran

mdb_co2 = MdbHitran(
    molecule_path=".database/CO2/CO2_2020",  # HITRAN-2020 folder

    nurange=[2200, 2400],
    crit=1e-28,
    Ttyp=296.0,          # Room temperature for line-strength cut

    gpu_transfer=False,  # Keep on host memory for small selections

)

# Activate later if you instantiated with activation=False

mdb_co2.activate(mdb_co2.df)

HITEMP Example

from exojax.database.hitemp.api import MdbHitemp

mdb_h2o = MdbHitemp(
    molecule_path=".database/H2O/1H2-16O/POKAZATEL",
    nurange=[1500, 2000],
    crit=1e-27,
    Ttyp=2000.0,
    gpu_transfer=True,
    engine="vaex",      # Faster lazy-IO for large files

)

# Create a snapshot for opacity calculators

h2o_snapshot = mdb_h2o.to_snapshot()

Working with Atomic Line Lists (VALD)

The VALD workflow differs slightly because raw VALD "Long format" files are converted to HDF5 on first read via read_ExAll. After conversion, the same masking and JAX-array generation steps apply. The AdbVald class creates a combined view, while AdbSepVald provides a species-separated view exposing a separate axis for each atomic/ionic species—useful for line-by-line opacity calculations.

from exojax.database.vald.api import AdbVald, AdbSepVald

# VALD "Extract All" output file

vald_path = "./vald/Fe_extracted_All.txt"

adb = AdbVald(
    path=vald_path,
    nurange=[5000.0, 6000.0],
    crit=1e-30,
    Irwin=False,        # Use Barklem & Collet (2016) partition functions

    gpu_transfer=True,
)

# Species-separated view (e.g., Fe I vs Fe II)

adb_sep = AdbSepVald(adb)
print("Number of species:", adb_sep.N_usp)
print("Shape (species, lines):", adb_sep.nu_lines.shape)

Database Activation and Memory Management

Activation builds the JAX-compatible arrays and computes pressure-broadening coefficients. By default, activation=True converts NumPy arrays to JAX jnp.arrays, computes natural and collisional broadening coefficients (gamma_natural, gamma_air, gamma_self), and stores them on the selected device according to gpu_transfer. If you instantiate with activation=False, call activate() manually and pass the dataframe:

mdb.activate(mdb.df)

All database objects expose a minimal, JAX-friendly public API:

  • nu_lines – line centre wavenumbers (NumPy)
  • dev_nu_lines – same data as JAX DeviceArray (used by opacity modules)
  • logsij0 – log of the reference line strength (Sij0)
  • A, elower, jlower, jupper, gpp – standard spectroscopic parameters
  • gamma_natural, gamma_air, gamma_self – pressure-broadening coefficients

Because the classes implement __eq__, they can be safely compared in tests or cached. The to_snapshot() method returns a data-only DTO (MDBSnapshot) consisting solely of NumPy arrays—this is what opacity calculators like OpaPremodit expect, keeping the heavy database implementation decoupled from the radiative-transfer pipeline.

Integrating with Opacity Calculators

Pass the database object (or its snapshot) directly to opacity calculators in exojax.opacity:

from exojax.opacity.premodit.api import OpaPremodit
from exojax.rt.atmrt import ArtEmisPure

# Compute emission spectrum for CO using Premodit opacity

opa = OpaPremodit(mdb_co, nu_grid=mdb_co.nu_lines, gpu_transfer=True)
rt = ArtEmisPure(opa, T=[1500.0], P=[1e5])   # Simple isothermal atmosphere

flux = rt.calc_spectrum()

Summary

  • Select the appropriate class for your data source: MdbExomol for high-temperature molecular lines, MdbHitran/MdbHitemp for HITRAN-schema data, or AdbVald/AdbSepVald for atomic lines.
  • Filter at load time using nurange for wavenumber limits and crit/Ttyp for line-strength cuts to minimize memory usage.
  • Control hardware placement with gpu_transfer and I/O performance with engine ("vaex" recommended for large files).
  • Activate the database to generate JAX arrays and broadening coefficients, or use to_snapshot() to create a lightweight DTO for opacity modules.
  • Import directly from the specific submodule (e.g., exojax.database.exomol.api) rather than the deprecated shim in exojax.database.api.

Frequently Asked Questions

What is the difference between MdbHitran and MdbHitemp?

MdbHitran targets standard HITRAN line lists optimized for Earth atmospheric temperatures, while MdbHitemp handles high-temperature extensions (like HITEMP water) required for hot exoplanets. MdbHitemp inherits from MdbCommonHitempHitran and can use the "vaex" engine for efficient lazy loading of large files.

How do I convert a VALD "Long format" file for use in ExoJAX?

ExoJAX automatically converts VALD "Extract All" text files to HDF5 format on first read via the internal read_ExAll method in src/exojax/database/vald/api.py. Simply point AdbVald to the .txt file; the HDF5 cache will be created in the same directory for subsequent loads.

Should I use gpu_transfer=True for small line selections?

For small spectral ranges or limited line counts, set gpu_transfer=False to keep arrays in host memory and avoid GPU allocation overhead. Enable gpu_transfer=True only when you need maximum performance for large opacity calculations or when integrating with GPU-bound radiative transfer solvers.

What does the crit parameter actually filter?

The crit parameter defines a threshold for the line strength Sij evaluated at temperature Ttyp. Lines weaker than crit are excluded by the load mask during dataframe initialization, reducing memory footprint and computation time. This is applied alongside the nurange wavenumber window and optional elower_max energy limits.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →