Routines allow for reduction to geocentric and topocentric equatorial coordinates and can correct for: precession, annual and diurnal aberration, annual and diurnal parallax, nutation, light travel time, light deflection and atmospheric refraction (in both optical and millimetre/sub-millimetre).
Calendar routines allow for conversion between calendar time, UNIX time, sidereal time and Julian Dates, and offsets between Universal Coordinated Time (UTC), Universal Time (UT1) and Terrestrial Time (TT) are readily calculated.
Routines for transforming from equatorial to horizon coordinates are also provided.
AEPHEM is based on AA, by Stephen L. Moshier, available at http://www.moshier.net/. Most algorithms are taken from the Astronomical Almanac, and references for each function are provided in these help pages. The functions for parsing JPL ephemerides are based on the http://ephemeris.com software library.
APHEM is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
Copyright (C) 2008 Adam Hincks, Princeton University.
Reducing the rectangular, heliocentric coordinates to an apparent altitude and azimuth on the surface of the earth is a subtle process requiring several corrections. The functions that perform the reductions are described in Astrometric Reductions.
#include <aephem.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #define LATITUDE -12.345 // Degrees east of the meridian. #define LONGITUDE -67.890 // Degrees north of the equator. #define ALTITUDE 5200 // Metres above sea level. int main(int argc, char *argv[]) { double jd_ut, jd_ut1, jd_tt, last, ra, dec, dist, alt, az; jd_ut = ae_ctime_to_jd(time(NULL)); // Current Julian date in UT measure. jd_ut1 = jd_ut + ae_dut1(jd_ut) * AE_D_PER_S; // UT1 measure. jd_tt = jd_ut1 + ae_delta_t(jd_ut1) * AE_D_PER_S; // TT measure. last = aes_last(jd_ut1, LONGITUDE); // Local apparent sidereal time. // Get the geocentric ra/dec of Mars. ae_geocentric_from_orbit(jd_tt, ae_orb_earth, ae_orb_mars, &ra, &dec, &dist); // Get the apparent ra/dec of Mars (no atmospheric model). aes_topocentric(jd_ut1, LATITUDE, LONGITUDE, dist, &ra, &dec); // Convert to alt/az. ae_radec_to_altaz(last, LATITUDE, ra, dec, &alt, &az); printf("JD (UT1) = %.5f, JD (TT) = %.5f\n", jd_ut1, jd_tt); printf("Apparent ra/dec of Mars = " ae_hms_fmt ", " ae_dms_fmt "\n", ae_hms_arg(ra), ae_dms_arg(dec)); printf("Az/alt of Mars = " ae_dms_fmt ", " ae_dms_fmt "\n", ae_dms_arg(az), ae_dms_arg(alt)); return 0; }
Compile with: gcc -o quick_example quick_example.c -laephem -lm
ae_ or aes_. The latter prefix indicates a "simplified" function which requires fewer arguments but may sacrifice flexibility or efficiency.
Global variables also begin with the prefix ae_; similarly, constants (defined as preprocessor macros) begin with AE_.
Here are some useful constants for converting between units:
Some functions require the local apparent sidereal time (LAST). In AEPHEM, LAST is always passed and returned in units of degrees. The LAST is the sidereal time at the geographical location of the observer, hence "local". It has also been corrected for nutation so that the true length of the day is used, hence "apparent", as opposed to mean sidereal time (MST), which uses the mean length of the day. Routines for calculating the LAST, and other sidereal times are:
There are several time scales pertinent to ephemerides and astronomical reductions. This is necessary because the length of the day varies as tidal forces alter the earth's rotation. The day is lengthening by about a second every two years, though on shorter time scales the rotational period is variable and difficult to predict. The different timescales are designed to cope with this erratic behaviour for different applications. The important ones for AEPHEM are:
.
. TT is used in ephemerides.
In AEPHEM, function prototypes indicate which timescale is expected by appending a lower-case suffix, i.e., jd_utc, jd_ut1, jd_tt.
The following functions can be used to convert between UTC, UT1 and TT. Note that these functions return times in units of seconds, while JD's are in units of days; take care to convert to days when adjusting a JD.
;
.Here are some useful constants:
References:
ptable of the ae_orbit_t variable is NULL, ae_kepler() computes the position from the orbital information stored in the other structure members — i, W, w, a, etc. Otherwise, it computes the position using the perturbation coefficients.Of the application of Kepler's Laws, little need be said here. The curious user may refer to the source code of ae_kepler() which is copiously documented.
Built-in tables of perturbation coefficients are provided for the eight planets, the moon and Pluto. The global ae_orbit_t variables ae_orb_mercury, ae_orb_venus, etc., contain these perturbation coefficient tables and are suitable for passing to ae_kepler(). Additionally, pointers to these global variables are stored in ae_orb_planet, with the indices in the order of the enum ae_ss_bodies_t.
The tables of coefficients were derived by a least squares fit of periodic terms to JPL's DE404 ephemerides. The periodic frequencies used were determined by spectral analysis and comparison with VSOP87 and other analytical planetary theories. The least squares fit to DE404 covers the interval from -3000 to +3000 for the outer planets, and -1350 to +3000 for the inner planets.
The files mer404.c, ven404.c, ... , plu404.c contain numerical tables for computing the J2000 heliocentric ecliptic longitude, latitude, and distance of the indicated planet. Each file includes a table of statistics from a comparison with DE404. Maximum deviations from DE404 are shown, in arcseconds, over each interval of 500 Julian years. The figure tabulated for deviation in radial distance is scaled relative to the mean distance; to convert to astronomical units, multiply by 4.848e-6 times the mean distance in AU.
The lunar ephemeris files mlr404.c and mlat404.c generate positions relative to the mean equinox and ecliptic of date. They assume the DE403 precession constants used in precess.c and the obliquity in epsilon.c. These differ somewhat from DE200 or IAU constants but are thought to be more accurate.
See Appendix A: Perturbation Coefficient File Formats for details on the format of the perturbation table files.
To use a JPL ephemeris, first initialise with ae_jpl_init() to create an ae_jpl_handle_t variable. One can then use ae_jpl_get_coords() to determine coordinates. Call ae_jpl_close() to free a ae_jpl_handle_t variable.
The functions that performs these computations are described in the sections below. For straightforward applications, however, there are macros which automatically call the necessary reduction functions.
The first class of macros takes an object position and reduces it to its apparent geocentric coordinates in right ascension and declination at the epoch of observation. They are:
The second class of macros take a geocentric position and reduces it to its apparent coordinates at a particular location on the surface of the earth. For Solar System objects, the largest correction is for Diurnal Parallax. The macros are:
Here follow descriptions of the astrometric reductions which are provided for by AEPHEM, in the order that they are applied for reducing catalogue or ephemeris coordinates to topocentric apparent coordinates.
The light travel time for the inner planets is on the order of minutes, while for distant planets it can be hours. The size of the correction can be significant; for example, when Venus is near the earth, it is about 50 seconds of arc.
The functions that account for light-travel time are:
The effect is due to the bending of light in the sun's gravitational field. It is calculated with the function ae_relativity().
Use ae_annual_aberration() to correct for annual aberration.
The earth's precession changes the apparent position of celestial objects by about 50 seconds of arc per annum.
The function ae_precess() corrects for precession.
Nutation is usually expressed as a series. The largest term has a period of 6798 days and amplitudes of 17.2 seconds of arc in longitude and 9.2 seconds of arc in obliquity. The other terms have shorter periods and are significantly smaller.
To calculate the nutation in longitude and obliquity, use ae_nutation_lon_ob(). These values can then be used to correct for nutation using ae_nutate(). To do both these procedures in one step, use aes_nutate().
Diurnal aberration can be calculated with ae_diurnal_aberration().
Use ae_diurnal_parallax() to compute diurnal parallax.
AEPHEM provides two atmospheric refraction correction models. For visible bands, use ae_refrac_visible(); for infrared through millimetre, use ae_refrac_ulich().
| Correction | Summary | Approximate Size
|
| Light-Travel Time | Due to the finite speed of light, a body is seen at an old position on its orbit, not its current position. | Up to tens of seconds of arc.
|
| Light Deflection | Light rays passing near to the sun are bent by its gravitational field. | Maximum 1.8 seconds of arc.
|
| Annual Aberration | Aberration of light due to the earth's orbital motion. | Up to 20 seconds of arc.
|
| Precession | Precession of the earth's axis of rotation. | About 50 seconds of arc per annum.
|
| Nutation | `Nodding' of the earth's axis of rotation due to tidal interactions with the moon and sun. | Up to 17 seconds of arc.
|
| Diurnal Aberration | Aberration of light due to the earth's rotation. | Less than a third of a second of arc.
|
| Diurnal Parallax | Parallax of nearby objects due to the angle subtended by the earth's diameter. | Up to a minute of arc for nearby planets.
|
| Atmospheric Refraction | Refraction of light in the earth's atmosphere. | Several minutes of arc near the horizon. |
.cat.
Catalogues are columnated ASCII files. Columns are separated by spaces or tabs. Lines beginning with a hash (#) are comments and are ignored by AEPHEM.
An orbit catalogue file should have twelve columns, containing (in order):
) — the angle between the orbital plane and the plane of the ecliptic;
) — the angle in the plane of the ecliptic between the vernal point (
) and the point where the orbit crosses above the ecliptic;
) — the angle in the orbital plane between the longitude of the ascending node and the perihelion (the point in the orbit closest to the sun);
) — the distance between the centre of the orbit and the perihelion (or, equivalently, the aphelion);0) since it is readily calculated from the semi-major axis using Kepler's third law;
) — the eccentricity of the orbit determines the shape of the ellipse;
) — the angle between the perihelion and the point on the auxiliary circle (i.e., the the circle with the same centre and semi-major axis as the orbital ellipse) at which the planet would be at the epoch;
) is defined for these orbital elements;Here is an figure which visualises the orbital elements described above:
An star catalogue file should have thirteen columns, containing (in order):
);
);The constellation boundaries on the celestial sphere are stored in ae_constel_boundary. Given a right ascension and declination, ae_coord_to_constel_index() determines in which constellation they fall.
tabl[] of longitude coefficients, tabb[] of latitude coefficients, tabr[] of radius coefficients, and args[] of trigonometric argument harmonics. All the data are organised for efficient access by a computer. In the source files the data are broken up into lines of print, and the order of the lines of arguments in args[] corresponds to the order of the lines of longitude, latitude, and radius coefficients in the other arrays.
In the args table, the first column is the number of items combined to form the trigonometric argument. The next pairs of columns describe the items. The first column of each pair is the harmonic, the second column is the planet number. The last column is the highest polynomial degree of time for this argument.
Thus in mar404.c, the second line of the argument table args[] reads:
3, 4, 3, -8, 4, 3, 5, 2,
For each planet, the fundamental-frequency angular argument is an initial phase angle plus a frequency multiplied by the time variable. Thus, from the arrays freqs[] and phases[] in the file gplan.c,
where
is in units of 10,000 Julian years from J2000 and the result is measured in arcseconds.
Corresponding to this argument are the amplitude coefficients from the same line of the longitude, latitude, or radius table. The cosine and sine amplitude coefficients of the highest degree term appear first. For the longitude, the complete term corresponding to the second line of coefficients is, from tabl[],
where, as before,
The first line of args[] lists 0 periodic arguments. This is a special case denoting an expression that is just a polynomial in time. In mar404.c the first line of args[] reads
0, 4,
indicating a 4th degree polynomial in
. For the longitude, the coefficients of the polynomial are given in the corresponding line (the first line) of tabl[]. Thus, the complete term is
in arcseconds, where
is measured in units of 10,000 Julian years from J2000.
| AEPHEM documentation generated by Doxygen v1.5.8 at Tue Aug 4 08:54:09 2009. |