debian-skyfield/skyfield/documentation/planets.rst

313 lines
10 KiB
ReStructuredText
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

====================================
Planets, and Choosing an Ephemeris
====================================
If you are interested in observing the planets,
the Jet Propulsion Laboratory (JPL)
has prepared long tables that predict the positions of the planets
both in the the distant past and out into the future.
A table of positions is called an *ephemeris*
and those supplied by the JPL are of very high accuracy.
You can ask Skyfield to download an ephemeris from the JPL
by giving ``load()`` a filename.
Or you can load an ephemeris that youve already saved to disk
with :func:`~skyfield.iokit.load_file()`.
A popular choice of ephemeris is DE421.
It is recent, has good precision,
was designed for general-purpose use,
and is only 17 MB in size:
.. testsetup::
__import__('skyfield.tests.fixes').tests.fixes.setup()
.. testcode::
from skyfield.api import load
planets = load('de421.bsp')
Once an ephemeris file has been downloaded to your current directory,
re-running your program will simply reuse the copy on disk
instead of downloading it all over again.
After you have loaded an ephemeris and have used a statement like:
.. testcode::
mars = planets['Mars']
— to retrieve a planet, consult the chapter :doc:`positions`
to learn about all the positions that you can use it to generate.
Making an excerpt of an ephemeris
=================================
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 dont 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,
lets pull two weeks of data for Jupiters 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 :func:`~skyfield.iokit.load_file()`.
Popular ephemerides
===================
Here are several popular ephemerides that you can use with Skyfield.
The filenames matching ``de*``
predict the positions of many or all of the major planets,
while ``jup310.bsp`` focuses on Jupiter and its major moons:
========== ====== ============= ==============
Ephemeris Size Years Issued
========== ====== ============= ==============
de405.bsp 63 MB 1600 to 2200 May 1997
de406.bsp 287 MB 3000 to 3000 May 1997
de421.bsp 17 MB 1900 to 2050 February 2008
de422.bsp 623 MB 3000 to 3000 September 2009
de430t.bsp 128 MB 1550 to 2650 February 2010
jup310.bsp 932 MB 1900 to 2100 December 2013
========== ====== ============= ==============
You can think of negative years, as cited in the above table,
as being almost like years BC except that they are off by one.
Historians invented our calendar back before zero was a counting number,
so AD 1 was immediately preceded by 1 BC without a year in between.
But astronomers count backwards AD 2, AD 1, 0, 1, 2, and so forth.
So if you are curious about the positions of the planets back in 44 BC,
when Julius Caesar was assassinated,
be careful to ask an astronomer about the year 43 instead.
How segments are linked to predict positions
============================================
You can ``print()`` an ephemeris to learn which objects it supports.
.. testcode::
print(planets)
.. testoutput::
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
Bodies in JPL ephemeris files are each identified by an integer,
but Skyfield translates them so that you do not have to remember
that a code like 399 stands for the Earth and 499 for Mars.
Each ephemeris segment predicts the position of one body
with respect to another.
Sometimes several segments sometimes have to be combined
to generate a complete position.
The DE421 ephemeris shown above, for example,
can produce the position of the Sun directly.
But if you ask it for the position of Earth
then it will have to add together two distances:
* From the Solar Systems center (0) to the Earth-Moon barycenter (3)
* From the Earth-Moon barycenter (3) to the Earth itself (399)
This happens automatically behind the scenes.
All you have to say is ``planets[399]`` or ``planets['Earth']``
and Skyfield will put together a solution using the segments provided.
.. testcode::
earth = planets['earth']
print(earth)
.. testoutput::
Sum of 2 vectors:
+ Segment 'de421.bsp' 0 SOLAR SYSTEM BARYCENTER -> 3 EARTH BARYCENTER
+ Segment 'de421.bsp' 3 EARTH BARYCENTER -> 399 EARTH
Each time you ask this ``earth`` object for its position at a given time,
Skyfield will compute both of these underlying vectors
and add them together to generate the position.
Closing the file automatically
==============================
If you need to close files as you finish using them
instead of waiting until the application exits,
each Skyfield ephemeris offers a
:meth:`~skyfield.jpllib.SpiceKernel.close()` method.
It can either be called manually when you are done with an ephemeris,
or you can use Pythons |closing|_ context manager
to call the method automatically
at the completion of a ``with`` statement:
.. |closing| replace:: ``closing()``
.. _closing: https://docs.python.org/3/library/contextlib.html#contextlib.closing
.. testcode::
from contextlib import closing
ts = load.timescale(builtin=True)
t = ts.J2000
with closing(planets):
planets['venus'].at(t) # Ephemeris can be used here
planets['venus'].at(t) # But its closed outside the “with”
.. testoutput::
Traceback (most recent call last):
...
ValueError: seek of closed file
.. testcleanup::
__import__('skyfield.tests.fixes').tests.fixes.teardown()
.. _third-party-ephemerides:
Type 1 and Type 21 ephemeris formats
====================================
If you generate an ephemeris with a tool like NASAs
`HORIZONS <https://ssd.jpl.nasa.gov/horizons.cgi>`_ 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:
.. testcode::
load('wld23593.15')
.. testoutput::
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 Skyfields JPL ephemeris support.
The next obstacle, however, will be a lack of support
for Type 21 ephemerides in Skyfield:
.. testcode::
from skyfield.jpllib import SpiceKernel
kernel = SpiceKernel('wld23593.15')
.. testoutput::
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!
* https://pypi.org/project/spktype01/
* https://pypi.org/project/spktype21/
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:
.. testcode::
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)
.. testoutput::
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.