Constructing the Geometry

What is the Geometry?

Along with the Atmosphere, the Geometry object is one of the fundamental inputs required for a radiative transfer calculation.

At its core the Geometry object is just a list of LineOfSight. Each LineOfSight represents the geometry of a single measurements and is made up by three things:

  • The observer position in geocentric coordinates. For example, [3.676013154788849600e+005, 1.009976313640051500e+006, -6.871601202127538600e+006].

  • A unit look vector also in geocentric coordinates. For example, [2.884568631765662100e-001, 7.925287180643269000e-001, 5.372996083468238900e-001].

  • The time of the measurement, represented as a Modified Julian Date, for example, 54832.5. The time field is used to calculate the solar position.

Putting these three things together we can create the LineOfSight

[1]:
import sasktran as sk

line_of_sight = sk.LineOfSight(observer=[3.676013154788849600e+005, 1.009976313640051500e+006, -6.871601202127538600e+006],
                              look_vector=[2.884568631765662100e-001, 7.925287180643269000e-001,  5.372996083468238900e-001],
                              mjd=54832.5)

print(line_of_sight)
Observer: [367601.31547888496, 1009976.3136400515, -6871601.202127539]
Look: [0.2884568631765662, 0.7925287180643269, 0.5372996083468239]
MJD: 54832.5

For lines of sight that are limb viewing, each line of sight is often referred to from its tangent point

[2]:
print(line_of_sight.tangent_location())
ISKGeodetic: IAU 1976
 Latitude: -57.50000019273359, Longitude: 70.0, Altitude: 10002.995861731353

Multiple lines of sights can be created in the same fashion

[3]:
line_of_sight_2 = sk.LineOfSight(observer=[3.692808540679614500e+005, 1.014590807988641800e+006, -6.870844156040793300e+006],
                                 look_vector=[2.884568631765662100e-001, 7.925287180643269000e-001,  5.372996083468238900e-001],
                                 mjd=54832.5)

print(line_of_sight_2.tangent_location())
ISKGeodetic: IAU 1976
 Latitude: -57.50000023112414, Longitude: 70.0, Altitude: 12002.995861732867

The Geometry object is just a collection of these LineOfSight

[4]:
geometry = sk.Geometry()

geometry.lines_of_sight = [line_of_sight, line_of_sight_2]

print(geometry)
Geometry object containing 2 lines of sight

Convenience Classes

The default input for the Geometry are physical positions and time, which is easy to use if you are trying to model actual measurements from an actual instrument. However, for most simulation work calculating these raw physical lines of sight can be tedious, especially if it is desired to change parameters such as the solar position (which by default is set by the average time of the measurements). For this reason some convenience classes are provided which make geometry calculations simpler in many cases. For limb viewing the most useful convenience class is VerticalImage, which constructs a vertical set of measurements at a single instant in time based upon the tangent altitudes and solar angles

[5]:
from sasktran.geometry import VerticalImage

geometry = VerticalImage()
geometry.from_sza_saa(sza=60, saa=60, lat=0, lon=0, tanalts_km=[10, 20, 30, 40], mjd=54372, locallook=0,
                      satalt_km=600, refalt_km=20)

print(geometry)
Geometry object containing 4 lines of sight
Sun position forced to [0.5       0.75      0.4330127]

This creates a Geometry object with lines of sight that match the desired solar angles and tangent point information. There is an additional message saying that the sun position is forced to a specific vector, this indicates that the sun is no longer set by the time. The object is still made up of a list of LineOfSight objects that we can access directly.

[6]:
print(geometry.lines_of_sight[0])
print('-------------------------------------')
print(geometry.lines_of_sight[0].tangent_location())
Observer: [ 6398137.                0.         -2835095.13067904]
Look: [-0.00351341  0.          0.99999383]
MJD: 54372
-------------------------------------
ISKGeodetic: IAU 1976
 Latitude: 0.20130381481710838, Longitude: 0.0, Altitude: 9999.93036821498

In cases where there is not a convenience class such as VerticalImage that matches your specific use case, there is also a low level Geodetic object that can be used to help with constructing lines of sight.

Using the Geodetic Object

The Geodetic is a class that is designed to aid with various Earth coordinate systems. One of its major uses is to from geocentric (3 element x,y,z) to latitude, longitude, height, referenced to a specific Earth geoid (by default, IAU 1976). For example, we can convert our observer position used above,

[7]:
geo = sk.Geodetic()

geo.from_xyz([3.692808540679614500e+005, 1.014590807988641800e+006, -6.870844156040793300e+006])

print(geo)
ISKGeodetic: IAU 1976
 Latitude: -81.12320535369729, Longitude: 70.00000000000001, Altitude: 597895.4159141617

Or, we could convert our tangent point above to geocentric coordinates

[8]:
geo.from_lat_lon_alt(latitude=-57.49967218373388, longitude=70.0, altitude=12000.000104637467)

print(geo.location)
[ 1177109.33068763  3234081.30629361 -5366123.67907112]