Geometry

Module: sasktran.geometry

Objects used to specify the Lines of Sight and other geometric specifications to your Engine such as the sun’s position and where you would like the engines reference point to be. Note that at a minimum, a sasktran.Geometry object must specify a list of sasktran.LineOfSight objects (so that the engine knows what look vectors to calculate radiances for).

class sasktran.Geometry

Bases: object

Class which represents the Geometry for a radiative transfer calculation. Currently this is made up of a set of sasktran.LineOfSight which define the viewing geometry, and a sasktran.Geometry.sun property which controls the solar position. In the future this class may be extended to also control options such as the top of the atmosphere, and the ‘ground’ altitude.

Note that it is not always necessary to explicitly set the sun position. If no sun position is given then it is automatically calculated from the average mjd given in the lines of sight.

This class can be thought of as the geometry interface to the radiative transfer model. For simple problems, we can construct this class and modify the lines of sight directly, as is done in the example below. For more complicated problems it may be desirable to create a new class that inherits from this class, as is done in the VerticalImage class.

Examples

>>> import sasktran as sk
>>> geometry = sk.Geometry()
>>> los1 = sk.LineOfSight(mjd=54832.5, observer=[3.6760131547888e+005, 1.0099763136400e+006, -6.871601202127e+006],                              look_vector=[2.884568631765662e-001, 7.925287180643269e-001,  5.372996083468238e-001]),
>>> los2 = sk.LineOfSight(mjd=54832.5, observer=[3.6928085406796e+005, 1.0145908079886e+006, -6.870844156040e+006],                              look_vector=[2.88456863176566e-001, 7.925287180643269e-001,  5.372996083468238e-001])
>>> geometry.lines_of_sight = [los1, los2]
>>> print(geometry)
Geometry object containing 2 lines of sight
>>> geometry.sun = [0, 0, 1]
>>> print(geometry)
Geometry object containing 2 lines of sight
Sun position forced to [0, 0, 1]
property lines_of_sight

A list of sasktran.LineOfSight in which to calculate radiances.

Examples

>>> import sasktran as sk
>>> geometry = sk.Geometry()
>>> arg_office = sk.Geodetic()  # line of sight terminator
>>> arg_office.from_lat_lon_alt(52.131638, -106.633873, 0)
>>> observer = sk.Geodetic()   # line of sight observer
>>> observer.from_lat_lon_alt(0, -100, 35786000)
>>> look = (arg_office.location - observer.location)
>>> look = look / np.linalg.norm(look)  # don't forget to normalize the look vector
>>> # in this example we'll only add one line of sight (done below) but any number could be added to this list
>>> geometry.lines_of_sight = [              sk.LineOfSight(look_vector=look, observer=observer.location, mjd=57906),         ]
Type:

list

property reference_point
[latitude, longitude,

surface_altitude, mjd]. Note that longitude must be a value in the range [0, 360).

Notes

Reference points semantics are engine specific. Refer to your engines specific documentation for details.

Type:

np.ndarray((4,))

Type:

The reference point as a four element array. Format

property sun

Unit vector pointing to the sun in geodetic coordinates. See sasktran.Geodetic.location.

Examples

>>> import sasktran as sk
>>> geometry = sk.Geometry()
>>> sun = sk.Geodetic()
>>> sun.from_lat_lon_alt(22.26666667, -48.98333333, 0) # altitude (argument 3) doesnt matter here
>>> geometry.sun = sun.local_up # a geocentric unit vector pointing at the sun
Type:

np.ndarray((3,))

class sasktran.VerticalImage

Bases: Geometry

A specialized Geometry class which has various convenience methods to construct lines of sight corresponding to a vertical image of the atmosphere based on input solar zenith angles.

Examples

>>> from sasktran.geometry import VerticalImage
>>> geometry = VerticalImage()
>>> geometry.from_sza_saa(60, 60, 0, 0, [10, 20, 30, 40], 54372, 0)
>>> print(geometry)
Geometry object containing 4 lines of sight
Sun position forced to [ 0.5        0.75       0.4330127]
from_sza_saa(sza, saa, lat, lon, tanalts_km, mjd, locallook, satalt_km=600, refalt_km=20)

Constructs the geometry from a given solar zenith angle and solar azimuth angle

Parameters:
  • sza (float) – Solar zenith angle in degrees of the tangent point at refalt_km.

  • saa (float) – Solar azimuth angle in degrees of the tangent point at refalt_km.

  • lat (float) – Latitude in degrees (-90 to 90)

  • lon (float) – Longitude in degrees

  • tanalts_km (np.ndarray) – Tangent altitudes in km

  • mjd (float) – Modified Julian Date for the measurements

  • locallook (float) – Angle in degrees defining the look direction on the surface of the Earth. 0 corresponds to true north, 90 to East and so on.

  • satalt_km (float, optional) – Altitude of the observers in km. Default is 600 km.

  • refalt_km (float, optional) – Altitude that the given solar zenith angle and solar azimuth angle are valid at. Since the geometry represents a vertical image, the solar angles change for every line of sight.

class sasktran.NadirGeometry

Bases: Geometry

from_fov(mjd: float, observer: Geodetic, center: Geodetic, ntheta: int = 1, nphi: int = 1, dtheta: float = 0.0, dphi: float = 0.0, bearing: float | None = None)

Adds lines of sight by creating a rectangular grid of equally spaced angles surrounding a center line of sight. The center line of sight is defined by the observer position and the center position.

Parameters:
  • observer (sk.Geodetic) – Position of the observer.

  • center (sk.Geodetic) – The center of the bundle of lines of sight.

  • ntheta (int) – The number of rows in the angle grid.

  • nphi (int) – The number of columns in the angle grid.

  • dtheta (float) – The spacing between columns in the angle grid.

  • dphi (float) – The spacing between rows in the angle grid.

  • bearing (float) – The bearing (degrees, CW from north) of the center column’s intersection with the local horizontal at center. Defaults to None, which places the column in the plane containing the observer and the local vertical at center, or in the north/south direction if the los is vertical.

from_lat_lon(mjd, observer: Geodetic, lats, lons, elevations=0)

Construct lines of sight from arrays of points (latitude, longitude[, elevation]).

Notes

Arguments for this function are associated sequences (ie. the first observation is at (lats[0], lons[0], the second is at (lats[1], lons[1]) and so on). This means that if you have a geoegraphic grid of sample points, these arrays should be flattened before being passed to this function.

Arguments are broadcast together using numpy’s broadcast rules.

Examples

>>> geometry = sk.NadirGeometry()
>>> # make the look vector from TEMPO to the ARG office
>>> tempo = sk.Geodetic()
>>> tempo.from_lat_lon_alt(0, -100, 35786000)
>>> geometry.from_lat_lon(mjd=57906, observer=tempo, lats=52.131638, lons=-106.633873, elevations=0)
Parameters:
  • mjd (float, np.ndarray) – Modified Julian Data of observations. If mjd is a float then this mjd will be used for each line of sight. Else mjd’s are associated element-wise.

  • observer (sasktran.Geodetic or array of sasktran.Geodetic) – Observer locations.

  • lats (float, np.ndarray) – Latitudes of observations. If this argument is a float then this latitude will be used for each line of sight, otherwise latitudes will be flattened and associated element wise.

  • lons (float, np.ndarray) – Same as lats but for longitudes.

  • elevations (float, np.ndarray) – Used to specify the ground elevation (in meters) for each sample point.

from_zeniths_and_azimuth_difference(solar_zenith, observer_zeniths, azimuth_differences, solar_azimuth=180.0, mjd=58197.666, observer_alt=600000.0, reference_point=(52.1332, 253.33, 0, 58197.666))

Configures the geometry from arrays of solar zenith angles, observer zenith angles, and azimuth angle differences. If only one solar zenith angle is provided, from_zeniths_and_azimuths is called.

If multiple solar zenith angles are provided, a north-facing (azimuth=0) sun is positioned over the reference point with the average solar zenith angle, ground locations to the south are chosen to match the given solar zenith angles, and observers and look vectors are calculated from these ground locations. Since ground intersection points will be away from the reference point, calling transform_los_to_preserve_ground_angles() is recommended.

Notes

Observation parameters are forced to np.arrays and then broadcasted to a common shape. This means that any observation parameter can be a scalar (value used for all entries) or an array (each entry is individually specified).

A common application is to specify a meshgrid of zenith and azimuth angles. In this case, simply flatten the arrays before passing them as np.arrays.

Parameters:
  • solar_zenith (float) – Solar zenith angle in degrees.

  • solar_azimuth (float) – Solar azimuth angle (relative to North) in degrees.

  • observer_mjds (float, np.array) – Observation MJDs.

  • observer_zeniths (float, np.array) – Observation zenith angles in degrees.

  • observer_azimuths (float, np.array) – Observation azimuth angles (relative to North) in degrees.

  • observer_altitudes (float, np.array) – Observation surface altitude in meters.

  • reference_point (np.array) – The reference point as a four element array (lat, lon, alt, mjd).

from_zeniths_and_azimuths(solar_zenith: float, solar_azimuth: float, observer_mjds, observer_zeniths, observer_azimuths, observer_altitudes=600000.0, reference_point=None)

Configures the geometry from arrays of zenith and azimuth angles. Only one solar zenith angle can be specified.

Notes

Observation parameters are forced to np.arrays and then broadcasted to a common shape. This means that any observation parameter can be a scalar (value used for all entries) or an array (each entry is individually specified).

A common application is to specify a meshgrid of zenith and azimuth angles. In this case, simply flatten the arrays before passing them as np.arrays.

Parameters:
  • solar_zenith (float) – Solar zenith angle in degrees.

  • solar_azimuth (float) – Solar azimuth angle (relative to North) in degrees.

  • observer_mjds (float, np.array) – Observation MJDs.

  • observer_zeniths (float, np.array) – Observation zenith angles in degrees.

  • observer_azimuths (float, np.array) – Observation azimuth angles (relative to North) in degrees.

  • observer_altitudes (float, np.array) – Observation surface altitude in meters.

  • reference_point (np.array) – The reference point as a four element array (lat, lon, alt, mjd).

property lines_of_sight

A list of sasktran.LineOfSight in which to calculate radiances.

Examples

>>> import sasktran as sk
>>> geometry = sk.Geometry()
>>> arg_office = sk.Geodetic()  # line of sight terminator
>>> arg_office.from_lat_lon_alt(52.131638, -106.633873, 0)
>>> observer = sk.Geodetic()   # line of sight observer
>>> observer.from_lat_lon_alt(0, -100, 35786000)
>>> look = (arg_office.location - observer.location)
>>> look = look / np.linalg.norm(look)  # don't forget to normalize the look vector
>>> # in this example we'll only add one line of sight (done below) but any number could be added to this list
>>> geometry.lines_of_sight = [              sk.LineOfSight(look_vector=look, observer=observer.location, mjd=57906),         ]
Type:

list

property sun

Unit vector pointing to the sun in geodetic coordinates. See sasktran.Geodetic.location.

Examples

>>> import sasktran as sk
>>> geometry = sk.Geometry()
>>> sun = sk.Geodetic()
>>> sun.from_lat_lon_alt(22.26666667, -48.98333333, 0) # altitude (argument 3) doesnt matter here
>>> geometry.sun = sun.local_up # a geocentric unit vector pointing at the sun
Type:

np.ndarray((3,))

transform_los_to_preserve_ground_angles()

Adjusts all lines of sight that intersect the ground so that the solar/observer zenith/azimuth angles will be preserved on the osculating sphere. Currently the reference point must be manually set to use this method. If the ground intersection of a line of sight coincides with the reference point, no change will occur.

Notes

Locations on the geoid and on the osculating sphere with the same lat/lon coordinates will have the same local unit directions, and thus will have the same solar/observer angles if the sun vector and the look vector are kept constant.

Thus the only operation required is to translate the observer by the difference between the geoid/osculating sphere locations that share lat/lon coordinates with the ground intersection.

See Also

Lines of Sight

An object that describes a line of sight. A line of sight is made up of: (1) a look vector, (2) an observer position, (3) an obervation time.

Geodetic

Internally SASKTRAN use a Geodetic coordinate system. This class implements some helpers for working with geodetic coordinates.