Data Formatting#
ForMoSA reads observations from FITS table files (.fits). Each extension
holds a NumPy array; all arrays in the same file must be the same length. This
page explains what extensions are required for each observation type and shows
how to verify your file before running an analysis.
Required extensions#
The canonical name is what ForMoSA stores internally. Any alias in the Accepted aliases column
is equally valid when writing your FITS file — ForMoSA resolves them automatically.
WAVELENGTH_UNIT defaults to "um" (microns) if omitted.
Canonical name |
Accepted aliases |
Description |
Spectroscopic |
Photometric |
HCHR |
|---|---|---|---|---|---|
|
|
Wavelength array |
Required |
Required |
Required |
|
|
Wavelength unit string — one value repeated |
Optional |
Optional |
Optional |
|
|
Flux array |
Required |
Required |
Required |
|
|
1-σ flux uncertainty per point (use instead of |
Required* |
Required |
Required* |
|
|
Full covariance matrix — shape |
Required* |
— |
Required* |
|
|
Spectral resolution λ/Δλ per wavelength point |
Required |
— |
Required |
|
|
Observatory identifier, must match SVO |
— |
Required |
— |
|
|
Instrument identifier, must match SVO |
— |
Required |
— |
|
|
Filter identifier, must match SVO |
— |
Required |
— |
|
|
Stellar speckle reference spectrum |
— |
— |
Required |
|
|
Telluric or instrumental transmission spectrum applied to the model before comparison |
Optional |
— |
Optional |
|
|
One or more systematic noise components (shape |
— |
— |
Optional |
* ERROR or COVARIANCE — one of the two is required for spectroscopic observations; COVARIANCE is not supported for photometry.
Important
For photometric observations, FACILITY, INSTRUMENT, and FILTER_ID must be consistent with
the SVO Filter Profile Service
naming convention. ForMoSA uses these strings to automatically download and
cache the filter transmission curve.
Creating a FITS file with astropy#
import numpy as np
from astropy.io import fits
# Example: K-band spectroscopic observation
wav = np.linspace(2.0, 2.5, 500) # µm
flx = np.random.normal(1.0, 0.05, 500)
err = np.full(500, 0.05)
res = np.full(500, 4000.0) # R ~ 4000
unit = np.full(500, "um", dtype="U10") # one string per wavelength point
hdul = fits.HDUList([
fits.PrimaryHDU(),
fits.ImageHDU(wav, name="WAVELENGTH"),
fits.ImageHDU(unit, name="WAVELENGTH_UNIT"),
fits.ImageHDU(flx, name="FLUX"),
fits.ImageHDU(err, name="ERROR"),
fits.ImageHDU(res, name="RESOLUTION"),
])
hdul.writeto("my_observation.fits", overwrite=True)
Inspecting and plotting your file#
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits
with fits.open("my_observation.fits") as hdul:
hdul.info() # prints all extensions and their shapes
wav = hdul["WAVELENGTH"].data
flx = hdul["FLUX"].data
err = hdul["ERROR"].data
plt.figure(figsize=(10, 4))
plt.plot(wav, flx, label="flux")
plt.fill_between(wav, flx - err, flx + err, alpha=0.3, label="1σ")
plt.xlabel("Wavelength (µm)")
plt.ylabel("Flux")
plt.legend()
plt.tight_layout()
plt.show()
MOSAIC mode: multiple files#
When combining multiple instruments, provide one .fits file per instrument and
list them all in ConfigPath.observation_path:
from ForMoSA.config.global_config import ConfigPath
config_path = ConfigPath(
observation_path=[
"data/sphere_yjh.fits", # SPHERE YJH low-res spectroscopy
"data/gravity_k.fits", # GRAVITY K-band spectroscopy
"data/nircam_photo.fits", # JWST NIRCam photometry
],
adapt_store_path="adapted_grid/",
result_path="results/",
model_path="atm_grids/ExoREM.nc",
)
ForMoSA will assign each file an index (0, 1, 2, …) that you can use to set
per-instrument parameters such as rv_0, rv_1, etc. in ConfigParameters.