Skip to content

Earth Orientation Data

The eop module provides data structures and functions for the updating, loading, and use of Earth orientation parameter (EOP) data.

Earth Orientation Parameters are empirically observed, estimated parameters that describe the irregularities in Earth's rotation in space. When combined with their specific related models they provide the mechanism to transform between an Earth-Centered Earth-Fixed (ECEF) reference frame and an inertial reference frame.

IERS

The International Earth Rotation Service (IERS) was established in 1987 by the International Astronomical Union and the International Union of Geodesy and Geophysics. The IERS provides data on Earth orientation, on the International Celestial Reference System/Frame, and on the International Terrestrial Reference System/Frame. The IERS also maintains conventions containing models, constants and standards used for modeling Earth orientation.

The IERS deals with reference systems and reference frames. A reference system is an idealized mathematical concept for defining a reference used to represent the state of objects in that system. The two primary reference systems developed by the IERS are the International Celestial Reference System (ICRS) and International Terrestrial Reference System (ITRS).

A reference system is a concept and cannot be used directly, therefore the IERS develops reference frames, which are specific realizations of a given reference system. A reference frame realization defines the models, standards, and associated data products for users to actually interact and use that reference system. The primary reference frames of the IERS are the International Celestial Reference Frame (ICRF) and International Terrestrial Reference Frame (ITRF).

The ICRS and ITRS models are defined with respect to the solar system barycenter1. However, for many satellite-specific engineering applications we are primarily concerned with geocentric references, centered at Earth. Therefore, RAstro primarily deals with the Geocentric Celestial Reference Frame (GCRF) and Geocentric Terrestrial Reference Frame (GTRF). For most intents and purposes the international and geocentric references are identical as there is no rotation component between ICRS and GCRS (or ITRF and GCRF)2. The transformation between the two reference systems and frames is simply a pure translation.

For a more detailed discussion of reference frames and systems please read IERS Technical Note 36 provides an in-depth discussion of the concepts presented and discussed here.

Earth Orientation Products

The IERS provides various Earth orientation products which are derived from Very Long Baseline Interferometry (VLBI) or a network of terrestrial GPS3 reference stations. The continual observations made by these stations are combined with specific reference frame realizations (e.g. the IAU 2010 conventions) to model Earth orientation and enable the transformation between inertial and Earth-fixed reference frames.

The Earth orientation parameter products come in multiple variations, all of which can be found at the IERS data products site. These variations arise from the selection of precession-nutation model, ITRF realization, the data sources, and data processing time span. There are two precession-nutation models widely in use today: IAU 1980 nutation theory and the IAU2006/2000A precession-nutation model. The ITRF 2014 realization is the most recent realization and preferred in most cases.

For data products there are two primary distinctions: standard products and long term products. Standard products, which are produced daily, to provide a daily estimate of the past Earth orientation along with forward-looking predictions available for use in planning. Long term data products are only available for past days, and are produced less frequently, but provider higher accurate estimates of Earth orientation.

For most purposes the standard products provide sufficient accuracy along with the benefit of having fairly accurate forward-looking predictions. Therefore, RAstro defaults to using standard Earth Orientation data products wherever possible. Unless otherwise stated or specified, RAstro uses IERS standard product generated with respect to IAU 2006/2000A precession-nutation model and consistent with ITRF2014.

Earth Orientation Parameters

Rastro provides the EarthOrientationData object to handle loading, storing, and providing Earth orientation data for use. The package also includes default data files for ease of use that are sufficient for most purposes.

Loading Data Data Sets

Earth orientation data is loaded by creating an instance of an EarthOrientationData object with from the desired data source. There are four methods that can be used: from_default_standard, from_c04_file, from_default_standard, and from_standard_file. The from_default_standard and from_c04_file methods will load long-term IERS C04 products and expect to be passed such as an input. Similarly, from_default_standard and from_standard_file can be used to load either Bulletin A or Bulletin B data from the IERS standard file product format.

When creating any new Earth Orientation data instance there are two parameters that are set at loading time which will determine how the EOP instances handles data returns for certain cases. The first parameter is the extrapolate parameter, which can have a value of Zero, Hold, or Error. This value will determine how requests for data points beyond the end of the loaded data are handled. The possible behaviors are - Zero: Returned values will be 0.0 where data is not available - Hold: Will return the last available returned value when data is not available - Error: Data access attempts where data is not present will panic and terminate the program

The second parameter the the interpolate setting. When interpolate is set to true and data requests made for a point that wasn't explicitly loaded as part of the input data set will be linearly interpolated to the desired time. When set to false, the function call will return the last value prior to the requested data.

Below is an example of loading C04 data

use rastro::eop::{EarthOrientationData, EOPExtrapolation};

fn main() {
    // Example 1: Load Default C04 File with extrapolation

    // EOPExtrapolation is a enum that sets the extrapolation mode. It has possible values of:
    //   - EOPExtrapolation::Hold
    //   - EOPExtrapolation::Zero
    //   - EOPExtrapolation::Error
    //
    // The Interpolation mode here is set as `true`
    let eop = EarthOrientationData::from_default_c04(EOPExtrapolation::Hold, true);

    // Last ut1_utc offset stored in table.
    // eop.mjd_max is the maximum MJD date of data loaded in the table.
    let last_ut1_utc = eop.get_ut1_utc(eop.mjd_max.into());

    // Get UT1_UTC value that is well beyond the end of the loaded data
    let hold_ut1_utc = eop.get_ut1_utc(9999999.9);

    // Confirm that the EOP provider extrapolated beyond the end of the table by holding the value
    assert!(last_ut1_utc == hold_ut1_utc);


    // Example 2: Load Default C04 data with "Zero" extrapolation value
    let eop = EarthOrientationData::from_default_c04(EOPExtrapolation::Zero, true);

    // Confirm that values beyond the end of table are zero
    assert!(eop.get_ut1_utc(9999999.9) == 0.0);

    // Example 3: Load C04 data from user-provided file

    // let filepath = Path::new("~/PATH/TO/YOUR/EOP_FILE/iau2000A_c04_14.txt");
    // let eop = EarthOrientationData::from_c04_file(filepath, EOPExtrapolation::Error, false);
}
import rastro

if __name__ == '__main__':
    # Example 1: Load Default C04 File with extrapolation

    # EOPExtrapolation is string that maps to the Rust extrapolation mode. The possible values are:
    #   - "Hold"
    #   - "Zero"
    #   - "Error"
    #
    # The Interpolation mode here is set as `True`
    eop = rastro.EarthOrientationData.from_default_c04("Hold", True)

    # Last ut1_utc offset stored in table.
    # eop.mjd_max is the maximum MJD date of data loaded in the table.
    last_ut1_utc = eop.get_ut1_utc(eop.mjd_max)

    # Get UT1_UTC value that is well beyond the end of the loaded data
    hold_ut1_utc = eop.get_ut1_utc(9999999.9)

    # Confirm that the EOP provider extrapolated beyond the end of the table by holding the value
    assert last_ut1_utc == hold_ut1_utc

    # Example 2: Load Default C04 data with "Zero" extrapolation value
    eop = rastro.EarthOrientationData.from_default_c04("Zero", True)

    # Confirm that values beyond the end of table are zero
    assert eop.get_ut1_utc(9999999.9) == 0.0

    # Example 3: Load C04 data from user-provided file

    # filepath = "~/PATH/TO/YOUR/EOP_FILE/iau2000A_c04_14.txt"
    # eop = EarthOrientationData::from_c04_file(filepath, "Error", False)

The process for loading standard data is similar. However, when loading standard files there is one other parameter which comes into play, the Earth Orientation Type. This type setting determines whether the Bulletin A or Bulletin B data is loaded into the object when parsing the file. In rust

use rastro::eop::{EarthOrientationData, EOPExtrapolation, EOPType};

fn main() {
    // Example 1: Load Default C04 File with extrapolation

    // EOPExtrapolation is a enum that sets the extrapolation mode. It has possible values of:
    //   - EOPExtrapolation::Hold
    //   - EOPExtrapolation::Zero
    //   - EOPExtrapolation::Error
    //
    // The Interpolation mode here is set as `true`
    //
    // EOPType is an enum that sets indicates which type of Earth Orientation to load from a file.
    // It is also a property of all EarthOrientationData objects that provides what type of data
    // was loaded into the object. Possible values are:
    //   - EOPType::StandardBulletinA
    //   - EOPType::StandardBulletinB
    //   - EOPType::C04
    let eop = EarthOrientationData::from_default_standard(EOPExtrapolation::Hold, true, EOPType::StandardBulletinA);

    // Last ut1_utc offset stored in table.
    // eop.mjd_max is the maximum MJD date of data loaded in the table.
    let last_ut1_utc = eop.get_ut1_utc(eop.mjd_max.into());

    // Get UT1_UTC value that is well beyond the end of the loaded data
    let hold_ut1_utc = eop.get_ut1_utc(9999999.9);

    // Confirm that the EOP provider extrapolated beyond the end of the table by holding the value
    assert!(last_ut1_utc == hold_ut1_utc);


    // Example 2: Load Default C04 data with "Zero" extrapolation value
    let eop = EarthOrientationData::from_default_standard(EOPExtrapolation::Zero, true, EOPType::StandardBulletinB);

    // Confirm that values beyond the end of table are zero
    assert!(eop.get_ut1_utc(9999999.9) == 0.0);

    // Example 3: Load Standard data from user-provided file

    // let filepath = Path::new("~/PATH/TO/YOUR/EOP_FILE/iau2000A_finals_ab.txt");
    // let eop = EarthOrientationData::from_standard_file(filepath, EOPExtrapolation::Error, false, EOPType::StandardBulletinB);
}
import rastro

if __name__ == '__main__':
    # Example 1: Load Default C04 File with extrapolation

    # EOPExtrapolation is string that maps to the Rust extrapolation mode. The possible values are:
    #   - "Hold"
    #   - "Zero"
    #   - "Error"
    #
    # The Interpolation mode here is set as `True`
    #
    # EOPType is an enum that sets indicates which type of Earth Orientation to load from a file.
    # It is also a property of all EarthOrientationData objects that provides what type of data
    # was loaded into the object. Possible values are:
    #   - "StandardBulletinA"
    #   - "StandardBulletinB"
    #   - "C04"
    eop = rastro.EarthOrientationData.from_default_standard("Hold", True, "StandardBulletinA")

    # Last ut1_utc offset stored in table.
    # eop.mjd_max is the maximum MJD date of data loaded in the table.
    last_ut1_utc = eop.get_ut1_utc(eop.mjd_max)

    # Get UT1_UTC value that is well beyond the end of the loaded data
    hold_ut1_utc = eop.get_ut1_utc(9999999.9)

    # Confirm that the EOP provider extrapolated beyond the end of the table by holding the value
    assert last_ut1_utc == hold_ut1_utc

    # Example 2: Load Default C04 data with "Zero" extrapolation value
    eop = rastro.EarthOrientationData.from_default_standard("Zero", True, "StandardBulletinB")

    # Confirm that values beyond the end of table are zero
    assert eop.get_ut1_utc(9999999.9) == 0.0

    # Example 3: Load Standard data from user-provided file

    # filepath = "~/PATH/TO/YOUR/EOP_FILE/iau2000A_finals_ab.txt"
    # eop = EarthOrientationData::from_standard_file(filepath, "Error", False, "StandardBulletinA")

Note

For applications where the time is in the future it is recommended to use standard EOP data as standard files contain predictions for approximately 1 year into the future and will increase accuracy of analysis by accounting for Earth orientation corrections.

For analysis for scenarios in the past it is recommended to use the final C04 products as they contain the highest accress estimates of Earth orientation data.

Accessing Earth Orientation Data

Most of the time the data stored by the Earth orientation object is not used directly, instead the object is passed to others that will make the appropraite access calls.

If your application calls for accessing The EarthOrientationData object provides a number of methods for accessing different Earth orientation Parameters stored by the object.

use rastro::eop::{EarthOrientationData, EOPExtrapolation, EOPType};

#[allow(non_snake_case)]
#[allow(unused)]
fn main() {
    // Load Default C04 File with extrapolation
    let eop = EarthOrientationData::from_default_standard(EOPExtrapolation::Hold, true, EOPType::StandardBulletinA);

    // Get UT1-UTC off set for a given MJD. Value is in seconds.
    let ut1_utc = eop.get_ut1_utc(59569.0);

    // Get x- and y-components of polar motion. Value is in radians.
    let (pm_x, pm_y) = eop.get_pm(59569.0);

    // Get dX and dY Precession/Nutation model corrections. Value is in radians.
    let (dX, dY) = eop.get_dxdy(59569.0);

    // Get Length of Day (LOD) offset. Value is in seconds.
    let lod = eop.get_lod(59569.0);
}
import rastro

if __name__ == '__main__':
    # Load Default C04 File with extrapolation
    eop = rastro.EarthOrientationData.from_default_standard("Hold", True, "StandardBulletinA")

    # Get UT1-UTC off set for a given MJD. Value is in seconds.
    ut1_utc = eop.get_ut1_utc(59569.0)

    # Get x- and y-components of polar motion. Value is in radians.
    pm_x, pm_y = eop.get_pm(59569.0)

    # Get dX and dY Precession/Nutation model corrections. Value is in radians.
    dX, dY = eop.get_dxdy(59569.0)

    # Get Length of Day (LOD) offset. Value is in seconds.
    lod = eop.get_lod(59569.0)

One example of using the Earth orientation data directly is plotting the evolution of the difference between the UT1 and UTC timescales. The discontinuous jumps are when leap seconds were introduced.

Plot Source
fig_ut1_utc_evolution.py
# Generate plot of mean anomaly versus true anomaly for a range of eccentricies.
# Highlights the effect of eccentricity on the difference of the two.


import os
import pathlib
import numpy as np
import plotly.graph_objects as go
import plotly.io as pio
import rastro

## Define Constants
SCRIPT_NAME = pathlib.Path(__file__).stem
OUTDIR = os.getenv("RASTRO_FIGURE_OUTPUT_DIR") # Build Environment Variable
OUTFILE = f"{OUTDIR}/{SCRIPT_NAME}.html"

## Create figure
fig = go.Figure()
fig.update_layout(dict(paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)'))
fig.update_yaxes(
    tickmode='linear', title_text="UT1-UTC offset [seconds]"
)

## Generate and plot data

# Load EOP Data
eop = rastro.EarthOrientationData.from_default_standard("Hold", True, "StandardBulletinA")

# Get range of dates stores in EOP data
days = np.arange(eop.mjd_min, eop.mjd_max, 1)

# Get UT1-UTC offsets
ut1_utc = [eop.get_ut1_utc(mjd) for mjd in days]

fig.add_trace(go.Scatter(x=days, y=ut1_utc))

# Update Axes
fig.update_xaxes(
    tickmode='linear', tick0=eop.mjd_min, dtick=300, tickformat='5f',
    title_text="Modified Julian Date"
)
fig.update_xaxes(
    showgrid=True, gridwidth=1, gridcolor='LightGrey', range=[eop.mjd_min, eop.mjd_max],
    showline=True, linewidth=2, linecolor='Grey'
)
fig.update_yaxes(
    showgrid=True, gridwidth=1, gridcolor='LightGrey',
    showline=True, linewidth=2, linecolor='Grey'
)

pio.write_html(fig, file=OUTFILE, include_plotlyjs='cdn', full_html=False, auto_play=False)

Downloading updated Earth Orientation Data

The final functionality that Rastro provides is the ability to download new Earth orientation parameter data files.

The functions download_c04_eop_file and download_standard_eop_file can be used to downloaded the latest product files from IERS servers and store them locally at the specified filepath. The download functions will attempt to create the necessary directory structure if required.

use rastro::eop::{download_c04_eop_file, download_standard_eop_file};

fn main() {
    // Download latest C04 final product file
    download_c04_eop_file("./c04_file.txt").unwrap();

    // Download latest standard product file
    download_standard_eop_file("./standard_file.txt").unwrap();
}
import rastro

if __name__ == '__main__':
    # // Download latest C04 final product file
    rastro.eop.download_c04_eop_file("./c04_file_py.txt")

    # // Download latest standard product file
    rastro.eop.download_standard_eop_file("./standard_file_py.txt")

If using the RAstro CLI, product files can be download with

rastro eop download --product final final_c04_eop_file.txt

or

rastro eop download --product standard standard_eop_file.txt

  1. A barycenter is the center of mass of two or more bodies. The solar system barycenter is the center of mass of the entire solar system. Due to significant mass contributions and distances of Jupiter and Saturn, the solar system barycenter evolves in time and is sometimes outside of the Sun's outer radius. 

  2. For applications requiring the highest levels of fidelity, the equations of motion of an Earth satellite, with respect to the GCRS will contain a relativistic Coriolis force due to geodesic precession not present in the ICRS. 

  3. Now frequently GNSS receivers 

Back to top