Coordinate Conversions¶
This notebook tutorial shows how to convert between coordinate systems using a sample trajectory retrieved from SSCWeb.
In [1]:
Copied!
# Import satellite flythrough coordinate conversion code for more info on the coordinate systems.
from kamodo_ccmc.flythrough.utils import ConvertCoord
help(ConvertCoord)
# Import satellite flythrough coordinate conversion code for more info on the coordinate systems.
from kamodo_ccmc.flythrough.utils import ConvertCoord
help(ConvertCoord)
Help on function ConvertCoord in module kamodo_ccmc.flythrough.utils:
ConvertCoord(inTime, c1, c2, c3, inCoord, inType, outCoord, outType, verbose=False)
This function uses spacepy and astropy to convert time and position arrays
from one coordinate system to another. It will correct obvious errors in
the return units, but may not catch all incorrect values.
INPUTS:
inTime array: time in UTC timestamp
c1 array: x (in R_earth)*, lon (in deg)
c2 array: y (in R_earth)*, lat (in deg)
c3 array: z (in R_earth)*, alt (in km), radius (in R_earth)
inCoord string: case-sensitive string from list:
'GDZ', 'GEO', 'GSM', 'GSE', 'SM', 'GEI', 'MAG', 'SPH', 'RLL'
(SpacePy coordinates)
'teme', 'icrs', 'fk5', 'fk4', 'itrs', 'galactic', 'galactocentric',
'cirs', 'tete', 'precessedgeocentric', 'geocentricmeanecliptic',
'geocentrictrueecliptic', 'hcrs', 'barycentricmeanecliptic',
'heliocentricmeanecliptic', 'barycentrictrueecliptic',
'heliocentrictrueecliptic', 'heliocentriceclipticiau76',
'custombarycentricecliptic', 'lsr', 'lsrk', 'lsrd', 'supergalactic',
'galacticlsr', 'fk4noeterms' (AstroPy coordinates)
Note: Not compatible with AstroPy's HADec and AltAz coordinate systems.
Note: Conversions using the galactocentric coordinate system are not
conserved (a conversion to and then from this coordinate system
does not return the same beginning values).
inType string: car, sph
outCoord string: (same list as for inCoord string)
outType string: car, sph
OUTPUT:
c1 array: x (in R_earth)*, lon (in deg)
c2 array: y (in R_earth)*, lat (in deg)
c3 array: z (in R_earth)*, alt (in km), radius (in R_earth)
units array: [unit_c1, unit_c2, unit_c3] (for example ['deg','deg','km']
or ['R_E','R_E','R_E'])
*SpacePy's GDZ car coordinate system requires and produces (x, y, z) in km.
The resource information on SpacePy's coordinate conversion function is
sparse at best, so the below information has been collected via other
resources and our own testing of the function. The data concerning the
spherical coordinate systems are collected into a table format for
easier perusal. Some details concerning the AstroPy coordinate systems
are also below.
For cartesian coordinates, all of the input values after time should be in
earth radii (R_E) in order (x, y, z) to work properly, except for GDZ.
For spherical coordinates, all of the input values after time should be in
order (longitude, latitude, altitude or radius). The longitude and
latitude values should be in degrees, altitude values in kilometers,
and radius values in earth radii (R_E) from the Earth's center. All
latitude values should fall between -90 and 90 degrees. The longitude
range differs between the coordinate systems and is given for each in
the table below.
The intepretations of the input coordinates vary between the AstroPy
coordinate systems (see below). We leave it to the user to determine
the proper input values accordingly.
The longitude values returned for a given coordinate converted to an
AstroPy coordinate system are always positive (0 to 360 degrees).
SpacePy
Abbrev. Full Name Lon. range vertical variable
--------------------------------------------------------------------------
GDZ Geodetic (WGS 84) (-180, 180) Altitude (km)
GEO Geographic (-180, 180) Radius (R_E)
GSM Geocentric Solar Magnetospheric (-180, 180) Radius (R_E)
GSE Geocentric Solar Ecliptic (-180, 180) Radius (R_E)
SM Solar Magnetic (-180, 180) Radius (R_E)
GEI Geocentric Equatorial Inertial (-180, 180) Radius (R_E)
(also ECI = Earth-Centered Inertial)
MAG Geomagnetic (-180, 180) Radius (R_E)
SPH Spherical (0, 360) Radius (R_E)
RLL Radius, Latitude, Longitude (-180, 180) Radius (R_E)
For descriptions of most of the coordinate systems, see
https://sscweb.gsfc.nasa.gov/users_guide/Appendix_C.shtml and
"Geophysical Coordinate Transformations", C.T. Russell, Cosmic
Electrodynamics, Vol. 2, pp. 184 - 196, 1971.
The current links to SpacePy's coordinate documentation and wrapped
conversion functions are:
https://spacepy.github.io/autosummary/spacepy.coordinates.Coords.html
http://svn.code.sf.net/p/irbem/code/trunk/manual/user_guide.html
AstroPy coordinate systems:
https://docs.astropy.org/en/stable/coordinates/skycoord.html
Spherical coordinates in the AstroPy coordinate systems are interpreted as
described below with the units [x,y,z] = [deg, deg, R_E].
(All z values must be in R_E, not km.)
teme: ['lon', 'lat', 'distance']
icrs: ['ra', 'dec', 'distance']
fk5: ['ra', 'dec', 'distance']
fk4: ['ra', 'dec', 'distance']
itrs: ['lon', 'lat', 'distance']
galactic: ['l', 'b', 'distance']
galactocentric: ['lon', 'lat', 'distance']
cirs: ['ra', 'dec', 'distance']
tete: ['ra', 'dec', 'distance']
precessedgeocentric: ['ra', 'dec', 'distance']
geocentricmeanecliptic: ['lon', 'lat', 'distance']
geocentrictrueecliptic: ['lon', 'lat', 'distance']
hcrs: ['ra', 'dec', 'distance']
barycentricmeanecliptic: ['lon', 'lat', 'distance']
heliocentricmeanecliptic: ['lon', 'lat', 'distance']
barycentrictrueecliptic: ['lon', 'lat', 'distance']
heliocentrictrueecliptic: ['lon', 'lat', 'distance']
heliocentriceclipticiau76: ['lon', 'lat', 'distance']
custombarycentricecliptic: ['lon', 'lat', 'distance']
lsr: ['ra', 'dec', 'distance']
lsrk: ['ra', 'dec', 'distance']
lsrd: ['ra', 'dec', 'distance']
galacticlsr: ['l', 'b', 'distance']
fk4noeterms: ['ra', 'dec', 'distance']
supergalactic: ['sgl', 'sgb', 'distance']
Cartesian coordinates in the AstroPy coordinate systems are interpreted as
(x,y,z) with a few exceptions (below) and always in R_E (earth radii).
galactic: ['u', 'v', 'w']
supergalactic: ['sgx', 'sgy', 'sgz']
C:\Users\rringuet\Anaconda3\envs\Kamodo_Jan2023\lib\site-packages\spacepy\time.py:2367: UserWarning: Leapseconds may be out of date. Use spacepy.toolbox.update(leapsecs=True)
warnings.warn('Leapseconds may be out of date.'
Retrieve a real satellite trajectory as input¶
In [2]:
Copied!
# Typical coordinates possible through SSCWeb are GEO, GSE, SM, and GSM (all cartesian and in R_E).
from kamodo_ccmc.flythrough import SatelliteFlythrough as SF
from datetime import datetime, timezone
start = datetime(2015, 3, 18, 6, 26, 40).replace(tzinfo=timezone.utc)
end = datetime(2015, 3, 18, 12, 11, 40).replace(tzinfo=timezone.utc)
traj_dict, coord_type = SF.SatelliteTrajectory('grace1', start.timestamp(), end.timestamp(), coord_type='GEO')
# Show the range of each coordinate.
print('Coordinate system:', coord_type)
print('sat_time = utc timestamp:', traj_dict['sat_time'].min(), traj_dict['sat_time'].max())
print(datetime.utcfromtimestamp(traj_dict['sat_time'].min()), datetime.utcfromtimestamp(traj_dict['sat_time'].max()))
print('c1 = x(R_E):', traj_dict['c1'].min(), traj_dict['c1'].max())
print('c2 = y(R_E):', traj_dict['c2'].min(), traj_dict['c1'].max())
print('c3 = z(R_E):', traj_dict['c3'].min(), traj_dict['c1'].max())
# Typical coordinates possible through SSCWeb are GEO, GSE, SM, and GSM (all cartesian and in R_E).
from kamodo_ccmc.flythrough import SatelliteFlythrough as SF
from datetime import datetime, timezone
start = datetime(2015, 3, 18, 6, 26, 40).replace(tzinfo=timezone.utc)
end = datetime(2015, 3, 18, 12, 11, 40).replace(tzinfo=timezone.utc)
traj_dict, coord_type = SF.SatelliteTrajectory('grace1', start.timestamp(), end.timestamp(), coord_type='GEO')
# Show the range of each coordinate.
print('Coordinate system:', coord_type)
print('sat_time = utc timestamp:', traj_dict['sat_time'].min(), traj_dict['sat_time'].max())
print(datetime.utcfromtimestamp(traj_dict['sat_time'].min()), datetime.utcfromtimestamp(traj_dict['sat_time'].max()))
print('c1 = x(R_E):', traj_dict['c1'].min(), traj_dict['c1'].max())
print('c2 = y(R_E):', traj_dict['c2'].min(), traj_dict['c1'].max())
print('c3 = z(R_E):', traj_dict['c3'].min(), traj_dict['c1'].max())
Attribute/Key names of return dictionary: dict_keys(['sat_time', 'c1', 'c2', 'c3']) Coordinate system: GEO-car sat_time = utc timestamp: 1426660020.0 1426680660.0 2015-03-18 06:27:00 2015-03-18 12:11:00 c1 = x(R_E): -0.9270195119 1.0114874276 c2 = y(R_E): -1.0605838293 1.0114874276 c3 = z(R_E): -1.0639983632 1.0114874276
Convert to a spherical coordinate system in SpacePy¶
In [3]:
Copied!
# The syntax to convert:
c1, c2, c3, units = ConvertCoord(traj_dict['sat_time'], traj_dict['c1'], traj_dict['c2'], traj_dict['c3'],
*coord_type.split('-'), 'SM', 'sph')
# Show the range of each coordinate. Note the time does not change.
print('Coordinate system: SM-sph')
print('c1 = longitude(deg):', c1.min(), c1.max())
print('c2 = latitude(deg):', c2.min(), c2.max())
print('c3 = radius(R_E):', c3.min(), c3.max())
print('units (c1, c2, c3):',units)
# The syntax to convert:
c1, c2, c3, units = ConvertCoord(traj_dict['sat_time'], traj_dict['c1'], traj_dict['c2'], traj_dict['c3'],
*coord_type.split('-'), 'SM', 'sph')
# Show the range of each coordinate. Note the time does not change.
print('Coordinate system: SM-sph')
print('c1 = longitude(deg):', c1.min(), c1.max())
print('c2 = latitude(deg):', c2.min(), c2.max())
print('c3 = radius(R_E):', c3.min(), c3.max())
print('units (c1, c2, c3):',units)
Coordinate system: SM-sph c1 = longitude(deg): -175.82629680633556 150.11391934929247 c2 = latitude(deg): -88.63688132453802 88.71473929655991 c3 = radius(R_E): 1.0599501466186172 1.0644604465687955 units (c1, c2, c3): ['deg', 'deg', 'R_E']
Convert to a cartesian coordinate system in AstroPy¶
In [4]:
Copied!
# The syntax to convert:
c1, c2, c3, units = ConvertCoord(traj_dict['sat_time'], traj_dict['c1'], traj_dict['c2'], traj_dict['c3'],
*coord_type.split('-'), 'teme', 'car')
# Show the range of each coordinate. Note the time does not change
print('Coordinate system: teme-car')
print('c1 = x(R_E):', c1.min(), c1.max())
print('c2 = y(R_E):', c2.min(), c2.max())
print('c3 = z(R_E):', c3.min(), c3.max())
print('units (c1, c2, c3):',units)
# The syntax to convert:
c1, c2, c3, units = ConvertCoord(traj_dict['sat_time'], traj_dict['c1'], traj_dict['c2'], traj_dict['c3'],
*coord_type.split('-'), 'teme', 'car')
# Show the range of each coordinate. Note the time does not change
print('Coordinate system: teme-car')
print('c1 = x(R_E):', c1.min(), c1.max())
print('c2 = y(R_E):', c2.min(), c2.max())
print('c3 = z(R_E):', c3.min(), c3.max())
print('units (c1, c2, c3):',units)
Coordinate system: teme-car c1 = x(R_E): -0.2046378793907867 0.20505787042036003 c2 = y(R_E): -1.0421557059743505 1.0437086971696456 c3 = z(R_E): -1.0640045699238057 1.0598887612232442 units (c1, c2, c3): ['R_E', 'R_E', 'R_E']