Go to notebook file


[1]:
%reload_ext eradiate.notebook.tutorials

Last updated: 2024-03-07 15:49 (eradiate v0.25.1.dev31+g2a83b0ba.d20240229)

Molecular atmosphere basics#

Overview

In this tutorial, we introduce Eradiate’s molecular atmosphere simulation features.

Prerequisites

What you will learn

  • How to configure a standard 1D atmospheric profile.

  • How to rescale the atmospheric composition of standard profiles to fit more current data.


Importing modules#

We start by importing the eradiate, numpy and matplotlib.pyplot modules. Additionally, we load the Eradiate IPython extension for a smoother notebook experience.

[2]:
%load_ext eradiate
import eradiate
import joseki
import numpy as np
import matplotlib.pyplot as plt

We also import the MolecularAtmosphere class and alias the unit registry for convenience:

[3]:
from eradiate.scenes.atmosphere import MolecularAtmosphere
from eradiate import unit_registry as ureg

Introduction#

Eradiate’s MolecularAtmosphere represents a one-dimensional clear-sky—i.e. no clouds neither aerosols—atmosphere.

MolecularAtmosphere is mainly characterised by two attributes:

  • absorption_data: one or multiple datasets tabulating the air volume absorption coefficient against thermophysical properties and spectral coordinates.

  • thermoprops: the atmosphere’s thermophysical properties profile, namely a dataset that tabulates the thermophysical properties (air pressure, air temperature and air constituents’ mole fraction) against altitude.

The default value for absorption_data depends on the active mode:

  • in monochromatic mode, a low-resolution (wavenumber step: 1 cm⁻¹) monochromatic absorption dataset covering the wavelength range [250, 3125] nm, is selected. It includes H2O, CO2 and O3 as air constituents.

  • in CKD mode, an absorption dataset suitable for the use of the correlated \(k\)-distribution method in the wavenumber band [18100, 18200] cm⁻¹, i.e. [549.45, 552.48] nm wavelength range, is selected. This dataset is part of a collection of datasets covering the wavenumber range [3200, 40000] cm⁻¹, each dataset corresponding to one 100 cm⁻¹ wide band.

Changing the value for absorption_data might be necessary to select the datasets relevant to the desired working spectral range. The attribute accepts datasets from the Eradiate online data store as well as external datasets as long as they comply with the absorption dataset schema (see Absorption data).

The default value for thermoprops is set to produce the AFGL (1986) U.S. Standard profile on a regular altitude grid from 0 to 120 km with a step of 1 km, without the so-called additional molecules [Anderson et al., 1986]. Changing the thermoprops allows one to select among different standard profiles, including customizing their altitude grid or rescaling their total amounts of different air constituents, e.g. carbon dioxide, but also to load a customized profile of their own.

Let us instanciate the default MolecularAtmosphere in monochromatic mode:

[4]:
eradiate.set_mode("mono")

us_standard = MolecularAtmosphere()

Inspection of the object reveals that the absorption_data attribute maps each absorption dataset to its wavelength range.

[5]:
us_standard
[5]:

MolecularAtmosphere(
    id='atmosphere',
    geometry=PlaneParallelGeometry(
        toa_altitude=120.0 km,
        ground_altitude=0.0 km,
        zgrid=ZGrid(
            levels=[0.0 100.0 200.0 ... 119800.0 119900.0 120000.0] m,
            _layers=[50.0 150.0 250.0 ... 119750.0 119850.0 119950.0] m,
            _layer_height=100.0 m,
            _total_height=120000.0 m
        ),
        width=1000000.0 km
    ),
    scale=None,
    absorption_data=[250.00 3125.00] nm: <xarray.Dataset | source='/home/leroyv/Documents/src/rayference/rtm/eradiate/resources/data/stable/spectra/absorption/mono/komodo/komodo.nc'>,
    _thermoprops=<xarray.Dataset>,
    _phase=RayleighPhaseFunction(id='phase_atmosphere'),
    has_absorption=True,
    has_scattering=True,
    error_handler_config={
        'x': {'missing': 'ignore', 'scalar': 'ignore', 'bounds': 'raise'},
        'p': {'missing': 'raise', 'scalar': 'raise', 'bounds': 'ignore'},
        't': {'missing': 'raise', 'scalar': 'raise', 'bounds': 'ignore'}
    }
)

Inspection of the thermoprops attribute returns the thermophysical properties profile corresponding to the U.S. Standard profile without additional molecules and interpolated on a regular altitude grid from 0 to 120 km with a 1 km step (the original profile is tabulated a slightly coarser and irregular grid) [Anderson et al., 1986].

[6]:
us_standard.thermoprops
[6]:
<xarray.Dataset> Size: 11kB
Dimensions:  (z: 121)
Coordinates:
  * z        (z) float64 968B 0.0 1.0 2.0 3.0 4.0 ... 117.0 118.0 119.0 120.0
Data variables:
    p        (z) float64 968B 1.013e+05 8.988e+04 7.95e+04 ... 0.002834 0.00254
    t        (z) float64 968B 288.2 281.7 275.2 268.7 ... 336.0 348.0 360.0
    n        (z) float64 968B 2.548e+25 2.313e+25 ... 6.029e+17 5.114e+17
    x_H2O    (z) float64 968B 0.00775 0.00607 0.00463 ... 2.08e-07 2e-07
    x_O3     (z) float64 968B 2.66e-08 2.93e-08 3.24e-08 ... 1.4e-09 5e-10
    x_N2O    (z) float64 968B 3.2e-07 3.2e-07 3.2e-07 ... 1.904e-10 1.85e-10
    x_CO     (z) float64 968B 1.5e-07 1.45e-07 1.4e-07 ... 4.83e-05 5e-05
    x_CH4    (z) float64 968B 1.7e-06 1.7e-06 1.7e-06 ... 4.2e-08 3.6e-08 3e-08
    x_CO2    (z) float64 968B 0.00033 0.00033 0.00033 ... 3.6e-05 3.5e-05
    x_O2     (z) float64 968B 0.209 0.209 0.209 0.209 ... 0.0811 0.0768 0.0725
Attributes:
    Conventions:  CF-1.10
    title:        AFGL (1986) us-standard atmosphere thermophysical profile
    institution:  Air Force Geophysics Laboratory
    source:       Atmospheric model (U.S. Standard Atmosphere) adapted from s...
    history:      2024-03-07T14:49:33 - dataset interpolation by joseki, vers...
    references:   Anderson, G.P. and Chetwynd J.H. and Clough S.A. and Shettl...
    url:          https://archive.org/details/DTIC_ADA175173
    urldate:      2022-12-12

This profile specifies the input thermophysical parameters to the functions computing the atmosphere’s radiative properties, notably the volume scattering and absorption coefficients. These radiative properties are computed on the atmosphere’s altitude grid under the corresponding thermophysical conditions and together with the atmosphere’s spatial extension, they completely describe the participating medium for ray tracing computations.

Instanciating the MolecularAtmosphere class in CKD mode this time:

[7]:
eradiate.set_mode("ckd")

us_standard = MolecularAtmosphere()

Modifying the thermophysical profile#

Thermophysical profiles are managed by the joseki library. This library makes available a collection of standard atmospheric profiles in a format convenient for Eradiate. It comes with various functionalities to modify a given profile as well as to compute characteristic quantities of a profile.

Setting the standard profile#

Joseki references several standard profiles with identifiers. For example, the U.S. Standard atmosphere is associated the identifier afgl_1986-us_standard. When setting the thermoprops parameter, a specification dictionary may be passed wherein the identifier value can be set. For example, the default U.S. Standard thermophysical profile is selected with:

[8]:
us_standard = MolecularAtmosphere(
    thermoprops={
        "identifier": "afgl_1986-us_standard",
        "z": np.linspace(0.0, 120.0, 121) * ureg.km,
    },
)

Use another standard profile by setting identifier to another value, e.g. "afgl_1986-midlatitude_summer":

[9]:
midlatitude_summer = MolecularAtmosphere(
    thermoprops={
        "identifier": "afgl_1986-midlatitude_summer",
        "z": np.linspace(0.0, 120.0, 121) * ureg.km,
    },
)

List all available identifiers with joseki.identifiers().

Setting the altitude grid#

A common profile customization involves changing the altitude grid that the thermophysical profile is discretized on. You can create a high resolution version of the profile by decreasing the altitude step for example:

[10]:
us_standard = MolecularAtmosphere(
    thermoprops={
        "identifier": "afgl_1986-us_standard",
        "z": np.linspace(0.0, 120.0, 12001) * ureg.km,  # 10 meter step
    },
)

Alternatively, you can modify the altitude grid so as to truncate the profile from the top:

[11]:
us_standard = MolecularAtmosphere(
    thermoprops={
        "identifier": "afgl_1986-us_standard",
        "z": np.linspace(0.0, 50.0, 51) * ureg.km,  # atmosphere now extends up to 50 km
    },
)

Rescaling#

Another typical profile modification is to rescale the total amount of specific air constituents, e.g. carbon dioxide. The carbon dioxide mole fraction in the AFGL 1986 standard profiles is almost constant with altitude and equal to 334 parts per million (ppm), i.e. 0.000334. Update the atmospheric carbon dioxide content, to e.g. 400 ppm, as illustrated below:

[12]:
# First, create the original standard profile:
thermoprops = joseki.make(
    identifier="afgl_1986-us_standard",
    z=np.linspace(0.0, 120.0, 121) * ureg.km,
)

# Then, rescale it:
rescaled = thermoprops.joseki.rescale(
    factors={
        "CO2": 400 / 334,
    }
)

# Finally instanciate the MolecularAtmosphere class with the rescaled
# thermophysical profile
us_standard = MolecularAtmosphere(
    thermoprops=rescaled,
)

Additional settings#

Refer to the joseki documentation for further details.

Setting the absorption data#

The absorption_data parameter accepts multiple input types. Refer to the MolecularAtmosphere API to explore your options. After the MolecularAtmosphere object is built, the attribute absorption_data contains a mapping of absorption dataset and their wavelength range. Special care must be taken that absorption datasets are able to accomodate the range of thermophysical parameters in thermoprops. If you are planning to use absorption datasets shipped with Eradiate, a convenient way to set absorption_data is to use a tuple that contains a dataset codename and the desired working wavelength range.

For example, in CKD mode, if you wish to work within the [635, 685] nm:

[13]:
eradiate.set_mode("ckd")

us_standard = MolecularAtmosphere(
    absorption_data=("monotropa", [635.0, 685.0] * ureg.nm)
)

Disabling absorption or scattering#

The absorption or scattering coefficient can be forced to 0 using the has_absorption and has_scattering switches. The following atmosphere definition has no absorption, only scattering:

[14]:
scattering_only_atmosphere = MolecularAtmosphere(
    has_absorption=False,
    has_scattering=True,
)

Final words#

The various customisation options we explored in this tutorial can be used in all the experiments with support for molecular atmospheres.

Further reading#