Engine

Module: sasktran.engine

Engines are objects that can calculate radiances. Some of these engines can also calculate analytic or optimized Weighting Functions. One of the primary design objectives of SASKTRAN is to build a flexible radiative transfer framework so that the different components of a radiative transfer calculation are as modular as possible. This is our motivation for calling these objects engines as opposed to radiative transfer algorithms.

SASKTRAN’s primary engine product is SASKTRAN HR.

Base Class

Engines require a Geometry object, and an Atmosphere object at a minimum to get the gemetric and atmospheric specifications for the calculation.

class sasktran.Engine(name: str, geometry: sasktran.geometry.Geometry = None, atmosphere: sasktran.atmosphere.Atmosphere = None, wavelengths: list = None, options: dict = None)

Bases: object

Base class for objects which can perform radative transfer calculations.

calculate_radiance(output_format='numpy', full_stokes_vector=False, stokes_orientation='geographic')

Calculate radiances.

Parameters
  • output_format (str, optional) – Determines the output format, one of [‘numpy’ or ‘xarray’]. If output_format=’numpy’, the radiance and optionally the weighting functions are returned as numpy arrays. If output_format=’xarray’ the radiance and weighting functions are returned inside of an xarray Dataset object.

  • full_stokes_vector (bool, optional) – If True, the full stokes vector is output. If False only the first element of the stokes vector is included. Note that setting this does not automatically enable vector calculations within the model, it only changes the output format, every model requires a different setting to be changed to change the calculation mode. Default: False

  • stokes_orientation (str, optional) – One of ‘geographic’ or ‘solar’. The geographic basis is defined relative to the plane formed by the observer position and look vector. Here, Q, would be the linear polarization component for the nominal ‘up’ direction of an instrument. The solar basis is defined relative to the scattering direction from the sun. A single scatter calculation would have all of the polarization component in Q, and U would be 0. Default: ‘geographic’.

Returns

If output_format=’numpy’: The first np.ndarray is always the computed radiances. The shape of the computed radiances is (W, L) where W is the number of wavelengths, and L is the number of lines of sight. If atmosphere.wf_species != None then a second np.ndarray will be returned containing the computed weighting functions. The shape of this np.ndarray is engine specific but typically (W, L, A) where A is the number of altitudes at which at which the weighting functions were calculated. If full_stokes_vector is set to True, then what is returned is an array of sasktran.StokesVector objects.

If output_format=’xarray’: A dataset containing the radiance and weighting functions with appropriate coordinates.

Return type

np.ndarray or np.ndarray, np.ndarray or xarray.Dataset

property atmosphere

The engines atmosphere definition object.

Type

sasktran.Atmosphere

property geometry

The engines geometry definition object.

Type

sasktran.Geometry

property options

Dictionary map of additional engine options.

Examples

>>> import sasktran as sk
>>> engine = sk.EngineHR()
>>> engine.options['numordersofscatter'] = 1
Type

dict

property wavelengths

Wavelengths in nm to perform the radiative transfer calculation at.

Examples

>>> import sasktran as sk
>>> engine = sk.EngineHR()
>>> engine.wavelengths = 600 # Single wavelength
>>> engine.wavelengths = [600, 340] # Multiple wavelengths
Type

np.ndarray or float

Note

Most engines have a lot of features and configuration options. We have tried to make engine default configurations as reasonable as possible but obviously these defaults cannot efficiently handle every possible case. Because of this, users have to be aware additional engine configuration might be necessary to obtain efficinent and accurate results. These additional configuration options are set through engine options (see sasktran.Engine.options).

SASKTRAN HR

SASKTRAN HR is our primary engine product. The HR engine solves the radiative transfer equation in a region of interest using the successive orders technique on a true spherical Earth. The main highlights of the engine are:

  • Support to calculate the Weighting Functions of target species

  • Adapative integration within optically thick regions

  • Polarized or scalar radiance calculations

  • Support for gradients across a region of interest using high resolution diffusive fields

  • Support for terminator conditions

  • Support for thermal emissions

  • Support for elevated surface topology

class sasktran.EngineHR(geometry: sasktran.geometry.Geometry = None, atmosphere: sasktran.atmosphere.Atmosphere = None, wavelengths: list = None, options: dict = None)

Bases: sasktran.engine.Engine

Examples

>>> import sasktran as sk
>>> # configure your geometry
>>> geometry = sk.VerticalImage()
>>> geometry.from_sza_saa(60, 60, 0, 0, [10, 20, 30, 40], 54372, 0)
>>> # configure your atmosphere
>>> atmosphere = sk.Atmosphere()
>>> atmosphere['rayleigh'] = sk.Species(sk.Rayleigh(), sk.MSIS90())
>>> atmosphere.atmospheric_state = sk.MSIS90()
>>> atmosphere['o3'] = sk.Species(sk.O3DBM(), sk.Labow())
>>> atmosphere['no2'] = sk.Species(sk.NO2Vandaele1998(), sk.Pratmo())
>>> atmosphere.brdf = sk.Lambertian(0.3)
>>> # make your engine
>>> engine = sk.EngineHR(geometry=geometry, atmosphere=atmosphere, wavelengths=[350, 400, 450])
>>> rad = engine.calculate_radiance()
>>> print(rad) 
[[ 0.11674...  0.10872...  0.04904...  0.01456...]
 [ 0.10837...  0.08537...  0.02897...  0.00804...]
 [ 0.10318...  0.06396...  0.01829...  0.00483...]]
calculate_radiance(output_format='numpy', full_stokes_vector=False, stokes_orientation='geographic')

Calculate radiances.

Parameters
  • output_format (str, optional) – Determines the output format, one of [‘numpy’ or ‘xarray’]. If output_format=’numpy’, the radiance and optionally the weighting functions are returned as numpy arrays. If output_format=’xarray’ the radiance and weighting functions are returned inside of an xarray Dataset object.

  • full_stokes_vector (bool, optional) – If True, the full stokes vector is output. If False only the first element of the stokes vector is included. Note that setting this does not automatically enable vector calculations within the model, it only changes the output format, every model requires a different setting to be changed to change the calculation mode. Default: False

  • stokes_orientation (str, optional) – One of ‘geographic’ or ‘solar’. The geographic basis is defined relative to the plane formed by the observer position and look vector. Here, Q, would be the linear polarization component for the nominal ‘up’ direction of an instrument. The solar basis is defined relative to the scattering direction from the sun. A single scatter calculation would have all of the polarization component in Q, and U would be 0. Default: ‘geographic’.

Returns

If output_format=’numpy’: The first np.ndarray is always the computed radiances. The shape of the computed radiances is (W, L) where W is the number of wavelengths, and L is the number of lines of sight. If atmosphere.wf_species != None then a second np.ndarray will be returned containing the computed weighting functions. The shape of this np.ndarray is engine specific but typically (W, L, A) where A is the number of altitudes at which at which the weighting functions were calculated. If full_stokes_vector is set to True, then what is returned is an array of sasktran.StokesVector objects.

If output_format=’xarray’: A dataset containing the radiance and weighting functions with appropriate coordinates.

Return type

np.ndarray or np.ndarray, np.ndarray or xarray.Dataset

property atmosphere_dimensions

Sets the number of dimensions for the atmosphere in the radiative transfer calculation.

Input

Setting

1

One-dimensional in altitude

2

Two-dimensional in altitude and angle along the line of sight

3

Fully three-dimensional

Default: 1

property grid_spacing

Sets many options dealing with general grids and discretizations in the model. In general, if you are interested in things on the scale of 1000 m, then set this to 1000 m. For most applications setting this property is sufficient, however for advanced users it may be necessary to set some grids individually.

Default: 1000 m

property include_emissions

Enables support for atmospheric emissions inside the model. If set to True, any Emission objects that are included in the Atmosphere will be used in the radiative transfer calculation. Note that the default value is False, ignoring emissions.

Default: False

property num_diffuse_profiles

Advanced option that controls the number of diffuse profiles in the model. If worried about the accuracy of the multiple scatter signal, this should be the first option to try changing. A diffuse profile represents a (latitude, longitude) where the multiple scatter signal is calculated. The default value of 1 indicates that the multiple scatter signal is only calculated at the reference point, or the average tangent point. If you increase the value to 5, then there will be 5 locations along the line of sight where the full multiple scatter calculation is done. Outside of these areas the multiple scatter signal is interpolated. Odd numbers of diffuse profiles are preferred (but not necessary) since this facilitates one profile being placed at the tangent point.

To determine if this setting has an effect on your calculation it is recommended to first compare the results between 1, 5, and 11 diffuse profiles.

The amount of diffuse profiles to obtain an accurate depends heavily on a variety of things, but most heavily the solar zenith and solar scattering angles. When the sun is high in the sky (low solar zenith angle) 1–3 diffuse profiles is usually sufficient. However, when looking across the solar terminator (sza ~90, ssa < 90) it might be necessary to use upwards of 50 diffuse profiles to obtain a signal accurate to better than 0.5%. More information on the number of required diffuse profiles can be found in Zawada, D. J., Dueck, S. R., Rieger, L. A., Bourassa, A. E., Lloyd, N. D., and Degenstein, D. A.: High-resolution and Monte Carlo additions to the SASKTRAN radiative transfer model, Atmos. Meas. Tech., 8, 2609-2623, https://doi.org/10.5194/amt-8-2609-2015, 2015.

property num_orders_of_scatter

Controls the number of orders of scatter used inside the model. The number of orders of scatter controls the accuracy of the model. When set to 1, only light directly scattered from the sun is accounted for, with no multiple scattering.

The model runs substantially faster when set to 1 scatter order, therefore a common use case is to do development/testing with this property set to 1. There is very little speed difference between 2 orders of scatter and 50 orders of scatter, so usually it is recommended to set this to either 1 or 50.

Default: 50

property num_threads

Controls the number of threads to use when multithreading the radiative transfer calculation. The default value of 0 indicates that the number of threads used will be equal to the number of available logical cores on the target machine.

Setting this value to a lower number than the number of available cores can be useful when running a radiative transfer calculation in the background and the computer is too slow to multitask.

Default: 0

property polarization

The polarization mode of the model. Can either be set to ‘scalar’ or ‘vector’.

Default: ‘scalar’

property refraction

Determines whether or not refraction effects should be included in the radiative transfer calculation. If set to true, then refraction effects will be considered where the model supports it. Currently this is only available for the observer line of sight rays (solar rays and multiple scattering will not account for refraction).

Note that refraction support is experimental and may have some side effects. Currently known limitations are that the surface_elevation and top_of_atmosphere_altitudeproperty may not work properly with refraction enabled.

Enabling refraction also changes the ray tracer slightly, meaning that calculations with and without refraction enabled may differ slightly due to integration accuracies/quadrature points, etc. It is recommended to experiment with the grid_spacing property to ensure that the calculation is done with enough precision.

Default: false

property surface_elevation

Sets the elevation of the surface in [m] for the model. This setting can be used to account for changes in the Earth’s topography.

Default: 0 m

property top_of_atmosphere_altitude

Sets the altitude of the top of the atmosphere. Above this altitude it is assumed there is no atmosphere. The default value of 100000 m is typically suitable for stratospheric applications but for the mesosphere it is sometimes necessary to increase this value.

Default: 100000 m

Additional Documentation

For additional documentation and options see: https://arg.usask.ca/docs/SasktranIF/hr.html.

SASKTRAN-DISCO

SASKTRAN Disco is a radiative transfer engine similar to the well known DISORT and LIDORT radiative transfer algorithms. The engine can handle the following:

class sasktran.EngineDO(geometry: sasktran.geometry.Geometry = None, atmosphere: sasktran.atmosphere.Atmosphere = None, wavelengths: list = None, options: dict = None)

Bases: sasktran.engine.Engine

Examples

>>> import sasktran as sk
>>> # Configure the geometry
>>> geometry = sk.NadirGeometry()
>>> tempo = sk.Geodetic()
>>> tempo.from_lat_lon_alt(0, -100, 35786000)
>>> lats = np.linspace(20, 50, 4)
>>> lons = np.linspace(-110, -90, 3)
>>> lats, lons = np.meshgrid(lats, lons, indexing='ij')
>>> geometry.from_lat_lon(mjd=57906.63472, observer=tempo, lats=lats, lons=lons)
>>> # Configure the atmosphere
>>> atmosphere = sk.Atmosphere()
>>> atmosphere['rayleigh'] = sk.Species(sk.Rayleigh(), sk.MSIS90())
>>> atmosphere['o3'] = sk.Species(sk.O3DBM(), sk.Labow())
>>> atmosphere['no2'] = sk.Species(sk.NO2Vandaele1998(), sk.Pratmo())
>>> atmosphere.brdf = sk.Kokhanovsky()
>>> # Calcualte radiance
>>> engine = sk.EngineDO(geometry=geometry, atmosphere=atmosphere, wavelengths=[350, 450])
>>> rad = engine.calculate_radiance()
>>>
>>> # print radiances
>>> print(rad[0].reshape((4, 3))) # radiance at 350nm
[[ 0.15726175  0.19468353  0.22767423]
 [ 0.1666762   0.20027906  0.22962238]
 [ 0.17116222  0.1995542   0.22411801]
 [ 0.17099479  0.1932349   0.21235274]]
>>> print(rad[1].reshape((4, 3))) # radiance at 450nm
[[ 0.15884236  0.19815234  0.23287579]
 [ 0.16822132  0.20341264  0.23415734]
 [ 0.17226753  0.20184478  0.22736965]
 [ 0.1716201   0.19441591  0.21402527]]
calculate_radiance(output_format='numpy', full_stokes_vector=False)

Calculate radiances.

Parameters
  • output_format (str, optional) – Determines the output format, one of [‘numpy’ or ‘xarray’]. If output_format=’numpy’, the radiance and optionally the weighting functions are returned as numpy arrays. If output_format=’xarray’ the radiance and weighting functions are returned inside of an xarray Dataset object.

  • full_stokes_vector (bool, optional) – If True, the full stokes vector is output. If False only the first element of the stokes vector is included. Note that setting this does not automatically enable vector calculations within the model, it only changes the output format, every model requires a different setting to be changed to change the calculation mode. Default: False

  • stokes_orientation (str, optional) – One of ‘geographic’ or ‘solar’. The geographic basis is defined relative to the plane formed by the observer position and look vector. Here, Q, would be the linear polarization component for the nominal ‘up’ direction of an instrument. The solar basis is defined relative to the scattering direction from the sun. A single scatter calculation would have all of the polarization component in Q, and U would be 0. Default: ‘geographic’.

Returns

If output_format=’numpy’: The first np.ndarray is always the computed radiances. The shape of the computed radiances is (W, L) where W is the number of wavelengths, and L is the number of lines of sight. If atmosphere.wf_species != None then a second np.ndarray will be returned containing the computed weighting functions. The shape of this np.ndarray is engine specific but typically (W, L, A) where A is the number of altitudes at which at which the weighting functions were calculated. If full_stokes_vector is set to True, then what is returned is an array of sasktran.StokesVector objects.

If output_format=’xarray’: A dataset containing the radiance and weighting functions with appropriate coordinates.

Return type

np.ndarray or np.ndarray, np.ndarray or xarray.Dataset

Additional Documentation

For additional documentation see Sasktran-Disco.

See Also

Geometry

Objects which describe the geometry of the calculations to the engine. At a minimum these objects define the Lines of Sight, but can also specify things such as the suns position and the polling reference point.

Atmosphere

An object that describes the atmospheric constituents, and surface type to the engine. Atmospheric constituents are defined by a list of Species, and surfaces are defined by a given BRDF.