Swephprg
Swephprg
Swiss Ephemeris is made available by its authors under a dual licensing system. The software developer, who
uses any part of Swiss Ephemeris in his or her software, must choose between one of the two license models,
which are
a) GNU public license version 2 or later
b) Swiss Ephemeris Professional License
The choice must be made before the software developer distributes software containing parts of Swiss
Ephemeris to others, and before any public service using the developed software is activated.
If the developer chooses the GNU GPL software license, he or she must fulfill the conditions of that license,
which includes the obligation to place his or her whole software project under the GNU GPL or a compatible
license. See http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
If the developer chooses the Swiss Ephemeris Professional license, he must follow the instructions as found in
http://www.astro.com/swisseph/ and purchase the Swiss Ephemeris Professional Edition from Astrodienst and
sign the corresponding license contract.
Appendix.....................................................................................................................70
Update and release history........................................................................................................70
Changes from version 2.07 to 2.07.01.........................................................................................72
Changes from version 2.06 to 2.07.............................................................................................72
Changes from version 2.05.01 to 2.06.........................................................................................74
Changes from version 2.05 to 2.05.01.........................................................................................74
Changes from version 2.04 to 2.05.............................................................................................74
Changes from version 2.03 to 2.04.............................................................................................76
Changes from version 2.02.01 to 2.03.........................................................................................76
Changes from version 2.02 to 2.02.01.........................................................................................77
Changes from version 2.01 to 2.02.............................................................................................77
Changes from version 2.00 to 2.01.............................................................................................79
Changes from version 1.80 to 2.00.............................................................................................80
Changes from version 1.79 to 1.80.............................................................................................81
Changes from version 1.78 to 1.79.............................................................................................81
Changes from version 1.77 to 1.78.............................................................................................81
Changes from version 1.76 to 1.77.............................................................................................81
Changes from version 1.75 to 1.76.............................................................................................82
Changes from version 1.74 to version 1.75..................................................................................82
Changes from version 1.73 to version 1.74..................................................................................82
Changes from version 1.72 to version 1.73..................................................................................82
Changes from version 1.71 to version 1.72..................................................................................83
Changes from version 1.70.03 to version 1.71..............................................................................83
Changes from version 1.70.02 to version 1.70.03.........................................................................83
Changes from version 1.70.01 to version 1.70.02.........................................................................83
Changes from version 1.70.00 to version 1.70.01.........................................................................83
Changes from version 1.67 to version 1.70..................................................................................83
Changes from version 1.66 to version 1.67..................................................................................84
Changes from version 1.65 to version 1.66..................................................................................84
Changes from version 1.64.01 to version 1.65.00.........................................................................84
Changes from version 1.64 to version 1.64.01..............................................................................84
Changes from version 1.63 to version 1.64..................................................................................84
Changes from version 1.62 to version 1.63..................................................................................84
Changes from version 1.61.03 to version 1.62..............................................................................84
Changes from version 1.61 to 1.61.01.........................................................................................85
Changes from version 1.60 to 1.61.............................................................................................85
Changes from version 1.51 to 1.60.............................................................................................85
Changes from version 1.50 to 1.51.............................................................................................85
Changes from version 1.40 to 1.50.............................................................................................85
Changes from version 1.31 to 1.40.............................................................................................86
Changes from version 1.30 to 1.31.............................................................................................86
Changes from version 1.27 to 1.30.............................................................................................86
Changes from version 1.26 to 1.27.............................................................................................86
Changes from version 1.25 to 1.26.............................................................................................86
Changes from version 1.22 to 1.23.............................................................................................86
Changes from version 1.21 to 1.22.............................................................................................86
Changes from version 1.20 to 1.21.............................................................................................86
Changes from version 1.11 to 1.20.............................................................................................87
Changes from version 1.10 to 1.11.............................................................................................87
Changes from version 1.04 to 1.10.............................................................................................87
Changes from Version 1.03 to 1.04.............................................................................................87
Changes from Version 1.02 to 1.03.............................................................................................87
Changes from Version 1.01 to 1.02.............................................................................................87
Changes from Version 1.00 to 1.01............................................................................................88
Appendix A..................................................................................................................88
What is missing ?.....................................................................................................................88
Index...........................................................................................................................89
Swiss Ephemeris 4
Swiss Ephemeris 5
Note:
The functions swe_calc_ut() and swe_fixstar_ut() were introduced with Swisseph version 1.60.
If you use a Swisseph version older than 1.60 or if you want to work with Ephemeris Time, you have to proceed as follows instead:
5. At the end of your computations close all files and free memory calling swe_close();
If the environment variable SE_EPHE_PATH exists in the environment where Swiss Ephemeris is used, its
content is used to find the ephemeris files. The variable can contain a directory name, or a list of directory
names separated by ; (semicolon) on Windows or : (colon) on Unix.
void swe_set_ephe_path(char *path);
Usually an application will want to set its own ephemeris, e.g. as follows:
swe_set_ephe_path(”C:\\SWEPH\\EPHE”);
The argument can be a single directory name or a list of directories, which are then searched in sequence. The
argument of this call is ignored if the environment variable SE_EPHE_PATH exists and is not empty.
If you want to make sure that your program overrides any environment variable setting, you can use putenv()
to set it to an empty string.
If the path is longer than 256 bytes, swe_set_ephe_path() sets the path \SWEPH\EPHE instead.
If no environment variable exists and swe_set_ephe_path() is never called, the built-in ephemeris path is
used. On Windows it is ”\sweph\ephe” relative to the current working drive, on Unix it is "/users/ephe".
Asteroid ephemerides are looked for in the subdirectories ast0, ast1, ast2 .. ast9 of the ephemeris directory
and, if not found there, in the ephemeris directory itself. Asteroids with numbers 0 – 999 are expected in directory
ast0, those with numbers 1000 – 1999 in directory ast1 etc.
The environment variable SE_EPHE_PATH is most convenient when a user has several applications installed
which all use the Swiss Ephemeris but would normally expect the ephemeris files in different application-specific
directories. The use can override this by setting the environment variable, which forces all the different
applications to use the same ephemeris directory. This allows him to use only one set of installed ephemeris files
Swiss Ephemeris 7
for all different applications. A developer should accept this override feature and allow the sophisticated users to
exploit it.
1.2 swe_close()
/* close Swiss Ephemeris */
void swe_close(void);
At the end of your computations you can release most resources (open files and allocated memory) used by the
Swiss Ephemeris DLL.
The following parameters survive a call of swe_calc():
the ephemeris path set by swe_set_ephe_path()
the JPL file name set by swe_set_jpl_file()
the geographical location set by swe_set_topo() for topocentric planetary positions
the sidereal mode set by swe_set_sid_mode() for sidereal planetary positions
As soon as you make a call to swe_calc() or swe_fixstar(), the Swiss Ephemeris re-opens again.
1.3 swe_set_jpl_file()
/* set name of JPL ephemeris file */
void swe_set_jpl_file(char *fname);
If you work with the JPL ephemeris, SwissEph uses the default file name which is defined in swephexp.h as
SE_FNAME_DFT. Currently, it has the value ”de406.eph” or ”de431.eph”.
If a different JPL ephemeris file is required, call the function swe_set_jpl_file() to make the file name known to
the software, e.g.
swe_set_jpl_file(”de405.eph”);
This file must reside in the ephemeris path you are using for all your ephemeris files.
If the file name is longer than 256 byte, swe_set_jpl_file() cuts the file name to a length of 256 bytes. The
error will become visible after the first call of swe_calc(), when it will return zero positions and an error
message.
1.4 swe_version()
/* find out version number of your Swiss Ephemeris version */
char *swe_version(char *svers);
/* svers is a string variable with sufficient space to contain the version number (255 char) */
The function returns a pointer to the string svers, i.e. to the version number of the Swiss Ephemeris that your
software is using.
1.5 swe_get_library_path()
/* find out the library path of the DLL or executable */
char *swe_get_library_path(char *spath);
/* spath is a string variable with sufficient space to contain the library path (255 char) */
The function returns a pointer to the string spath, which contains the path in which the executable resides. If it is
running with a DLL, then spath contains the path of the DLL.
int swe_calc_ut ( double tjd_ut, int ipl, int iflag, double* xx, char* serr),
where
tjd_ut =Julian day, Universal Time
ipl =body number
iflag =a 32 bit integer containing bit flags that indicate what kind of computation is wanted
xx =array of 6 doubles for longitude, latitude, distance, speed in long., speed in lat., and speed in dist.
serr[256] =character string to return error messages in case of error.
and
int swe_calc(double tjd_et, int ipl, int iflag, double *xx, char *serr),
same but
tjd_et = Julian day, Ephemeris time, where tjd_et = tjd_ut + swe_deltat(tjd_ut)
#define SE_NPLANETS 23
#define SE_FICT_OFFSET 40
#define SE_NFICT_ELEM 15
#define SE_AST_OFFSET 10000
Additional asteroids
Body numbers of other asteroids are above SE_AST_OFFSET (=10000) and have to be constructed as follows:
ipl = SE_AST_OFFSET + Minor_Planet_Catalogue_number;
e.g. Eros : ipl = SE_AST_OFFSET + 433
The names of the asteroids and their catalogue numbers can be found in seasnam.txt.
Examples are:
5 Astraea
6 Hebe
7 Iris
8 Flora
9 Metis
10 Hygiea
30 Urania
42 Isis not identical with "Isis-Transpluto"
153 Hilda (has an own asteroid belt at 4 AU)
227 Philosophia
251 Sophia
259 Aletheia
275 Sapientia
279 Thule (asteroid close to Jupiter)
375 Ursula
433 Eros
763 Cupido different from Witte's Cupido
944 Hidalgo
1181 Lilith (not identical with Dark Moon 'Lilith')
1221 Amor
1387 Kama
1388 Aphrodite
1862 Apollo (different from Witte's Apollon)
3553 Damocles highly eccentric orbit betw. Mars and Uranus
3753 Cruithne ("second moon" of earth)
4341 Poseidon Greek Neptune (different from Witte's Poseidon)
4464 Vulcano fire god (different from Witte's Vulkanus and intramercurian Vulcan)
5731 Zeus Greek Jupiter (different from Witte's Zeus)
7066 Nessus third named Centaur (beween Saturn and Pluto)
There are two ephemeris files for each asteroid (except the main asteroids), a long one and a short one:
The larger file is about 10 times the size of the short ephemeris. If the user does not want an ephemeris for the
time before 1500 he might prefer to work with the short files. If so, just copy the files ending with ”s.se1” to your
hard disk. Swe_calc() tries the long one and on failure automatically takes the short one.
Swiss Ephemeris 10
Asteroid ephemerides are looked for in the subdirectories ast0, ast1, ast2 .. ast9 etc of the ephemeris
directory and, if not found there, in the ephemeris directory itself. Asteroids with numbers 0 – 999 are expected
in directory ast0, those with numbers 1000 – 1999 in directory ast1 etc.
Note that not all asteroids can be computed for the whole period of Swiss Ephemeris. The orbits of some of
them are extremely sensitive to perturbations by major planets. E.g. CHIRON, cannot be computed for the time
before 650 AD and after 4650 AD because of close encounters with Saturn. Outside this time range, Swiss
Ephemeris returns the error code, an error message, and a position value 0. Be aware, that the user will have to
handle this case in his program. Computing Chiron transits for Jesus or Alexander the Great will not work.
The same is true for Pholus before 3850 BC, and for many other asteroids, as e.g. 1862 Apollo. He becomes
chaotic before the year 1870 AD, when he approaches Venus very closely. Swiss Ephemeris does not provide
positions of Apollo for earlier centuries !
Fictitious planets
Fictitious planets have numbers greater than or equal to 40. The user can define his or her own fictitious planets.
The orbital elements of these planets must be written into the file seorbel.txt. The function swe_calc() looks
for the file seorbel.txt in the ephemeris path set by swe_set_ephe_path(). If no orbital elements file is
found, swe_calc() uses the built-in orbital elements of the above mentioned Uranian planets and some other
bodies. The planet number of a fictitious planet is defined as
All orbital elements except epoch and equinox may have T terms, where
T = (tjd – epoch) / 36525.
(See, e.g., Vulcan, the second last elements set (not the ”Uranian” Vulcanus but the intramercurian hypothetical
planet Vulcan).) ”T * T”, ”T2”, ”T3” are also allowed.
The equinox can either be entered as a Julian day or as ”J1900” or ”B1950” or ”J2000” or, if the equinox of date
is required, as ”JDATE”. If you use T terms, note that precession has to be taken into account with JDATE,
whereas it has to be neglected with fixed equinoxes.
No T term is required with the mean anomaly, i.e. for the speed of the body, because our software can compute
it from semi-axis and gravity. However, a mean anomaly T term had to be added with Vulcan because its speed
is not in agreement with the laws of physics. In such cases, the software takes the speed given in the elements
and does not compute it internally.
From Version 1.62 on, the software also accepts orbital elements for fictitious bodies that move about the earth.
As an example, study the last elements set in the excerpt of seorbel.txt above. After the name of the body, ”,
geo” has to be added.
A special body number SE_ECL_NUT is provided to compute the obliquity of the ecliptic and the nutation. Of
course nutation is already added internally to the planetary coordinates by swe_calc() but sometimes it will be
needed as a separate value.
If no bits are set, i.e. if iflag == 0, swe_calc() computes what common astrological ephemerides (as available
in book shops) supply, i.e. an apparent body position in geocentric ecliptic polar coordinates ( longitude,
latitude, and distance) relative to the true equinox of the date.
If the speed of the body is required, set iflag = SEFLG_SPEED
For mathematical points as the mean lunar node and the mean apogee, there is no apparent position.
Swe_calc() returns true positions for these points.
Swiss Ephemeris 12
If you need another kind of computation, use the flags explained in the following paragraphs (c.f. swephexp.h).
Their names begin with ‚SEFLG_‘. To combine them, you have to concatenate them (inclusive-or) as in the
following example:
iflag = SEFLG_SPEED | SEFLG_TRUEPOS; (or: iflag = SEFLG_SPEED + SEFLG_TRUEPOS;) // C
iflag = SEFLG_SPEED or SEFLG_TRUEPOS;(or: iflag = SEFLG_SPEED + SEFLG_TRUEPOS;) // Pascal
With this value of iflag, swe_calc() will compute true positions ( i.e. not accounted for light-time ) with speed.
The flag bits, which are defined in swephexp.h, are:
If none of this flags is specified, swe_calc() tries to compute the default ephemeris. The default ephemeris is
defined in swephexp.h:
#define SEFLG_DEFAULTEPH SEFLG_SWIEPH
In this case the default ephemeris is Swiss Ephemeris. If you have not specified an ephemeris in iflag,
swe_calc() tries to compute a Swiss Ephemeris position. If it does not find the required Swiss Ephemeris file
either, it computes a Moshier position.
Swe_calc() does not compute speed if you do not add the speed flag SEFLG_SPEED. E.g.
iflag |= SEFLG_SPEED;
The computation of speed is usually cheap, so you may set this bit by default even if you do not need the speed.
b. Topocentric positions
To compute topocentric positions, i.e. positions referred to the place of the observer (the birth place) rather than
to the center of the earth, do as follows:
call swe_set_topo(geo_lon, geo_lat, altitude_above_sea) (The geographic longitude and latitude must
be in degrees, the altitude in meters.)
add the flag SEFLG_TOPOCTR to iflag
call swe_calc(...)
c. Heliocentric positions
To compute a heliocentric position, add SEFLG_HELCTR.
A heliocentric position can be computed for all planets including the moon. For the sun, lunar nodes and lunar
apogees the coordinates are returned as zero; no error message appears.
d. Barycentric positions
SEFLG_BARYCTR yields coordinates as referred to the solar system barycenter. However, this option is not
completely implemented. It was used for program tests during development. It works only with the JPL and the
Swiss Ephemeris, not with the Moshier ephemeris; and only with physical bodies, but not with the nodes and
the apogees.
Moreover, the barycentric Sun of Swiss Ephemeris has ”only” a precision of 0.1”. Higher accuracy would have
taken a lot of storage, on the other hand it is not needed for precise geocentric and heliocentric positions. For
more precise barycentric positions the JPL ephemeris file should be used.
A barycentric position can be computed for all planets including the sun and moon. For the lunar nodes and
lunar apogees the coordinates are returned as zero; no error message appears.
e. Astrometric positions
For astrometric positions, which are sometimes given in the Astronomical Almanac, the light-time correction is
computed, but annual aberration and the light-deflection by the sun neglected. This can be done with
SEFLG_NOABERR and SEFLG_NOGDEFL. For positions related to the mean equinox of 2000, you must set
SEFLG_J2000 and SEFLG_NONUT, as well.
h. Sidereal positions
To compute sidereal positions, set bit SEFLG_SIDEREAL and use the function swe_set_sid_mode() in order
to define the ayanamsha you want. For more information, read the description of this function.
Apparent positions of JPL Horizons can be reproduced with about 0.001 arcsec precision using the flag
SEFLG_JPLHOR. For best accuracy, the daily earth orientation parameters (EOP) delta_psi and delta_eps
relative to the IAU 1980 precession/nutation model must be downloaded and saved in the ephemeris path
defined by swe_set_ephe_path(). The EOP files are found on the IERS website:
http://www.iers.org/IERS/EN/DataProducts/EarthOrientationData/eop.html
The following files are required:
1. EOP 08 C04 (IAU1980) - one file (1962-now)
http://datacenter.iers.org/eop/-/somos/5Rgv/document/tx14iers.0z9/eopc04_08.62-now
Put this file into your ephemeris path and rename it as “eop_1962_today.txt”.
2. finals.data (IAU1980)
http://datacenter.iers.org/eop/-/somos/5Rgv/document/tx14iers.0q0/finals.data
Put this file into your ephemeris path, too, and rename it as “eop_finals.txt”.
If the Swiss Ephemeris does not find these files, it defaults to SEFLG_JPLHORA, which is a very good
approximation of Horizons, at least for 1962 to present.
SEFLG_JPLHORA can be used independently for the whole time range of the Swiss Ephemeris.
Note, the Horizons mode works only with planets and fixed stars. With lunar nodes and apsides, we use our
standard methods.
If you need rectangular coordinates ( SEFLG_XYZ ), swe_calc() returns x, y, z, dx, dy, dz in AU.
Once you have computed a planet, e.g., in ecliptic coordinates, its equatorial position or its rectangular
coordinates are available, too. You can get them very cheaply ( little CPU time used ), calling again swe_calc()
with the same parameters, but adding SEFLG_EQUATORIAL or SEFLG_XYZ to iflag. swe_calc() will not
compute the body again, just return the data specified from internal storage.
A fatal error code (< 0) and an error string are returned in one of the following cases:
On success, the return code contains flag bits that indicate what kind of computation has been done. This value
will usually be equal to iflag, however sometimes may differ from it. If an option specified by iflag cannot be
fulfilled or makes no sense, swe_calc just does what can be done. E.g., if you specify that you want JPL
ephemeris, but swe_calc cannot find the ephemeris file, it tries to do the computation with any available
ephemeris. The ephemeris actually used will be indicated in the return value of swe_calc. So, to make sure that
swe_calc () has found the ephemeris required, you may want to check, e.g.:
if (return_code > 0 && (return_code & SEFLG_JPLEPH))
However, usually it should be sufficient to do the ephemeris test once only, at the very beginning of the program.
In such cases, there is also a warning in the error string serr, saying that:
warning: SwissEph file 'sepl_18.se1' not found in PATH '…' ; using Moshier eph.;
Apart from that, positive values of return_code need not be checked, but maybe usefull for debugging purposes
or for understanding what exactly has been done by the function.
Some flags may be removed, if they are incompatible with other flags, e.g:
The file seasnam.txt need not be ordered in any way. There must be one asteroid per line, first its catalogue
number, then its name. The asteroid number may or may not be in brackets.
Swiss Ephemeris 17
Example:
(3192) A'Hearn
(3654) AAS
(8721) AMOS
(3568) ASCII
(2848) ASP
(677) Aaltje
...
In the same way, the function swe_fixstar2_ut() does the same as swe_fixstar2() except that it expects
Universal Time as input time.
The functions swe_fixstar2_ut() and swe_fixstar2() were introduced with SE 2.07. They do the same as
swe_fixstar_ut() and swe_fixstar2() except that they are a lot faster and have a slightly different behavior,
explained below.
For new projects, we recommend using the new functions swe_fixstar2_ut() and swe_fixstar2().
Performance will be a lot better if a great number of fixed star calculations are done. If performance
is a problem with your old projects, we recommend replacing the old functions by the new ones. However, the
output should be checked carefully, because the behavior of old and new functions is not exactly identical.
(explained below)
long swe_fixstar(char *star, double tjd_et, long iflag, double* xx, char* serr);
long swe_fixstar2_ut(char* star, double tjd_ut, long iflag, double* xx, char* serr);
long swe_fixstar2(char *star, double tjd_et, long iflag, double* xx, char* serr);
where
star =name of fixed star to be searched, returned name of found star
tjd_ut =Julian day in Universal Time (swe_fixstar_ut())
tjd_et =Julian day in Ephemeris Time (swe_fixstar())
iflag =an integer containing several flags that indicate what kind of computation is wanted
xx =array of 6 doubles for longitude, latitude, distance, speed in long., speed in lat., and speed in
dist.
serr[256] =character string to contain error messages in case of error.
The fixed stars functions only work if the fixed stars data file sefstars.txt is found in the ephemeris path. If
the file sefstars.txt is not found, the old file fixstars.cat is searched and used instead, if present. However, it
is strongly recommended to *not* use the old file anymore. The data in the file are outdated, and the
algorithms are also not as accurate as those used with the file sefstars.txt.
The parameter star must provide for at least 41 characters for the returned star name. If a star is found, its
name is returned in this field in the following format:
traditional_name, nomenclature_name e.g. "Aldebaran,alTau".
The nomenclature name is usually the so-called Bayer designation or the Flamsteed designation, in some cases
also Henry Draper (HD) or other designations.
Swiss Ephemeris 18
The function has three modes to search for a star in the file sefstars.txt:
star contains a traditional name: the first star in the file sefstars.txt is used whose traditional name fits the
given name. All names are mapped to lower case before comparison and white spaces are removed.
Changed behavior: The search string must match the complete star name. If you want to use a partial string,
you have to add the wildcard character ‘%’ to the search string, e.g. “aldeb%”. (The old functions treat each
search string as ending with a wildcard.)
Note that the function overwrites the variable star. Both the full traditional name and the nomenclature
name are copied into the variable, separated by a comma. E.g. if star is given the value “aldeb”, then
swe_fixstar() overwrites this with “Aldebaran,alTau”. The new string can also be used for a new search of the
same star.
star contains a comma, followed by a nomenclature name, e.g. ",alTau": the search string is understood to
be the nomenclature name ( the second field in a star record). Letter case is observed in the comparison for
nomenclature names.
star contains a positive number ( in ASCII string format, e.g. "234"):
Changed behavior: The numbering of stars follows a sorted list of nomenclature names. (With the old
functions, the n-th star of the fixed star file is returned.)
star contains a traditional name: the first star in the file sefstars.txt is used whose traditional name fits the
given name. All names are mapped to lower case before comparison and white spaces are removed.
If star has n characters, only the first n characters of the traditional name field were compared.
Note that the function overwrites the variable star. Both the full traditional name and the nomenclature
name are copied into the variable, separated by a comma. E.g. if star is given the value “aldeb”, then
swe_fixstar() overwrites this with “Aldebaran,alTau”. The new string can also be used for a new search of the
same star.
star begins with a comma, followed by a nomenclature name, e.g. ",alTau": the search string is understood
to be the nomenclature name ( the second field in a star record). Letter case is observed in the comparison
for nomenclature names. Here again, star is overwritten by the string “Aldebaran,alTau”.
star contains a positive number ( in ASCII string format, e.g. "234"):
The star data in the 234-th non-comment line in the file sefstars.txt are used. Comment lines that begin
with # and are ignored. Here again, star will be overwritten by the traditional name and the nomenclature
name, separated by a comma, e.g. “Aldebaran,alTau”.
For correct spelling of nomenclature names, see file sefstars.txt. Nomenclature names are usually Bayer
designations and are composed of a Greek letter and the name of a star constellation. The Greek letters were
originally used to write numbers, therefore they actually number the stars of the constellation. The abbreviated
nomenclature names we use in sefstars.txt are constructed from two lowercase letters for the Greek letter (e.g.
”al” for ”alpha”, except “omi” and “ome”) and three letters for the constellation (e.g. ”Tau” for ”Tauri”).
The searching of stars by sequential number (instead of name or nomenclature name) is a practical feature if
one wants to list all stars:
for i=1; i<10000; i++) { // choose any number greater than number of lines (stars) in file
sprintf(star, "%d", i);
returncode = swe_fixstar2(star, tjd, ...);
… whatever you want to do with the star positons …
if (returncode == ERR)
break;
}
The function and the DLL should survive damaged sefstars.txt files which contain illegal data and star names
exceeding the accepted length. Such fields are cut to acceptable length.
There are a few special entries in the file sefstars.txt:
Swiss Ephemeris 19
# Gal. Center (SgrA*) according to Simbad database,
# speed of SgrA* according to Reid (2004), "The Proper Motion of Sagittarius A*”,
# p. 873: -3.151 +- 0.018 mas/yr, -5.547 +- 0.026 mas/yr. Component in RA must be
# multiplied with cos(decl).
Galactic Center,SgrA*,ICRS,17,45,40.03599,-29,00,28.1699,-2.755718425, -5.547, 0.0,0.125,999.99, 0, 0
# The solar apex, or the Apex of the Sun's Way, refers to the direction that the Sun travels
# with respect to the so-called Local Standard of Rest.
Apex ,Apex,1950,18,03,50.2, 30,00,16.8, 0.000, 0.00,-16.5,0.0000,999.99, 0, 0
# Old Galactic Pole IAU 1958 relative to ICRS according to the same publication p. 7
Gal.Pole IAU1958,GP1958,ICRS,12,51,26.27469,27,07,41.7087,0.0,0.0,0.0,0.0,0.0,0,0
# The following "object" played an important role in 2011 and 2017 dooms day predictions,
# as well as in some conspiration theories. It consists of the infrared objects
# IRAS 13458-0823 and IRAS 13459-0812. Central point measured by DK.
Infrared Dragon,IDrag, ICRS,13,48,0.0,-9,0,0.0,0,0,0,0,0.0, 19, 477
You may edit the star catalogue and move the stars you prefer to the top of the file. With older versions of the
Swiss Ephemeris, this will increase the speed of computations. The search mode is linear through the whole star
file for each call of swe_fixstar().
However, since SE 2.07 with the new functions swe_fixstar2() and swe_fixstar2_ut(), this won’t speed up
calculations anymore, and the calculation speed will be the same for all stars.
Attention:
With older versions of the Swiss Ephemeris, swe_fixstar() does not compute speeds of the fixed stars. If
you need them, you have to compute them on your own, calling swe_fixstar() for a second ( and third ) time.
Also, distance is always returned as 1 for all stars.
Since SE 2.07 distances and daily motions are included in the return array.
Distances are given in AU. To convert them from AU to lightyears or parsec, please use the following defines,
which are located in swephexp.h:
#define SE_AUNIT_TO_LIGHTYEAR (1.0/63241.077088071)
#define SE_AUNIT_TO_PARSEC (1.0/206264.8062471)
The daily motions of the fixed stars contain components of precession, nutation, aberration, parallax and the
proper motions of the stars.
The new function swe_fixstar2_mag() (since SE 2.07) is more efficient if great numbers of fixed stars are
calculated.
int32 swe_nod_aps_ut(double tjd_ut, int32 ipl, int32 iflag, int32 method, double *xnasc, double
*xndsc, double *xperi, double *xaphe, char *serr);
where
tjd_ut =Julian day in Universal Time
ipl =planet number
iflag =same as with swe_calc_ut() and swe_fixstar_ut()
method =another integer that specifies the calculation method, see explanations below
xnasc =array of 6 doubles for ascending node
xndsc =array of 6 doubles for descending node
xperi =array of 6 doubles for perihelion
xaphe =array of 6 doubles for aphelion
serr[256] =character string to contain error messages in case of error.
5.2 swe_nod_aps()
int32 swe_nod_aps(double tjd_et, int32 ipl, int32 iflag, int32 method, double *xnasc, double
*xndsc, double *xperi, double *xaphe, char *serr);
same, but
tjd_et = Julian day in Ephemeris Time
The parameter iflag allows the same specifications as with the function swe_calc_ut(). I.e., it contains the
Ephemeris flag, the heliocentric, topocentric, speed, nutation flags etc. etc.
The parameter method tells the function what kind of nodes or apsides are required:
#define SE_NODBIT_MEAN 1
Mean nodes and apsides are calculated for the bodies that have them, i.e. for the Moon and the planets Mercury
through Neptune, osculating ones for Pluto and the asteroids. This is the default method, also used if method=0.
#define SE_NODBIT_OSCU 2
Osculating nodes and apsides are calculated for all bodies.
#define SE_NODBIT_OSCU_BAR 4
Osculating nodes and apsides are calculated for all bodies. With planets beyond Jupiter, the nodes and apsides
are calculated from barycentric positions and speed. Cf. the explanations in swisseph.doc.
If this bit is combined with SE_NODBIT_MEAN, mean values are given for the planets Mercury - Neptune.
int32 swe_get_orbital_elements(
double tjd_et,
int32 ipl, int32 iflag,
double *dret,
char *serr);
5.4 swe_orbit_max_min_true_distance()
This function calculates calculates the maximum possible distance, the minimum possible distance, and the
current true distance of planet, the EMB, or an asteroid. The calculation can be done either heliocentrically or
geocentrically. With heliocentric calculations, it is based on the momentary Kepler ellipse of the planet. With
geocentric calculations, it is based on the Kepler ellipses of the planet and the EMB. The geocentric calculation
is rather expensive..
Solar eclipses:
swe_sol_eclipse_when_loc( tjd...) finds the next eclipse for a given geographic position.
swe_sol_eclipse_when_glob( tjd...) finds the next eclipse globally.
swe_sol_eclipse_where() computes the geographic location of a solar eclipse for a given tjd.
swe_sol_eclipse_how() computes attributes of a solar eclipse for a given tjd, geographic longitude,
latitude and height.
Lunar eclipses:
swe_lun_eclipse_when_loc(tjd...) finds the next lunar eclipse for a given geographic position.
swe_lun_eclipse_when(tjd...) finds the next lunar eclipse.
swe_lun_eclipse_how() computes the attributes of a lunar eclipse for a given tjd.
Planetary phenomena:
swe_pheno_ut() and swe_pheno() compute phase angle, phase, elongation, apparent diameter, and
apparent magnitude of the Sun, the Moon, all planets and asteroids.
Swiss Ephemeris 23
6.1. swe_sol_eclipse_when_loc()
To find the next eclipse for a given geographic position, use swe_sol_eclipse_when_loc().
int32 swe_sol_eclipse_when_loc(
double tjd_start, /* start date for search, Jul. day UT */
int32 ifl, /* ephemeris flag */
double *geopos, /* 3 doubles for geographic lon, lat, height.
Eastern longitude is positive,
western longitude is negative,
northern latitude is positive,
southern latitude is negative */
double *tret, /* return array, 10 doubles, see below */
double *attr, /* return array, 20 doubles, see below */
AS_BOOL backward, /* TRUE, if backward search */
char *serr); /* return error string */
6.2. swe_sol_eclipse_when_glob()
To find the next eclipse globally:
int32 swe_sol_eclipse_when_glob(
double tjd_start, /* start date for search, Jul. day UT */
int32 ifl, /* ephemeris flag */
int32 ifltype, /* eclipse type wanted: SE_ECL_TOTAL etc. or 0, if any eclipse type */
double *tret, /* return array, 10 doubles, see below */
AS_BOOL backward, /* TRUE, if backward search */
char *serr); /* return error string */
This function requires the time parameter tjd_start in Universal Time and also yields the return values (tret[]) in
UT. For conversions between ET and UT, use the function swe_deltat().
Note: An implementation of this function with parameters in Ephemeris Time would have been possible. The
question when the next solar eclipse will happen anywhere on earth is independent of the rotational position of
the earth and therefore independent of Delta T. However, the function is often used in combination with other
eclipse functions (see example below), for which input and output in ET makes no sense, because they concern
local circumstances of an eclipse and therefore are dependent on the rotational position of the earth. For this
reason, UT has been chosen for the time parameters of all eclipse functions.
ifltype specifies the eclipse type wanted. It can be a combination of the following bits (see swephexp.h):
#define SE_ECL_CENTRAL 1
#define SE_ECL_NONCENTRAL 2
#define SE_ECL_TOTAL 4
#define SE_ECL_ANNULAR 8
#define SE_ECL_PARTIAL 16
#define SE_ECL_ANNULAR_TOTAL 32
If your code does not work, please study the sample code in swetest.c.
Swiss Ephemeris 25
The function returns:
6.3. swe_sol_eclipse_how ()
To calculate the attributes of an eclipse for a given geographic position and time:
int32 swe_sol_eclipse_how(
double tjd_ut, /* time, Jul. day UT */
int32 ifl, /* ephemeris flag */
double *geopos /* geogr. longitude, latitude, height above sea.
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
double *attr, /* return array, 20 doubles, see below */
char *serr); /* return error string */
6.4. swe_sol_eclipse_where ()
This function can be used to find out the geographic position, where, for a given time, a central eclipse is central
or where a non-central eclipse is maximal.
If you want to draw the eclipse path of a total or annular eclipse on a map, first compute the start and end time of
the total or annular phase with swe_sol_eclipse_when_glob(), then call swe_sol_eclipse_how() for
several time intervals to get geographic positions on the central path. The northern and southern limits of the
umbra and penumbra are not implemented yet.
Swiss Ephemeris 26
int32 swe_sol_eclipse_where (
double tjd_ut, /* time, Jul. day UT */
int32 ifl, /* ephemeris flag */
double *geopos, /* return array, 2 doubles, geo. long. and lat.
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
double *attr, /* return array, 20 doubles, see below */
char *serr); /* return error string */
The function returns:
declare as attr[20]!
*/
6.5. swe_lun_occult_when_loc()
To find the next occultation of a planet or star by the moon for a given location, use
swe_lun_occult_when_loc().
The same function can also be used for local solar eclipses instead of swe_sol_eclipse_when_loc(), but is a bit
less efficient.
int32 swe_lun_occult_when_loc(
double tjd_start, /* start date for search, Jul. day UT */
int32 ipl, /* planet number */
char* starname, /* star name, must be NULL or ”” if not a star */
int32 ifl, /* ephemeris flag */
double *geopos, /* 3 doubles for geogr. longitude, latitude, height above sea.
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
double *tret, /* return array, 10 doubles, see below */
double *attr, /* return array, 20 doubles, see below */
AS_BOOL backward, /* TRUE, if backward search */
char *serr); /* return error string */
Occultations of some stars may be very rare or do not occur at all. Usually the function searches an event
until it finds one or reaches the end of the ephemeris. In order to avoid endless loops, the function can be
called using the flag ifl |= SE_ECL_ONE_TRY. If called with this flag, the function searches the next date
when the Moon is in conjunction with the object and finds out whether it is an occultation. The function does
not check any other conjunctions in the future or past.
If the return value is > 0, there is an occulation and tret and attr contain the information about it.
If the return value is = 0, there is no occulation; tret[0] contains the date of closest conjunction.
If the return value is = -1, there is an error.
In order to find events in a particular time range (tjd_start < tjd < tjd_stop), one can write a loop and call
the function as often as date (tjd < tjd_stop). After each call, increase the tjd = tret[0] + 2.
If one has a set of stars or planets for which one wants to find occultations for the same time range, one has
to run the same loop for each of these object. If the events have to be listed in chronological order, one has
to sort them before output.
6.6. swe_lun_occult_when_glob()
To find the next occultation of a planet or star by the moon globally (not for a particular geographic
location), use swe_lun_occult_when_glob().
The same function can also be used for global solar eclipses instead of swe_sol_eclipse_when_glob(), but is a bit
less efficient.
An explanation of the ifl |= SE_ECL_ONE_TRY is given above in paragraph about the function
swe_lun_occult_when_loc().
/* retflag
-1 (ERR) on error (e.g. if swe_calc() for sun or moon fails)
0 (if no occultation / eclipse has been found)
SE_ECL_TOTAL or SE_ECL_ANNULAR or SE_ECL_PARTIAL or SE_ECL_ANNULAR_TOTAL
SE_ECL_CENTRAL
SE_ECL_NONCENTRAL
int32 swe_lun_occult_where (
double tjd_ut, /* time, Jul. day UT */
int32 ipl, /* planet number */
char* starname, /* star name, must be NULL or ”” if not a star */
int32 ifl, /* ephemeris flag */
double *geopos, /* return array, 2 doubles, geo. long. and lat.
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
double *attr, /* return array, 20 doubles, see below */
char *serr); /* return error string */
6.8.a. swe_lun_eclipse_when_loc ()
To find the next lunar eclipse observable from a given geographic position:
Swiss Ephemeris 30
int32 swe_lun_eclipse_when_loc(
double tjd_start, /* start date for search, Jul. day UT */
int32 ifl, /* ephemeris flag */
double *geopos, /* 3 doubles for geogr. longitude, latitude, height above sea.
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
double *tret, /* return array, 10 doubles, see below */
double *attr, /* return array, 20 doubles, see below */
AS_BOOL backward, /* TRUE, if backward search */
char *serr); /* return error string */
If your code does not work, please study the sample code in swetest.c.
6.8.b. swe_lun_eclipse_when ()
To find the next lunar eclipse:
int32 swe_lun_eclipse_when(
double tjd_start, /* start date for search, Jul. day UT */
int32 ifl, /* ephemeris flag */
int32 ifltype, /* eclipse type wanted: SE_ECL_TOTAL etc. or 0, if any eclipse type */
double *tret, /* return array, 10 doubles, see below */
AS_BOOL backward, /* TRUE, if backward search */
char *serr); /* return error string */
If your code does not work, please study the sample code in swetest.c.
6.9. swe_lun_eclipse_how ()
This function computes the attributes of a lunar eclipse at a given time:
int32 swe_lun_eclipse_how(
double tjd_ut, /* time, Jul. day UT */
int32 ifl, /* ephemeris flag */
double *geopos, /* input array, geopos, geolon, geoheight
eastern longitude is positive,
western longitude is negative,
northern latitude is positive,
southern latitude is negative */
double *attr, /* return array, 20 doubles, see below */
char *serr); /* return error string */
int32 swe_rise_trans(
double tjd_ut, /* search after this time (UT) */
int32 ipl, /* planet number, if planet or moon */
char *starname, /* star name, if star; must be NULL or empty, if ipl is used */
int32 epheflag, /* ephemeris flag */
int32 rsmi, /* integer specifying that rise, set, or one of the two meridian transits is
wanted. see definition below */
double *geopos, /* array of three doubles containing
* geograph. long., lat., height of observer */
double atpress, /* atmospheric pressure in mbar/hPa */
double attemp, /* atmospheric temperature in deg. C */
double *tret, /* return address (double) for rise time etc. */
char *serr); /* return address for error message */
int32 swe_rise_trans_true_hor(
double tjd_ut, /* search after this time (UT) */
int32 ipl, /* planet number, if planet or moon */
char *starname, /* star name, if star; must be NULL or empty, if ipl is used */
int32 epheflag, /* ephemeris flag */
int32 rsmi, /* integer specifying that rise, set, orone of the two meridian transits is
wanted. see definition below */
double *geopos, /* array of three doubles containing
* geograph. long., lat., height of observer */
double atpress, /* atmospheric pressure in mbar/hPa */
double attemp, /* atmospheric temperature in deg. C */
double horhgt, /* height of local horizon in deg at the point where the body rises or sets*/
double *tret, /* return address (double) for rise time etc. */
char *serr); /* return address for error message */
The second function has one additional parameter horhgt for the height of the local horizon at the point where
the body rises or sets.
The astronomical sunrise is defined as the time when the upper limb of the solar disk is seen appearing at the
horizon. The astronomical sunset is defined as the moment the upper limb of the solar disk disappears below the
horizon.
The function swe_rise_trans() by default follows this definition of astronomical sunrises and sunsets. Also,
astronomical almanacs and news papers publish astronomical sunrises and sunset according to this definition.
Hindu astrology and Hindu calendars use a different definition of sunrise and sunset. They consider the Sun as
rising or setting, when the center of the solar disk is exactly at the horizon. In addition, the Hindu method ignores
atmospheric refraction. Moreover, the geocentric rather than topocentric position position is used and the small
ecliptic latitude of the Sun is ignored.
In order to calculate correct Hindu rising and setting times, the flags SE_BIT_NO_REFRACTION and
SE_BIT_DISC_CENTER must be added (or'ed) to the parameter rsmi. From Swiss Ephemeris version 2.06 on, a
flag SE_BIT_HINDU_RISING is supported. It includes the flags flags SE_BIT_NO_REFRACTION,
SE_BIT_DISC_CENTER and SE_BIT_GEOCTR_NO_ECL_LAT.
In order to calculate the sunrise of a given date and geographic location, one can proceed as in the following
program (tested code!):
int main()
{
char serr[AS_MAXCH];
double epheflag = SEFLG_SWIEPH;
int gregflag = SE_GREG_CAL;
int year = 2017;
int month = 4;
int day = 12;
int geo_longitude = 76.5; // positive for east, negative for west of Greenwich
int geo_latitude = 30.0;
int geo_altitude = 0.0;
double hour;
// array for atmospheric conditions
double datm[2];
datm[0] = 1013.25; // atmospheric pressure;
// irrelevant with Hindu method, can be set to 0
datm[1] = 15; // atmospheric temperature;
// irrelevant with Hindu method, can be set to 0
// array for geographic position
double geopos[3];
geopos[0] = geo_longitude;
geopos[1] = geo_latitude;
geopos[2] = geo_altitude; // height above see level in meters;
// irrelevant with Hindu method, can be set to 0
swe_set_topo(geopos[0], geopos[1], geopos[2]);
int ipl = SE_SUN; // object whose rising is wanted
char starname[255]; // name of star, if a star's rising is wanted
// is "" or NULL, if Sun, Moon, or planet is calculated
double trise; // for rising time
double tset; // for setting time
// calculate the julian day number of the date at 0:00 UT:
double tjd = swe_julday(year,month,day,0,gregflag);
Swiss Ephemeris 34
// convert geographic longitude to time (day fraction) and subtract it from tjd
// this method should be good for all geographic latitudes except near in
// polar regions
double dt = geo_longitude / 360.0;
tjd = tjd - dt;
// calculation flag for Hindu risings/settings
int rsmi = SE_CALC_RISE | SE_BIT_HINDU_RISING;
// or SE_CALC_RISE + SE_BIT_HINDU_RISING;
// or SE_CALC_RISE | SE_BIT_DISC_CENTER | SE_BIT_NO_REFRACTION |
SE_BIT_GEOCTR_NO_ECL_LAT;
int return_code = swe_rise_trans(tjd, ipl, starname, epheflag, rsmi, geopos, datm[0], datm[1], &trise, serr);
if (return_code == ERR) {
// error action
printf("%s\n", serr);
}
// conversion to local time zone must be made by the user. The Swiss Ephemeris
// does not have a function for that.
// After that, the julian day number of the rising time can be converted into
// date and time:
swe_revjul(trise, gregflag, &year, &month, &day, &hour);
printf("sunrise: date=%d/%d/%d, hour=%.6f UT\n", year, month, day, hour);
// To calculate the time of the sunset, you can either use the same
// tjd increased or trise as start date for the search.
rsmi = SE_CALC_SET | SE_BIT_DISC_CENTER | SE_BIT_NO_REFRACTION;
return_code = swe_rise_trans(tjd, ipl, starname, epheflag, rsmi, geopos, datm[0], datm[1], &tset, serr);
if (return_code == ERR) {
// error action
printf("%s\n", serr);
}
printf("sunset : date=%d/%d/%d, hour=%.6f UT\n", year, month, day, hour);
}
int32 swe_pheno_ut(
double tjd_ut, /* time Jul. Day UT */
int32 ipl, /* planet number */
int32 iflag, /* ephemeris flag */
double *attr, /* return array, 20 doubles, see below */
char *serr); /* return error string */
int32 swe_pheno(
double tjd_et, /* time Jul. Day ET */
int32 ipl, /* planet number */
int32 iflag, /* ephemeris flag */
double *attr, /* return array, 20 doubles, see below */
char *serr); /* return error string */
void swe_azalt(
double tjd_ut, // UT
int32 calc_flag, // SE_ECL2HOR or SE_EQU2HOR
double *geopos, // array of 3 doubles: geograph. long., lat., height
double atpress, // atmospheric pressure in mbar (hPa)
double attemp, // atmospheric temperature in degrees Celsius
double *xin, // array of 3 doubles: position of body in either ecliptical or equatorial coordinates,
// depending on calc_flag
double *xaz); // return array of 3 doubles, containing azimuth, true altitude, apparent altitude
If calc_flag=SE_ECL2HOR, set xin[0]= ecl. long., xin[1]= ecl. lat., (xin[2]=distance (not required));
else
if calc_flag= SE_EQU2HOR, set xin[0]=right ascension, xin[1]=declination, (xin[2]= distance (not
required));
#define SE_ECL2HOR 0
#define SE_EQU2HOR 1
The apparent altitude of a body depends on the atmospheric pressure and temperature. If only the true altitude is
required, these parameters can be neglected.
If atpress is given the value 0, the function estimates the pressure from the geographical altitude given in
geopos[2] and attemp. If geopos[2] is 0, atpress will be estimated for sea level.
6.13. swe_azalt_rev()
The function swe_azalt_rev() is not precisely the reverse of swe_azalt(). It computes either ecliptical or
equatorial coordinates from azimuth and true altitude. If only an apparent altitude is given, the true altitude has
to be computed first with the function swe_refrac() (see below).
It is defined as follows:
void swe_azalt_rev(
double tjd_ut,
int32 calc_flag, /* either SE_HOR2ECL or SE_HOR2EQU */
double *geopos, /* array of 3 doubles for geograph. pos. of observer */
double *xin, /* array of 2 doubles for azimuth and true altitude of planet */
double *xout); // return array of 2 doubles for either ecliptic or
// equatorial coordinates, depending on calc_flag
For the definition of the azimuth and true altitude, see chapter 4.9 on swe_azalt().
#define SE_HOR2ECL 0
#define SE_HOR2EQU 1
double swe_refrac(
double inalt,
Swiss Ephemeris 36
double atpress, /* atmospheric pressure in mbar (hPa) */
double attemp, /* atmospheric temperature in degrees Celsius */
int32 calc_flag); /* either SE_TRUE_TO_APP or SE_APP_TO_TRUE */
where
#define SE_TRUE_TO_APP 0
#define SE_APP_TO_TRUE 1
The refraction depends on the atmospheric pressure and temperature at the location of the observer.
If atpress is given the value 0, the function estimates the pressure from the geographical altitude given in
geopos[2] and attemp. If geopos[2] is 0, atpress will be estimated for sea level.
There is also a more sophisticated function swe_refrac_extended(), It allows correct calculation of refraction
for altitudes above sea > 0, where the ideal horizon and planets that are visible may have a negative height. (for
swe_refrac(), negative apparent heights do not exist!)
double swe_refract_extended(
double inalt, /* altitude of object above geometric horizon in degrees, where
geometric horizon = plane perpendicular to gravity */
double geoalt, /* altitude of observer above sea level in meters */
double atpress, /* atmospheric pressure in mbar (hPa) */
double lapse_rate, /* (dattemp/dgeoalt) = [°K/m] */
double attemp, /* atmospheric temperature in degrees Celsius */
int32 calc_flag); /* either SE_TRUE_TO_APP or SE_APP_TO_TRUE */
function returns:
case 1, conversion from true altitude to apparent altitude:
- apparent altitude, if body appears above is observable above ideal horizon
- true altitude (the input value), otherwise
"ideal horizon" is the horizon as seen above an ideal sphere (as seen from a plane over the ocean with
a clear sky)
case 2, conversion from apparent altitude to true altitude:
- the true altitude resulting from the input apparent altitude, if this value is a plausible apparent altitude,
i.e. if it is a position above the ideal horizon
- the input altitude otherwise
int32 swe_heliacal_ut(
double tjdstart, /* Julian day number of start date for the search of the heliacal event */
double *dgeo /* geographic position (details below) */
double *datm, /* atmospheric conditions (details below) */
double *dobs, /* observer description (details below) */
char *objectname, /* name string of fixed star or planet */
int32 event_type, /* event type (details below) */
int32 helflag, /* calculation flag, bitmap (details below) */
double *dret, /* result: array of at least 50 doubles, of which 3 are used at the moment */
char * serr /* error string */
);
Some other SE_HELFLAG_ bits found in swephexp.h were made fore mere test purposes and may change in
future releases. Please do not use them and do not request any support or information related to them.
Strange phenomena:
- Venus’ heliacal rising can occur before her heliacal setting. In such cases the planet may be seen both as a
morning star and an evening star for a couple of days. Example:
swetest -hev1 -p3 -b1.1.2008 -geopos8,47,900 -at1000,10,20,0.15 -obs21,1 -n1 -lmt
Venus heliacal rising : 2009/03/23 05:30:12.4 LMT (2454913.729310), visible for: 4.9 min
swetest -hev2 -p3 -b1.1.2008 -geopos8,47,900 -at1000,10,20,0.15 -obs21,1 -n1 -lmt
Venus heliacal setting: 2009/03/25 18:37:41.6 LMT (2454916.276175), visible for: 15.1 min
- With good visibility and good eye sight (high Snellen ratio), the “evening first” of the Moon may actually begin
in the morning, because the Moon becomes visible before sunset. Note the LMT and duration of visibility in the
following example:
swetest -hev3 -p1 -b1.4.2008 -geopos8,47,900 -at1000,10,40,0.15 -obs21,1.5 -n1 -lmt
Swiss Ephemeris 38
Moon evening first : 2008/04/06 10:33:44.3 LMT (2454562.940096), visible for: 530.6 min
- Stars that are circumpolar, but come close to the horizon, may have an evening last and a morning first, but
swe_heliacal_ut() will not find it. It only works if a star crosses the horizon.
- In high geographic latitudes > 55 (?), unusual things may happen. E.g. Mars can have a morning last
appearance. In case the period of visibility lasts for less than 5 days, the function swe_heliacal_ut() may miss the
morning first.
- With high geographic latitudes heliacal appearances of Mercury and Venus become rarer.
The user must be aware that strange phenomena occur especially for high geographic latitudes and circumpolar
objects and that the function swe_heliacal_ut() may not always be able to handle them correctly. Special cases
can best be researched using the function swe_vi_limit_mag().
double swe_vis_limit_mag(
double tjdut, /* Julian day number */
double *dgeo /* geographic position (details under swe_heliacal_ut() */
double *datm, /* atmospheric conditions (details under swe_heliacal_ut()) */
double *dobs, /* observer description (details under swe_heliacal_ut()) */
char *objectname, /* name string of fixed star or planet */
int32 helflag, /* calculation flag, bitmap (details under swe_heliacal_ut()) */
double *dret, /* result: magnitude required of the object to be visible */
char * serr /* error string */
);
Function returns
-1 on error
-2 object is below horizon
0 OK, photopic vision
&1 OK, scotopic vision
&2 OK, near limit photopic/scotopic vision
Details for arrays dgeo[], datm[], dobs[] and the other parameters are given under “6.15. Heliacal risings etc.:
swe_heliacal_ut()”.
double swe_heliacal_pheno_ut(
double tjd_ut, /* Julian day number */
double *dgeo /* geographic position (details under swe_heliacal_ut() */
double *datm, /* atmospheric conditions (details under swe_heliacal_ut()) */
Swiss Ephemeris 39
double *dobs, /* observer description (details under swe_heliacal_ut()) */
char *objectname,/* name string of fixed star or planet */
int32 event_type, /* event type (details under function swe_heliacal_ut()) */
int32 helflag, /* calculation flag, bitmap (details under swe_heliacal_ut()) */
double *darr, /* return array */
char * serr /* error string */
);
int swe_date_conversion (
int y , int m , int d , /* year, month, day */
double hour, /* hours (decimal, with fraction) */
char c, /* calendar ‘g’[regorian]|’j’[ulian] */
double *tjd); /* return value for Julian day */
void swe_revjul (
double tjd, /* Julian day number */
int gregflag, /* Gregorian calendar: 1, Julian calendar: 0 */
int *year, /* target addresses for year, etc. */
int *month, int *day, double *hour);
swe_julday() and swe_date_conversion() compute a Julian day number from year, month, day, and hour.
swe_date_conversion() checks in addition whether the date is legal. It returns OK or ERR.
Swiss Ephemeris 40
swe_revjul() is the reverse function of swe_julday(). It computes year, month, day and hour from a Julian
day number.
The variable gregflag tells the function whether the input date is Julian calendar ( gregflag = SE_JUL_CAL) or
Gregorian calendar ( gregflag = SE_GREG_CAL).
Usually, you will set gregflag = SE_GREG_CAL.
The Julian day number has nothing to do with Julius Cesar, who introduced the Julian calendar, but was invented
by the monk Julianus. The Julian day number tells for a given date the number of days that have passed since
the creation of the world which was then considered to have happened on 1 Jan –4712 at noon. E.g. the
1.1.1900 corresponds to the Julian day number 2415020.5.
Midnight has always a JD with fraction 0.5, because traditionally the astronomical day started at noon. This was
practical because then there was no change of date during a night at the telescope. From this comes also the
fact that noon ephemerides were printed before midnight ephemerides were introduced early in the 20th century.
Past leap seconds are hard coded in the Swiss Ephemeris. Future leap seconds can be specified in the file
seleapsec.txt, see ch. 7.3.
Note, in case of leap seconds, the input or output time may be 60.9999 seconds. Input or output forms have to
allow for this.
How do I get correct planetary positions, sidereal time, and house cusps, starting from a wall clock date and
time?
And how do you get the date and wall clock time from a Julian day number? Depending on whether you have
tjd_et (Julian day as ET (TT)) or tjd_ut (Julian day as UT (UT1)), use one of the two functions swe_jdet_to_utc()
or swe_jdut1_to_utc().
…
/* first, we calculate UTC from TT (ET) */
swe_jdet_to_utc(tjd_et, gregflag, &iyear_utc, &imonth_utc, &iday_utc, &ihour_utc, &imin_utc,
&dsec_utc);
/* now, UTC to local time (note the negative sign before d_timezone): */
swe_utc_time_zone(iyear_utc, imonth_utc, iday_utc, ihour_utc, imin_utc, dsec_utc,
-d_timezone, &iyear, &imonth, &iday, &ihour, &imin, &dsec)
Swiss Ephemeris 42
7.3. Handling of leap seconds and the file seleapsec.txt
The insertion of leap seconds is not known in advance. We will update the Swiss Ephemeris whenever the IERS
announces that a leap second will be inserted. However, if the user does not want to wait for our update or does
not want to download a new version of the Swiss Ephemeris, he can create a file seleapsec.txt in the ephemeris
directory. The file looks as follows (lines with # are only comments):
# This file contains the dates of leap seconds to be taken into account
# by the Swiss Ephemeris.
# For each new leap second add the date of its insertion in the format
# yyyymmdd, e.g. "20081231" for 31 december 2008.
# The leap second is inserted at the end of the day.
20081231
7.4. Mean solar time versus True solar time: swe_time_equ(), swe_lmt_to_lat(),
swe_lat_to_lmt()
Universal Time (UT or UTC) is based on Mean Solar Time, AKA Local Mean Time, which is a uniform
measure of time. A day has always the same length, independent of the time of the year.
In the centuries before mechanical clocks where used, when the reckoning of time was mostly based on sun
dials, the True Solar Time was used, also called Local Apparent Time.
The difference between Local Mean Time and Local Apparent Time is called the equation of time. This
difference can become as large as 20 minutes.
If a historical date was noted in Local Apparent Time, it must first be converted to Local Mean Time by
applying the equation of time, before it can be used to compute Universal Time (for the houses) and finally
Ephemeris Time (for the planets).
This conversion can be done using the function swe_lat_to_lmt(). The reverse function is swe_lmt_to_lat(). If
required, the equation of time itself, i. e. the value e = LAT – LMT, can be calculated using the function
swe_time_equ()
/* Equation of Time
*
* The function returns the difference between local apparent and local mean time in days.
* E = LAT - LMT
* Input variable tjd is UT.
*/
int swe_time_equ(double tjd, double* e, char* serr);
For converions between Local Apparent Time and Local Mean Time, it is recommended to use the following
functions:
The Julian day number, you compute from a birth date, will be Universal Time (UT, former GMT) and can
be used to compute the star time and the houses. However, for the planets and the other factors, you have to
convert UT to Ephemeris time (ET):
8.1 swe_deltat_ex()
tjde = tjd + swe_deltat_ex(tjd, ephe_flag, serr);
where tjd = Julian day in UT, tjde = in ET
ephe_flag = ephemeris flag (one of SEFLG_SWIEPH, SEFLG_JPLEPH, SEFLG_MOSEPH)
serr = string pointer for warning messages.
The calculation of ephemerides in UT depends on Delta T, which depends on the ephemeris-inherent value of the
tidal acceleration of the Moon. The function swe_deltat_ex() can provide ephemeris-dependend values of
Delta T and is therefore better than the old function swe_deltat(), which has to make an uncertain guess of
what ephemeris is being used. One warning must be made, though:
It is not recommended to use a mix of old and new ephemeris files sepl*.se1, semo*.se1, seas*.se1, because the
old files were based on JPL Ephemeris DE406, whereas the new ones are based on DE431, and both
ephemerides have adifferent inherent tidal acceleration of the Moon. A mixture of old and new ephemeris files
may lead to inconsistent ephemeris output. Using old asteroid files se99999.se1 together with new ones, can be
tolerated, though.
8.2 swe_deltat()
tjde = tjd + swe_deltat(tjd); where tjd = Julian day in UT, tjde = in ET
(Also, it is safe if you first call swe_set_tid_acc() with the tidal acceleration you want. However, please do not
use this function unless you really know what you are doing.)
For best control of the values returned, use function swe_deltat_ex() instead (see 8.1 above).
The calculation of ephemerides in UT depends on Delta T, which depends on the ephemeris-inherent value of the
tidal acceleration of the Moon. In default mode, the function swe_deltat() automatically tries to find the
required values. Two warnings must be made, though:
1. It is not recommended to use a mix of old and new ephemeris files sepl*.se1, semo*.se1, seas*.se1, because
the old files were based on JPL Ephemeris DE406, whereas the new ones are based on DE431, and both
ephemerides have adifferent inherent tidal acceleration of the Moon. A mixture of old and new ephemeris files
may lead to inconsistent ephemeris output. Using old asteroid files se99999.se1 together with new ones, can be
tolerated, though.
2. The function swe_deltat() uses a default value of tidal acceleration (that of DE431). However, after calling
some older ephemeris, like Moshier ephemeris, DE200, or DE406, swe_deltat() might provide slightly different
values.
To find out the value of the tidal acceleration currently used, call the function
acceleration = swe_get_tidacc();
The values that acceleration can have are listed in swephexp.h. (e.g. SE_TIDAL_200, etc.)
Once the function swe_set_tid_acc() has been used, the automatical setting of tidal acceleration is blocked. In
order to unblock it again, call
swe_set_tid_acc(SE_TIDAL_AUTOMATIC);
8.4. swe_set_delta_t_userdef()
This function allows the user to set a fixed Delta T value that will be returned by swe_deltat() or swe_deltat_ex().
The same Delta T value will then be used by swe_calc_ut(), eclipse functions, heliacal functions, and all
functions that require UT as input time.
In order to return to automatic Delta T, call this function with the following value:
swe_set_delta_t_userdef(SE_DELTAT_AUTOMATIC);
This function must be called before topocentric planet positions for a certain birth place can be computed. It tells
Swiss Ephemeris, what geographic position is to be used. Geographic longitude geolon and latitude geolat must
be in degrees, the altitude above sea must be in meters. Neglecting the altitude can result in an error of
about 2 arc seconds with the moon and at an altitude 3000 m. After calling swe_set_topo(), add
SEFLG_TOPOCTR to iflag and call swe_calc() as with an ordinary computation. E.g.:
This function can be used to specify the mode for sidereal computations.
swe_calc() or swe_fixstar() has then to be called with the bit SEFLG_SIDEREAL.
If swe_set_sid_mode() is not called, the default ayanamsha (Fagan/Bradley) is used.
If a predefined mode is wanted, the variable sid_mode has to be set, while t0 and ayan_t0 are not considered,
i.e. can be 0. The predefined sidereal modes are:
#define SE_SIDM_FAGAN_BRADLEY 0
#define SE_SIDM_LAHIRI 1
#define SE_SIDM_DELUCE 2
#define SE_SIDM_RAMAN 3
#define SE_SIDM_USHASHASHI 4
#define SE_SIDM_KRISHNAMURTI 5
#define SE_SIDM_DJWHAL_KHUL 6
#define SE_SIDM_YUKTESHWAR 7
#define SE_SIDM_JN_BHASIN 8
#define SE_SIDM_BABYL_KUGLER1 9
#define SE_SIDM_BABYL_KUGLER2 10
#define SE_SIDM_BABYL_KUGLER3 11
#define SE_SIDM_BABYL_HUBER 12
#define SE_SIDM_BABYL_ETPSC 13
#define SE_SIDM_ALDEBARAN_15TAU 14
#define SE_SIDM_HIPPARCHOS 15
#define SE_SIDM_SASSANIAN 16
#define SE_SIDM_GALCENT_0SAG 17
#define SE_SIDM_J2000 18
#define SE_SIDM_J1900 19
#define SE_SIDM_B1950 20
#define SE_SIDM_SURYASIDDHANTA 21
#define SE_SIDM_SURYASIDDHANTA_MSUN 22
#define SE_SIDM_ARYABHATA 23
#define SE_SIDM_ARYABHATA_MSUN 24
#define SE_SIDM_SS_REVATI 25
#define SE_SIDM_SS_CITRA 26
#define SE_SIDM_TRUE_CITRA 27
#define SE_SIDM_TRUE_REVATI 28
#define SE_SIDM_TRUE_PUSHYA 29
#define SE_SIDM_GALCENT_RGBRAND 30
#define SE_SIDM_GALEQU_IAU1958 31
#define SE_SIDM_GALEQU_TRUE 32
#define SE_SIDM_GALEQU_MULA 33
Swiss Ephemeris 46
#define SE_SIDM_GALALIGN_MARDYKS 34
#define SE_SIDM_TRUE_MULA 35
#define SE_SIDM_GALCENT_MULA_WILHELM 36
#define SE_SIDM_ARYABHATA_522 37
#define SE_SIDM_BABYL_BRITTON 38
#define SE_SIDM_USER 255
namely:
"Fagan/Bradley", /* 0 SE_SIDM_FAGAN_BRADLEY */
"Lahiri", /* 1 SE_SIDM_LAHIRI */
"De Luce", /* 2 SE_SIDM_DELUCE */
"Raman", /* 3 SE_SIDM_RAMAN */
"Usha/Shashi", /* 4 SE_SIDM_USHASHASHI */
"Krishnamurti", /* 5 SE_SIDM_KRISHNAMURTI */
"Djwhal Khul", /* 6 SE_SIDM_DJWHAL_KHUL */
"Yukteshwar", /* 7 SE_SIDM_YUKTESHWAR */
"J.N. Bhasin", /* 8 SE_SIDM_JN_BHASIN */
"Babylonian/Kugler 1", /* 9 SE_SIDM_BABYL_KUGLER1 */
"Babylonian/Kugler 2", /* 10 SE_SIDM_BABYL_KUGLER2 */
"Babylonian/Kugler 3", /* 11 SE_SIDM_BABYL_KUGLER3 */
"Babylonian/Huber", /* 12 SE_SIDM_BABYL_HUBER */
"Babylonian/Eta Piscium", /* 13 SE_SIDM_BABYL_ETPSC */
"Babylonian/Aldebaran = 15 Tau", /* 14 SE_SIDM_ALDEBARAN_15TAU */
"Hipparchos", /* 15 SE_SIDM_HIPPARCHOS */
"Sassanian", /* 16 SE_SIDM_SASSANIAN */
"Galact. Center = 0 Sag", /* 17 SE_SIDM_GALCENT_0SAG */
"J2000", /* 18 SE_SIDM_J2000 */
"J1900", /* 19 SE_SIDM_J1900 */
"B1950", /* 20 SE_SIDM_B1950 */
"Suryasiddhanta", /* 21 SE_SIDM_SURYASIDDHANTA */
"Suryasiddhanta, mean Sun", /* 22 SE_SIDM_SURYASIDDHANTA_MSUN */
"Aryabhata", /* 23 SE_SIDM_ARYABHATA */
"Aryabhata, mean Sun", /* 24 SE_SIDM_ARYABHATA_MSUN */
"SS Revati", /* 25 SE_SIDM_SS_REVATI */
"SS Citra", /* 26 SE_SIDM_SS_CITRA */
"True Citra", /* 27 SE_SIDM_TRUE_CITRA */
"True Revati", /* 28 SE_SIDM_TRUE_REVATI */
"True Pushya (PVRN Rao)", /* 29 SE_SIDM_TRUE_PUSHYA */
"Galactic Center (Gil Brand)", /* 30 SE_SIDM_GALCENT_RGBRAND */
"Galactic Equator (IAU1958)", /* 31 SE_SIDM_GALEQU_IAU1958 */
"Galactic Equator", /* 32 SE_SIDM_GALEQU_TRUE */
"Galactic Equator mid-Mula", /* 33 SE_SIDM_GALEQU_MULA */
"Skydram (Mardyks)", /* 34 SE_SIDM_GALALIGN_MARDYKS */
"True Mula (Chandra Hari)", /* 35 SE_SIDM_TRUE_MULA */
"Dhruva/Gal.Center/Mula (Wilhelm)", /* 36 SE_SIDM_GALCENT_MULA_WILHELM */
"Aryabhata 522", /* 37 SE_SIDM_ARYABHATA_522 */
"Babylonian/Britton", /* 38 SE_SIDM_BABYL_BRITTON */
For information about the sidereal modes, please read the chapter on sidereal calculations in swisseph.doc.
To define your own sidereal mode, use SE_SIDM_USER (= 255) and set the reference date (t0) and the initial
value of the ayanamsha (ayan_t0).
ayan_t0 = tropical_position_t0 – sidereal_position_t0.
Without additional specifications, the traditional method is used. The ayanamsha measured on the ecliptic of t0
is subtracted from tropical positions referred to the ecliptic of date.
Note, this method will NOT provide accurate results if you want coordinates referred to the ecliptic of one of the
following equinoxes:
#define SE_SIDM_J2000 18
#define SE_SIDM_J1900 19
#define SE_SIDM_B1950 20
Instead, you have to use a correct coordinate transformation as described in the following:
Swiss Ephemeris 47
Special uses of the sidereal functions:
If a user-defined ayanamsha is set using SE_SIDM_USER, then the t0 is usually considered to be TT (ET).
However, t0 can be provided as UT if SE_SIDM_USER is combined with SE_SIDBIT_USER_UT.
If a correct transformation to the ecliptic of t0 is required the following bit can be added (‘ored’) to the value of
the variable sid_mode:
This procedure is required for the following sidereal modes, i.e. for transformation to the ecliptic of one of the
standard equinoxes:
#define SE_SIDM_J2000 18
#define SE_SIDM_J1900 19
#define SE_SIDM_B1950 20
The function swe_set_sidmode() can also be used for calculating ”precession-corrected transits”. There are
two methods, of which you have to choose the one that is more appropriate for you:
1. If you already have tropical positions of a natal chart, you can proceed as follows:
where tjd_et_natal is the Julian day of the natal chart (Ephemeris time).
After this calculate the transits, using the function swe_calc() with the sidereal bit:
iflag |= SEFLG_SIDEREAL;
iflgret = swe_calc(tjd_et_transit, ipl_transit, iflag, xpt, serr);
2. If you do not have tropical natal positions yet, if you do not need them and are just interested in transit times,
you can have it simpler:
swe_set_sid_mode( SE_SIDBIT_USER + SE_SIDBIT_ECL_T0, tjd_et, 0 );
iflag |= SEFLG_SIDEREAL;
iflgret = swe_calc(tjd_et_natal, ipl_natal, iflag, xp, serr);
iflgret = swe_calc(tjd_et_transit, ipl_transit, iflag, xpt, serr);
In this case, the natal positions will be tropical but without nutation. Note that you should not use them for other
purposes.
Swiss Ephemeris 48
c) solar system rotation plane
For sidereal positions referred to the solar system rotation plane, use the flag
Note: the parameters set by swe_set_sid_mode() survive calls of the function swe_close().
It is not recommended to use the ayanamsha functions for calculating sidereal planetary positions from tropical
positions, since this could lead to complicated confusions. For sidereal planets, please use swe_calc_ut() and
swe_calc() with the flag SEFLG_SIDEREAL.
Use the ayanamsha function only for “academical” purposes, e.g. if you want to indicate the value of the
ayanamsha on a horoscope chart. In this case, it is recommended to indicate the ayanamsha including nutation.
Ayanamsha without nutation may be useful in historical research, where the focus usually is on the mere
precessional component of the ayanamsha.
Special case of “true” ayanamshas such as “True Chitrapaksha” etc.: The flags SEFLG_TRUEPOS,
SEFLG_NOABERR and SEFLG_NOGDEFL can be used here, but users should not do that unless they really
understand what they are doing. It means that the same flags are internally used for the calculation of the
reference star (e.g. Citra/Spica). Slightly different ayanamsha values will result depending on these flags.
Before calling one of these functions, you have to set the sidereal mode with swe_set_sid_mode(), unless you
want the default sidereal mode, which is the Fagan/Bradley ayanamsha.
/* input variables:
* tjd_ut = Julian day number in UT
* (tjd_et = Julian day number in ET/TT)
* iflag = ephemeris flag (one of SEFLG_SWIEPH, SEFLG_JPLEPH, SEFLG_MOSEPH)
* plus some other optional SEFLG_...
* output values
* daya = ayanamsha value (pointer to double)
* serr = error message or warning (pointer to string)
* The function returns either the ephemeris flag used or ERR (-1)
*/
int32 swe_get_ayanamsa_ex_ut(double tjd_ut, int32 iflag, double *daya, char *serr);
int32 swe_get_ayanamsa_ex(double tjd_et, int32 iflag, double *daya, char *serr);
double swe_get_ayanamsa_ut(double tjd_ut); /* input: Julian day number in UT */
double swe_get_ayanamsa(double tjd_et); /* input: Julian day number in ET/TT */
The differences between the values provided by the new and old functions are very small and possibly only
relevant for precision fanatics.
Swiss Ephemeris 49
The function swe_get_ayanamsa_ut() was introduced with Swisseph Version 1.60 and expects Universal
Time instead of Ephemeris Time. (cf. swe_calc_ut() and swe_calc())
Where latitude is an input parameter (or output parameter) in Swiss Ephemeris functions, it is always
geographic latitude. This is the latitude found in Atlases and Google Earth.
If internally in a function a conversion to geocentric latitude is required (because the 3-d point on the oblate Earth
is needed), this is done automatically.
For such conversions, however, the Swiss Ephemeris only uses an ellipsoid for the form of the Earth. It does not
use the irregular geoid. This can result in an altitude error of up to 500 meters, or error of the topocentric Moon of
up to 0.3 arc seconds.
Astrologers who claim that for computing the ascendant or houses one needs geocentric latitude are wrong. The
flattening of the earth does not play a part in house calculations. Geographic latitude should always be used with
house calculations.
Swiss Ephemeris 50
13.2 swe_houses_armc()
int swe_houses_armc(
double armc, /* ARMC */
double geolat, /* geographic latitude, in degrees */
double eps, /* ecliptic obliquity, in degrees */
int hsys, /* house method, ascii code of one of the letters documdented below */
double *cusps, /* array for 13 (or 37 for system G) doubles */
double *ascmc); /* array for 10 doubles */
13.3 swe_houses_ex()
/* extended function; to compute tropical or sidereal positions */
int swe_houses_ex(
double tjd_ut, /* Julian day number, UT */
int32 iflag, /* 0 or SEFLG_SIDEREAL or SEFLG_RADIANS */
double geolat, /* geographic latitude, in degrees */
double geolon, /* geographic longitude, in degrees
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
int hsys, /* house method, one-letter case sensitive code (list, see further below) */
double *cusps, /* array for 13 (or 37 for system G) doubles */
double *ascmc); /* afrray for 10 doubles */
13.4 swe_house_name()
/* returns the name of the house method, maximum 40 chars
*/
char * swe_house_name(
int hsys, /* house method, ascii code of one of the letters PKORCAEVXHTBG */
);
The function swe_houses() is most comfortable, if you need the houses for a given date and geographic
position. Sometimes, however, you will want to compute houses from an ARMC, e.g. with the composite
horoscope which has no date, only the composite ARMC of two natal ARMCs. In such cases, you can use the
function swe_houses_armc(). To compute the composite ecliptic obliquity eps, you will have to call
sweph_calc() with ipl = SE_ECL_NUT for both birth dates and calculate the average of both eps.
Note that tjd_ut must be Universal Time, whereas planets are computed from Ephemeris Time
tjd_et = tjd_ut + delta_t(tjd_ut).
Also note that the array cusps must provide space for 13 doubles (declare as cusp[13]), otherwise you risk a
program crash. With house system ‘G’ (Gauquelin sector cusps), declare it as cusp[37].
Swiss Ephemeris 51
Note: With house system ‘G’, the cusp numbering is in clockwise direction.
The extended house function swe_houses_ex() does exactly the same calculations as swe_houses(). The
difference is that swe_houses_ex() has a parameter iflag, which can be set to SEFLG_SIDEREAL, if sidereal
house positions are wanted. Before calling swe_houses_ex() for sidereal house positions, the sidereal mode
can be set by calling the function swe_set_sid_mode(). If this is not done, the default sidereal mode, i.e. the
Fagan/Bradley ayanamsha, will be used.
There is no extended function for swe_houses_armc(). Therefore, if you want to compute such obscure things
as sidereal composite house cusps, the procedure will be more complicated:
/* sidereal composite house computation; with true epsilon, but without nutation in longitude */
swe_calc(tjd_et1, SE_ECL_NUT, 0, x1, serr);
swe_calc(tjd_et2, SE_ECL_NUT, 0, x2, serr);
armc1 = swe_sidtime(tjd_ut1) * 15;
armc2 = swe_sidtime(tjd_ut2) * 15;
armc_comp = composite(armc1, armc2); /* this is a function created by the user */
eps_comp = (x1[0] + x2[0]) / 2;
nut_comp = (x1[2] + x2[2]) / 2;
tjd_comp = (tjd_et1 + tjd_et2) / 2;
aya = swe_get_ayanamsa(tjd_comp);
swe_houses_armc(armc_comp, geolat, eps_comp, hsys, cusps, ascmc);
for (i = 1; i <= 12; i++)
cusp[i] = swe_degnorm(cusp[i] – aya – nut_comp);
for (i = 0; i < 10; i++)
ascmc[i] = swe_degnorm(asc_mc[i] – aya – nut_comp);
ascmc must be an array of 10 doubles. ascmc[8... 9] are 0 and may be used for additional points in future
releases.
Placidus and Koch house cusps cannot be computed beyond the polar circle. In such cases, swe_houses()
switches to Porphyry houses (each quadrant is divided into three equal parts) and returns the error code ERR.
The house method codes are actually case sensitive. At the moment, there still are no lowercase house method
codes. At the moment, if a lowercase code is passed to the function, it will convert it into uppercase. However, in
future, lower case codes may be used for new house methods. In such cases, lower and uppercase won’t be
equivalent anymore.
The Vertex is the point on the ecliptic that is located in precise western direction. The opposition of the Vertex
is the Antivertex, the ecliptic east point.
The variables armc, geolat, eps, and xpin[0] and xpin[1] (ecliptic longitude and latitude of the planet) must
be in degrees. serr must, as usually, point to a character array of 256 byte.
The function returns a value between 1.0 and 12.999999, indicating in which house a planet is and how far from
its cusp it is.
Swiss Ephemeris 53
With house system ‘G’ (Gauquelin sectors), a value between 1.0 and 36.9999999 is returned. Note that, while all
other house systems number house cusps in counterclockwise direction, Gauquelin sectors are numbered in
clockwise direction.
With Koch houses, the function sometimes returns 0, if the computation was not possible. This happens most
often in polar regions, but it can happen at latitudes below 66°33’ as well, e.g. if a body has a high declination
and falls within the circumpolar sky. With circumpolar fixed stars (or asteroids) a Koch house position may be
impossible at any geographic location except on the equator.
The user must decide how to deal with this situation.
You can use the house positions returned by this function for house horoscopes (or ”mundane” positions). For
this, you have to transform it into a value between 0 and 360 degrees. Subtract 1 from the house number and
multiply it with 30, or mund_pos = (hpos – 1) * 30;
You will realize that house positions computed like this, e.g. for the Koch houses, will not agree exactly with the
ones that you get applying the Huber ”hand calculation” method. If you want a better agreement, set the ecliptic
latitude xpin[1]= 0;. Remaining differences result from the fact that Huber’s hand calculation is a simplification,
whereas our computation is geometrically accurate.
Currently, geometrically correct house positions are provided for the following house methods:
P Placidus, K Koch, C Campanus, R Regiomontanus, U Krusinski,
A/E Equal, V Vehlow, W Whole Signs, D Equal/MC, N Equal/Zodiac,
O Porphyry, B Alcabitius, X Meridian, F Carter, M Morinus,
T Polich/Page, H Horizon, G Gauquelin.
A simplified house position (distance_from_cusp / house_size) is currently provided for the following house
methods:
Y APC houses, L Pullen SD, Q Pullen SR, I Sunshine, S Sripati.
This function requires TROPICAL positions in xpin. SIDEREAL house positions are identical to tropical ones in
the following cases:
If the traditional method is used to compute sidereal planets ( sid_pos = trop_pos – ayanamsha ). Here the
function swe_house_pos() works for all house systems.
If a non-traditional method (projection to the ecliptic of t0 or to the solar system rotation plane) is used and
the definition of the house system does not depend on the ecliptic. This is the case with Campanus,
Regiomontanus, Placidus, Azimuth houses, axial rotation houses. This is NOT the case with equal
houses, Porphyry and Koch houses. You have to compute equal and Porphyry house positions on your
own. We recommend to avoid Koch houses here. Sidereal Koch houses make no sense with these sidereal
algorithms.
There are two functions that can be used to calculate Gauquelin sectors:
swe_house_pos. Full details about this function are presented in the previous section. To calculate Gauquelin
sectors the parameter hsys must be set to 'G' (Gauquelin sectors). This function will then return the sector
position as a value between 1.0 and 36.9999999. Note that Gauquelin sectors are numbered in clockwise
direction, unlike all other house systems.
swe_gauquelin_sector - detailed below.
int32 swe_gauquelin_sector(
double tjd_ut, /* input time (UT) */
int32 ipl, /* planet number, if planet, or moon
* ipl is ignored if the following parameter (starname) is set*/
char *starname, /* star name, if star */
int32 iflag, /* flag for ephemeris and SEFLG_TOPOCTR */
int32 imeth, /* method: 0 = with lat., 1 = without lat.,
/* 2 = from rise/set, 3 = from rise/set with refraction */
double *geopos, /* array of three doubles containing
Swiss Ephemeris 54
* geograph. long., lat., height of observer */
double atpress, /* atmospheric pressure, only useful with imeth=3;
* if 0, default = 1013.25 mbar is used*/
double attemp, /* atmospheric temperature in degrees Celsius, only useful with imeth=3 */
double *dgsect, /* return address for gauquelin sector position */
char *serr); /* return address for error message */
This function returns OK or ERR (-1). It returns an error in a number of cases, for example circumpolar bodies
with imeth=2. As with other SE functions, if there is an error, an error message is written to serr. dgsect is used to
obtain the Gauquelin sector sector position as a value between 1.0 and 36.9999999. Gauquelin sectors are
numbered in clockwise direction.
There are six methods of computing the Gauquelin sector position of a planet:
1. Sector positions from ecliptical longitude AND latitude:
There are two ways of doing this:
Call swe_house_pos() with hsys = 'G', xpin[0] = ecliptical longitude of planet, and xpin[1] = ecliptical
latitude. This function returns the sector position as a value between 1.0 and 36.9999999.
Call swe_gauquelin_sector() with imeth=0. This is less efficient than swe_house_pos because it
recalculates the whole planet whereas swe_house_pos() has an input array for ecliptical positions
calculated before.
4. Sector positions of a planet from rising and setting times of planets, taking into account atmospheric
refraction.
The rising and setting of the disk center is used:
Call swe_gauquelin_sector() with imeth = 3.
6. Sector positions of a planet from rising and setting times of planets, taking into account atmospheric
refraction.
The rising and setting of the disk edge is used:
Call swe_gauquelin_sector() with imeth = 5.
long swe_calc_ut(
double tjd_ut, /* Julian day number, Universal Time */
int ipl, /* planet number */
long iflag, /* flag bits */
double *xx, /* target address for 6 position values: longitude, latitude, distance,
long. speed, lat. speed, dist. speed */
char *serr); /* 256 bytes for error string */
long swe_calc(
double tjd_et, /* Julian day number, Ephemeris Time */
int ipl, /* planet number */
long iflag, /* flag bits */
double *xx, /* target address for 6 position values: longitude, latitude, distance,
long. speed, lat. speed, dist. speed */
char *serr); /* 256 bytes for error string */
Fixed stars
long swe_fixstar_ut(
char *star, /* star name, returned star name 40 bytes */
double tjd_ut, /* Julian day number, Universal Time */
long iflag, /* flag bits */
double *xx, /* target address for 6 position values: longitude, latitude, distance,
long. speed, lat. speed, dist. speed */
char *serr); /* 256 bytes for error string */
long swe_fixstar(
char *star, /* star name, returned star name 40 bytes */
double tjd_et, /* Julian day number, Ephemeris Time */
long iflag, /* flag bits */
double *xx, /* target address for 6 position values: longitude, latitude, distance,
long. speed, lat. speed, dist. speed */
char *serr); /* 256 bytes for error string */
Compute the attributes of a solar eclipse for a given tjd, geographic long., latit. and height
int32 swe_sol_eclipse_how(
double tjd_ut, /* time, Jul. day UT */
int32 ifl, /* ephemeris flag */
double *geopos, /* geogr. longitude, latitude, height */
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
double *attr, /* return array, 20 doubles, see below */
char *serr); /* return error string */
Find out the geographic position where a central eclipse is central or a non-central one maximal
int32 swe_sol_eclipse_where (
double tjd_ut, /* time, Jul. day UT */
int32 ifl, /* ephemeris flag */
double *geopos, /* return array, 2 doubles, geo. long. and lat. */
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
Swiss Ephemeris 57
double *attr, /* return array, 20 doubles, see below */
char *serr); /* return error string */
or
int32 swe_lun_occult_where (
double tjd_ut, /* time, Jul. day UT */
int32 ipl, /* planet number */
char* starname, /* star name, must be NULL or ”” if not a star */
int32 ifl, /* ephemeris flag */
double *geopos, /* return array, 2 doubles, geo. long. and lat.
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
double *attr, /* return array, 20 doubles, see below */
char *serr); /* return error string */
Find the next occultation of a body by the moon for a given geographic position
(can also be used for solar eclipses )
int32 swe_lun_occult_when_loc(
double tjd_start, /* start date for search, Jul. day UT */
int32 ipl, /* planet number */
char* starname, /* star name, must be NULL or ”” if not a star */
int32 ifl, /* ephemeris flag */
double *geopos, /* 3 doubles for geo. lon, lat, height eastern longitude is positive,
western longitude is negative, northern latitude is positive,
southern latitude is negative */
double *tret, /* return array, 10 doubles, see below */
double *attr, /* return array, 20 doubles, see below */
AS_BOOL backward, /* TRUE, if backward search */
char *serr); /* return error string */
int32 swe_lun_occult_when_glob(
double tjd_start, /* start date for search, Jul. day UT */
int32 ipl, /* planet number */
char* starname, /* star name, must be NULL or ”” if not a star */
int32 ifl, /* ephemeris flag */
int32 ifltype, /* eclipse type wanted */
double *geopos, /* 3 doubles for geo. lon, lat, height eastern longitude is positive,
western longitude is negative, northern latitude is positive,
southern latitude is negative */
double *tret, /* return array, 10 doubles, see below */
double *attr, /* return array, 20 doubles, see below */
AS_BOOL backward, /* TRUE, if backward search */
char *serr); /* return error string */
int32 swe_rise_trans_true_hor(
double tjd_ut, /* search after this time (UT) */
int32 ipl, /* planet number, if planet or moon */
char *starname, /* star name, if star */
int32 epheflag, /* ephemeris flag */
int32 rsmi, /* integer specifying that rise, set, orone of the two meridian transits is
wanted. see definition below */
double *geopos, /* array of three doubles containing
* geograph. long., lat., height of observer */
double atpress, /* atmospheric pressure in mbar/hPa */
double attemp, /* atmospheric temperature in deg. C */
double horhgt, /* height of local horizon in deg at the point where the body rises or sets*/
double *tret, /* return address (double) for rise time etc. */
char *serr); /* return address for error message */
void swe_azalt(
double tjd_ut, /* UT */
int32 calc_flag, /* SE_ECL2HOR or SE_EQU2HOR */
double *geopos, /* array of 3 doubles: geogr. long., lat., height */
double atpress, /* atmospheric pressure in mbar (hPa) */
double attemp, /* atmospheric temperature in degrees Celsius */
double *xin, /* array of 3 doubles: position of body in either ecliptical or equatorial
coordinates, depending on calc_flag */
double *xaz); /* return array of 3 doubles, containing azimuth, true altitude, apparent
altitude */
void swe_azalt_rev(
double tjd_ut,
int32 calc_flag, /* either SE_HOR2ECL or SE_HOR2EQU */
double *geopos, /* array of 3 doubles for geograph. pos. of observer */
double *xin, /* array of 2 doubles for azimuth and true altitude of planet */
double *xout); /* return array of 2 doubles for either ecliptic or equatorial coordinates,
depending on calc_flag */
double swe_refrac(
double inalt,
double atpress, /* atmospheric pressure in mbar (hPa) */
double attemp, /* atmospheric temperature in degrees Celsius */
int32 calc_flag); /* either SE_TRUE_TO_APP or SE_APP_TO_TRUE */
/* older function: */
/* Ephemeris time (ET) = Universal time (UT) + swe_deltat(UT)*/
double swe_deltat(double tjd);
Julian day number from year, month, day, hour, with check whether date is legal
/*Return value: OK or ERR */
int swe_date_conversion (
int y , int m , int d , /* year, month, day */
double hour, /* hours (decimal, with fraction) */
char c, /* calendar ‘g’[regorian]|’j’[ulian] */
double *tjd); /* target address for Julian day */
TT (ET1) to UTC
/* input: Julian day number in ET (TT), calendar flag
* output: year, month, day, hour, min, sec in UTC */
void swe_jdet_to_utc (
double tjd_et, /* Julian day number in ET (TT) */
gregflag, /* Gregorian calendar: 1, Julian calendar: 0 */
int32 *iyear, int32 *imonth, int32 *iday,
int32 *ihour, int32 *imin, double *dsec, /* note : second is a decimal */
)
UTC to TT (ET1)
/* input: Julian day number in UT (UT1), calendar flag
* output: year, month, day, hour, min, sec in UTC */
void swe_jdut1_to_utc (
double tjd_ut, /* Julian day number in ET (TT) */
gregflag, /* Gregorian calendar: 1, Julian calendar: 0 */
int32 *iyear, int32 *imonth, int32 *iday,
int32 *ihour, int32 *imin, double *dsec, /* note : second is a decimal */
)
Equation of time
/ * function returns the difference between local apparent and local mean time.
e = LAT – LMT. tjd_et is ephemeris time */
int swe_time_equ(double tjd_et, double *e, char *serr);
double swe_sidtime0(
double tjd_ut, /* Julian day number, UT */
double eps, /* obliquity of ecliptic, in degrees */
double nut); /* nutation, in degrees */
char * swe_house_name(
int hsys, /* house method, ascii code of one of the letters PKORCAEVXHTBG */
);
int swe_houses_armc(
double armc, /* ARMC */
double geolat, /* geographic latitude, in degrees */
double eps, /* ecliptic obliquity, in degrees */
int hsys, /* house method, one of the letters PKRCAV */
double *cusps, /* array for 13 doubles */
double *ascmc); /* array for 10 doubles */
double swe_gauquelin_sector(
double tjd_ut, /* search after this time (UT) */
int32 ipl, /* planet number, if planet, or moon */
char *starname, /* star name, if star */
int32 iflag, /* flag for ephemeris and SEFLG_TOPOCTR */
int32 imeth, /* method: 0 = with lat., 1 = without lat.,
/* 2 = from rise/set, 3 = from rise/set with refraction */
double *geopos, /* array of three doubles containing
* geograph. long., lat., height of observer */
double atpress, /* atmospheric pressure, only useful with imeth=3;
* if 0, default = 1013.25 mbar is used*/
double attemp, /* atmospheric temperature in degrees Celsius, only useful with imeth=3 */
double *dgsect, /* return address for gauquelin sector position */
char *serr); /* return address for error message */
Swiss Ephemeris 64
void swe_cotrans(
double *xpo, /* 3 doubles: long., lat., dist. to be converted; distance remains unchanged,
can be set to 1.00 */
double *xpn, /* 3 doubles: long., lat., dist. Result of the conversion */
double eps); /* obliquity of ecliptic, in degrees. */
double swe_split_deg(double ddeg, int32 roundflag, int32 *ideg, int32 *imin, int32 *isec, double
*dsecfr, int32 *isgn);
Distance in degrees
/* former function name: difdegn() */
double swe_difdegn (double p1, double p2);
Distance in degrees
/* former function name: difdeg2n() */
double swe_difdeg2n(double p1, double p2);
Day of week
/*Monday = 0, ... Sunday = 6 former function name: day_of_week() */
int swe_day_of_week(double jd);
You can use our programs swetest.c and swewin.c as examples.To compile swetest or swewin with a DLL:
Swiss Ephemeris release 1.61 is the last release for which 16-bit compilers have been supported and for
which a 16-bit DLL has been created.
The Visual Basic declarations for the DLL functions and for some important flag parameters are in the file
\sweph\vb\swedecl.txt and can be inserted directly into a VB program.
A sample VB program vbsweph is included on the distribution, in directory \sweph\vb. To run this sample, the
DLL file swedll32.dll must be copied into the vb directory or installed in the Windows system directory.
This function copies its result into the string pointer plname; the calling program must provide sufficient space
so that the result string fits into it. As usual in C programming, the function copies the return string into the
provided area and returns the pointer to this area as the function value. This allows to use this function directly in
a C print statement.
1. The string parameter plname must be initialized to a string of sufficient length before the call; the content
does not matter because it is overwritten by the called function. The parameter type must be
ByVal plname as String.
2. The returned string is terminated by a NULL character. This must be searched in VB and the VB string
length must be set accordingly. Our sample program demonstrates how this can be done:
3. The function value itself is a pointer to character. This function value cannot be used in VB because VB does
not have a pointer data type. In VB, such a Function can be either declared as type ”As long” and the
return value ignored, or it can be declared as a Sub. We have chosen to declare all such functions as ‚Sub‘,
which automatically ignores the return value.
Declare Sub swe_get_planet_name (ByVal ipl as Long, ByVal plname as String)
19. Using the DLL with Borland Delphi and C++ Builder
19.1 Delphi 2.0 and higher (32-bit)
The information in this section was contributed by Markus Fabian, Bern, Switzerland.
In Delphi 2.0 the declaration of the function swe_calc() looks like this:
xx : Array[0..5] of double;
Swiss Ephemeris 68
function swe_calc (tjd : double; // Julian day number
ipl : Integer; // planet number
iflag : Longint; // flag bits
var xx[0] : double;
sErr : PChar // Error-String;
) : Longint; stdcall; far; external 'swedll32.dll' Name '_swe_calc@24';
With the following command command you create a special lib file in the current directory:
IMPLIB –f –c swe32bor.lib \sweph\bin\swedll32.dll
1. Install the Swiss Ephemeris. Either you download the Swiss Ephemeris DLL from
http://www.astro.com/swisseph or you download the Swiss Ephemeris C source code and compile a
static or dynamic shared library. We built the package on a Linux system and use a shared library of the
Swiss Ephemeris functions.
If you work on a Windows machine and prefer to use the Swiss Ephemeris DLL, you may want to study Rüdiger
Plantiko's Perl module for the Swiss Ephemeris at http://www.astrotexte.ch/sources/SwissEph.zip. There is also
a documentation in German language by Rüdiger Plantiko at http://www.astrotexte.ch/sources/swe_perl.html).
Until version 2.04, all sample programs were compiled with the Microsoft Visual C++ 5.0 compiler (32-bit).
Project and Workspace files for these environments are included with the source files.
Swiss Ephemeris 69
Since version 2.05, all sample programs and DLLs were compiled on Linux with MinGW. 64-bit programs
contain a ‘64’ string in their names.
Directory structure:
Sweph\bin DLL, LIB and EXE file
Sweph\src source files, resource files
sweph\src\swewin32 32-bit windows sample program, uses swedll32.dll
sweph\src\swetest 32-bit character mode sample program
sweph\src\swetest64 64-bit character mode sample program
sweph\src\swete32 32-bit character mode sample program, uses swedll32.dll
sweph\src\swete64 64-bit character mode sample program, uses swedll64.dll
sweph\src\swedll32.dll 32-bit DLL
sweph\src\swedll64.dll 64-bit DLL
sweph\src\swedll32.lib
sweph\src\swedll64.lib
swewin32.exe
The project files are in \sweph\src\swewin32
swewin.c
swedll32.lib
swewin.rc
swewin.h
swephexp.h
swedll.h
sweodef.h
resource.h
define macro USE_DLL
1. check environment variable SE_EPHE_PATH ; if it exists it is used, and if it has invalid content, the program
fails.
2. Try to find the ephemeris files in the current working directory
3. Try to find the ephemeris files in the directory where the executable resides
4. Try to find a directory named \SWEPH\EPHE in one of the following three drives:
where the executable resides
current drive
drive C:
As soon as it succeeds in finding the first ephemeris file it looks for, it expects all required ephemeris files to
reside there. This is a feature of the sample programs only, as you can see in our C code.
The DLL itself has a different and simpler mechanism to search for ephemeris files, which is described with the
function swe_set_ephe_path() above.
Swiss Ephemeris 70
21. The source code distribution
Starting with release 1.26, the full source code for the Swiss Ephemeris DLL is made available. Users can
choose to link the Swiss Ephemeris code directly into their applications. The source code is written in Ansi C
and consists of these files:
Bytes Date File name Comment
1639 Nov 28 17:09 Makefile unix makefile for library
API interface files
15050 Nov 27 10:56 swephexp.h SwissEph API include file
14803 Nov 27 10:59 swepcalc.h Placalc API include file
Internal files
8518 Nov 27 10:06 swedate.c
2673 Nov 27 10:03 swedate.h
8808 Nov 28 19:24 swedll.h
24634 Nov 27 10:07 swehouse.c
2659 Nov 27 10:05 swehouse.h
31279 Nov 27 10:07 swejpl.c
3444 Nov 27 10:05 swejpl.h
38238 Nov 27 10:07 swemmoon.c
2772 Nov 27 10:05 swemosh.h
18687 Nov 27 10:07 swemplan.c
311564 Nov 27 10:07 swemptab.c
7291 Nov 27 10:06 sweodef.h
28680 Nov 27 10:07 swepcalc.c
173758 Nov 27 10:07 sweph.c
12136 Nov 27 10:06 sweph.h
55063 Nov 27 10:07 swephlib.c
4886 Nov 27 10:06 swephlib.h
43421 Nov 28 19:33 swetest.c
In most cases the user will compile a linkable or shared library from the source code, using his favorite C
compiler, and then link this library with his application.
If the user programs in C, he will only need to include the header file swephexp.h with his application; this in turn
will include sweodef.h. All other source files can ignored from the perspective of application development.
sweph.cdr
sweph.gif
swephin.cdr
swephin.gif
swephprg.doc Documentation for programming, a MS Word-97 file
swephprg.rtf
swisseph.doc General information on Swiss Ephemeris
swisseph.rtf
The files with suffix .CDR are Corel Draw 7.0 documents with the Swiss Ephemeris icons.
Swiss Ephemeris 71
24. Swisseph with different hardware and compilers
Depending on what hardware and compiler you use, there will be slight differences in your planetary
calculations. For positions in longitude, they will be never larger than 0.0001" in longitude. Speeds show no
difference larger than 0.0002 arcsec/day.
The following factors show larger differences between HPUX and Linux on a Pentium II processor:
Mean Node, Mean Apogee:
HPUX PA-Risc non-optimized versus optimized code:
differences are smaller than 0.001 arcsec/day
The differences originate from the fact that the floating point arithmetic in the Pentium is executed with 80 bit
precision, whereas stored program variables have only 64 bit precision. When code is optimized, more
intermediate results are kept inside the processor registers, i.e. they are not shortened from 80bit to 64 bit.
When these results are used for the next calculation, the outcome is then slightly different.
In the computation of speed for the nodes and apogee, differences between positions at close intervals are
involved; the subtraction of nearly equal values results shows differences in internal precision more easily than
other types of calculations. As these differences have no effect on any imaginable application software and are
mostly within the design limit of Swiss Ephemeris, they can be savely ignored.
IMPORTANT: The Swisseph DLL will not work properly if you call it from more than one thread.
swetrace.c:
Swiss Ephemeris 72
#include "sweodef.h"
#include "swephexp.h"
void main()
{
double tjd, t, nut, eps; int i, ipl, retc; long iflag;
double armc, geolat, cusp[12], ascmc[10]; int hsys;
double xx[6]; long iflgret;
char s[AS_MAXCH], star[AS_MAXCH], serr[AS_MAXCH];
/*SWE_DELTAT*/
tjd = 2451337.870000000; t = swe_deltat(tjd);
printf("swe_deltat: %f\t%f\t\n", tjd, t);
/*SWE_CALC*/
tjd = 2451337.870757482; ipl = 0; iflag = 258;
iflgret = swe_calc(tjd, ipl, iflag, xx, serr); /* xx = 1239992 */
/*SWE_CLOSE*/
swe_close();
Appendix
Update and release history
Updated By
30-sep-97 Alois added chapter 10 (sample programs)
7-oct-97 Dieter inserted chapter 7 (house calculation)
8-oct-97 Dieter Appendix ”Changes from version 1.00 to 1.01”
12-oct-1997 Alois Added new chapter 10 Using the DLL with Visual Basic
26-oct-1997 Alois improved implementation and documentation of swe_fixstar()
28-oct-1997 Dieter Changes from Version 1.02 to 1.03
29-oct-1997 Alois added VB sample extension, fixed VB declaration errors
9-Nov-1997 Alois added Delphi declaration sample
8-Dec-97 Dieter remarks concerning computation of asteroids, changes to version 1.04
8-Jan-98 Dieter changes from version 1.04 to 1.10.
12-Jan-98 Dieter changes from version 1.10 to 1.11.
21-Jan-98 Dieter calculation of topocentric planets and house positions (1.20)
28-Jan-98 Dieter Delphi 1.0 sample and declarations for 16- and 32-bit Delphi (1.21)
11-Feb-98 Dieter version 1.23
7-Mar-1998 Alois version 1.24 support for Borland C++ Builder added
4-June-1998 Alois version 1.25 sample for Borland Delphi-2 added
29-Nov-1998 Alois version 1.26 source code information added §16, Placalc API added
1-Dec-1998 Dieter chapter 19 and some additions in beginning of Appendix.
2-Dec-1998 Alois Equation of Time explained (in §4), changes version 1.27 explained
3-Dec-1998 Dieter Note on ephemerides of 1992 QB1 and 1996 TL66
17-Dec-1998 Alois Note on extended time range of 10'800 years
22 Dec 1998 Alois Appendix A
12-Jan-1999 Dieter Eclipse functions added, version 1.31
19-Apr-99 Dieter version 1.4
8-Jun-99 Dieter Chapter 21 on tracing an debugging Swisseph
27-Jul-99 Dieter Info about sidereal calculations
16-Aug-99 Dieter version 1.51, minor bug fixes
15-Feb-00 Dieter many things for version 1.60
Swiss Ephemeris 73
19-Mar-00 Vic Ogi SWEPHPRG.DOC re-edited
17-apr-02 Dieter Documentation for version 1.64
26-Jun-02 Dieter Version 1.64.01
31-dec-2002 Alois edited doc to remove references to 16-bit version
12-jun-2003 Alois/Dieter Documentation for version 1.65
10-Jul-2003 Dieter Documentation for version 1.66
25-May-2004 Dieter Documentation of eclipse functions updated
31-Mar-2005 Dieter Documentation for version 1.67
3-May-2005 Dieter Documentation for version 1.67.01
22-Feb-2006 Dieter Documentation for version 1.70.00
2-May-2006 Dieter Documentation for version 1.70.01
5-Feb-2006 Dieter Documentation for version 1.70.02
30-Jun-2006 Dieter Documentation for version 1.70.03
28-Sep-2006 Dieter Documentation for version 1.71
29-May-2008 Dieter Documentation for version 1.73
18-Jun-2008 Dieter Documentation for version 1.74
27-Aug-2008 Dieter Documentation for version 1.75
7-April-2009 Dieter Documentation of version 1.76
3-Sep-2013 Dieter Documentation of version 1.80
10-Sep-2013 Dieter Documentation of version 1.80 corrected
11-Feb-2014 Dieter Documentation of version 2.00
4-Mar-2014 Dieter Documentation of swe_rise_trans() corrected
18-Mar-2015 Dieter Documentation of version 2.01
11-Aug-2015 Dieter Documentation of version 2.02
14-Aug-2015 Dieter Documentation of version 2.02.01
16-Oct-2015 Dieter Documentation of version 2.03
21-Oct-2015 Dieter Documentation of version 2.04
27-May-2015 Dieter Documentation of version 2.05
27-May-2015 Dieter Documentation of version 2.05.01
10-Jan-2016 Dieter Documentation of version 2.06
5-Jan-2018 Dieter Documentation of version 2.07
1-Feb-2018 Dieter Documentation of version 2.07.01
Release Date
1.00 30-sep-1997
1.01 9-oct-1997 houses(), sidtime() made more convenient for developer, Vertex added.
houses() changed again, Visual Basic support, new numbers for fictitious planets
1.02 16-oct-1997
This release was pushed to all existing licensees at this date.
minor bug fixes, improved swe_fixstar() functionality. This release was not
1.03 28-Oct-1997 pushed, as the changes and bug fixes are minor; no changes of function
definitions occurred.
1.04 8-Dec-1997 minor bug fixes; more asteroids.
1.10 9-Jan-1998 bug fix, s. Appendix. This release was pushed to all existing licensees at this date.
1.11 12-Jan-98 small improvements
1.20 20-Jan-98 New: topocentric planets and house positions; a minor bug fix
1.21 28-Jan-98 Delphi declarations and sample for Delphi 1.0
1.22 2-Feb-98 Asteroids moved to subdirectory. Swe_calc() finds them there.
1.23 11-Feb-98 two minor bug fixes.
1.24 7-Mar-1998 Documentation for Borland C++ Builder added, see section 14.3
1.25 4-June-1998 Sample for Borland Delphi-2 added
1.26 29-Nov-1998 full source code made available, Placalc API documented
1.27 2-dec-1998 Changes to SE_EPHE_PATH and swe_set_ephe_path()
1.30 17-Dec-1998 Time range extended to 10'800 years
1.31 12-Jan-1999 New: Eclipse functions added
1.40 19-Apr-99 New: planetary phenomena added; bug fix in swe_sol_ecl_when_glob();
1.50 27-Jul-99 New: SIDEREAL planetary positions and houses; new fixstars.cat
1.51 16-Aug-99 Minor bug fixes
1.60 15-Feb-2000 Major release with many new features and some minor bug fixes
1.61 11-Sep-2000 Minor release, additions to se_rise_trans(), swe_houses(), ficitious planets
1.61.01 18-Sep-2000 Minor release, added Alcabitus house system
1.61.02 10-Jul-2001 Minor release, fixed bug which prevented asteroid files > 22767 to be accepted
Minor release, fixed bug which was introduced in 1.61.02: Ecliptic was computed
1.61.03 20-Jul-2001
in Radians instead of degrees
Swiss Ephemeris 74
Minor release, several bug fixes, code for fictitious satellites of the earth, asteroid
1.62.00 23-Jul-2001
files > 55535 are accepted
1.62.01 16-Oct-2001 Bug fix, string overflow in sweph.c::read_const(),
1.63.00 5-Jan-2002 Added house calculation to sweetest.c and swetest.exe
House system ‘G’ for house functions and function swe_gauquelin_sector() for
Gauquelin sector calculations
1.64.00 6-Mar-2002
Occultations of planets and fixed stars by the moon
New Delta T algorithms
1.64.01 26-Jun-2002 Bug fix in swe_fixstar(). Stars with decl. between –1° and 0° were wrong
1.65.00 12-Jun-2003 Long variables replaced by INT32 for 64-bit compilers
1.66.00 10-Jul-2003 House system ‘M’ for Morinus houses
1.67.00 31-Mar-2005 Update Delta T
1.67.01 3-May-2005 Docu for sidereal calculations (Chap. 10) updated (precession-corrected transits)
1.70.00 22-Feb-2006 all relevant IAU resolutions up to 2005 have been implemented
1.70.01 2-May-2006 minor bug fix
1.70.02 5-May-2006 minor bug fix
1.70.03 30-June-2006 bug fix
1.71 28-Sep-2006 Swiss Ephemeris functions able to calculate minor planet no 134340 Pluto
1.72 28-Sep-2007 New function swe_refract_extended(), Delta T update, minor bug fixes
1.73 29-May-2008 New function swe_fixstars_mag(), Whole Sign houses
1.74 18-Jun-2008 Bug fixes
1.75 27-Aug-2008 Swiss Ephemeris can read newer JPL ephemeris files; bug fixes
1.76 7-April-2009 Heliacal risings, UTC and minor improvements/bug fixes
1.77 26-Jan-2010 swe_deltat(), swe_fixstar() improved, swe_utc_time_zone_added
1.78 3-Aug-2012 New precession, improvement of some eclipse functions, some minor bug fixes
1.79 18-Apr-2013 New precession, improvement of some eclipse functions, some minor bug fixes
1.80 3-Sep-2013 Security update, APC houses, bug fixes
2.00 11-Feb-2014 Swiss Ephemeris is now based on JPL Ephemeris DE431
Udates for tidal acceleration of the Moon with DE431, Delta T, and leap seconds.
2.01 18-MAR-2015
A number of bug fixes
New functions swe_deltat_ex() and swe_ayanamsa_ex()/swe_ayanamsa_ex_ut()
2.02 11-Aug-2015
A number of bug fixes
2.02.01 14-Aug-2015 Small corrections to new code, for better backward compatibility
2.03 16-Oct-2015 Swiss Ephemeris thread-safe (except DLL)
2.04 21-Oct-2015 Swiss Ephemeris DLL based on calling convention __stdcall again, as used to be
2.05 27-May-2015 Bug fixes, new ayanamshas, new house methods, osculating elements
2.05.01 27-May-2015 Bug fix in new function swe_orbit_max_min_true_distance()
2.06 10-Jan-2017 New Delta T calculation
2.07 10-Jan-2018 Better performance of swe_fixstar() and swe_rise_trans()
Compatibility with Microsoft Visual Studio, minor bugfixes (fixed star functions,
2.07.01 1-Feb-2018
leap seconds).
- New functions swe_fixstar2(), swe_fixstar2_ut(), and swe_fixstar2_mag() with greatly increased performance.
Important additional remarks are given further below.
- Fixed stars data file sefstars.txt was updated with new data from SIMBAD database.
Swiss Ephemeris 75
- swe_fixstar(): Distances (in AU) and daily motions of the stars have been added to the return array. The daily
motions contain components of precession, nutation, aberration, parallax and the proper motions of the stars.
The usage of correct fixed star distances leads to small changes in fixed star positions and calculations of
occultations of stars by the Moon (in particular swe_lun_occult_when_glob()).
To transform the distances from AU into lightyears or parsec, please use the following defines, which are in
swephexp.h:
#define AUNIT_TO_LIGHTYEAR (1.0/63241.077088071)
#define AUNIT_TO_PARSEC (1.0/206264.8062471)
- There was a bug with daily motions of planets in sidereal mode: They contained precession! (Nobody ever
noticed or complained for almost 20 years!)
- In JPL Horizons mode, the Swiss Ephemeris now reproduces apparent position as provided by JPL Horizons
with an accuracy of a few milliseconds of arc for its whole time range. Until SE 2.06 this has been possible only
after 1800. Please note, this applies to JPL Horizons mode only (SEFLG_JPLHOR and
SEFLG_JPLHOR_APPROX together with an original JPL ephemeris file; or swetest -jplhor, swetest -jplhora).
Our default astronomical methods are those of IERS Conventions 2010 and Astronomical Almanac, not those of
JPL Horizons.
- After consulting with sidereal astrologers, we have changed the behaviour of the function
swe_get_ayanamsa_ex(). See programmer's documentation swephprg.htm, chap. 10.2. Note this change has no
impact on the calculation of planetary positions, as long as you calculate them using the sidereal flag
SEFLG_SIDEREAL.
- Calculation of heliacal risings using swe_heliacal_ut() now also works with Bayer designations, with an initial
comma, e.g. “,alTau”.
Important additional information on the new function swe_fixstar2() and its derivatives with increased
performance:
Some users had criticised that swe_fixstar() was very inefficient because it reopened and scanned the file
sefstars.txt for each fixed star to be calculated. With version 2.07, the new function swe_fixstar2() reads the
whole file the first time it is called and saves all stars in a sorted array of structs. Stars are searched in this list
using the binary search function bsearch(). After a call of swe_close() the data will be lost. A new call of
swe_fixstar2() will reload all stars from sefstars.txt.
The declaration of swe_fixstar2() is identical to old swe_fixstar(), but its behaviour is slightly different:
Fixed stars can be searched by
- full traditional name
- Bayer/Flamsteed designation
- traditional name with wildcard character '%'
Swiss Ephemeris 76
(With previous versions, search string "aldeb" provided the star Aldebaran. This does not work anymore. For
abbreviated search strings, a ‘%’ wildcard must, be added, e.g. "aldeb%".)
With the old swe_fixstar(), it was possible to use numbers as search keys. The function then returned the n-th
star it found in the list. This functionality is still available in the new version of the function, but the star
numbering does no longer follow the order of the stars in the file, but the order of the sorted Bayer designations.
Nevertheless this feature is very practical if one wants to create a list of all stars.
for i=1; i<10000; i++) { // choose any number greater than number of lines (stars) in file
sprintf(star, "%d", i);
returncode = swe_fixstar2(star, tjd, ...);
… whatever you want to do with the star positons …
if (returncode == ERR)
break;
}
Delta T values from 1973 to today have been updated by values from IERS, with four-digit accuracy. Two small
bugs that interpolates these tabulated data have been fixed. Changes in Delta T within this time range are
smaller than 5 millisec. The accuracy possible with 1-year step width is about 0.05 sec. For better accuracy, we
would have to implement a table of monthly or daily delta t values.
Time conversions from or to UTC take into account the leap second of 31 Dec 2016.
Minor bug fixes in heliacal functions. E.g., heliacal functions now work with ObjectName in uppercase or
lowercase.
Function swe_house_pos() now provides geometrically correct planetary house positions also for the house
methods I, Y, S (Sunshine, APC, Scripati).
House method N (1 = 0° Widder) did not work properly with some sidereal zodiac options.
swe_houses_ex() with sidereal flag and rarely used flags SE_SIDBIT_ECL_T0 or SE_SIDBIT_SSY_PLANE
returned a wrong ARMC.
swetest understands a new parameter -utcHH:MM:SS, where input time is understood as UTC (whereas
-utHH:MM:SS understands it as UT1). Note: Output of dates is always in UT1.
1) The Fixed stars file sefstars.txt was updated with new data from the Simbad Database. Some errors in the
file were fixed.
2) Topocentric positons of planets: The value of speed was not very good. This problem was found by Igor
"TomCat" Germanenko in March 2015. A more accurate calculation of speed from three positions has now been
implemented.
In addition, topocentric positions had an error < 1 arcsec if the function swe_calc() was called without
SEFLG_SPEED. This problem was found by Bernd Müller and has now been fixed.
3) Initial calls of the Swiss Ephemeris: Some problems were fixed which appeared when users did
calculations without opening the Swiss, i.e. without calling the function swe_set_ephe_path().
Note: It is still strongly recommended to call this function in the beginning of an application in order to make sure
that the results are always consistent.
4) New function swe_get_orbital_elements() calculates osculating Kepler elements and some other data for
planets, Earth-Moon barycentre, Moon, and asteroids. The program swetest has a new option -orbel that displays
these data.
The internal definitions of the ayanamshas has been changed and can be based either on UT or on TT.
Nothing changes for the user, except with user-defined ayanamshas. The t0 used in swe_set_sidmode() is
considered to be TT, except if the new bit flag SE_SIDBIT_USER_UT (1024) is or'ed to the parameter sid_mode.
8) _TRUE_ ayanamshas algorithm (True Chitra, True Revati, True Pushya, True Mula, Galactic/Gil Brand,
Galactic/Wilhelm) always keep the intended longitude, with or without the following iflags: SEFLG_TRUEPOS,
SEFLG_NOABERR, SEFLG_NOGDEFL.
So far, the True Chitra ayanamsha had Spica/Chitra at 180° exactly if the apparent position of the star was
calculated, however not if the true position (without aberration/light deflection) was calculated. However, some
people may find it more natural if the star’s true true position is exactly at 180°.
- Occultation of fixed stars have provided four contacts instead of two. Now there are only two contacts.
10) Magnitudes for Venus and Mercury have been improved according to Hilten 2005.
The Swiss Ephemeris now provides the same magnitudes as JPL's Horizons System.
11) Heliacal functions: A few bugs discovered by Victor Reijs have been fixed, which however did not become
appearant very often.
12) User-defined Delta T: For archaeoastronomy (as suggested by Victor Reijs) a new function
swe_set_delta_t_userdef() was created that allows the user to set a particular value for delta t.
13) Function swe_nod_aps(): a bug was fixed that occurred with calculations for the EMB.
14) New function swe_get_library_path(): The function returns the path in which the executable resides. If it is
running with a DLL, then returns the path of the DLL.
Since VBA requires __stdcall, we return to __stdcall and to decorated function names.
The macro PASCAL_CONV, which had been misleading, was renamed as CALL_CONV.
Swiss Ephemeris 79
Changes from version 2.02.01 to 2.03
This is a minor release, mainly for those who wish a thread-safe Swiss Ephemeris. It was implemented
according to the suggestions made by Rüdiger Plantico and Skylendar. Any errors might be Dieter Koch’s fault.
On our Linux
system, at least, it seems to work.
However, it seems that that we cannot build a thread-safe DLL inhouse at the moment. If a group member could
provide a thread-safe DLL, that could be added to the Swiss Ephemeris download area.
Other changes:
Note, other issues that have been discussed recently or even longer ago had to be postponed.
- With version 2.02, software that does not use swe_set_ephe_path() or swe_set_jpl_file() to initialise the Swiss
Ephemeris may fail to calculate topocentric planets with swe_calc() or swe_calc_ut() (return value ERR). Version
2.02.01 is more tolerant again.
- Ayanamshas TRUE_REVATI, TRUE_PUSHYA now also work if not fixed stars file is found in the ephemeris
path. With TRUE_CHITRA, this has been the case for longer.
- Bug fixed: since version 2.00, the sidereal modes TRUE_CHITRA, TRUE_REVATI, TRUE_PUSHYA provided
wrong latitude and speed for the Sun.
- A bug was fixed in sidereal time functions before 1850 and after 2050. The bug was a side effect of some
other bug fix in Version 2.01. The error was smaller than 5 arc min for the whole time range of the ephemeris.
The bug also resulted in errors of similar size in azimuth calculations before 1850 and after 2050.
Moreover, the bug resulted in errors of a few milliarcseconds in topocentric planetary positions before 1850 and
after 2050.
In addition, the timings of risings, settings, and local eclipses may be slightly affected, again only before
1850 and after 2050
- A bug was fixed that sometimes resulted in a program crash when function calls with different ephemeris flags
Swiss Ephemeris 80
(SEFLG_JPLEPH, SEFLG_SWIEPH, and SEFLG_MOSEPH) were made in sequence.
- Delta T functions:
- New function swe_deltat_ex(tjd_ut, ephe_flag, serr), where ephe_flag is one of the following:
SEFLG_SWIEPH, SEFLG_JPLEPH, SEFLG_MOSEPH, and serr the usual string for error messages.
It is wise to use this new function instead of the old swe_deltat(), especially if one uses more than one
ephemeris or wants to compare different ephemerides in UT.
Detailed explanations about this point are given further below in the general remark concerning Swiss
Ephemeris 2.02 and above in chap. 8 (on Delta T functions).
- The old function swe_deltat() was slightly modified. It now assumes
SEFLG_JPLEPH, if a JPL file is open;
SEFLG_SWIEPH, if a Swiss Ephemeris sepl* or semo* file is found;
SEFLG_MOSEPH otherwise.
Usually, this modification does not result in values different from those provided by former versions SE 2.00
and 2.01.
- Ayanamsha functions:
- New functions swe_get_ayanamsa_ex(), swe_get_ayanamsa_ex_ut() had to be introduced for similar
reasons
as swe_deltat_ex(). However, differences are very small, especially for recent dates.
For detailed explanations about this point, see general remarks further below.
- The old function swe_get_ayanamsa() was modified in a similar way as swe_deltat().
Usually, this modification does not result in different results.
- swetest:
- The parameter -at(pressure),(temperature) can also be used with calculation of risings and altitudes of
planets.
- Some rounding errors in output were corrected.
- Small correction with SEFLG_MOSEPH: frame bias was not correctly handled so far. Planetary positions
change by less than 0.01 arcsec, which is far less than the inaccuracy of the Moshier ephemeris.
Since Swiss Ephemeris 2.0, which can handle a wide variety of JPL ephemerides, old design deficiencies of
some functions, in particular swe_deltat(), have become incommoding under certain circumstances. Problems
may (although need not) have occurred when the user called swe_calc_ut() or swe_fixstar_ut() for the remote
past or future or compared planetary positions calculated with different ephemeris flags (SEFLG_SWIEPH,
SEFLG_JPLEPH, SEFLG_MOSEPH).
The problem is that the Delta T function actually needs to know what ephemeris is being used but does not have
an input parameter ephemeris_flag. Since Swiss Ephemeris 2.00, the function swe_deltat() has therefore made
a reasonable guess what kind of ephemeris was being used, depending on the last call of the function
swe_set_ephe_path(). However, such guesses are not necessarily always correct, and the functions may have
returned slightly inconsistent return values, depending on previous calculations made by the user. Although the
resulting error will be always smaller than the inherent inaccuracy in historical observations, the design of the
function swe_deltat() is obviously inappropriate.
A similar problem exists for the function swe_get_ayanamsa() although the possible inconsistencies are very
small.
Swiss Ephemeris 81
To remedy these problems, Swiss Ephemeris 2.02 introduces new functions for the calculation of Delta T and
ayanamsha:
swe_deltat_ex(),
swe_get_ayanamsa_ex_ut(), and
swe_get_ayanamsa_ex()
(The latter is independent of Delta T, however some ayanamshas like True Chitrapaksha depend on a precise
fixed star calculation, which requires a solare ephemeris for annual aberration. Therefore, an ephemeris flag is
required.)
Of course, the old functions swe_deltat(), swe_get_ayanamsa(), and swe_get_ayanamsa_ut() are still supported
and work without any problems as long as the user uses only one ephemeris flag and calls the function
swe_set_ephe_path() (as well swe_set_jpl_file() if using SEFLG_JPLEPH) before calculating Delta T and
planetary positions. Nevertheless, it is recommended to use the new functions swe_deltat_ex(),
swe_get_ayanamsa_ex(), and swe_get_ayanamsa_ex_ut() in future projects.
Also, please note that if you calculate planets using swe_calc_ut(), and stars using swe_fixststar_ut(), you
usually need not worry about Delta T and can avoid any such complications.
Note: Still unsolved is the problem with the lunar node with SEFLG_SWIEPH, discovered recently by Mihai (I
don't know his full name).
https://groups.yahoo.com/neo/groups/swisseph/conversations/topics/4829?reverse=1
This problem, which has existed "forever", is tricky and will take more time to solve.
- leap seconds of 2012 and 2015 added. (Note, users can add future leap seconds themselves in file
seleapsec.txt.
- New values for Delta T until 2015, updated estimations for coming years.
- Topocentric speed of planets was buggy after 2050 and before 1850, which was particularly obvious with slow
planets like Neptune or Pluto. (Thanks to Igor "TomCat" Germanenko for pointing out this bug.)
This was caused by the new (since 2.0) long-term algorithm for Sidereal Time, which interfered with the
function swe_calc().
- Topocentric positions of the *Moon* after 2050 and before 1850 had an error of a few arc seconds, due to the
same problem. With the Sun and the planets, the error was < 0.01 arcsec.
- Another small bug with topocentric positions was fixed that had existed since the first release of topocentric
calculations, resulting in very small changes in position for the whole time range of the ephemeris.
Errors due to this bug were < 0.3 arcsec for the Moon and < 0.001" for other objects.
- A small bug in the new long-term algorithm for Sidereal Time, which is used before 1850 and after 2050, was
fixed. The error due to this bug was < 0.1 degree for the whole ephemeris time range.
- Since Version 2.0, swe_set_tid_acc() did not work properly anymore, as a result of the new mechanism that
chooses tidal acceleration depending on ephemeris. However, this function is not really needed anymore.
Swiss Ephemeris 82
- Sidereal modes SE_SIDBIT_ECL_T0, SE_SIDBIT_SSY_PLANE did not work correctly anymore with
ayanamshas other than Fagan/Bradley.
- Function swe_lun_eclipse_when_loc(): From now on, an eclipse is considered locally visible if the whole lunar
disk is above the local geometric horizon. In former versions, the function has returned incorrect data if the
eclipse ended after the rising of the upper and the rising of the lower limb of the moon or if it began between the
setting of the lower and the setting of the upper limb of the moon.
- The same applies for the function swe_sol_eclipse_when_loc(), which had a similar problem.
- Some solar and lunar eclipses were missing after the year 3000 CE.
The following functions were affected:
swe_lun_eclipse_when(), swe_sol_eclipse_when_glob(), swe_sol_eclipse_when_loc()
There was no such problem with the remote past, only with the remote future.
1. New ephemeris files sepl*.se1 and semo*.se1 were created from DE431, covering the time range from 11
Aug. -12999 jul. (= 4 May -12999 greg.) to 7 Jan. 16800. For consistent ephemerides, users are advised to
use either old sepl* and semo* files (based on DE406) or new files (based on DE431) but not mix old and
new ones together. The internal handling of old and new files is not 100% identical (because of 3. below).
2. Because the time range of DE431 is a lot greater than that of DE406, better algorithms had to be
implemented for objects not contained in JPL ephemerides (mean lunar node and apogee). Also, sidereal time
and the equation of time had to be updated in order to give sensible results for the whole time range. The results
may slightly deviate from former versions of the Swiss Ephemeris, even for epochs inside the time range of the
old ephemeris.
3. Until version 1.80, the Swiss Ephemeris ignored the fact that the different JPL ephemerides have a different
inherent value of the tidal acceleration of the Moon. Calculations of Delta T must be adjusted to this value in
order to get best results for the remote past, especially for ancient observations of the Moon and eclipses.
Version 2.0 might result in slightly different values for Deltat T when compared with older versions of the Swiss
Ephemeris. The correct tidal acceleration is automatically set in the functions swe_set_ephe_path() and
swe_set_jpl_file(), depending on the available lunar ephemeris. It can also be set using the function
swe_set_tid_acc(). Users who work with different ephemerides at the same time, must be aware of this issue.
The default value is that of DE430.
Swiss Ephemeris 83
- Former versions of the Swiss Ephemeris were able to exactly reproduce ephemerides of the Astronomical
Almanac. The new version also supports apparent position as given by the JPL Horizons web interface
(http://ssd.jpl.nasa.gov/horizons.cgi). Please read the chapter 2.4.5.i in this file above.
- swe_sidtime() was improved so that it give sensible results for the whole time range of DE431.
- swe_time_equ() was improved so that it give sensible results for the whole time range of DE431.
- New functions swe_lmt_to_lat() and swe_lat_to_lmt() were added. They convert local mean time into local
apparent time and reverse.
- New function swe_lun_eclipse_when_loc() provides lunar eclipses that are observable at a given geographic
position.
- New ayanamsha SE_SID_TRUE_CITRA (= 27, “true chitrapaksha ayanamsha”). The star Spica is always
exactly at 180°.
- New ayanamsha SE_SIDM_TRUE_REVATI (= 28), with the star Revati (zeta Piscium) always exactly at 0°.
Bug fixes:
- swetest.c, line 556: geopos[10], array size was too small in former versions
- swetest.c, option -t[time] was buggy
- a minor bugfix in swe_heliacal_ut(): in some cases, the morning last of the Moon was not found if visibility was
bad and the geographic latitude was beyond 50N/S.
- Fixed stars:
- There was an error in the handling of the proper motion in RA. The values given in fixstars.cat, which are
taken from the Simbad database (Hipparcos), are referred to a great circle and include a factor of cos(d0).
- There is a new fixed stars file sefstars.txt. The parameters are now identical to those in the Simbad database,
which makes it much easier to add new star data to the file. If the program function swe_fixstars() does not find
sefstars.txt, it will try the the old fixed stars file fixstars.cat and will handle it correctly.
- Fixed stars data were updated, some errors corrected.
- Search string for a star ignores white spaces.
- Other changes:
- New function swe_utc_time_zone(), converts local time to UTC and UTC to local time. Note, the function has
no knowledge about time zones. The Swiss Ephemeris still does not provide the time zone for a given place and
time.
- swecl.c:swe_rise_trans() has two new minor features: SE_BIT_FIXED_DISC_SIZE and
SE_BIT_DISC_BOTTOM (thanks to Olivier Beltrami)
- minor bug fix in swemmoon.c, Moshier's lunar ephemeris (thanks to Bhanu Pinnamaneni)
- solar and lunar eclipse functions provide additional data:
attr[8] magnitude, attr[9] saros series number, attr[10] saros series member number
Other updates:
- Delta T updated (-2009).
Swiss Ephemeris versions prior to 1.71 are not able to do any calculations for minor planet number 134340.
New features:
- Ephemerides of "interpolated lunar apogee and perigee", as published by Dieter Koch in 2000 (swetest -pcg).
For more info, see the documentation swisseph.doc, chapter 2.2.4.
- House system according to Bogdan Krusinski (character ‘U’).
For more info, see the documentation swisseph.doc, chapter 6.1.13.
Bug fixes:
- Calculation of magnitude was wrong with asteroid numbers < 10000 (10-nov-05)
2) Waldemath Black Moon elements have been added in seorbel.txt (with thanks to Graham Dawson).
Swiss Ephemeris 87
3) Occultations of the planets and fixed stars by the moon
- swe_lun_occult_when_loc() calculates occultations for a given geographic location
- swe_lun_occult_when_glob() calculates occultations globally
4) Minor bug fixes in swe_fixstar() (Cartesian coordinates), solar eclipse functions, swe_rise_trans()
5) sweclips.c integrated into swetest.c. Swetest now also calculates eclipses, occultations, risings and settings.
Bug fixes:
1) error in geocentric planetary descending nodes fixed
2) swe_calc() now allows hypothetical planets beyond SE_FICT_OFFSET + 15
3) position of hypothetical planets slightly corrected (< 0.01 arc second)
A change of the ephemeris bits in parameter iflag of function swe_calc() usually forces an implicit
swe_close() operation. Inside a loop, e.g. for drawing a graphical epehemeris, this can slow down a
program. Before this release, two calls with iflag = 0 and iflag = SEFLG_SWIEPH where considered
different, though in fact the same ephemeris is used. Now these two calls are considered identical, and
swe_close() is not performed implicitly.
For calls with the pseudo-planet-number ipl = SE_ECL_NUT, whose result does not depend on the chosen
ephemeris, the ephemeris bits are ignored completely and swe_close() is never performed implicitly.
In former versions, calls of the Moshier ephemeris with speed and without speed flag have returned a very
small difference in position (0.01 arc second). The reason was that, for precise speed, swe_calc() had to do
an additional iteration in the light-time calculation. The two calls now return identical position data.
Attention: Use these files only with the new DLL. Previous versions cannot deal with more than one additional
asteroid besides the main asteroids. This error did not appear so far, because only 433 Eros was on our CD-
ROM.
2. Houses
The calculation of houses has been simplified as well. Moreover, the Vertex has been added.
The version 1.01 structure of swe_houses() is:
int swe_houses(
double tjd_ut, /* julian day number, UT */
double geolat, /* geographic latitude, in degrees */
double geolon, /* geographic longitude, in degrees */
char hsys, /* house method, one of the letters PKRCAV */
double *asc, /* address for ascendant */
double *mc, /* address for mc */
double *armc, /* address for armc */
double *vertex, /* address for vertex */
double *cusps); /* address for 13 doubles: 1 empty + 12 houses */
Appendix A
What is missing ?
There are some important limits in regard to what you can expect from an ephemeris module. We do not tell
you:
how to draw a chart
Index
Flag Body, Point
Default ephemeris flag Additional asteroids
Ephemeris flags Fictitious planets
Flag bits Find a name
Speed flag How to compute
Special body SE_ECL_NUT
Uranian planets
Errors Variable
Asteroids Armc
Avoiding Koch houses Ascmc[..]
Ephemeris path length Atpress
Errors and return values Attemp
Fatal error Ayan_t0
House cusps beyond the polar circle Cusps[..]
Koch houses limitations Eps
Overriding environment variables Gregflag
Speeds of the fixed stars Hsys
Iflag
Ipl
Method
Rsmi
Sid_mode
Star
Function Description
Swe_azalt Computes the horizontal coordinates (azimuth and altitude)
Swe_azalt_rev computes either ecliptical or equatorial coordinates from azimuth and
true altitude
swe_calc computes the positions of planets, asteroids, lunar nodes and apogees
swe_calc_ut Modified version of swe_calc
swe_close releases most resources used by the Swiss Ephemeris
swe_cotrans Coordinate transformation, from ecliptic to equator or vice-versa
swe_cotrans_sp Coordinate transformation of position and speed, from ecliptic to
equator or vice-versa
swe_date_conversion computes a Julian day from year, month, day, time and checks
whether a date is legal
Swiss Ephemeris 93
swe_degnorm normalization of any degree number to the range 0 ... 360
swe_deltat Computes the difference between Universal Time (UT, GMT) and
Ephemeris time
swe_fixstar computes fixed stars
swe_fixstar_ut Modified version of swe_fixstar
swe_get_ayanamsa Computes the ayanamsha
swe_get_ayanamsa_ut Modified version of swe_get_ayanamsa
swe_get_planet_name Finds a planetary or asteroid name by given number
swe_get_tid_acc Gets the tidal acceleration
swe_heliacal_ut compute heliacal risings etc. of a planet or star
swe_house_pos compute the house position of a given body for a given ARMC
swe_houses Calculates houses for a given date and geographic position
swe_houses_armc computes houses from ARMC (e.g. with the composite horoscope
which has no date)
swe_houses_ex the same as swe_houses(). Has a parameter, which can be used, if
sidereal house positions are wanted
swe_jdet_to_utc Converts JD (ET/TT) to UTC
swe_jdut1_to_utc Converts JD (UT1) to UTC
swe_julday Conversion from day, month, year, time to Julian date
swe_lat_to_lmt Converts Local Apparent Time (LAT) to Local Mean Time (LMT)
swe_lmt_to_lat Converts Local Mean Time (LMT) to Local Apparent Time (LAT)
swe_lun_eclipse_how Computes the attributes of a lunar eclipse at a given time
swe_lun_eclipse_when Finds the next lunar eclipse
swe_lun_eclipse_when_loc Finds the next lunar eclipse observable from a geographic location
swe_nod_aps Computes planetary nodes and apsides: perihelia, aphelia, second
focal points of the orbital ellipses
swe_nod_aps_ut Modified version of swe_nod_aps
swe_pheno Function computes phase, phase angle, elongation, apparent
diameter, apparent magnitude
swe_pheno_ut Modified version of swe_pheno
swe_refrac The true/apparent altitude convertion
swe_refrac_extended The true/apparent altitude convertion
swe_revjul Conversion from Julian date to day, month, year, time
swe_rise_trans Computes the times of rising, setting and meridian transits
swe_rise_trans_true_hor Computes the times of rising, setting and meridian transits
relative to true horizon
swe_set_ephe_path Set application’s own ephemeris path
swe_set_jpl_file Sets JPL ephemeris directory path
swe_set_sid_mode Specifies the sidereal modes
swe_set_tid_acc Sets tidal acceleration used in swe_deltat()
swe_set_topo Sets what geographic position is to be used before topocentric
planet positions for a certain birth place can be computed
swe_sidtime returns sidereal time on Julian day
swe_sidtime0 returns sidereal time on Julian day, obliquity and nutation
End of SWEPHPRG.DOC