Coordinate Systems

Similart to the definitions in Astropy: we adopt the following terminology:

  • A Coordinate Representation (chart) is a particular way of describing a unique point in a vector space. Common ones include Cartesian3, Spherical, and Geodetic based on AbstractRepresentation.
  • A Reference System is a scheme for orienting points in a space and describing how they transform to other systems. For example, the Earth-centered, Earth-fixed (ECEF) reference system tells you (i) origin at the geocenter, (ii) axes rotate with the Earth. But it does not uniquely specify: (i) whether Z is ITRF pole, Conventional International Origin pole, "instantaneous rotation axis", etc (ii) whether the axes are aligned to a particular geodetic datum.
  • A Reference Frame is a specific realization of a reference system (e.g., the ICRF, or J2000 equatorial coordinates). For example, GEO is a simplified ECEF realization suitable for space-physics transformations (GEO↔GSE/GSM/SM/MAG). It differs from “true” geodesy realization like ITRF in that it ignores small corrections like polar motion and uses a simplified Earth rotation model.
  • A Coordinate is a combination of all of the above that specifies a unique point.

<!– - A Coordinate Transformation is a mapping between different coordinate systems. –>

The package exports the following types AbstractReferenceSystem, AbstractRepresentation, AbstractReferenceFrame, and AbstractCoordinateVector:

And related functions:

  • getcsys: Function to retrieve the coordinate system from an object
Notes

Because of the ambiguity of meaning of "coordinate system", this term should be avoided wherever possible. However, for backward compatibility, we still export AbstractCoordinateSystem which serves a practical purpose of combining reference frame and coordinate representation.

Implementation Approaches

Here we demonstrate two approaches to implementing coordinate vectors and their associated systems:

Approach 1: Explicit Coordinate System Field

Store the coordinate system directly as a field in the vector type:

julia> using SpaceDataModel: Cartesian3, AbstractReferenceFrame, AbstractCoordinateVector
julia> import SpaceDataModel: getcsys
julia> # Define a reference frame struct GEO <: AbstractReferenceFrame end
julia> # Define a vector with an explicit reference frame and representation struct CoordinateVector{F, R, T} <: AbstractCoordinateVector x::T y::T z::T end
julia> 𝐫 = CoordinateVector{GEO, Cartesian3, Float64}(1, 2, 3)Main.CoordinateVector{Main.GEO, SpaceDataModel.Cartesian3, Float64}(1.0, 2.0, 3.0)
julia> # Implementation of getcsys getcsys(::CoordinateVector{F, R}) where {F, R} = (F(), R())getcsys (generic function with 4 methods)
julia> getcsys(𝐫)(Main.GEO(), SpaceDataModel.Cartesian3())

Approach 2: Implicit Coordinate System

Associate a specific coordinate system with a vector type:

julia> # Define a vector type specific to a coordinate system
       struct GEOVector{D} <: AbstractCoordinateVector
           data::D
       end
julia> # Implementation of getcsys returns the appropriate system getcsys(::GEOVector) = (GEO(), Cartesian3())getcsys (generic function with 5 methods)
julia> 𝐫2 = GEOVector([1, 2, 3])Main.GEOVector{Vector{Int64}}([1, 2, 3])
julia> getcsys(𝐫2)(Main.GEO(), SpaceDataModel.Cartesian3())

Both approaches are highly efficient and provide equivalent performance due to Julia's type inference system.

using Chairmarks
@b getcsys($𝐫), getcsys($𝐫2)
(1.542 ns, 1.542 ns)

Elsewhere