Knowing Your Model Grid#
ForMoSA compares observations against pre-computed, self-consistent atmospheric
model grids stored as xarray .nc files.
This page explains what a grid file contains, which grids are available, and
how to inspect one before starting an analysis.
What is a model grid?#
A model grid is a multi-dimensional array of synthetic spectra computed by an atmospheric code (e.g. BT-Settl, Exo-REM, ATMO) over a regular grid of physical parameters such as effective temperature (\(T_{eff}\)), surface gravity (\(\log g\)), metallicity (\(\mathrm{[M/H]}\)), and \(\mathrm{[C/O]}\) ratio.
ForMoSA uses xarray.Dataset to represent grids. The dataset has:
Coordinates — one per physical parameter (e.g.
par1= \(T_{eff}\),par2= \(\log g\)). The namespar1–par4are fixed; what they mean depends on the grid.Data variable
flux— shape(N_par1, N_par2, …, N_wavelength).Data variable
res— the native spectral resolution at each wavelength point, shape(N_wavelength,).Coordinate
wavelength— the wavelength axis in microns.
Available grids#
The following grids have been pre-formatted for ForMoSA and are available for
download. Save them inside your atm_grids/ directory.
Grid |
Reference |
Download |
|---|---|---|
BT-Settl |
||
Exo-REM |
||
ATMO |
Note
Need a grid that isn’t listed here? The ForMoSA team can generate custom formatted grids on request — open an issue on GitHub.
Inspecting a grid#
import xarray as xr
# Open the grid (lazy-loads by default — no RAM spike)
grid = xr.open_dataset("atm_grids/BT-Settl.nc")
print(grid)
# Shows dimensions, coordinates, and data variables
# What parameter axes are available?
print(grid.coords)
# Range of Teff (par1) and logg (par2)
print("Teff range:", float(grid.par1.min()), "–", float(grid.par1.max()), "K")
print("logg range:", float(grid.par2.min()), "–", float(grid.par2.max()))
Plotting a single spectrum#
import xarray as xr
import matplotlib.pyplot as plt
grid = xr.open_dataset("atm_grids/BT-Settl.nc")
# Select the model closest to Teff=1600 K, logg=4.0
spectrum = grid.flux.sel(par1=1600, par2=4.0, method="nearest")
plt.figure(figsize=(10, 4))
plt.plot(grid.wavelength, spectrum, linewidth=0.8)
plt.xlabel("Wavelength (µm)")
plt.ylabel("Flux (model units)")
plt.title("BT-Settl: Teff = 1600 K, log g = 4.0")
plt.tight_layout()
plt.show()
Checking resolution coverage#
Before running analysis.adapt(), it is worth verifying that the grid’s native
spectral resolution is higher than your observation’s resolution at the relevant
wavelengths — otherwise the adaptation step cannot degrade the resolution correctly.
import xarray as xr
import matplotlib.pyplot as plt
grid = xr.open_dataset("atm_grids/BT-Settl.nc")
# Native resolution of the grid across wavelength
plt.figure(figsize=(10, 3))
plt.plot(grid.wavelength, grid.res)
plt.xlabel("Wavelength (µm)")
plt.ylabel("Spectral resolution λ/Δλ")
plt.title("BT-Settl native resolution")
plt.tight_layout()
plt.show()