skyscapes.physical_model.exojax#
ExoJAX-backed physical-model components.
Self-contained subpackage holding everything specific to the ExoJAX
radiative-transfer backend: the ExoJaxPhysicalModel orchestrator,
swappable physics components (T-P, absorption, scattering, clouds,
surface), PSG cross-section helpers, and Earth-epoch archetypes.
The backend-agnostic AbstractPhysicalModel interface and the
simple non-RT physical models (Lambertian, grid) live one level up in
skyscapes.physical_model.
Submodules#
Attributes#
Classes#
Sum of per-species line-list / cross-section absorption. |
|
Per-layer absorption opacity from line lists / cross-sections. |
|
Per-layer cloud opacity (mixed scattering + absorption). |
|
Per-species mass-mixing-ratio profile evaluated at layer pressures. |
|
Per-layer scattering opacity (e.g. Rayleigh). |
|
Bottom-of-atmosphere reflectivity. |
|
Temperature-pressure profile. |
|
Build instructions for the implicit residual gas. |
|
Implicit residual gas filling the unallocated mass fraction. |
|
Well-mixed gas: constant mmr at every layer. |
|
Per-layer optical-property contribution from one component. |
|
Wavelength-independent (gray) Lambertian surface. |
|
Single-layer gray-scattering cloud. |
|
Single-layer cloud with Mie-scattering optical properties. |
|
One atmospheric molecule with an altitude-resolved mixing ratio. |
|
Build instructions for one molecule. |
|
Disable cloud opacity: zero contribution. |
|
Disable scattering entirely: contributes zero opacity. |
|
Power-law T-P profile: |
|
Rayleigh scattering from tracked species + optional bulk residual. |
|
Gaussian-in-log-pressure peak; canonical for O3. |
|
Constant below a step pressure, drops sharply above; canonical for H2O. |
|
Wavelength-dependent surface reflectivity. |
|
PSG cross-section opacity for O3 (Serdyuchenko et al. 2014). |
|
Composition-based reflected-light planet model over ExoJAX's 2-stream RT. |
|
Cross-section-backed opacity from any PSG xs file. |
Functions#
|
Construct (molmass, rayleigh_xs) for the implicit residual gas. |
|
Build a Mie cloud component by pre-computing Mie params. |
|
Construct (molmass, opa, rayleigh_xs) for one molecule. |
|
Build the heavy shared engines and pre-built per-species data. |
|
VMRs -> dict of Earth-realistic profiles per species. |
|
Convert VMR dict to log10 MMR dict with K-shaped arrays. |
|
Convert volume-mixing-ratio dict to mass-mixing-ratio dict. |
Package Contents#
- skyscapes.physical_model.exojax.MOLECULE_RECIPES: dict[str, MoleculeRecipe]#
- class skyscapes.physical_model.exojax.Absorption[source]#
Bases:
skyscapes.physical_model.exojax.components.base.AbstractAbsorptionSum of per-species line-list / cross-section absorption.
Iterates over the species tuple, skipping any with
opa is None(e.g. a species included purely for its Rayleigh contribution).- compute(species, Tarr, pressure, gravity, rt_engine)[source]#
Sum per-species absorption optical depth.
- Parameters:
species (tuple[skyscapes.physical_model.exojax.components.species.MolecularSpecies, Ellipsis])
Tarr (jaxtyping.Array)
pressure (jaxtyping.Array)
gravity (jaxtyping.Array)
- Return type:
skyscapes.physical_model.exojax.components.base.Contribution
- class skyscapes.physical_model.exojax.AbstractAbsorption[source]#
Bases:
equinox.ModulePer-layer absorption opacity from line lists / cross-sections.
Concrete implementations iterate over the atmosphere’s
MolecularSpeciestuple, calling each species’opaengine and summing the contributions.- abstractmethod compute(species, Tarr, pressure, gravity, rt_engine)[source]#
Absorption contribution.
dtau_scatterandg_weighted_numare zero for pure absorbers, but the return shape is the same as for scattering components so the atmosphere can combine them uniformly.- Parameters:
species (tuple[skyscapes.physical_model.exojax.components.species.MolecularSpecies, Ellipsis])
Tarr (jaxtyping.Array)
pressure (jaxtyping.Array)
gravity (jaxtyping.Array)
- Return type:
- class skyscapes.physical_model.exojax.AbstractClouds[source]#
Bases:
equinox.ModulePer-layer cloud opacity (mixed scattering + absorption).
- abstractmethod compute(log_pressure_bar_scalar, log_opt_depth_scalar, pressure, n_nu)[source]#
Cloud contribution.
For a single-scattering-albedo cloud the scattering and absorption parts are both nonzero; for a purely scattering cloud
dtau_total == dtau_scatter.- Parameters:
log_pressure_bar_scalar (jaxtyping.Array)
log_opt_depth_scalar (jaxtyping.Array)
pressure (jaxtyping.Array)
n_nu (int)
- Return type:
- class skyscapes.physical_model.exojax.AbstractMmrProfile[source]#
Bases:
equinox.ModulePer-species mass-mixing-ratio profile evaluated at layer pressures.
- class skyscapes.physical_model.exojax.AbstractScattering[source]#
Bases:
equinox.ModulePer-layer scattering opacity (e.g. Rayleigh).
- abstractmethod compute(species, bulk, gravity, rt_engine, n_layers, n_nu)[source]#
Scattering contribution from tracked species + optional bulk gas.
For a pure scatterer
dtau_total == dtau_scatter;g_weighted_numis zero for isotropic Rayleigh.- Parameters:
species (tuple[skyscapes.physical_model.exojax.components.species.MolecularSpecies, Ellipsis])
bulk (skyscapes.physical_model.exojax.components.species.BulkGasResidual | None)
gravity (jaxtyping.Array)
n_layers (int)
n_nu (int)
- Return type:
- class skyscapes.physical_model.exojax.AbstractSurface[source]#
Bases:
equinox.ModuleBottom-of-atmosphere reflectivity.
- class skyscapes.physical_model.exojax.AbstractTPProfile[source]#
Bases:
equinox.ModuleTemperature-pressure profile.
- class skyscapes.physical_model.exojax.BulkGasRecipe[source]#
Build instructions for the implicit residual gas.
- Attributes:
- name: Gas name; must match an ExoJAX polarizability key (or
provide
polarizability_override).
molmass: Molar mass [g/mol]. polarizability_override: Override polarizability if missing
from ExoJAX’s table.
- class skyscapes.physical_model.exojax.BulkGasResidual[source]#
Bases:
equinox.ModuleImplicit residual gas filling the unallocated mass fraction.
The mass-mixing ratio is computed dynamically as
max(0, 1 - sum(tracked species mmrs)). Contributes only to Rayleigh scattering (no line-list absorption is associated with the bulk gas in this model – N2 is essentially transparent across 300–1100 nm, H2/He likewise).- Attributes:
name: Gas name, e.g.
"N2"for Earth or"H2"for gas giants. molmass: Molar mass [g/mol]. rayleigh_xs: Rayleigh cross-section [cm^2/molecule] on theatmosphere’s wavenumber grid, shape
(n_nu,).
- rayleigh_xs: jaxtyping.Array#
- class skyscapes.physical_model.exojax.ConstantMmr[source]#
Bases:
AbstractMmrProfileWell-mixed gas: constant mmr at every layer.
Use for gases with chemical lifetimes longer than mixing timescales in the modelled pressure range (CO2, CH4, O2, N2, etc. in troposphere + lower stratosphere).
- Attributes:
log_mmr: Log10 mass-mixing ratio, shape
(K,)(per planet).
- log_mmr: jaxtyping.Array#
- class skyscapes.physical_model.exojax.Contribution[source]#
Bases:
NamedTuplePer-layer optical-property contribution from one component.
- Fields:
- dtau_total: Layer optical depth this component adds to the total
opacity budget, shape
(n_layers, n_nu).- dtau_scatter: Subset of
dtau_totalthat is scattering (non-absorbing), shape
(n_layers, n_nu). For a pure absorber this is zero. For Rayleighssa=1so it equalsdtau_total. For a partly-absorbing cloud with single- scattering albedossa_c, this isssa_c * dtau_cloud.- g_weighted_num:
g * dtau_scatternumerator for the weighted- average asymmetry parameter, shape
(n_layers, n_nu). Rayleigh contributes zero (isotropic,g=0). A cloud with asymmetryg_ccontributesg_c * ssa_c * dtau_cloud.
- dtau_total: jaxtyping.Array#
- dtau_scatter: jaxtyping.Array#
- g_weighted_num: jaxtyping.Array#
- class skyscapes.physical_model.exojax.FlatSurface[source]#
Bases:
skyscapes.physical_model.exojax.components.base.AbstractSurfaceWavelength-independent (gray) Lambertian surface.
Equivalent to
WavelengthDependentSurfacewith a flat spectrum but structurally explicit; useful when callers want to document “I am intentionally using a featureless surface”.- Attributes:
log_albedo: Log10 surface albedo per planet, shape
(K,).
- log_albedo: jaxtyping.Array#
- class skyscapes.physical_model.exojax.GrayCloud[source]#
Bases:
skyscapes.physical_model.exojax.components.base.AbstractCloudsSingle-layer gray-scattering cloud.
The total cloud scattering optical depth is distributed across layers via a Gaussian in log-pressure (softmax-normalised so the weights are well-defined even when the cloud pressure is far outside the layer grid – useful for ablation runs with
log_opt_depth = -inf).Wavelength-grey: the cloud’s cross-section is constant across the spectrum. A Mie cloud with composition-dependent scattering would be a separate component implementing the same contract.
- Attributes (PyTree leaves, fittable):
log_pressure_bar: Log10 cloud-deck pressure [bar], shape
(K,). log_opt_depth: Log10 of the vertically-integrated cloudscattering optical depth, shape
(K,).- Static attributes (configuration):
ssa: Single-scattering albedo (default 1.0, pure scattering). g: Asymmetry parameter (default 0.85, forward-peaked). log_sigma: Vertical-distribution width in log10(P) [dex].
- log_pressure_bar: jaxtyping.Array#
- log_opt_depth: jaxtyping.Array#
- compute(log_pressure_bar_scalar, log_opt_depth_scalar, pressure, n_nu)[source]#
Gray cloud contribution at a single pressure level.
- Parameters:
log_pressure_bar_scalar (jaxtyping.Array)
log_opt_depth_scalar (jaxtyping.Array)
pressure (jaxtyping.Array)
n_nu (int)
- Return type:
skyscapes.physical_model.exojax.components.base.Contribution
- class skyscapes.physical_model.exojax.MieCloud[source]#
Bases:
skyscapes.physical_model.exojax.components.base.AbstractCloudsSingle-layer cloud with Mie-scattering optical properties.
The total cloud scattering optical depth is distributed vertically via a softmax-Gaussian in log-pressure (same as
GrayCloud). What’s different is that the single-scattering albedo and asymmetry parameter come from pre-computed Mie cross-sections rather than being scalar constants – they vary with wavelength according to the condensate’s refractive index n(lambda) + k(lambda).- Attributes (PyTree leaves, fittable):
log_pressure_bar: Log10 cloud-deck pressure [bar], shape
(K,). log_opt_depth: Log10 of the vertically-integrated cloudextinction optical depth, shape
(K,).
Pre-computed Mie quantities (built at engine time, shared across planets):
- ssa_grid: Single-scattering albedo on the wavenumber grid,
shape
(n_nu,).sigma_scattering / sigma_extinction.- g_grid: Asymmetry parameter on the wavenumber grid,
shape
(n_nu,).
- Static config:
- condensate: Condensate name (
"H2O","H2O_ice", "MgSiO3", etc.). Matters for the repr; the actual Mie params are baked into ssa_grid and g_grid.
rg_um: Geometric mean particle radius [um]. sigmag: Geometric standard deviation of the lognormal size
distribution.
- log_sigma: Cloud-deck vertical Gaussian half-width in
log10(pressure) [dex].
- condensate: Condensate name (
- log_pressure_bar: jaxtyping.Array#
- log_opt_depth: jaxtyping.Array#
- ssa_grid: jaxtyping.Array#
- g_grid: jaxtyping.Array#
- compute(log_pressure_bar_scalar, log_opt_depth_scalar, pressure, n_nu)[source]#
Mie-cloud contribution: gray-depth distribution, spectral ssa/g.
- Parameters:
log_pressure_bar_scalar (jaxtyping.Array)
log_opt_depth_scalar (jaxtyping.Array)
pressure (jaxtyping.Array)
n_nu (int)
- Return type:
skyscapes.physical_model.exojax.components.base.Contribution
- class skyscapes.physical_model.exojax.MolecularSpecies[source]#
Bases:
equinox.ModuleOne atmospheric molecule with an altitude-resolved mixing ratio.
The mixing ratio is encoded as a profile component (e.g.
ConstantMmrfor well-mixed gases,StratosphericPeakMmrfor O3,TroposphericMmrfor H2O) rather than a single scalar, so altitude variation is represented explicitly.- Attributes:
- profile: Per-species mmr profile. Owns the fittable
log-mixing-ratio leaves.
name: Molecule name, e.g.
"H2O". molmass: Molar mass [g/mol]. opa: Opacity engine. Either an ExoJAXOpaPremodit(forHITRAN-backed line-list molecules) or
O3ChappuisOpacity(for visible cross-section absorbers like O3). May beNoneif the species contributes only Rayleigh scattering.- rayleigh_xs: Pre-computed Rayleigh cross-section
[cm^2/molecule] on the atmosphere’s wavenumber grid, shape
(n_nu,). Set to all-zeros to disable per-species Rayleigh contribution.
- opa: Any#
- rayleigh_xs: jaxtyping.Array#
- class skyscapes.physical_model.exojax.MoleculeRecipe[source]#
Build instructions for one molecule.
- Attributes:
- name: Molecule name (must match ExoJAX’s HITRAN / polarizability
keys when those tables apply).
- psg_xs_url: If set, use a PSG cross-section file at this URL
(
PsgCrossSectionOpacity) instead of an ExoJAX line-list opa. Required for species whose absorption is dominated by electronic transitions in the visible/NIR (e.g. O3 Chappuis, SO2 UV).- psg_xs_molmass: Molar mass [g/mol]; required when
psg_xs_url is set since we can’t extract it from HITRAN in that case.
- polarizability_override: Explicit polarizability [cm^3] for the
Rayleigh cross-section, used when ExoJAX’s table doesn’t have an entry.
NoneletsOpaRayleighlook it up.
- class skyscapes.physical_model.exojax.NoCloud[source]#
Bases:
skyscapes.physical_model.exojax.components.base.AbstractCloudsDisable cloud opacity: zero contribution.
Equivalent to a
GrayCloudwithlog_opt_depth = -infbut structurally explicit, so thatisinstance(atm.clouds, NoCloud)documents intent in code that builds cloud-free atmospheres.- compute(log_pressure_bar_scalar, log_opt_depth_scalar, pressure, n_nu)[source]#
Return zero-everywhere cloud contribution.
log_pressure_bar_scalarandlog_opt_depth_scalarare accepted for parity withGrayCloudbut unused.- Parameters:
log_pressure_bar_scalar (jaxtyping.Array)
log_opt_depth_scalar (jaxtyping.Array)
pressure (jaxtyping.Array)
n_nu (int)
- Return type:
skyscapes.physical_model.exojax.components.base.Contribution
- class skyscapes.physical_model.exojax.NullScattering[source]#
Bases:
skyscapes.physical_model.exojax.components.base.AbstractScatteringDisable scattering entirely: contributes zero opacity.
Useful for ablation studies (e.g. quantifying how much Rayleigh affects a retrieval) and for atmospheres where scattering is negligible.
- compute(species, bulk, gravity, rt_engine, n_layers, n_nu)[source]#
Return zero-everywhere contribution.
- Parameters:
species (tuple[skyscapes.physical_model.exojax.components.species.MolecularSpecies, Ellipsis])
bulk (skyscapes.physical_model.exojax.components.species.BulkGasResidual | None)
gravity (jaxtyping.Array)
n_layers (int)
n_nu (int)
- Return type:
skyscapes.physical_model.exojax.components.base.Contribution
- class skyscapes.physical_model.exojax.PowerLawTPProfile[source]#
Bases:
skyscapes.physical_model.exojax.components.base.AbstractTPProfilePower-law T-P profile:
T(P) = T_eq * P^alpha.The two parameters are PyTree leaves but they are passed to
compute_Tarr()as scalar args rather than being read fromselfso the atmosphere can vmap over per-planet axes without extra plumbing.- Attributes:
T_eq_K: Reference temperature at 1 bar [K], shape
(K,). T_alpha: Power-law exponent, shape(K,).
- T_eq_K: jaxtyping.Array#
- T_alpha: jaxtyping.Array#
- class skyscapes.physical_model.exojax.RayleighScattering[source]#
Bases:
skyscapes.physical_model.exojax.components.base.AbstractScatteringRayleigh scattering from tracked species + optional bulk residual.
Iterates over the atmosphere’s species tuple plus the bulk gas (if present), computing each gas’s contribution from its own
rayleigh_xsandmolmass. The bulk gas’s mass-mixing ratio is computed dynamically asmax(0, 1 - sum(tracked mmrs)).To disable per-species Rayleigh while keeping the bulk: set the species’
rayleigh_xsto zeros. To disable scattering entirely: useNullScattering.- compute(species, bulk, gravity, rt_engine, n_layers, n_nu)[source]#
Sum tracked-species + bulk-gas Rayleigh contributions.
Bulk gas mmr is computed per-layer as
max(0, 1 - sum(species profiles at this pressure)), so altitude variation of the tracked species translates into altitude variation of the bulk-gas residual.- Parameters:
species (tuple[skyscapes.physical_model.exojax.components.species.MolecularSpecies, Ellipsis])
bulk (skyscapes.physical_model.exojax.components.species.BulkGasResidual | None)
gravity (jaxtyping.Array)
n_layers (int)
n_nu (int)
- Return type:
skyscapes.physical_model.exojax.components.base.Contribution
- class skyscapes.physical_model.exojax.StratosphericPeakMmr[source]#
Bases:
AbstractMmrProfileGaussian-in-log-pressure peak; canonical for O3.
mmr(P) = 10**log_peak_mmr * exp(-0.5 * ((log10(P) - log_peak_pressure_bar) / log_sigma_decades)**2).For Earth’s O3:
log_peak_pressure_bar = log10(0.01) = -2(10 mbar, ~30 km altitude),log_sigma_decades = 0.5.- Attributes:
log_peak_mmr: Log10 of the peak mmr, shape
(K,). log_peak_pressure_bar: Log10 pressure [bar] at peak,(K,). log_sigma_decades: Gaussian width in log10-pressure,(K,).
- log_peak_mmr: jaxtyping.Array#
- log_peak_pressure_bar: jaxtyping.Array#
- log_sigma_decades: jaxtyping.Array#
- class skyscapes.physical_model.exojax.TroposphericMmr[source]#
Bases:
AbstractMmrProfileConstant below a step pressure, drops sharply above; canonical for H2O.
Uses a sigmoid in log-pressure for smooth transition (differentiable for HMC retrievals). For Earth’s H2O: tropospheric ~3e-3 below 0.1 bar, ~3e-6 above.
- Attributes:
log_mmr_below: Log10 mmr at high pressure (below cold trap),
(K,). log_mmr_above: Log10 mmr at low pressure (above cold trap),(K,). log_pressure_step_bar: Log10 transition pressure [bar],(K,). log_transition_width_decades: Width of the sigmoid transitionin log10-pressure,
(K,). Smaller = sharper step.
- log_mmr_below: jaxtyping.Array#
- log_mmr_above: jaxtyping.Array#
- log_pressure_step_bar: jaxtyping.Array#
- log_transition_width_decades: jaxtyping.Array#
- class skyscapes.physical_model.exojax.WavelengthDependentSurface[source]#
Bases:
skyscapes.physical_model.exojax.components.base.AbstractSurfaceWavelength-dependent surface reflectivity.
The bottom-of-atmosphere reflectivity is
10**log_albedo * spectrum: thelog_albedoPyTree leaf is a per-planet fittable scaling, andspectrumis a fixed wavelength-dependent profile (vegetation red-edge, water absorption, snow/ice, …) shared across planets.- Attributes:
log_albedo: Log10 surface albedo scaling per planet, shape
(K,). spectrum: Wavelength-dependent reflectivity profile,shape
(n_nu,). Defaults to flat ones for “no spectral shape; albedo is constant across the band”.
- log_albedo: jaxtyping.Array#
- spectrum: jaxtyping.Array#
- compute_refl(log_albedo_scalar, n_nu)[source]#
Return wavelength-dependent surface reflectivity.
n_nuis accepted for parity withFlatSurfacebut unused – the wavelength axis comes fromself.spectrum.- Parameters:
log_albedo_scalar (jaxtyping.Array)
n_nu (int)
- Return type:
jaxtyping.Array
- skyscapes.physical_model.exojax.build_bulk_prebuilt(*, name, nu_grid)[source]#
Construct (molmass, rayleigh_xs) for the implicit residual gas.
- skyscapes.physical_model.exojax.build_mie_cloud(*, nu_grid, log_pressure_bar, log_opt_depth, condensate='H2O', rg_um=10.0, sigmag=2.0, log_sigma=DEFAULT_CLOUD_LOG_SIGMA)[source]#
Build a Mie cloud component by pre-computing Mie params.
On first use for a given condensate this triggers two downloads / computations cached under
./.database/particulates/virga/:Refractive-index file (small, fetched from Zenodo).
Mie-grid lookup table (built locally via PyMieScatt; takes a couple of minutes per condensate). Subsequent calls reuse the cache.
- Args:
- nu_grid: Wavenumber grid [cm^-1] from
log_pressure_bar: Per-planet log10 cloud pressure [bar]. log_opt_depth: Per-planet log10 total cloud extinction tau. condensate: Condensate name. ExoJAX/Virga ships e.g.
"H2O","H2O_ice","NH3","MgSiO3","Mg2SiO4","Fe","KCl","Na2S","ZnS","MnS","Cr","Al2O3","TiO2".- rg_um: Mean particle radius [um] of the lognormal size
distribution.
sigmag: Geometric standard deviation of the size distribution. log_sigma: Vertical-distribution Gaussian half-width [dex].
- Returns:
A
MieCloudinstance ready to drop intoExoJaxPhysicalModel.
- skyscapes.physical_model.exojax.build_species_prebuilt(*, name, nu_grid, nu_min, nu_max, databases_dir, crit)[source]#
Construct (molmass, opa, rayleigh_xs) for one molecule.
Used by
build_exojax_engines; not typically called by users directly. Returns the static parts of aMolecularSpecies(everything exceptlog_mmr).
- skyscapes.physical_model.exojax.O3_MOLMASS = 47.9982#
- class skyscapes.physical_model.exojax.O3ChappuisOpacity(nu_grid, cache_dir=None, xs_table_path=None)[source]#
Bases:
skyscapes.physical_model.exojax.psg_xs.PsgCrossSectionOpacityPSG cross-section opacity for O3 (Serdyuchenko et al. 2014).
- Parameters:
nu_grid (jaxtyping.Array | numpy.ndarray)
cache_dir (str | pathlib.Path | None)
xs_table_path (str | pathlib.Path | None)
- skyscapes.physical_model.exojax.DEFAULT_MOLECULES: tuple[str, Ellipsis] = ('H2O', 'CO2', 'CH4', 'O2', 'O3')#
- class skyscapes.physical_model.exojax.ExoJaxPhysicalModel[source]#
Bases:
skyscapes.physical_model.base.AbstractPhysicalModelComposition-based reflected-light planet model over ExoJAX’s 2-stream RT.
- Per-planet state (PyTree leaves, fittable):
log_gravity_cgs: Log10 surface gravity [cm/s^2], shape
(K,). species: Tuple ofMolecularSpecies. Each species ownsits own
log_mmr(per-planet, shape(K,)). The number and identity of species is configurable viabuild_exojax_engines().bulk: Optional
BulkGasResidual(implicit residual gas).
Components (each owns its own per-planet PyTree leaves where applicable):
tp_profile: T-P profile component (e.g.
PowerLawTPProfile). absorption: Absorption orchestrator (e.g.Absorption). scattering: Scattering component (e.g.RayleighScattering,NullScattering).clouds: Cloud component (e.g.
GrayCloud,NoCloud). surface: Surface component (e.g.WavelengthDependentSurface).- Shared / configuration attributes:
rt_engine: ExoJAX
ArtReflectPureinstance. nu_grid: Wavenumber grid [cm^-1]. n_nu: Length ofnu_grid(static for JIT).
- log_gravity_cgs: jaxtyping.Array#
- species: tuple[skyscapes.physical_model.exojax.components.MolecularSpecies, Ellipsis]#
- rt_engine: Any#
- nu_grid: jaxtyping.Array#
- classmethod from_default_setup(*, log_mmrs, T_eq_K, T_alpha, log_surface_albedo, log_gravity_cgs, log_cloud_pressure_bar=None, log_cloud_opt_depth=None, surface_albedo_spectrum=None, molecules=None, bulk_gas='N2', wavelength_min_nm=400.0, wavelength_max_nm=1000.0, n_wavenumbers=2000, n_layers=100, pressure_top_bar=1e-05, pressure_btm_bar=1.0, databases_dir=None, crit=0.0)[source]#
One-shot convenience: build engines + default components in one call.
Defaults to Earth-like physics:
PowerLawTPProfile,Absorption,RayleighScatteringwith N2 bulk,GrayCloud(Earth water clouds), and a flatWavelengthDependentSurface.- Args:
- log_mmrs: Dict mapping molecule name to per-planet log10
mass-mixing ratio, shape
(K,)each. The dict’s molecules determine which species are built.
T_eq_K: Per-planet equatorial T [K],
(K,). T_alpha: Per-planet T-P power-law exponent,(K,). log_surface_albedo: Per-planet surface scaling,(K,). log_gravity_cgs: Per-planet log10 gravity,(K,). log_cloud_pressure_bar: Per-planet cloud-deck pressure,(K,). log_cloud_opt_depth: Per-planet cloud optical depth,(K,). surface_albedo_spectrum:(n_nu,)spectral profile.Defaults to flat ones.
- molecules: Override molecule list (default: derived from
log_mmrs.keys()).
bulk_gas: Implicit residual gas (default
"N2"). wavelength_min_nm: Seebuild_exojax_engines(). wavelength_max_nm: Seebuild_exojax_engines(). n_wavenumbers: Seebuild_exojax_engines(). n_layers: Seebuild_exojax_engines(). pressure_top_bar: Seebuild_exojax_engines(). pressure_btm_bar: Seebuild_exojax_engines(). databases_dir: Seebuild_exojax_engines(). crit: Seebuild_exojax_engines().
- Parameters:
T_eq_K (jaxtyping.Array)
T_alpha (jaxtyping.Array)
log_surface_albedo (jaxtyping.Array)
log_gravity_cgs (jaxtyping.Array)
log_cloud_pressure_bar (jaxtyping.Array | None)
log_cloud_opt_depth (jaxtyping.Array | None)
surface_albedo_spectrum (jaxtyping.Array | None)
bulk_gas (str | None)
wavelength_min_nm (float)
wavelength_max_nm (float)
n_wavenumbers (int)
n_layers (int)
pressure_top_bar (float)
pressure_btm_bar (float)
databases_dir (str | None)
crit (float)
- Return type:
- classmethod from_default_setup_cached(*, log_mmrs, T_eq_K, T_alpha, log_surface_albedo, log_gravity_cgs, log_cloud_pressure_bar=None, log_cloud_opt_depth=None, surface_albedo_spectrum=None, molecules=None, bulk_gas='N2', wavelength_min_nm=400.0, wavelength_max_nm=1000.0, n_wavenumbers=2000, n_layers=100, pressure_top_bar=1e-05, pressure_btm_bar=1.0, databases_dir=None, crit=0.0, cache_dir=None)[source]#
Cached one-shot factory: returns a fast
PrecomputedPhysicalModel.Hashes every input and looks up a cached spectrum on disk. On cache hit, returns the cached spectrum in ~10 ms. On cache miss, builds the full
ExoJaxPhysicalModelviafrom_default_setup(), runs the 2-stream RT once, precomputes the reflectivity, saves to disk, and returns thePrecomputedPhysicalModel.Use this when the physical-model parameters are fixed across many evaluations (coronagraphoto sims, ETC studies). For HMC retrievals where parameters vary, use
from_default_setup()directly.- Args:
- cache_dir: Override the cache directory. Defaults to
~/.cache/skyscapes/physical_models/.
log_mmrs: See
from_default_setup(). T_eq_K: Seefrom_default_setup(). T_alpha: Seefrom_default_setup(). log_surface_albedo: Seefrom_default_setup(). log_gravity_cgs: Seefrom_default_setup(). log_cloud_pressure_bar: Seefrom_default_setup(). log_cloud_opt_depth: Seefrom_default_setup(). surface_albedo_spectrum: Seefrom_default_setup(). molecules: Seefrom_default_setup(). bulk_gas: Seefrom_default_setup(). wavelength_min_nm: Seefrom_default_setup(). wavelength_max_nm: Seefrom_default_setup(). n_wavenumbers: Seefrom_default_setup(). n_layers: Seefrom_default_setup(). pressure_top_bar: Seefrom_default_setup(). pressure_btm_bar: Seefrom_default_setup(). databases_dir: Seefrom_default_setup(). crit: Seefrom_default_setup().- Returns:
A
PrecomputedPhysicalModelwith no RT cost at evaluation time.
- Parameters:
log_mmrs (dict[str, jaxtyping.Array | skyscapes.physical_model.exojax.components.AbstractMmrProfile])
T_eq_K (jaxtyping.Array)
T_alpha (jaxtyping.Array)
log_surface_albedo (jaxtyping.Array)
log_gravity_cgs (jaxtyping.Array)
log_cloud_pressure_bar (jaxtyping.Array | None)
log_cloud_opt_depth (jaxtyping.Array | None)
surface_albedo_spectrum (jaxtyping.Array | None)
bulk_gas (str | None)
wavelength_min_nm (float)
wavelength_max_nm (float)
n_wavenumbers (int)
n_layers (int)
pressure_top_bar (float)
pressure_btm_bar (float)
databases_dir (str | None)
crit (float)
cache_dir (str | pathlib.Path | None)
- Return type:
- _reflectivity_one_planet(k)[source]#
Plane-parallel reflectivity for the k-th planet, shape
(n_nu,).Indexes every K-shaped leaf at position
k(cheap; JIT traces this as plain array indexing). With per-species mmr profiles the previous “vmap over an extracted log_mmrs array” pattern broke because different profile types have different K-shaped fields – a Python loop over K avoids that issue without losing JIT efficiency at K=1 (the common case).- Parameters:
k (int)
- Return type:
jaxtyping.Array
- _reflectivity_all_planets()[source]#
Plane-parallel reflectivity for every planet, shape
(K, n_nu).Loops over K planets in Python. JIT unrolls the loop; for the common K=1 case this is a single iteration with no overhead. For HMC retrievals (K=1 per sample), the JIT cache is reused across MCMC steps.
- Return type:
jaxtyping.Array
- contrast(phase_angle_rad, dist_AU, wavelength_nm, Rp_Rearth)[source]#
Per-planet, per-time geometric-albedo contrast at one wavelength.
- Args:
phase_angle_rad: Star-planet-observer phase angle,
(K, T). dist_AU: Star-planet distance [AU],(K, T). wavelength_nm: Scalar wavelength [nm]. Rp_Rearth: Planet radius [Earth radii], shape(K,).- Returns:
Contrast =
A_g(lambda) * Lambert_phase(beta) * (Rp/d)^2, shape(K, T). The 2-stream RT produces the plane- parallel (spherical) reflectivity; we convert to geometric albedo via the Lambertian-sphere factor 2/3 (Seager 2010, eq 3.36) so the output is a geometric-albedo contrast – the same convention asLambertianPhysicalModel.
- Parameters:
phase_angle_rad (jaxtyping.Array)
dist_AU (jaxtyping.Array)
wavelength_nm (jaxtyping.Array)
Rp_Rearth (jaxtyping.Array)
- Return type:
jaxtyping.Array
- contrast_cube(phase_angle_rad, dist_AU, wavelengths_nm, Rp_Rearth)[source]#
Per-planet, per-time contrast across many wavelengths.
Returns
(W, K, T)geometric-albedo contrast cube. Computes the underlying 2-stream RT exactly once per planet rather than once per wavelength; applies the spherical-to-geometric Lambertian-sphere conversion (Seager 2010, eq 3.36) the same way ascontrast().- Parameters:
phase_angle_rad (jaxtyping.Array)
dist_AU (jaxtyping.Array)
wavelengths_nm (jaxtyping.Array)
Rp_Rearth (jaxtyping.Array)
- Return type:
jaxtyping.Array
- skyscapes.physical_model.exojax.build_exojax_engines(*, molecules=DEFAULT_MOLECULES, bulk_gas='N2', wavelength_min_nm=400.0, wavelength_max_nm=1000.0, n_wavenumbers=2000, n_layers=100, pressure_top_bar=1e-05, pressure_btm_bar=1.0, databases_dir=None, crit=0.0)[source]#
Build the heavy shared engines and pre-built per-species data.
Each molecule’s opacity engine (line-list LSD tables or cross- section interpolant) is built once here and reused across many atmosphere instantiations that vary only the per-planet
log_mmrs. The retrieval-friendly construction pattern is:engines = build_exojax_engines(molecules=("H2O", "CO", "O2")) def make_atmosphere(per_planet_log_mmrs): return ExoJaxPhysicalModel.from_default_setup( log_mmrs=per_planet_log_mmrs, ..., **engines )
- Args:
- molecules: Tuple of molecule names to include. Must all appear
in
MOLECULE_RECIPES. Default is the 5-molecule biosignature set.- bulk_gas: Implicit residual gas name (
"N2","H2", "He"), orNoneto disable the bulk-gas Rayleigh contribution. Default"N2"for terrestrial atmospheres.
wavelength_min_nm: Short-wavelength end of the spectral range [nm]. wavelength_max_nm: Long-wavelength end of the spectral range [nm]. n_wavenumbers: Number of points in the wavenumber grid. n_layers: Number of layers in the plane-parallel RT solver. pressure_top_bar: Pressure at the top of the model [bar]. pressure_btm_bar: Pressure at the bottom of the model [bar]. databases_dir: ExoJAX line-list cache. crit: Line-strength cutoff [cm/(molecule.cm^-2)] passed to
MdbHitran(default0.0= no filtering). Setcrit=1e-26for ~25% speedup at HWO contrast levels.- Returns:
Dict ready to be
**-unpacked intoExoJaxPhysicalModel. Keys:rt_engine,nu_grid,n_nu,species_prebuilt(dict mapping name to{molmass, opa, rayleigh_xs}),bulk_prebuilt(dict with{name, molmass, rayleigh_xs}orNone).
- skyscapes.physical_model.exojax.vmr_dict_to_earth_profile_dict(vmrs, K=1, bulk_gas='N2')[source]#
VMRs -> dict of Earth-realistic profiles per species.
Most species get a
ConstantMmr(well-mixed assumption). For H2O and O3, where Earth’s altitude profile differs sharply from uniform, the function builds:H2O:
TroposphericMmrwith the supplied VMR below the cold trap and a 3-decade drop above (parametrized atP = 0.1 bar).O3:
StratosphericPeakMmrwith the supplied VMR as the peak value atP = 10 mbar(Gaussian width 0.5 dex).
All values are taken from canonical Earth-atmosphere structure – customize by constructing your own profile dict if you need to fit per-planet profile parameters in an HMC retrieval.
- Args:
- vmrs:
{name: VMR}; H2O VMR is interpreted as the tropospheric value, O3 VMR as the stratospheric peak.
K: Number of planets (per-planet broadcasting). bulk_gas: Implicit residual gas name.
- vmrs:
- Returns:
{name: AbstractMmrProfile}ready to pass aslog_mmrs=toExoJaxPhysicalModel.from_default_setup().
- skyscapes.physical_model.exojax.vmr_dict_to_log_mmr_dict(vmrs, K=1, bulk_gas='N2')[source]#
Convert VMR dict to log10 MMR dict with K-shaped arrays.
Each value in the returned dict is shape
(K,)so it can be passed directly aslog_mmrs=toExoJaxPhysicalModel.from_default_setup(). The same VMR is used for every planet – to give per-planet variation, modify the returned arrays before constructing the atmosphere.Every species gets a
ConstantMmrprofile by default (uniform mmr at every altitude). For Earth-realistic profiles (O3 stratospheric peak, H2O cold-trap drop) usevmr_dict_to_earth_profile_dict()instead.
- skyscapes.physical_model.exojax.vmr_dict_to_mmr_dict(vmrs, bulk_gas='N2')[source]#
Convert volume-mixing-ratio dict to mass-mixing-ratio dict.
Computes mean molecular weight from the supplied VMRs plus the bulk-gas residual (mmr_bulk = 1 - sum(vmrs_tracked), in VMR space; then convert all to mass). Used internally by
vmr_dict_to_log_mmr_dict(); exposed here for inspection.- Args:
- vmrs:
{name: VMR}for tracked molecules. Sum must be < 1 (the residual is the bulk gas).
- bulk_gas: Name of the implicit residual gas (
"N2"for terrestrial atmospheres,
"H2"for gas giants, …). Must appear inBULK_GAS_RECIPES.
- vmrs:
- Returns:
{name: MMR}for the tracked molecules. The bulk gas’s MMR is not returned –ExoJaxPhysicalModelcomputes it dynamically as the residual.
- class skyscapes.physical_model.exojax.PsgCrossSectionOpacity(name, url, molmass, nu_grid, cache_dir=None, xs_table_path=None, cache_filename=None)[source]#
Cross-section-backed opacity from any PSG xs file.
Quacks like ExoJAX’s
OpaPremodit: exposesxsmatrix(Tarr, pressure) -> (n_layers, n_nu)and amolmassattribute, so it slots into the sameopa_enginestuple as the line-list-backed opacity engines.Pressure broadening is ignored. The PSG cross-section files describe electronic-continuum / pre-broadened absorption; the pressure-dependence at typical atmospheric pressures is below the photon-noise floor for HWO contrast levels. Temperature interpolation is linear against the file’s temperature axis, with out-of-range temperatures clamped to the nearest endpoint.
For files with a single temperature column the cross-section is returned independent of layer temperature.
- Attributes:
name: Molecule name (e.g.
"O3","SO2"). molmass: Molar mass [g/mol]. Caller supplies; used byopacity_profile_xsto convert mmr to column density.nu_grid: Wavenumber grid [cm^-1] this adapter was built for.
- Parameters:
name (str)
url (str)
molmass (float)
nu_grid (jaxtyping.Array | numpy.ndarray)
cache_dir (str | pathlib.Path | None)
xs_table_path (str | pathlib.Path | None)
cache_filename (str | None)
- name#
- molmass#
- nu_grid#
- _T_grid#
- _sigma_at_nu#
- xsmatrix(Tarr, pressure)[source]#
Cross-section matrix at the requested layer temperatures.
pressureis accepted for interface parity withOpaPremoditbut is unused.- Args:
Tarr: Layer temperatures [K], shape
(n_layers,). pressure: Layer pressures [bar], shape(n_layers,);ignored.
- Returns:
Cross-section matrix [cm^2/molecule], shape
(n_layers, n_nu). Temperatures outside the PSG file’s range clamp to the nearest endpoint cross-section. For single-temperature files the returned matrix is constant in T.
- Parameters:
Tarr (jaxtyping.Array)
pressure (jaxtyping.Array)
- Return type:
jaxtyping.Array