Use a JPL planetary ephemeris to predict planet positions.

## Project description

This package lets you use a Jet Propulsion Laboratory (JPL) ephemeris to predict the position and velocity of a planet, or the magnitude and rate-of-change of the Earth’s nutation, or of the angle of the Moon’s libration. Its only dependency is NumPy. To take the smallest and most convenient ephemeris as an example, you can install this package alongside the 27 MB ephemeris DE421 with two commands:

pip install jplephem pip install de421

Loading DE421 and computing a position require one line of Python each, given a barycentric dynamical time expressed as a Julian date:

import de421 from jplephem import Ephemeris eph = Ephemeris(de421) x, y, z = eph.position('mars', 2444391.5) # 1980.06.01

The result of calling `position()` is a 3-element NumPy array giving
the planet’s position in the solar system in kilometers along the three
axes of the ICRF (a more precise reference frame than J2000 but oriented
in the same direction). If you also want to know the planet’s velocity,
call `position_and_velocity()` instead:

position, velocity = eph.position_and_velocity('mars', 2444391.5) x, y, z = position # a NumPy array xdot, ydot, zdot = velocity # another array

Velocities are returned as kilometers per day.

Both of these methods will also accept a NumPy array, which is the most efficient way of computing a series of positions or velocities. For example, the position of Mars at each midnight over an entire year can be computed with:

import numpy as np t0 = 2444391.5 t = np.arange(t0, t0 + 366.0, 1.0) x, y, z = eph.position('mars', 2444391.5)

You will find that `x`, `y`, and `z` in this case are each a NumPy
array of the same length as your input `t`.

The string that you provide to `e.compute()`, like `'mars'` in the
example above, actually names the data file that you want loaded from
the ephemeris package. To see the list of data files that an ephemeris
provides, consult its `names` attribute. Most of the JPL ephemerides
provide thirteen data sets:

earthmoon mercury pluto venus jupiter moon saturn librations neptune sun mars nutations uranus

Each ephemeris covers a specific range of dates, beyond which it cannot provide reliable predictions of each planet’s position. These limits are available as attributes of the ephemeris:

t0, t1 = eph.jalpha, eph.jomega

The ephemerides currently available as Python packages (the following links explain the differences between them) are:

- DE405 (May 1997) — 54 MB covering years 1600 through 2200
- DE406 (May 1997) — 190 MB covering years -3000 through 3000
- DE421 (February 2008) — 27 MB covering years 1900 through 2050
- DE422 (September 2009) — 531 MB covering years -3000 through 3000
- DE423 (February 2010) — 36 MB covering years 1800 through 2200

## Earth and Moon

The raw ephemerides provide one position for the Earth-Moon barycenter, and another for the position of the Moon relative to the geocenter. The JPL expects you to combine these values yourself if you want the Solar System location of the Earth or Moon, which gives you the chance to be more efficient by asking the ephemeris for each position only once:

barycenter = eph.position('earthmoon', j) moonvector = eph.position('moon', j) earth = barycenter - moonvector * eph.earth_share moon = barycenter + moonvector * eph.moon_share

## High-Precision Dates

Since all modern Julian dates are numbers larger than 2.4 million, a standard 64-bit Python or NumPy float necessarily leaves only a limited number of bits available for the fractional part. Technical Note 2011-02 from the United States Naval Observatory’s Astronomical Applications Department suggests that the precision possible with a 64-bit floating point Julian date is around 20.1 µs.

If you need to supply times and receive back planetary positions with greater precision than 20.1 µs, then you have two options.

First, you can supply times using the special `float96` NumPy type,
which is also aliased to the name `longfloat`. If you provide either
a `float96` scalar or a `float96` array as your `tdb` parameter to
any `jplephem` routine, you should get back a high-precision result.

Second, you can split your date or dates into two pieces, and supply
them as a pair of arguments two `tdb` and `tdb2`; one popular
approach for how to split your date is to use the `tdb` float for the
integer Julian date, and `tdb2` for the fraction that specifies the
time of day. Nearly all `jplephem` routines accept this optional
`tdb2` argument if you wish to provide it, thanks to the work of
Marten van Kerkwijk!

## Waiting To Compute Velocity

When a high-level astronomy library computes the distance between an
observer and a solar system body, it typically measures the light travel
delay between the observer and the body, and then uses a loop to take
the position several steps backwards in time until it has determined
where the planet *was* back when the light left its surface (or cloud
deck) that is reaching the eye or sensor of the observer right *now*.

To make such a loop less computationally expensive — a loop that only
needs to compute the planet position repeatedly, and can wait to compute
the velocity until the loop’s conclusion — `jplephem` provides a way
to split the `position_and_velocity()` call into two pieces. This
lets you examine the position *before* deciding whether to also proceed
with the expense of computing the velocity.

The key is the special `compute_bundle()` method, which returns a
tuple containing the coefficients and intermediate results that are
needed by *both* the position and the velocity computations. There is
nothing wasted in calling `compute_bundle()` whether you are going to
ask for the position, the velocity, or both as your next computing step!

So your loop can look something like this:

while True: bundle = eph.compute_bundle('mars', tdb) position = eph.position_from_bundle(bundle) # ...determine whether you are happy... if you_are_happy: break # ...otherwise, adjust `tdb` and then let # control return back to the top of the loop # Now we can re-use the values in `bundle`, for free! velocity = eph.velocity_from_bundle(bundle)

This is especially important when the number of dates in `tdb` is
large, since vector operations over thousands or millions of dates are
going to take a noticeable amount of time, and every mass operation that
can be avoided will help move your program toward completion.

## Reporting issues

You can report any issues, bugs, or problems at the GitHub repository:

## Changelog

**2013 November 26 — Version 1.2**

- Helge Eichhorn fixed the default for the
`position_and_velocity()`argument`tdb2`so it defaults to zero days instead of 2.0 days. Tests were added to prevent any future regression.

**2013 July 10 — Version 1.1**

- Deprecates the old
`compute()`method in favor of separate`position()`and`position_and_velocity()`methods. - Supports computing position and velocity in two separate phases by
saving a “bundle” of coefficients returned by
`compute_bundle()`. - From Marten van Kerkwijk: a second
`tdb2`time argument, for users who want to build higher precision dates out of two 64-bit floats.

**2013 January 18 — Version 1.0**

- Initial release

## References

The Jet Propulsion Laboratory’s “Solar System Dynamics” page introduces the various options for doing solar system position computations: http://ssd.jpl.nasa.gov/?ephemerides

The plain ASCII format element sets from which the `jplephem` Python
ephemeris packages are built, along with documentation, can be found at:
ftp://ssd.jpl.nasa.gov/pub/eph/planets/ascii/

Equivalent FORTRAN code for using the ephemerides be found at the same FTP site: ftp://ssd.jpl.nasa.gov/pub/eph/planets/fortran/

## Project details

## Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help | File type | Python version | Upload date |
---|---|---|---|

jplephem-1.2.tar.gz (9.4 kB) Copy SHA256 hash SHA256 | Source | None | Nov 26, 2013 |