How to Configure ExoJAX to Use Different Opacity Calculation Methods (Premodit vs Modit)
ExoJAX provides two primary opacity calculators—OpaPremodit and OpaModit—that share a common interface, allowing you to switch between pre-computed and on-the-fly line-profile calculations by simply changing the imported class.
When performing radiative transfer calculations for exoplanet atmospheres, selecting the right opacity calculation method is critical for balancing speed and memory usage. The hajimekawahara/exojax repository implements a pluggable architecture where you can configure ExoJAX to use different opacity calculation methods without modifying your radiative transfer pipeline.
Understanding ExoJAX Opacity Calculators
ExoJAX separates the opacity calculation logic from the radiative-transfer solver through an abstract base class pattern. Both high-performance methods inherit from OpaCalc defined in src/exojax/opacity/opacalc.py.
OpaPremodit (Pre-computed Modified Discrete Integral Transform) lives in src/exojax/opacity/premodit/api.py. This class pre-computes the line contribution grid on a fixed temperature-pressure mesh, making it ideal for large-scale retrievals where the line list remains static.
OpaModit (on-the-fly Modified Discrete Integral Transform) is implemented in src/exojax/opacity/modit/api.py. This calculator recomputes line-profile contributions for each temperature-pressure layer at runtime, offering greater flexibility when you need to vary atmospheric structures frequently.
Both classes are re-exported from the public API in src/exojax/opacity/__init__.py, which you access via:
from exojax.opacity import OpaPremodit, OpaModit
Choosing Between Premodit and Modit
The decision between these opacity calculation methods depends on your specific workflow requirements regarding speed, memory, and flexibility.
Use OpaPremodit when:
- You need maximum speed for cross-section generation
- The line list and temperature-pressure grid remain constant across iterations
- You can afford higher memory usage for storing the pre-computed grid
- You are running large-scale retrievals or grid-based forward models
Use OpaModit when:
- You need to change temperature profiles or abundances frequently between calculations
- Memory constraints prevent storing large pre-computed grids
- You are performing exploratory runs or parameter studies with varying atmospheric conditions
- You require moderate speed with maximum flexibility
Configuring ExoJAX for Different Opacity Methods
The configuration process involves three steps: loading your molecular database, defining your wavenumber grid, and instantiating your chosen opacity calculator class.
Common Setup: Database and Wavenumber Grid
Before selecting an opacity method, initialize the molecular database and spectral grid. This setup code works regardless of which calculator you choose:
import numpy as np
from exojax.spec import MdbExomol
from exojax.utils.grids import nu_grid_logspace
# Load molecular line list (example: methane)
mdb = MdbExomol('.cache/CH4/12C-1H4/12C-1H4__12C-1H4.exomol')
# Define wavenumber grid in cm^-1
nus = nu_grid_logspace(2000.0, 5000.0, 3000)
Using Premodit for Fast Static Calculations
To configure ExoJAX for pre-computed opacity calculations, import OpaPremodit from src/exojax/opacity/premodit/api.py and pass your database and grid:
from exojax.opacity import OpaPremodit
from exojax.rt import ArtEmisPure
# Initialize Premodit opacity calculator
opa = OpaPremodit(mdb, nu_grid=nus, allow_32bit=True)
# Use with any radiative transfer solver
art = ArtEmisPure(opa, pressure=1.0e5, temperature=1500.0)
flux = art.calc_flux()
The allow_32bit=True parameter enables single-precision calculations for faster GPU computation, while the opa object now contains the pre-computed grid stored in memory.
Using Modit for Flexible On-the-Fly Calculations
For dynamic calculations where atmospheric parameters change frequently, import OpaModit from src/exojax/opacity/modit/api.py:
from exojax.opacity import OpaModit
from exojax.rt import ArtTransPure
# Initialize Modit with optional grid resolution parameter
opa = OpaModit(mdb, nu_grid=nus, dit_grid_resolution=0.1, allow_32bit=True)
# Example transmission calculation with varying pressure grid
art = ArtTransPure(opa, pressure=np.logspace(5, -2, 100), temperature=1200.0)
trans = art.calc_transmission()
The dit_grid_resolution parameter controls the resolution of the Discrete Integral Transform grid, allowing you to balance accuracy against computation time.
Runtime Switching Between Methods
Because both classes implement the same interface defined in src/exojax/opacity/opacalc.py, you can switch methods at runtime using a configuration flag:
use_premodit = True # Set to False to use Modit
if use_premodit:
from exojax.opacity import OpaPremodit as OpaCalc
else:
from exojax.opacity import OpaModit as OpaCalc
# Unified initialization works for either class
opa = OpaCalc(mdb, nu_grid=nus, allow_32bit=True)
This pattern allows you to maintain a single radiative transfer pipeline while testing both opacity calculation methods or selecting the appropriate calculator based on runtime constraints.
Summary
- ExoJAX opacity calculators are located in
src/exojax/opacity/premodit/api.py(OpaPremodit) andsrc/exojax/opacity/modit/api.py(OpaModit). - Both classes inherit from the abstract base
OpaCalcinsrc/exojax/opacity/opacalc.py, ensuring a consistent interface. - Premodit pre-computes line contributions for maximum speed but requires static temperature-pressure grids and higher memory.
- Modit computes line profiles on-the-fly for greater flexibility with varying atmospheric conditions and lower memory usage.
- Configuration requires only changing the imported class while keeping the initialization signature
(mdb, nu_grid, ...)consistent. - Radiative transfer solvers like
ArtEmisPureorArtTransPureaccept either calculator without code modification.
Frequently Asked Questions
What is the difference between Premodit and Modit in ExoJAX?
OpaPremodit pre-computes the line contribution grid on a fixed temperature-pressure mesh for maximum speed, while OpaModit recomputes line-profile contributions for each layer at runtime. According to the source code in src/exojax/opacity/premodit/api.py, Premodit builds the grid once during initialization, whereas src/exojax/opacity/modit/api.py shows Modit calculating contributions dynamically.
When should I use OpaPremodit versus OpaModit?
Use OpaPremodit for large-scale retrievals where the line list and atmospheric grid remain constant, as it offers the fastest cross-section generation despite higher memory usage. Choose OpaModit when you need to vary temperature profiles, pressures, or abundances frequently between calculations, as it rebuilds the opacity grid on-the-fly with lower memory overhead.
Can I switch opacity methods without changing my radiative transfer code?
Yes. Both OpaPremodit and OpaModit inherit from the abstract base class OpaCalc defined in src/exojax/opacity/opacalc.py, exposing identical methods to radiative transfer solvers. You can switch between them by simply changing the import statement, and solvers like ArtEmisPure in src/exojax/rt/art_emis_pure.py will accept either calculator interchangeably.
Where are the opacity calculator classes defined in the ExoJAX source?
The OpaPremodit class is implemented in src/exojax/opacity/premodit/api.py, and OpaModit is implemented in src/exojax/opacity/modit/api.py. Both are re-exported from the public API via src/exojax/opacity/__init__.py. The common interface they share is defined in src/exojax/opacity/opacalc.py.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →