C source code for JPL DE ephemerides

Last updated 29 March 2005

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

  • JPL DE basics
  • What this source code does
  • Finding DE files
  • Other DE source code
  • Some utilities for manipulating DE data
  • Why this source code exists
  • Reasons to use JPL DE rather than analytic series
  • What this source code should eventually do
  • Copyright/legal issues
  • 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 this source code does: At present, this source code provides a way to compute positions from the JPL DE-200 and 4xx binary ephemerides. Unlike most other source codes for this purpose, it can handle either "little-Endian" or "big-Endian" 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.) 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.

    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 works. 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.)

    A modest amount of optimization has been added, discussed a bit in the file IMPROVE.DOC 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 WATCOM 32-bit compiler, and 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. (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.)

    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. Those not wishing to expend money can download more pieces of these (or other) ephemerides from this JPL ftp site. The full ephemerides tend to be large (DE-406 runs to about 200 MBytes), but as you'll see, "subset" ephemerides are available covering shorter spans. In particular, this file from the second JPL site covers the years 1800 to 2100, and is a mere 9.7 MBytes.

    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.

    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.

    All of these provide ephemerides in "wrong-Endian" byte order. 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).

    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 "wrong-Endian" format. As far as I know, this is the only source for ephemerides in Intel order. According to the documentation on the site, the ("wrong-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).

    Bolder citizens can download JPL ephemerides in ASCII form from this site. Assorted software is available to convert these to binary form. This allows one to play around with older ephemerides such as DE-102 (now of historical interest only) or newer ephemerides such as DE-413, DE-414, and DE-418. You can click here for documentation of these ephemerides and comments on how to convert from ASCII to binary form.

    Other DE source code: In addition to Piotr Dybczyński's C source code (the basis for the source code on this page), 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.

    What looks to be a better implementation than these 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.

    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 would 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 to use DE ephemerides, and may soon do the same for my Guide software. (Both 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 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, until recently) 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.

    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, 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. 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. 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 in the public domain. Of course, should you use it, an acknowledgment would be appreciated, and I'd like to know about it. Also, I would ask that any improvements made to the code be supplied to me to be posted for others to use (or, perhaps better still, just send me a link to your own posting of such code.)