# How to Configure ExoJAX to Use Different Opacity Calculation Methods (Premodit vs Modit)

> Learn how to configure ExoJAX for different opacity calculation methods. Easily switch between Premodit and Modit for your atmospheric modeling needs with this guide.

- Repository: [Hajime Kawahara/exojax](https://github.com/hajimekawahara/exojax)
- Tags: how-to-guide
- Published: 2026-03-03

---

**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`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/opacalc.py).

**`OpaPremodit`** (Pre-computed Modified Discrete Integral Transform) lives in [`src/exojax/opacity/premodit/api.py`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/__init__.py), which you access via:

```python
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:

```python
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`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/premodit/api.py) and pass your database and grid:

```python
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`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/modit/api.py):

```python
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`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/opacalc.py), you can switch methods at runtime using a configuration flag:

```python
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`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/premodit/api.py) (`OpaPremodit`) and [`src/exojax/opacity/modit/api.py`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/modit/api.py) (`OpaModit`).
- **Both classes inherit** from the abstract base `OpaCalc` in [`src/exojax/opacity/opacalc.py`](https://github.com/hajimekawahara/exojax/blob/main/src/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 `ArtEmisPure` or `ArtTransPure` accept 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`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/premodit/api.py), Premodit builds the grid once during initialization, whereas [`src/exojax/opacity/modit/api.py`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/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`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/premodit/api.py), and `OpaModit` is implemented in [`src/exojax/opacity/modit/api.py`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/modit/api.py). Both are re-exported from the public API via [`src/exojax/opacity/__init__.py`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/__init__.py). The common interface they share is defined in [`src/exojax/opacity/opacalc.py`](https://github.com/hajimekawahara/exojax/blob/main/src/exojax/opacity/opacalc.py).