C source code for JPL DE ephemerides

Last updated 2011 December 27

Click here to download the source code (about 35 KBytes)

What this source code does: At present, this source code provides several tools for manipulating and computing positions from JPL DE-xxx binary and ASCII ephemerides. Unlike most other source codes for this purpose, it can handle either "little-Endian" (Intel) or "big-Endian" (PowerPC, SPARC) ephemerides, and can swap between assorted ephemeris versions without needing to be recompiled; instead, when it first reads an ephemeris, the byte order and ephemeris version are determined. It works under DOS/Windows and under Linux (and probably other OSes, but my machine only dual-boots to those two), and in 32-bit and 64-bit environments. It is based on C source code from Piotr A. Dybczyński, of the Astronomical Observatory of the A. Mickiewicz University; I essentially used the inner details of his code to do computations, and heavily revised the interface to that code; the result now bears only a passing resemblance to the original.

Also, the basic ephemeris functions are encapsulated so that you can use them without needing to know a great deal about how the inner portions of the code work. You can just call the functions and use the results. The error handling has been cleaned up; instead of bombing out inelegantly when a file is not opened or some similar error occurs, an error code is returned, and you can then decide what to do about it (notify a user, try another file name, etc.)

Quite a bit of optimization has been added, discussed in the file improve.txt in the source ZIP file. The source is somewhat more readable, with terse variable names replaced with descriptive ones and some comments added.

The code has also been arranged so that it can be made into a Win32 DLL. This is not, of itself, especially useful, except that it does make it straightforward to call the functions from languages such as BASIC and Pascal that support calls to DLLs, as well as from some scriptable languages (though I must confess I'm not too knowledgeable about how that works.)

The extension '.cpp' is used to force the stricter type-checking of C++ compilers. However, you can rename all the sources to '.c' and compile with any C compiler.

I've tested my source with Microsoft 16-bit and 32-bit compilers, the OpenWatcom 32-bit compiler, MinGW, and with gcc in Linux. The source is sufficiently generic that it should port readily to any platform, including ones with byte order opposite to that of the PC (it's been tested on a PowerPC Mac). The source code does not really think in terms of 'little-Endian' and 'big-Endian' byte order. Instead, it checks to see if the ephemerides have a byte order opposite to that of the current computer, and then swaps bytes as needed, on the fly. That's why there's nothing along the lines of an #ifdef BIG_ENDIAN in the source code.

JPL DE basics: Fortunately, I need not write much here, because the Readme file from the JPL ftp site covers the basics better than I could anyway. Those looking for more information as to the inner workings of DE ephemerides, as well as how to convert their raw output into useful positions, may be interested in the book Fundamental Ephemeris Computations, by Paul J. Heafner, published by Willmann-Bell.

This page, apparently written for folks dealing with the timing issues of pulsars, goes into some of the mathematical/algorithmic details of how DE data is used. Most of it is stuff you do not really need to know if all you want to do is to get positions out of DE files.

What's the difference between JPL ephemeris XXX and JPL ephemeris YYY?: The ephemerides have gone through three "series": the 100 series, the 200 series, and the 400 series. (Actually, there was a fourth "000" series, but I've yet to see any actual ephemerides, just comments mentioning that such ephemerides once existed.) DE-1xx was referenced to the B1950 ecliptic, and is basically of historical interest only. The DE-2xx series switched to J2000; in fact, DE-200 was nothing more than DE-118 rotated into the J2000 plane. DE-202 included some new data that hadn't been available when the DE-1xx series was created. Most of the versions are described here.

The DE-4xx series has almost completely displaced DE-2xx. It includes still more observations, and comes in several "flavors". DE-405 and DE-406 get the most use. The former covers the years 1600 to 2200 at maximum precision; DE-406 covers the years -3000 to +3000 at only slightly reduced precision. As described at the above link, for DE406, "...the interpolating accuracy is no worse than 25 meters for any planet and no worse than 1 meter for the moon." In other words, most people will notice no difference whatsoever.

Not described at the above link are DE-404 (a "long ephemeris" version of DE-403, again providing a longer time span at the cost of some precision), DE-408 (a very long time span ephemeris that I've been unable to find anywhere), and DE-418 (a recent version that appears to incorporate lots of data that wasn't used in previous versions, and at least in theory, ought to be still more accurate). But again, for most uses, any DE-4xx ephemeris ought to be more than accurate enough.

Finding DE files: You can purchase a CD-ROM from Willmann-Bell containing the full DE-200, DE-405, and DE-406, for about US $25.

You can also download more pieces of these (or other) ephemerides from this JPL ftp site. The Linux folder contains ephemerides in the order intended for Intel machines; the SunOS folder contains data for opposite-Endian machines. (Files with either endianness will work with this software.) Other folders provide test data, ASCII versions of the ephemerides, and some inter-office memoranda describing each version of the ephemerides. Almost all DE ephemeride versions are available, ranging from the very archaic DE-102 to the "latest and greatest" DE-422, DE-423, and DE-424 (and possibly newer ones by the time you read this).

I'd recommend either DE-422 or DE-423. Both incorporate observations that were unavailable in previous DEs. The former covers the entire range from years -3000 to +3000. However, the file is a 544-MByte download. DE-423 is provided as two 13-MByte files. One covers 1900 to 2050; the other, 2050 to 2200. If desired, they can be merged into a single 26-MByte ephemeris covering 1900 to 2200 using the merge_de utility that is part of the source code on this page.

DE-424 was created "primarily to support the NASA Mars Science Laboratory navigation team during early cruise" (according to the Readme file for DE-424). It doesn't seem to be recommended for general use.

Bolder citizens can download JPL ephemerides in ASCII form from the ascii folder of the above site. Assorted software is available to convert these to binary form, or you can use the asc2eph routine supplied with the source code on this page. In at least a few cases, the "pre-built" binary ephemerides in the Linux and SunOS folders don't have the full range of the source ephemerides. In such cases, you may want to download ASCII ephemerides and make your own. This also allows you to make an ephemeris file covering a specific range. If, for example, you know you'll only be dealing with data between years 2000 and 2012, you can make a much smaller binary ephemeris covering only those years.

You can click here for documentation of these ephemerides.

The following are mostly of historical interest, or perhaps of interest if one is looking for smaller downloads:

One can also click here to get the full DE-405 (55 MBytes) in non-Intel order, or you can click here to get the full DE-405 (55 MBytes) in Intel order. Either file covers the years 1600 to 2200.

Steve Hutcheon kindly pointed me to this ZIPped DE file (about 50.8 MBytes), supplied as part of the OCCULT software for computing occultation data.

From this site , you can download a DE-405 file covering the years 1940 to 2060 (about 11 Mbytes). One slight problem: the ASCII header indicates a time span of 1600 to 2200. That won't affect the source code on this site, nor most other software, but your mileage may vary. The same site provides a DE-410 file covering the years 1960 to 2020, about 5.5 MBytes. Note that the use of DE-410 is usually discouraged.

Interestingly, the IMCCE (formerly known as the Bureau des Longitudes) in Paris is now providing ephemerides in the same format as JPL. (Note that these ephemerides have something of a flaw: the ranges start at noon instead of midnight, which can lead to small errors for almost all ephemeris code. I made some small revisions to my own code -- look for comments about IMCCE in jpleph.cpp for details -- that allow it to get around this problem; but other software may not have been modified yet to allow reading of IMCCE files.)

You can click here for the download page, which offers ephemerides covering roughly 1900 to 2100 (about 18 MBytes) or 1000 to 3000 (about 180 MBytes), in both endiannesses. All four files will work with the software on this page, and with most other JPL ephemeris software... but not all; there are a few subtle differences in these files that may throw software that isn't expecting them, and the aforementioned flaw is probably a show-stopper for most uses. You can click here for the paper describing how these ephemerides were created.

If I'm understanding the paper correctly, it sounds as if the IMCCE ephemerides may offer benefits when dealing with Venus; it incorporates some Venus Express data that is not yet present in the JPL ephemerides.

If you have a copy of Guide 8.0, you already have a large chunk of DE. On the second CD-ROM, the jpl_eph directory contains the file sub_de.406. This gives ephemerides for years 1800 to 2200, and is provided courtesy of Willmann-Bell.

If you have a copy of the Guide 9.0 DVD, you'll find both the sub_de.406 and jpl_eph.422 in the jpl_eph directory. jpl_eph.422 covers years -3000 to +3000, and is about 557 MBytes.

All of these provide ephemerides in big-Endian byte order, suitable for PowerPCs and Sparc. However, the source code provided on this page and the Find_Orb orbit determination software will read such ephemerides anyway. The ephemeris files have extensions such as .200, .405, or .406, depending on which DE they're from.

Note that the ftp sites and the Willmann-Bell CD-ROM also provide DE data in ASCII form. None of my software (at least right now) makes use of ASCII DE (and it wouldn't be very useful to do so anyway). Instead, the asc2eph program converts them to the more usual binary form. (And eph2asc can do the reverse conversion, though it's hard to come up with cases where that would be useful.)

Steve Preston has pointed out to me that the folks behind the OrbFit orbit calculation software have posted some pieces of DE-405 on their ftp site. You can get pieces of DE-405 in either Intel or big-Endian format. According to the documentation on the site, the (big-Endian) de405.dat file covers years 1970 to 2020. The Intel-order de405_win.dat file covers the years 1960 to 2020. However, the file sizes seem to indicate that the range of the latter could be about 150 years. I've not investigated to find out what it really is.

Assorted pieces of DE-200, 202, 403, 405, and 406 are also available here (though this site is currently unavailable).

Other DE source code: Truthfully, I think rather well of the JPL ephemeris source code posted on this page. But there are a lot of implementations of these functions, and you may find that you prefer one of them, especially if C is not your cup of tea.

In addition to Piotr Dybczyński's C source code (the basis for the source code on this page, though it's almost completely changed now), there are (at least) two other versions of C source code to access DE ephemerides mentioned on the JPL site, as well as source codes in FORTRAN and Java. Almost all of the C source code versions have a testeph.c program that reads a 'testpos.###' file, where '###' is the ephemeris version number, and checks to ensure that the code functions correctly. The version from this site is no exception; the test program is supplied, and also serves as an example of how to use the functions.

The ephemeris.com implementation looks to be an improvement on the original routines; it is available here. It looks as if the author has made many of the same changes I did to produce a "saner" set of routines.

Alan W. Irwin has fixed some problems with the ephemeris.com code and added a Fortran interface and a modern build system. He has released his ephcom2 version as ephcom-2.0.1; click here for details.

There is also yet another version of C++ source code to access DE ephemerides on this site. Documentation appears to be extensive, but in Spanish, and I therefore can't say much about this code.

Shinobu Takesako has posted this page of C source code for reading DE files. It includes a potentially very useful program to convert from the UNIX format to the DOS one, and vice versa. This is of no real help if you're using the code provided on this site, which handles either format. But most software out there is not so flexible, and requires DE files in the platform-specific format.

Also, the book Fundamental Ephemeris Computations includes source code in both PowerBasic and C, which goes beyond the basic "get rectangular coordinates for this object" to higher-level functions.

Some utilities for manipulating DE data: On the JPL ftp site, DE is provided in 'chunks' of a few megabytes. It can be nice to be able to merge two or more together to make a single ephemeris file covering a longer time span. In the other direction, persons with the Willmann-Bell CD, containing DE ephemerides as single files of up to 200 MBytes, might like a means of making a "sub-ephemeris" covering only a few years.

You can click here to download C source and Windows executables for both utilities (about 44 KBytes). Run the programs without command-line arguments, and each will give a summary of how it is to be used. Both will work with either byte order (if fed Intel-order files, they will create Intel-order output; if fed UNIX-order files, they will create UNIX-order output.) The sub_eph.cpp function requires the basic astronomical function library provided elsewhere on this site (just so that it can do date conversions). The merge_de.cpp program is a "standalone" beast.

Another utility of possible interest is Shinobu Takesako's code to convert DE files from Intel to UNIX byte order, or vice versa.

Why this source code exists: As mentioned above, there are at least least three different, freely-available C sources for DE access, plus FORTRAN and Java sources, and one could question the need for a fourth. However, I've revised Find_Orb and Guide to use DE ephemerides. (Both can compute planetary/lunar positions using analytic Poisson series, a sort of hybrid of the familiar Taylor power series and trigonometric series. This isn't bad, but there are reasons to use DE rather than analytic series, which is why Find_Orb and Guide can now use DE when available.)

The current C sources are suitable if you're writing your own software and can do a lot of your own programming, to craft them to your project of choice, for a program that won't be redistributed to others. But people using Find_Orb or Guide will not wish to recompile every time they swap ephemeris versions, or get a new ephemeris with a different byte order. They may want to switch to different ephemeris files: I hope to supply a small piece of DE-405 and/or DE-406 with the programs, covering a short time frame, but people can get DE from ftp sites, or purchase it on CD-ROM. They may want to use DE-405 over the time span it covers, switching to DE-406 when they get outside that time span. Also, DE-200 is not obsolete; it's used in the Astronomical Almanac, and people may want to replicate results from that publication.

Reasons to use JPL DE rather than analytic series: Much current astronomy software (including my own, in some situations) uses analytic series rather than the "original" DE. For computing planetary ephemerides, I've been using PS-1996 for high precision and VSOP-87 where only lower precision is needed. For lunar ephemerides, I've been using ELP-82. All of these were developed at the Bureau des Longitudes in Paris, and both are really sufficient for most purposes. They express lunar and planetary positions as the sum of a series of trigonometric terms, some multiplied by powers of time (a Poisson series). I've written and posted C source code to compute PS-1996 positions and C source code to compute ELP-82 positions on this site.

On the plus side, these analytic series are convenient in that you have a small file of a few hundred KBytes with which to deal, and their use is well-documented in books such as Meeus' Astronomical Algorithms. You can also throw away small terms if you don't really need immense accuracy. In some places in my code, I've just added up the first few terms of VSOP to get a "ballpark" (within a few arcminutes) position (see sm_vsop.cpp in the Find_Orb source code.)

However, there are a few things favoring DE use. ELP and VSOP are based on DE-200, which is essentially obsolete with the availability of DE-4xx ephemerides. PS-1996 is a little better off, being based on DE-403; it provides an extremely accurate match, right down to the milliarcsecond level. However, DE-403 has been supplanted by DE-405 and DE-406. And the time range of PS-1996 is limited to 1900 to 2100 (except for Neptune and Pluto, which extend back to 1850 and 1700 respectively.) For more distant dates, and for anything involving the moon, all we've got are DE-200 based results.

Also, computing a position from DE is much faster than doing so from an analytic series. Users of my Find_Orb orbit determination software may have seen it slow down on long integration runs, primarily because it computes thousands of positions using ELP-82 and PS-1996. Switch over to use of DE (which Find_Orb can do), and you see quite a speedup.

What this source code should eventually do: I'd like to revise the source code a bit so that it can also read ASCII ephemerides. (Admittedly of limited utility, since one can and should convert ASCII ephemerides to binary anyway.) It could then read all three of the basic ephemeris flavors: little-Endian binary, big-Endian binary, and ASCII. It would be able to do so without needing adjustment by the user; it would simply open the file and determine the type of ephemeris, and the inner details would be of no concern to the user (or the programmer).

Once it could do so, it would be relatively straightforward to provide code to write out a new DE binary ephemeris. That is, one might use the code to open up a DE ephemeris (of any of the three flavors), and ask that a smaller ephemeris covering a particular time span be written out, in any of the three flavors.

Of somewhat lesser importance, I'd like the program to be able to process other JPL ephemerides preceding DE-200. These are mostly of historical interest only, since they're in the B1950 system (DE-2xx ephemerides are in J2000, and DE-4xx are in ICRF) and are not as accurate in any case. Also, they are not as readily available as the later ephemerides. However, such historical interest does exist (say, when one needs to replicate an older result), and I have some interest as well in Steve Moshier's DE118i source code. This code takes initial state vectors and does the numerical integration, using the same physical model as an older JPL ephemeris, to create a "DE-118i" ephemeris. I can't say this is high on my agenda... if it turns out, though, that one can supply new state vectors and some new constants to create something very close to DE-4xx, my interest will increase greatly. (To do so, I would need to compute Chebyshev polynomial coefficients, but this is not especially difficult.) One could then compute, for example, a DE-405-level accuracy ephemeris covering the full time span of DE-406; or make a DE-formatted ephemeris covering tens or hundreds of millennia, perhaps at lower precision. At the very least, it would let you download a small program and use it to generate an enormous multi-hundred-MByte ephemeris, rather than requiring you to download that enormous ephemeris.

Copyright/legal issues: This code is released under the GPL (General Public License).