Skyfield: Home • Table of Contents • Changelog • API Reference
For planets and their moons, NASA’s Jet Propulsion Laboratory (JPL) offers high accuracy tables of positions for time spans ranging from decades to centuries. Each table is called an ephemeris, from the ancient Greek word for daily. Here’s how to download and open the JPL ephemeris DE421 and ask for the position of Mars:
from skyfield.api import load
ts = load.timescale()
t = ts.utc(2021, 2, 26, 15, 19)
planets = load('de421.bsp') # ephemeris DE421
mars = planets['Mars Barycenter']
barycentric = mars.at(t)
Or you can compute the position of Mars from another vantage point in the Solar System:
earth = planets['Earth']
astrometric = earth.at(t).observe(mars)
For details:
load()
routine
and how you can choose the directory
to which it downloads files.
Note that ephemeris files never receive updates,
so once you have a file like de421.bsp
on disk
you never need to download it again.barycentric
and astrometric
positions
computed in the code above.To learn more about ephemeris files themselves, keep reading here.
Here are the most popular general-purpose ephemeris files, from the JPL’s famous “DE” Development Ephemeris series.
Issued | Short | Medium | Long |
---|---|---|---|
1997 | de405.bsp 1600 to 2200
63 MB
|
de406.bsp −3000 to 3000
287 MB
|
|
2008 | de421.bsp 1900 to 2050
17 MB
|
de422.bsp −3000 to 3000
623 MB
|
|
2013 | de430_1850-2150.bsp 1850 to 2150
31 MB
|
de430t.bsp 1550 to 2650
128 MB
|
de431t.bsp –13200 to 17191
3.5 GB
|
2020 | de440s.bsp 1849 to 2150
32 MB
|
de440.bsp 1550 to 2650
114 MB
|
de441.bsp −13200 to 17191
3.1 GB
|
You can find even more ephemeris files on the Internet at the various Ephemeris download links listed near the bottom of this page.
How can you choose the right ephemeris for your project?
Make sure that the planets, moons, or other bodies you want to observe
are among the targets supported by the ephemeris.
See Listing the targets that an ephemeris supports below
if you want to download ephemeris files
and examine their contents yourself.
Some online ephemeris directories include an index
that lists the content of each ephemeris in the directory;
look for a file with a name like README.txt
or aa_summaries.txt
.
Choose the shortest ephemeris that will cover the dates your project needs. Not only will a shorter file save download time and disk space, but the most recent short-term ephemerides DE430 and DE440 are more accurate than their long-term counterparts DE431 and DE441 because the shorter files include the effect of the Moon’s liquid core, an effect that’s “not suitable for backward integration of more than a few centuries.”
If you need a specific range of ancient dates but find a long-term ephemeris too large, read the section below about Making an excerpt of an ephemeris — you should be able to generate a smaller file that includes only the range of dates you need.
The most recent ephemeris files should be the most accurate because they are built using the highest accuracy data from humankind’s telescopes and spacecraft.
Note that ephemeris files don’t provide numbers for how accurate their planet positions are. Sometimes you can find ballpark estimates of accuracy in an ephemeris file’s official report. The report The Planetary and Lunar Ephemerides DE430 and DE431, for example, states that:
You can find links to the various ephemeris reports in the Ephemeris bibliography at the bottom of this page. Some ephemeris files also have a built-in text summary you can print to the screen:
print(planets.spk.daf.comments())
; de421.bsp LOG FILE
;
; Created 2008-02-12/11:33:34.00.
...
The more recent ephemeris files tend to have the most informative comment texts.
I myself use DE421 and DE422
because they’re small, accurate, and cover long enough time periods
for all of my projects.
When the time comes to upgrade,
I’ll probably move next to DE440;
its short-term de440s.bsp
file is especially attractive
because it’s only twice the size of DE421
while delivering higher accuracy plus an extra century of data.
To find out what difference the choice of ephemeris makes, simply run a sample calculation with one ephemeris then again using another. The difference will usually be far below the resolution of your instruments unless (a) you’re doing radio astronomy or (b) you’re planning to place an actual payload in orbit around the target body.
You can use print()
to check whether an ephemeris
lists a specific planet or moon.
Here, for example, are the targets supported by DE421:
print(planets)
SPICE kernel file 'de421.bsp' has 15 segments
JD 2414864.50 - JD 2471184.50 (1899-07-28 through 2053-10-08)
0 -> 1 SOLAR SYSTEM BARYCENTER -> MERCURY BARYCENTER
0 -> 2 SOLAR SYSTEM BARYCENTER -> VENUS BARYCENTER
0 -> 3 SOLAR SYSTEM BARYCENTER -> EARTH BARYCENTER
0 -> 4 SOLAR SYSTEM BARYCENTER -> MARS BARYCENTER
0 -> 5 SOLAR SYSTEM BARYCENTER -> JUPITER BARYCENTER
0 -> 6 SOLAR SYSTEM BARYCENTER -> SATURN BARYCENTER
0 -> 7 SOLAR SYSTEM BARYCENTER -> URANUS BARYCENTER
0 -> 8 SOLAR SYSTEM BARYCENTER -> NEPTUNE BARYCENTER
0 -> 9 SOLAR SYSTEM BARYCENTER -> PLUTO BARYCENTER
0 -> 10 SOLAR SYSTEM BARYCENTER -> SUN
3 -> 301 EARTH BARYCENTER -> MOON
3 -> 399 EARTH BARYCENTER -> EARTH
1 -> 199 MERCURY BARYCENTER -> MERCURY
2 -> 299 VENUS BARYCENTER -> VENUS
4 -> 499 MARS BARYCENTER -> MARS
Skyfield can generate positions for any body that an ephemeris links to target zero, the Solar System barycenter. For example, DE421 — as you can see above — provides a segment directly linking the Solar System barycenter with the Sun:
sun = planets['Sun']
print(sun)
'de421.bsp' segment 0 SOLAR SYSTEM BARYCENTER -> 10 SUN
By contrast, generating a position for the Moon with DE421 requires Skyfield to add together two segments behind the scenes. The first segment provides the position of the Earth-Moon center of gravity, while the second segment provides the offset from there to the Moon.
moon = planets['Moon']
print(moon)
Sum of 2 vectors:
'de421.bsp' segment 0 SOLAR SYSTEM BARYCENTER -> 3 EARTH BARYCENTER
'de421.bsp' segment 3 EARTH BARYCENTER -> 301 MOON
Note that most planets are so massive compared to their moons
that you can ignore the difference
between the planet and its system barycenter.
If you want to observe Mars or Jupiter from elsewhere in the Solar System,
just ask for the Mars Barycenter
or Jupiter Barycenter
position instead.
The Earth-Moon system is unusual
for featuring a satellite with so much mass —
though even in that case,
their common barycenter is always inside the Earth.
Only Pluto has a satellite so massive and so distant
that the Pluto-Charon barycenter is in space between them.
Several of the ephemeris files listed below are very large. While most programmers will follow the example above and use DE421, if you wish to go beyond its 150-year period you will need a larger ephemeris. And programmers interested in the moons of Jupiter will need JUP310, which weighs in at nearly a gigabyte.
What if you need data from a very large ephemeris, but don’t require its entire time span?
When you installed Skyfield another library named jplephem
will have been installed.
When invoked from the command line,
it can build an excerpt of a larger ephemeris
without needing to download the entire file,
thanks to the fact that HTTP supports a Range:
header
that asks for only specific bytes of a file.
For example,
let’s pull two weeks of data for Jupiter’s moons
(using a shell variable $u
for the URL
only to make the command less wide here on the screen
and easier to read):
$ u=https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/satellites/jup310.bsp
$ python -m jplephem excerpt 2018/1/1 2018/1/15 $u jup_excerpt.bsp
The resulting file jup_excerpt.bsp
weighs in
at only 0.2 MB instead of 932 MB
but supports all of the same objects as the original JUP310
over the given two-week period:
$ python -m jplephem spk jup_excerpt.bsp
File type DAF/SPK and format LTL-IEEE with 13 segments:
2458119.75..2458210.50 Jupiter Barycenter (5) -> Io (501)
2458119.50..2458210.50 Jupiter Barycenter (5) -> Europa (502)
2458119.00..2458210.50 Jupiter Barycenter (5) -> Ganymede (503)
2458119.00..2458210.50 Jupiter Barycenter (5) -> Callisto (504)
...
You can load and use it directly off of disk
with load_file()
.
If you need to close files as you finish using them
instead of waiting until the application exits,
each Skyfield ephemeris offers a
close()
method.
You can either call it manually,
or use Python’s closing()
context manager
to call close()
automatically when a block of code finishes:
from contextlib import closing
ts = load.timescale()
t = ts.J2000
with closing(planets):
planets['venus'].at(t) # Ephemeris can be used here
If you generate an ephemeris with a tool like NASA’s HORIZONS system, it might be in a format not yet natively supported by Skyfield. The first obstacle to opening the ephemeris might be its lack of a recognized suffix:
load('wld23593.15')
Traceback (most recent call last):
...
ValueError: Skyfield does not know how to open a file named 'wld23593.15'
A workaround for the unusual filename extension is to open the file manually using Skyfield’s JPL ephemeris support. The next obstacle, however, will be a lack of support for Type 21 ephemerides in Skyfield:
from skyfield.jpllib import SpiceKernel
kernel = SpiceKernel('wld23593.15')
Traceback (most recent call last):
...
ValueError: SPK data type 21 not yet supported
Older files with a similar format might instead generate the complaint “SPK data type 1 not yet supported.”
Happily, thanks to Shushi Uetsuki, a pair of third-party libraries exist that offer preliminary support for Type 1 and Type 21 ephemerides!
Their documentation already includes examples of generating raw coordinates,
but many Skyfield users will want to use them
in conjunction with standard Skyfield methods like observe()
.
To integrate them with the rest of Skyfield,
you will want to define a new vector function class
that calls the third-party module to generate coordinates:
from skyfield.constants import AU_KM
from skyfield.vectorlib import VectorFunction
from spktype21 import SPKType21
t = ts.utc(2020, 6, 9)
eph = load('de421.bsp')
earth = eph['earth']
class Type21Object(VectorFunction):
def __init__(self, kernel, target):
self.kernel = kernel
self.center = 0
self.target = target
def _at(self, t):
k = self.kernel
r, v = k.compute_type21(0, self.target, t.whole, t.tdb_fraction)
return r / AU_KM, v / AU_KM, None, None
kernel = SPKType21.open('wld23593.15')
chiron = Type21Object(kernel, 2002060)
ra, dec, distance = earth.at(t).observe(chiron).radec()
print(ra)
print(dec)
00h 27m 38.99s
+05deg 57' 08.9"
Hopefully this third-party support for Type 1 and Type 23 SPK ephemeris segments will be sufficient for projects that need them, until there is time for a Skyfield contributor to integrate such support into Skyfield itself.
Skyfield knows a URL for each of the most popular ephemeris files —
so you can simply load('de421.bsp')
and Skyfield will know where to download the file
if you don’t already have it on disk.
But for more obscure ephemeris files
you might need to give load()
the full URL instead.
Here are some common sites from which you can download official ephemeris files:
For planets:
For planet moons:
DE405 / DE406
DE421
DE430 / DE431
DE440 / DE441
Analysis mentioning several ephemerides
File format .bsp
documentation
.bsp
files)