Source code for skyscapes.physical_model.exojax.components.surface
"""Surface reflectivity components."""
from __future__ import annotations
import jax.numpy as jnp
from jaxtyping import Array
from .base import AbstractSurface
[docs]
class WavelengthDependentSurface(AbstractSurface):
"""Wavelength-dependent surface reflectivity.
The bottom-of-atmosphere reflectivity is
``10**log_albedo * spectrum``: the ``log_albedo`` PyTree leaf is a
per-planet fittable scaling, and ``spectrum`` is 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: Array
spectrum: Array
[docs]
def compute_refl(self, log_albedo_scalar: Array, n_nu: int) -> Array:
"""Return wavelength-dependent surface reflectivity.
``n_nu`` is accepted for parity with :class:`FlatSurface` but
unused -- the wavelength axis comes from ``self.spectrum``.
"""
return (10.0**log_albedo_scalar) * self.spectrum
[docs]
class FlatSurface(AbstractSurface):
"""Wavelength-independent (gray) Lambertian surface.
Equivalent to ``WavelengthDependentSurface`` with 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: Array
[docs]
def compute_refl(self, log_albedo_scalar: Array, n_nu: int) -> Array:
"""Return scalar albedo broadcast across the wavenumber grid."""
return (10.0**log_albedo_scalar) * jnp.ones(n_nu)