Skyfield’s Accuracy and Efficiency

This document is a work in progress, that will be expanded into a full guide. Right now it covers only one topic.

Precession and Nutation

As explained in the section on Apparent right ascension and declination, Skyfield uses the IAU 2000A precession-nutation model to determine the orientation of the Earth’s axes on any given date. This is used in:

  • Apparent right ascension and declination as returned by radec().

  • Geographic positions generated by an Earth ellipsoid like the wgs84 model.

  • The true_equator_and_equinox_of_date reference frame that can be used to generate (x,y,z) coordinates as described in the Coordinates chapter.

  • The ITRS reference frame offered through the itrs object, which combines the orientation of the poles and equinox with the daily rotation of the Earth.

In case you ever need to do low-level math of your own, each time object offers a matrix t.M that rotates coordinates from the ICRS into the Earth equatorial coordinate system of that date and time. See the section on Rotation Matrices for a guide to using a rotation matrix.

Polar Motion

It was discovered more than a century ago that the Earth’s crust has a slight freedom to wobble with respect to the Earth’s axis of rotation in space, because the continents and ocean basis are bound to the planet’s mass only through the fluid coupling of our planet’s viscous mantle. In Skyfield you can see the size of the effect by loading an official data file from the International Earth Rotation Service (IERS) and measuring the maximum excursions of the polar motion parameters x and y:

from skyfield.api import load
from skyfield.data import iers

url = load.build_url('finals2000A.all')
with load.open(url) as f:
    finals_data = iers.parse_x_y_dut1_from_finals_all(f)

ts = load.timescale()
iers.install_polar_motion_table(ts, finals_data)

tt, x_arcseconds, y_arcseconds = ts.polar_motion_table
print('x:', max(abs(x_arcseconds)), 'arcseconds')
print('y:', max(abs(y_arcseconds)), 'arcseconds')
x: 0.32548 arcseconds
y: 0.596732 arcseconds

In what kinds of Skyfield calculations does the exact position of the Earth’s crust come into play?

At the most basic level, the two polar motion rotations are applied directly to the ITRS reference frame in skyfield.framelib.itrs, supplementing the changes in the Earth’s orientation that Skyfield was already expecting thanks to its IAU 2000A precession and nutation models. This, in turn, slightly affects:

  • The position of an observer on the Earth’s surface.

  • The relative position of a target with respect to an observer on the Earth’s surface.

  • All alt-azimuth coordinates, since the polar angles x and y tilt the zenith and local horizon against which altitude and azimuth are measured for a particular observer.

  • The position of any observation target that’s located on the Earth’s surface — for example, if you are calculating the position of a ground station from the perspective of a space probe.

To have Skyfield apply polar motion when computing positions and coordinates, simply install the IERS tables on your timescale object as shown in the example code above. Polar motion will be used everywhere that it applies.

Using too many CPU cores

On some systems, users have reported that Skyfield consumes 100% of all of their CPUs and makes it difficult to do other work.

This isn’t something that Skyfield has direct control over. It’s the underlying NumPy library that decides how to perform each of the math operations that Skyfield requests. And in this case, the user’s installed version of NumPy was deciding to run a vector operation in parallel across all the CPUs. (Ironically, this made the operation slower!)

In case you find NumPy misbehaving in the same way on your system, the user reported that they were able to force single-threaded behavior by setting this environment variable:

export OPENBLAS_NUM_THREADS=1

The same solution might work on your system.