# Frames and Centers Reference
This document is the authoritative guide to the **reference frames** and
**reference centers** used in siderust. Read it before touching any coordinate
transformation or adding a new frame type to `affn`.
---
## 1. Reference Centers
A *center* is the origin of a coordinate system. In siderust every
`Position` carries both a center and a frame.
| `Barycentric` | `centers::Barycentric` | Solar-System barycentre |
| `Heliocentric` | `centers::Heliocentric` | Sun's centre of mass |
| `Geocentric` | `centers::Geocentric` | Earth's centre of mass |
| `Topocentric` | `centers::Topocentric` | Observer's location on Earth's surface |
| `Mercurycentric` | `centers::Mercurycentric` | Mercury's centre of mass |
| `Venuscentric` | `centers::Venuscentric` | Venus's centre of mass |
| `Marscentric` | `centers::Marscentric` | Mars's centre of mass |
| `Selenocentric` | `centers::Selenocentric` | Moon's centre of mass |
| `Jovicentric` | `centers::Jovicentric` | Jupiter's centre of mass |
| `Saturnocentric` | `centers::Saturnocentric` | Saturn's centre of mass |
| `Uranocentric` | `centers::Uranocentric` | Uranus's centre of mass |
| `Neptunocentric` | `centers::Neptunocentric` | Neptune's centre of mass |
| `Plutocentric` | `centers::Plutocentric` | Pluto's centre of mass |
`Topocentric` is *parameterised*: it carries a `Geodetic<ECEF>` so horizontal
coordinates know their own observation point without external context.
### Center-Shift Hub
All center-shift transformations route through the **Barycentric** hub:
```
Planetocentric → Barycentric → target center
```
For planets (Mercury–Pluto), barycentric positions are computed via Keplerian
orbit propagation (from `solar_system.rs`) plus Sun's barycentric offset.
For the Moon (Selenocentric), the position comes from the ephemeris
`moon_geocentric()` combined with Earth's barycentric position.
---
## 2. Earth-Fixed Frames
### 2.1 ECEF, Earth-Centred Earth-Fixed (WGS84 Earth-fixed convenience frame)
```rust
// affn::frames::ECEF
pub struct ECEF;
```
`ECEF` is the WGS84-tagged Earth-fixed frame used for geodetic site input and
for Earth-fixed Cartesian vectors in user-facing APIs.
**When to use `ECEF`:**
- Storing WGS84 geodetic coordinates (`Geodetic<ECEF>`).
- User-facing Earth-fixed Cartesian vectors when you want the familiar `ECEF`
label instead of `ITRF`.
**Provider-layer note:** frame rotations currently treat `ECEF` as
co-aligned with `ITRF`. The distinction between the two frames is therefore
ellipsoidal / metadata-oriented in siderust today:
- `Geodetic<ECEF>` uses **WGS84**
- `Geodetic<ITRF>` uses **GRS80**
- `Position<Geocentric, ECEF, U>` and `Position<Geocentric, ITRF, U>` share
the same Earth-orientation chain when rotated to inertial frames
### 2.2 ITRF, International Terrestrial Reference Frame (EOP-realised)
```rust
// affn::frames::ITRF
pub struct ITRF;
```
`ITRF` is the **physical** geocentric frame co-rotating with the solid Earth.
Its axes are realised through a global network of VLBI / SLR / GNSS stations.
The full IERS EOP chain applies:
```
ITRS → W⁻¹ → TIRS → ERA → CIRS → Q → GCRS/ICRS
```
**When to use `ITRF`:**
- Observatory geocentric coordinates sourced from ITRF2020 / VLBI solutions.
- Polar-motion-corrected baselines at the centimetre level.
- Any context where the phrase "ITRF coordinates" appears in the source data.
### 2.3 CIRS / TIRS, Intermediate Earth-orientation frames
```rust
pub struct CIRS;
pub struct TIRS;
```
These are the public intermediate frames of the IAU 2000/2006 Earth-rotation
chain:
```text
GCRS/ICRS ──Q──▶ CIRS ──ERA──▶ TIRS ──W──▶ ITRF/ECEF
```
Use them when you need to inspect or exchange states at a specific stage of the
Earth-orientation reduction instead of jumping directly between inertial and
Earth-fixed frames.
---
## 3. Celestial (Inertial) Frames
### 3.1 ICRS / ICRF
```rust
pub struct ICRS; // Spherical (α, δ)
pub struct ICRF; // Cartesian unit vector
```
The **International Celestial Reference System** is the primary inertial frame.
Axes are fixed by extragalactic radio sources (quasars). It is realised by
the ICRF catalogue.
**Note:** `ICRS` and `ICRF` differ only in coordinate style (spherical vs.
Cartesian direction); they share the same axes.
### 3.2 GCRS, Geocentric Celestial Reference System
```rust
pub struct GCRS;
```
**Approximation in siderust:** `GCRS` currently uses `frames::ICRS` axes
under the hood. The true GCRS is rotated from ICRS by < 1 mas (the
frame-bias matrix **B**), which is below the accuracy floor of most
calculations. If sub-mas accuracy is required, apply the frame-bias
explicitly.
### 3.3 EquatorialMeanJ2000 / EME2000
```rust
pub struct EquatorialMeanJ2000;
pub struct EME2000;
```
Mean equatorial frame referred to the standard epoch J2000.0
(JD 2 451 545.0 TT). Axes are defined by the mean ecliptic and equinox of
J2000, using the IAU 1976/1980 precession-nutation constants.
This is the **working frame** for most internal transforms in siderust
because precession-only rotations are cheap and widely tabulated.
`EME2000` is provided as an explicit CCSDS-facing synonym of the same axes.
Its transform to/from `EquatorialMeanJ2000` is the identity, but keeping the
name separate preserves frame provenance in exchanged data.
### 3.4 FK4 B1950
```rust
pub struct FK4B1950;
```
The **Fourth Fundamental Catalogue** equatorial frame, referred to the mean
equator and equinox of the Besselian epoch B1950.0. The FK4 → ICRS
transformation uses the Standish (1982) frame-tie rotation matrix.
**When to use `FK4B1950`:**
- Converting positions from legacy FK4-epoch catalogues.
- Cross-matching with historical observing records.
**Accuracy note:** The FK4 → FK5 (ICRS) transformation involves a frame
rotation, an equinox correction, and an E-term removal. siderust implements
the constant rotation matrix; E-term removal is not yet included.
### 3.5 TEME, True Equator, Mean Equinox
```rust
pub struct TEME;
```
The **True Equator, Mean Equinox** frame is the de facto reference for
SGP4/SDP4 (TLE) satellite orbit propagation. The TEME-to-TOD transformation
is a single rotation about the z-axis by the equation of the equinoxes:
```
TEME → Rz(Δψ · cos εA) → TOD (EquatorialTrueOfDate)
```
**When to use `TEME`:**
- Propagating TLE elements with SGP4/SDP4.
- Importing NORAD ephemerides.
### 3.6 Galactic
```rust
pub struct Galactic;
```
The **Galactic coordinate system** (IAU 1958), centred on the Sun, with the
fundamental plane parallel to the Galactic plane. Galactic longitude *l*
increases towards the Galactic centre; Galactic latitude *b* is positive
towards the North Galactic Pole.
The Galactic → ICRS rotation is a pre-computed constant matrix derived from
the North Galactic Pole coordinates (α = 192.85948°, δ = 27.12825°) and the
Galactic centre position angle (l₀ = 32.93192°), per Murray (1989).
### 3.7 Ecliptic Frames
| `EclipticMeanJ2000` | Mean ecliptic and equinox of J2000 |
| `EclipticMeanOfDate` | Mean ecliptic and equinox of observation epoch |
| `EclipticTrueOfDate` | True ecliptic (adds nutation in obliquity and longitude) |
---
## 4. Horizontal Frame
```rust
pub struct Horizontal;
```
Local horizontal frame centred on the observer. Spherical coordinates are
**(altitude, azimuth)**, altitude measured from the horizon (+90° = zenith),
azimuth measured from North through East.
Every `Position<Topocentric, Horizontal, U>` implicitly carries a
`Geodetic<ECEF>` via the `Topocentric` center parameter.
---
## 5. Planetary Body-Fixed Frames
These frames rotate with the respective body, defined by IAU 2015 rotation
parameters (α₀, δ₀, W). The transformation from body-fixed to ICRS is:
```
R = Rz(−(α₀ + 90°)) · Rx(−(90° − δ₀)) · Rz(−W)
```
where α₀ and δ₀ define the body's north pole direction in ICRS, and W is
the prime meridian angle (degrees).
The **frame marker types** (zero-sized structs) are defined in `affn::frames`
behind `feature = "astro"` so that `affn`'s derive macros can generate
inherent `Direction`/`Position` constructors and getters (`lat()`, `lon()`,
`radius()`). They are re-exported from `siderust::coordinates::frames`
and `siderust::coordinates::frames::planetary` for convenience.
The **IAU rotation parameters** remain in `siderust::coordinates::frames::planetary`.
The corresponding `FrameRotationProvider` implementations are organized under
`siderust::coordinates::transform::providers::frames_planetary`.
| Mercury body-fixed | `MercuryFixed` | Mercury | (lat, lon, radius) |
| Venus body-fixed | `VenusFixed` | Venus | (lat, lon, radius) |
| Mars body-fixed | `MarsFixed` | Mars | (lat, lon, radius) |
| Moon PA | `MoonPrincipalAxes` | Moon | (lat, lon, radius) |
| Jupiter System III | `JupiterSystemIII` | Jupiter | (lat, lon, radius) |
| Saturn body-fixed | `SaturnFixed` | Saturn | (lat, lon, radius) |
| Uranus body-fixed | `UranusFixed` | Uranus | (lat, lon, radius) |
| Neptune body-fixed | `NeptuneFixed` | Neptune | (lat, lon, radius) |
| Pluto body-fixed | `PlutoFixed` | Pluto | (lat, lon, radius) |
### IAU Rotation Parameters
Each body's rotation is defined by three functions of time:
- **α₀(T)**, right ascension of the north pole (degrees), T in Julian centuries
- **δ₀(T)**, declination of the north pole (degrees), T in Julian centuries
- **W(d)**, prime meridian angle (degrees), d in days from J2000.0
These are stored as `IauRotationParams` constants (e.g., `MARS_ROTATION`)
in `coordinates::frames::planetary`.
---
## 6. The Earth-Rotation Chain
The canonical ITRS → EquatorialMeanJ2000 rotation is implemented in
`crate::astro::earth_rotation_provider::itrs_to_equatorial_mean_j2000_rotation`.
The same chain is also exposed through public `FrameRotationProvider`
implementations for `GCRS`, `CIRS`, `TIRS`, `ITRF`, and `ECEF`.
```
ITRS ──W⁻¹──▶ TIRS ──ERA──▶ CIRS ──Q──▶ GCRS/ICRS ──P──▶ EquatorialMeanJ2000
```
| **W** | Polar motion (xₚ, yₚ, s′) | EOP → `polar_motion_matrix_from_eop` |
| **ERA** | Earth Rotation Angle | UT1 → `earth_rotation_angle` |
| **Q** | CIO/CIP (X, Y, s) | nutation IAU 2000B ± EOP dX,dY |
| **P** | Precession ICRS → MeanJ2000 | `FrameRotationProvider<ICRS, EquatorialMeanJ2000>` |
Public provider coverage now includes:
- `GCRS ↔ CIRS`
- `CIRS ↔ TIRS`
- `TIRS ↔ ITRF`
- `ICRS ↔ CIRS/TIRS/ITRF/ECEF`
- `EclipticMeanJ2000`, `EquatorialMeanJ2000`, `EME2000`, `ICRF`, `TEME`,
`Galactic`, and `FK4B1950` ↔ `CIRS/TIRS/ITRF/ECEF`
**Time-scale contract:** The `jd` argument to `itrs_to_equatorial_mean_j2000_rotation`
is a **Terrestrial Time (TT)** Julian Date.
---
## 7. Frame-Rotation Hub
All frame rotations route through the **ICRS** hub frame:
```
F1 → ICRS → F2
```
The following constant rotation matrices are pre-computed:
| FK4 B1950 → ICRS | `FK4_TO_ICRS` | Standish (1982) + frame bias |
| Galactic → ICRS | `GALACTIC_TO_ICRS` | Murray (1989), NGP coordinates |
| ICRS → EquatorialMeanJ2000 | `FRAME_BIAS_ICRS_TO_J2000` | IAU 2006 frame bias |
Time-dependent rotations:
| GCRS ↔ CIRS | CIO/CIP matrix **Q** |
| CIRS ↔ TIRS | Earth Rotation Angle |
| TIRS ↔ ITRF | Polar motion matrix **W** |
| TEME ↔ TOD | Rz(equation of equinoxes) |
| EquatorialMean ↔ EquatorialTrueOfDate | IAU 2006 precession + IAU 2000B nutation |
| Body-fixed ↔ ICRS | IAU 2015 rotation parameters |
Provider implementations are grouped by responsibility:
- `providers::frames_inertial`
- `providers::frames_earth`
- `providers::frames_catalog`
- `providers::frames_teme`
- `providers::frames_planetary`
- `providers::centers_standard`
- `providers::centers_planetary`
Shared helper utilities in `providers::mod` handle inversion, hub composition,
and rotation of ecliptic ephemeris vectors into the requested destination frame.
---
## 8. Geodetic Coordinates and Ellipsoid Conversion
### 8.1 `Geodetic<F, U>` (siderust) / `ellipsoidal::Position<C, F, U>` (affn)
```rust
pub type Geodetic<F, U = Meter> = affn::ellipsoidal::Position<Geocentric, F, U>;
```
`Geodetic<F>` is the first-class type for Earth-surface positions. The ellipsoid
is encoded in the frame `F` via `HasEllipsoid`:
- `Geodetic<ECEF>`, WGS84
- `Geodetic<ITRF>`, GRS80
### 8.2 Converting to/from Cartesian ECEF
```rust
use siderust::coordinates::centers::Geodetic;
use siderust::coordinates::frames::ECEF;
use qtty::*;
let coord = Geodetic::<ECEF>::new(-17.8925 * DEG, 28.7543 * DEG, 2396.0 * M);
let ecef = coord.to_cartesian::<Meter>();
// Round-trip
let back = Geodetic::<ECEF>::from_cartesian(&ecef);
```
Named getters (`lat()`, `lon()`, `altitude()`) are generated automatically by the
`#[frame(inherent, ellipsoid = "...")]` derive attribute on each frame.
---
## 9. Summary Table
| ICRS | Int'l Celestial Ref. System | Quasar positions | Star catalogues |
| GCRS | Geocentric CRS | ≈ ICRS (< 1 mas offset) | Aberration, parallax |
| MeanJ2000 | Equatorial Mean J2000 | IAU 1976 precession | Internal working frame |
| EME2000 | Earth Mean Equator/Equinox J2000 | Same axes as MeanJ2000 | CCSDS / flight-dynamics exchange |
| FK4 B1950 | FK4 Equatorial B1950 | FK4 catalogue | Legacy catalogues |
| TEME | True Equator Mean Equinox | SGP4 convention | TLE/satellite orbits |
| Galactic | Galactic (IAU 1958) | Galactic plane + NGP | Milky Way structure |
| EclMeanJ2000 | Ecliptic Mean J2000 | Ecliptic plane of J2000 | Planetary ephemerides |
| CIRS | Celestial Intermediate RS | CIP + CIO | Intermediate Earth-orientation diagnostics |
| TIRS | Terrestrial Intermediate RS | CIP + ERA | Intermediate Earth-orientation diagnostics |
| ECEF | Earth-Centred Earth-Fixed | Provider-aligned with ITRF; WGS84 geodetic tag | WGS84 site input / Earth-fixed vectors |
| ITRF | Int'l Terrestrial Ref. Frame | Full EOP chain | Geodetic / VLBI |
| MercuryFixed | Mercury body-fixed | IAU 2015 rotation | Mercury surface |
| VenusFixed | Venus body-fixed | IAU 2015 rotation | Venus surface |
| MarsFixed | Mars body-fixed | IAU 2015 rotation | Mars surface |
| MoonPA | Moon Principal Axes | IAU 2015 rotation | Lunar surface |
| JupiterSysIII | Jupiter System III | IAU 2015 rotation | Jupiter magnetosphere |
| SaturnFixed | Saturn body-fixed | IAU 2015 rotation | Saturn surface |
| UranusFixed | Uranus body-fixed | IAU 2015 rotation | Uranus surface |
| NeptuneFixed | Neptune body-fixed | IAU 2015 rotation | Neptune surface |
| PlutoFixed | Pluto body-fixed | IAU 2015 rotation | Pluto surface |
| Horizontal | Local horizon | Observer's local vertical | Telescope pointing |
---
## 10. Current Non-Goals
Local orbital frames (`RTN`, `LVLH`, `VNC`) and covariance transport between
them and the inertial Cartesian frame are now first-class through the
orbit-relative API in `astro::dynamics::frames::LocalOrbitalFrame<M>` and
`astro::dynamics::covariance::StateCovariance<F>`. Each instance is built
from a concrete `OrbitState`, so the state-dependent nature of the frame is
preserved at the type level.
Other operational frames (e.g. body-fixed frames for minor planets, or
observer-defined topocentric frames beyond `Horizontal`) are still out of
scope for the typed frame system.
---
*Last updated by the P0–P2 coordinate model refactor.*