[1]:
%reload_ext eradiate.notebook.tutorials
Last updated: 2023-01-26 09:24 (eradiate v0.22.6.dev24+ge8e434d7.d20221118)
Molecular atmosphere basics#
Overview
In this tutorial, we introduce Eradiate’s molecular atmosphere simulation features.
Prerequisites
Ability to run and visualise 1D simulations (see First steps with Eradiate).
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 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
We will perform simulations in narrow bands using Eradiate’s correlated-k distribution mode (ckd
). There is indeed little point performing monochromatic simulations, at least in this tutorial: running such simulations to compute the signal recorded for a given spectral band is very costly, and the CKD method brings in a significant speed-up.
[4]:
eradiate.set_mode("ckd")
Creating a standard molecular atmosphere#
The most obvious way to configure a molecular atmospheric profile would be to call the MolecularAtmosphere
constructor; however, proper initialisation of standard profiles is supposed to be done using specialised class method constructors. In CKD mode, the AFGL 1986 reference atmospheres [Anderson et al., 1986] are supported and created using the MolecularAtmosphere.afgl_1986()
class method:
[5]:
us_standard_atmosphere = MolecularAtmosphere.afgl_1986()
We just instantiated an molecular atmosphere object with default parameters. It notably uses the “U.S. Standard” reference atmospheric profile, default molecular density values and discretises the atmosphere vertically in 120 1 km-thick layers:
[6]:
us_standard_atmosphere
MolecularAtmosphere( id='atmosphere', geometry=PlaneParallelGeometry(width=1000000.0 km), scale=None, _thermoprops=<xarray.Dataset> Dimensions: (z_level: 121, z_layer: 120, species: 7) Coordinates: * z_level (z_level) float64 0.0 1.0 2.0 3.0 4.0 ... 117.0 118.0 119.0 120.0 * z_layer (z_layer) float64 0.5 1.5 2.5 3.5 4.5 ... 116.5 117.5 118.5 119.5 * species (species) object 'H2O' 'O3' 'N2O' 'CO' 'CH4' 'CO2' 'O2' Data variables: p (z_layer) float64 9.559e+04 8.469e+04 ... 0.002981 0.002687 t (z_layer) float64 284.9 278.4 271.9 265.4 ... 330.0 342.0 354.0 n (z_layer) float64 2.43e+25 2.203e+25 ... 6.486e+17 5.571e+17 mr (species, z_layer) float64 0.00691 0.00535 ... 0.07895 0.07465 Attributes: convention: CF-1.8 title: AFGL (1986) U.S. Standard atmosphere thermophysical properties history: 2021-05-19 17:37:17 - data creation - shicho.afgl86.make_dat... source: Atmospheric model (U.S. Standard Atmosphere) adapted from sa... references: Anderson, G.P. and Chetwynd J.H. and Clough S.A. and Shettle... comment: raw data was linearly interpolated on a regular layer altitu... identifier: afgl_1986-us_standard, phase=RayleighPhaseFunction(id='phase_atmosphere'), has_absorption=True, has_scattering=True, absorption_data_sets=None )
Eradiate supports the 6 AFGL reference atmospheres (see the MolecularAtmosphere.afgl_1986()
API documentation for the complete list). We can visualise the pressure and temperature profiles:
[7]:
def show_profile(*atmospheres, labels=None):
from matplotlib.ticker import ScalarFormatter
if labels is None:
label_iter = iter([None for _ in atmospheres])
else:
label_iter = iter(labels)
fig, axs = plt.subplots(1, 2, sharey=True)
for atmosphere in atmospheres:
temperature = atmosphere.radprops_profile.thermoprops.t
pressure = atmosphere.radprops_profile.thermoprops.p
with plt.rc_context({"lines.linestyle": ":", "lines.marker": "."}):
temperature.plot(y="z_layer", ax=axs[0])
pressure.plot(y="z_layer", ax=axs[1], label=next(label_iter))
formatter = ScalarFormatter(useMathText=True)
formatter.set_powerlimits((-3,2))
axs[1].xaxis.set_major_formatter(formatter)
axs[1].set_ylabel("")
if labels is not None:
fig.legend(
bbox_to_anchor=(1.0, 0.5),
loc="center left",
borderaxespad=0.0,
)
plt.tight_layout()
plt.show()
plt.close()
show_profile(us_standard_atmosphere)

The reference atmosphere is controlled by the model
parameter. For instance, the Midlatitude Summer reference atmosphere can be obtained with the midlatitude_summer
value. Let’s add it to our plot:
[8]:
midlatitude_summer_atmosphere = MolecularAtmosphere.afgl_1986(
model="midlatitude_summer"
)
show_profile(
us_standard_atmosphere,
midlatitude_summer_atmosphere,
labels=["U.S. Standard", "Midlatitude Summer"],
)

Changing the altitude grid#
The altitude grid can be specified manually using the levels
parameter. To change the number of levels to 26 (25 layers) and have the profile extend between 0 and 100 km, we simply have to write:
[9]:
us_standard_atmosphere_custom = MolecularAtmosphere.afgl_1986(
model="us_standard",
levels=np.linspace(0, 100, 26) * ureg.km,
)
[10]:
show_profile(us_standard_atmosphere_custom)

tutorials/getting_started/molecular_atmosphere.ipynb## Rescaling species concentration values
Arguably, reference atmospheric profiles are not always appropriate. In particular, the chemical composition of the atmosphere significantly varies as a function of time and location. Eradiate can vary reference profiles by rescaling species concentrations to account for the effects of a changing atmospheric composition. This is done using the concentrations
parameter. The following example varies the U.S. Standard atmosphere by setting:
the column mass density of water vapour to 15 kg / m²,
the volume mixing ratio of CO₂ at sea level to 400 ppm,
the column number density of O₃ to 350 Dobson units.
[11]:
us_standard_atmosphere_custom = MolecularAtmosphere.afgl_1986(
model="us_standard",
concentrations={
"H2O": 15.0 * ureg.kg / ureg.m ** 2, # column mass density
"CO2": 400e-6 * ureg.dimensionless, # volume mixing fraction at sea level
"O3": 350.0 * ureg.dobson_units, # column number density
},
)
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 Rayleigh scattering:
[12]:
rayleigh_atmosphere = MolecularAtmosphere.afgl_1986(
has_absorption=False, has_scattering=True
)
What about the monochromatic mode?#
In mono
mode, the AFGL 1986 atmospheric profiles are not supported. We provide instead the simpler U.S. Standard Atmosphere (1976) [NASA et al., 1976], which lacks many species contributing to radiative processes. This profile is accessed using the MolecularAtmosphere.ussa_1976()
class method:
[13]:
us76_atmosphere = MolecularAtmosphere.ussa_1976()
Profile customisation options are similar to those of the AFGL 1986 profiles.
Final words#
The various instantiation and customisation options we explored in this tutorial can be used in all the experiments supporting 1D atmospheric profiles.