The Atmospheric State#
The atmospheric state at it’s fundamental core is:
Extinction specified on the model geometry grid points.
Single scatter albedo specified on the model geometry grid points.
(optional) Scattering parameters (Legendre coefficients, phase functions) specified at the model geometry grid points
A representation of surface scattering (e.g. Lambertian surface)
It is possible to directly specify these quantities, however the easier way to use the model is through what we refer to as constituents.
Note
SASKTRAN2 is designed to perform efficient calculations for a static geometry and
multiple atmospheric states. For this reason all atmospheric optical quantities contain
an explicit wavelength dimension. Instead of extinction being a 1-D array at the geometry
grid points, it is a 2-D array (wavelength, geometry).
We refer to this dimension as the wavelength dimension
because that is most commonly what it is, but in reality it can be any dimension where the
atmospheric state varies.
Setting the Atmosphere from Constituents#
Most of the time the easiest way to construct the atmosphere is using
something that we call the constituent interface. All this means is
that the atmosphere is constructed in pieces through objects called constituents rather than all at once.
An example constituent could be Rayleigh scattering, or ozone absorption, or a Lambertian surface.
We start by setting up our sasktran2.Atmosphere object
import numpy as np
import sasktran2 as sk
model_geometry = sk.Geometry1D(cos_sza=0.6,
solar_azimuth=0,
earth_radius_m=6372000,
altitude_grid_m=np.arange(0, 65001, 1000),
interpolation_method=sk.InterpolationMethod.LinearInterpolation,
geometry_type=sk.GeometryType.Spherical)
config = sk.Config()
wavel = np.arange(280.0, 800.0, 0.1)
atmosphere = sk.Atmosphere(model_geometry, config, wavelengths_nm=wavel)
Note that here we have explicity passed the wavelength_nm parameter to the atmospheric state.
Most atmospheric constituents require that the wavelength (or wavenumber) is known in order to look up
things like cross sections from databases. On the same token, most constituents require that atmospheric
temperature and/or pressure is known for similar reasons, we can add that to the atmosphere
sk.climatology.us76.add_us76_standard_atmosphere(atmosphere)
atmosphere.pressure_pa
atmosphere.temperature_k
array([288.15 , 281.65 , 275.15 , 268.66 , 262.17 , 255.68 , 249.19 ,
242.7 , 236.21 , 229.73 , 223.25 , 221.93 , 220.61 , 219.29 ,
217.97 , 216.65 , 216.65 , 216.65 , 216.65 , 216.65 , 216.65 ,
217.63 , 218.61 , 219.59 , 220.57 , 221.55 , 222.542, 223.534,
224.526, 225.518, 226.51 , 228.894, 231.278, 233.662, 236.046,
238.43 , 240.814, 243.198, 245.582, 247.966, 250.35 , 252.38 ,
254.41 , 256.44 , 258.47 , 260.5 , 262.53 , 264.56 , 266.59 ,
268.62 , 270.65 , 268.287, 265.924, 263.561, 261.198, 258.835,
256.472, 254.109, 251.746, 249.383, 247.02 , 244.276, 241.532,
238.788, 236.044, 233.3 ])
In this case we used one of SASKTRAN2’s built in climatologies to set temperature/pressure. Alternatively
the properties sasktran2.Atmosphere.pressure_pa and sasktran2.Atmosphere.temperature_k
can be directly accessed and set to any user desired values.
Now that our base atmosphere is constructed, we can start adding constituents
atmosphere["rayleigh"] = sk.constituent.Rayleigh()
will add Rayleigh scattering to the atmosphere. If we want to add ozone absorption with a constant VMR profile of 1ppm, we can do,
alt_grid = np.arange(0, 100001, 10000)
atmosphere["ozone"] = sk.constituent.VMRAltitudeAbsorber(
optical_property=sk.optical.O3DBM(),
altitudes_m=alt_grid,
vmr=np.ones_like(alt_grid) * 1e-6
)
There are a few things to pay attention to here. The first is that the altitude grid is different
than our global geometry grid. Constituents aren’t limited to being specified on the global geometry grid,
interpolation to this grid will be internally performed at some stage though. The second thing is that we provided
something known as an optical property. An optical property is, in essence, a database of particle
cross sections and possibly scattering properties.
Once a constituent is added to the atmosphere it is possible to access it directly and modify it
atmosphere["ozone"].vmr *= 2
print(atmosphere["ozone"].vmr)
[2.e-06 2.e-06 2.e-06 2.e-06 2.e-06 2.e-06 2.e-06 2.e-06 2.e-06 2.e-06
2.e-06]
Available Constituents#
|
An implementation of Rayleigh scattering. |
An atmospheric constituent that is specified through volume mixing ratio (VMR) on an altitude grid. |
|
A scattering constituent that is defined by a number density on an altitude grid and an optical property |
|
A scattering constituent that is defined by a number density on an altitude grid and an optical property |
|
A constituent that is defined by a gaussian-shaped extinction profile. |
|
A Lambertian surface that is defined by albedo at discrete grid points. |