Swephprg
Swephprg
interface
to the
Swiss
Ephemeris
Copyright Astrodienst AG 1997-2021.
This document describes the proprietary programmer's interface to the Swiss Ephemeris library.
The 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
Swiss Ephemeris 2.08
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.
~2~
Swiss Ephemeris 2.10
Contents
1. The programming steps to get a planet’s position.............................................................................1
2. The Ephemeris file related functions.................................................................................................. 1
2.1. swe_set_ephe_path()................................................................................................................... 1
2.2. swe_close().................................................................................................................................. 1
2.3. swe_set_jpl_file().......................................................................................................................... 1
2.4. swe_version()............................................................................................................................... 1
2.5. swe_get_library_path()................................................................................................................. 1
2.6. swe_get_current_file_data()......................................................................................................... 1
3. Planetary Positions: The functions swe_calc_ut(), swe_calc(), and swe_calc_pctr()............................1
3.1. The call parameters..................................................................................................................... 1
3.2. Bodies (int ipl).............................................................................................................................. 1
3.2.1. Additional asteroids............................................................................................................... 1
3.2.2. Planetary moons and body centers........................................................................................1
3.2.3. Fictitious planets.................................................................................................................... 1
3.2.4. Obliquity and nutation........................................................................................................... 1
3.3. Options chosen by flag bits (long iflag)........................................................................................1
3.3.1. The use of flag bits................................................................................................................ 1
3.3.2. Ephemeris flags..................................................................................................................... 1
3.3.3. Speed flag.............................................................................................................................. 1
3.3.4. Coordinate systems, degrees and radians.............................................................................1
3.3.5. Specialties (going beyond common interest).........................................................................1
3.4. Position and Speed (double xx[6])............................................................................................... 1
3.5. Error handling and return values................................................................................................. 1
4. The function swe_get_planet_name()................................................................................................. 1
5. Fixed stars functions.......................................................................................................................... 1
5.1. Different functions for calculating fixed star positions.................................................................1
5.2. swe_fixstar2_ut(), swe_fixstar2(), swe_fixstar_ut(), swe_fixstar().................................................1
5.3. swe_fixstar2_mag(), swe_fixstar_mag().......................................................................................1
6. Apsides and nodes, Kepler elements and orbital periods...................................................................1
6.1. swe_nod_aps_ut() and swe_nod_aps().......................................................................................... 1
6.2. swe_get_orbital_elements() (Kepler elements and orbital data)...................................................1
6.3. swe_orbit_max_min_true_distance()............................................................................................1
7. Eclipses, risings, settings, meridian transits, planetary phenomena..................................................1
7.1. Example of a typical eclipse calculation.......................................................................................1
7.2. swe_sol_eclipse_when_loc()......................................................................................................... 1
7.3. swe_sol_eclipse_when_glob()....................................................................................................... 1
7.4. swe_sol_eclipse_how ()................................................................................................................ 1
7.5. swe_sol_eclipse_where ()............................................................................................................. 1
7.6. swe_lun_occult_when_loc().......................................................................................................... 1
7.7. swe_lun_occult_when_glob()........................................................................................................ 1
7.8. swe_lun_occult_where ().............................................................................................................. 1
7.9. swe_lun_eclipse_when_loc ()........................................................................................................ 1
7.10. swe_lun_eclipse_when ()........................................................................................................... 1
7.11. swe_lun_eclipse_how ()............................................................................................................. 1
7.12. swe_rise_trans() and swe_rise_trans_true_hor() (risings, settings, meridian transits)...............1
7.12.1. Sunrise in Astronomy and in Hindu Astrology........................................................................1
7.13. swe_pheno_ut() and swe_pheno(), planetary phenomena........................................................1
7.14. swe_azalt(), horizontal coordinates, azimuth, altitude..............................................................1
7.15. swe_azalt_rev()......................................................................................................................... 1
7.16. swe_refrac(), swe_refrac_extended(), refraction.......................................................................1
7.17. Heliacal risings etc.: swe_heliacal_ut()......................................................................................1
7.18. Magnitude limit for visibility: swe_vis_limit_mag()....................................................................1
swephprg.doc ~ ~ i c
Swiss Ephemeris 2.10
swephprg.doc ~ ~ i c
Swiss Ephemeris 2.10
17.3.2. Julian day number from year, month, day, hour, with check whether date is legal................1
17.3.3. Julian day number from year, month, day, hour.....................................................................1
17.3.4. Year, month, day, hour from Julian day number....................................................................1
17.3.5. Local time to UTC and UTC to local time................................................................................1
17.3.6. UTC to jd (TT and UT1)........................................................................................................... 1
17.3.7. TT (ET1) to UTC...................................................................................................................... 1
17.3.8. UTC to TT (ET1)...................................................................................................................... 1
17.3.9. Get tidal acceleration used in swe_deltat()............................................................................1
17.3.10. Set tidal acceleration to be used in swe_deltat()................................................................1
17.3.11. Equation of time................................................................................................................. 1
17.4. Initialization, setup, and closing functions................................................................................1
17.4.1. Set directory path of ephemeris files.....................................................................................1
17.5. House calculation...................................................................................................................... 1
17.5.1. Sidereal time......................................................................................................................... 1
17.5.2. Name of a house method....................................................................................................... 1
17.5.3. House cusps, ascendant and MC............................................................................................ 1
17.5.4. Extended house function; to compute tropical or sidereal positions......................................1
17.5.5. Get the house position of a celestial point.............................................................................1
17.5.6. Get the Gauquelin sector position for a body.........................................................................1
17.6. Auxiliary functions.................................................................................................................... 1
17.6.1. swe_cotrans(): coordinate transformation, from ecliptic to equator or vice-versa.................1
17.6.2. swe_cotrans_sp(): coordinate transformation of position and speed, from ecliptic to equator
or vice-versa...................................................................................................................................... 1
17.6.3. swe_get_planet_name(): get the name of a planet................................................................1
17.6.4. swe_degnorm(): normalize degrees to the range 0 ... 360.....................................................1
17.6.5. swe_radnorm(): normalize radians to the range 0 ... 2 PI.......................................................1
17.6.6. swe_split_deg(): split degrees to sign/nakshatra, degrees, minutes, seconds of arc..............1
17.7. Other functions that may be useful.......................................................................................... 1
17.7.1. Normalize argument into interval [0..DEG360]......................................................................1
17.7.2. Distance in centisecs p1 - p2 normalized to [0..360].............................................................1
17.7.3. Distance in degrees............................................................................................................... 1
17.7.4. Distance in centisecs p1 - p2 normalized to [-180..180]........................................................1
17.7.5. Distance in degrees............................................................................................................... 1
17.7.6. Round second, but at 29.5959 always down..........................................................................1
17.7.7. Double to long with rounding, no overflow check..................................................................1
17.7.8. Day of week........................................................................................................................... 1
17.7.9. Centiseconds -> time string................................................................................................... 1
17.7.10. Centiseconds -> longitude or latitude string.......................................................................1
17.7.11. Centiseconds -> degrees string..........................................................................................1
18. The SWISSEPH DLLs........................................................................................................................ 1
19. Using the DLL with Visual Basic 5.0................................................................................................. 1
20. Using the DLL with Borland Delphi and C++ Builder.......................................................................1
20.1. Delphi 2.0 and higher (32-bit)................................................................................................... 1
20.2. Borland C++ Builder................................................................................................................. 1
21. Using the Swiss Ephemeris with Perl............................................................................................... 1
22. The C sample program.................................................................................................................... 1
23. The source code distribution........................................................................................................... 1
24. The PLACALC compatibility API (chapter removed).........................................................................1
25. Documentation files........................................................................................................................ 1
26. Swisseph with different hardware and compilers............................................................................1
27. Debugging and Tracing Swisseph................................................................................................... 1
27.1. If you are using the DLL............................................................................................................ 1
27.2. If you are using the source code............................................................................................... 1
28. Updates........................................................................................................................................... 1
28.1. Updates of documention........................................................................................................... 1
28.2. Release History......................................................................................................................... 1
swephprg.doc ~ ~ i c
Swiss Ephemeris 2.10
swephprg.doc ~ ~ i c
Swiss Ephemeris 2.10
swephprg.doc ~ ~ i c
Swiss Ephemeris 2.10 Index
To compute a celestial body or point with SWISSEPH, you have to do the following steps (use swetest.c
as an example). The details of the functions will be explained in the following chapters.
1. Set the directory path of the ephemeris files, e.g.:
swe_set_ephe_path(”C:\\SWEPH\\EPHE”);
2. From the birth date, compute the Julian day number:
jul_day_UT = swe_julday(year, month, day, hour, gregflag);
3. Compute a planet or other bodies:
ret_flag = swe_calc_ut(jul_day_UT, planet_no, flag, lon_lat_rad, err_msg);
or a fixed star:
ret_flag = swe_fixstar_ut(star_nam, jul_day_UT, flag, lon_lat_rad, err_msg);
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:
first, if necessary, convert universal time (UT) to ephemeris time (ET):
jul_day_ET = jul_day_UT + swe_deltat(jul_day_UT);
then compute a planet or other bodies:
ret_flag = swe_calc(jul_day_ET, planet_no, flag, lon_lat_rad, err_msg);
or a fixed star:
ret_flag = swe_fixstar(star_nam, jul_day_ET, flag, lon_lat_rad, err_msg);
4. At the end of your computations close all files and free memory calling swe_close();
Here is a miniature sample program, it is in the source distribution as swemini.c:
#include "swephexp.h" /* this includes "sweodef.h" */
int main()
{
char *sp, sdate[AS_MAXCH], snam[40], serr[AS_MAXCH];
int jday = 1, jmon = 1, jyear = 2000;
double jut = 0.0;
double tjd_ut, te, x2[6];
long iflag, iflgret;
int p;
swe_set_ephe_path(NULL);
iflag = SEFLG_SPEED;
while (TRUE) {
printf("\nDate (d.m.y) ?");
gets(sdate);
/* stop if a period . is entered */
if (*sdate == '.')
return OK;
if (sscanf (sdate, "%d%*c%d%*c%d", &jday, &jmon, &jyear) < 1) exit(1);
/*
* we have day, month and year and convert to Julian day number
*/
tjd_ut = swe_julday(jyear, jmon, jday, jut, SE_GREG_CAL);
/*
* compute Ephemeris time from Universal time by adding delta_t
* not required for Swisseph versions smaller than 1.60
*/
/* te = tjd_ut + swe_deltat(tjd_ut); */
swephprg.doc ~1~ i c
Swiss Ephemeris 2.10 Index
2.1. swe_set_ephe_path()
This is the first function that should be called before any other function of the Swiss Ephemeris. Even if
you don’t want to set an ephemeris path and use the Moshier ephemeris, it is nevertheless
recommended to call swe_set_ephe_path(NULL), because this function makes important initializations.
If you don’t do that, the Swiss Ephemeris may work, but the results may be not 100% consistent.
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.
swephprg.doc ~2~ i c
Swiss Ephemeris 2.10 Index
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 for all different applications. A developer should accept this override
feature and allow the sophisticated users to exploit it.
2.2. swe_close()
2.3. swe_set_jpl_file()
2.4. swe_version()
2.5. swe_get_library_path()
swephprg.doc ~3~ i c
Swiss Ephemeris 2.10 Index
2.6. swe_get_current_file_data()
This is function can be used to find out the start and end date of an *se1 ephemeris file after a call of
swe_calc().
The function returns data from internal file structures sweph.fidat used in the last call to swe_calc() or
swe_fixstar(). Data returned are (currently) 0 with JPL files and fixed star files. Thus, the function is only
useful for ephemerides of planets or asteroids that are based on *.se1 files.
// ifno = 0 planet file sepl_xxx, used for Sun .. Pluto, or jpl file
// ifno = 1 moon file semo_xxx
// ifno = 2 main asteroid file seas_xxx if such an object was computed
// ifno = 3 other asteroid or planetary moon file, if such object was computed
// ifno = 4 star file
// Return value: full file pathname, or NULL if no data
// tfstart = start date of file,
// tfend = end data of fila,
// denum = jpl ephemeris number 406 or 431 from which file was derived
// all three return values are zero for a jpl file or a star file.
const char *CALL_CONV swe_get_current_file_data(
int ifno,
double *tfstart,
double *tfend,
int *denum);
Before calling one of these functions or any other Swiss Ephemeris function, it is strongly
recommended to call the function swe_set_ephe_path(). Even if you don’t want to set an ephemeris
path and use the Moshier ephemeris, it is nevertheless recommended to call
swe_set_ephe_path(NULL), because this function makes important initializations. If you don’t do
that, the Swiss Ephemeris may work but the results may be not 100% consistent.
swe_calc_ut() was introduced with Swisseph version 1.60 and makes planetary calculations a bit
simpler. For the steps required, see the chapter The programming steps to get a planet’s position.
swe_calc_ut() and swe_calc() work exactly the same way except that swe_calc() requires
Ephemeris Time (more accurate: Terrestrial Time (TT)) as a parameter whereas swe_calc_ut()
expects Universal Time (UT). For common astrological calculations, you will only need swe_calc_ut()
and will not have to think any more about the conversion between Universal Time and Ephemeris Time.
swe_calc_ut() and swe_calc() compute positions of planets, asteroids, lunar nodes and apogees.
They are defined as follows:
int32 swe_calc_ut(
double tjd_ut,
int32 ipl,
int32 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
swephprg.doc ~4~ i c
Swiss Ephemeris 2.10 Index
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
int32 swe_calc(
double tjd_et,
int32 ipl,
int32 iflag,
double *xx,
char *serr);
same but
tjd_et = Julian day, Ephemeris time, where tjd_et = tjd_ut + swe_deltat(tjd_ut)
A detailed description of these variables will be given in the following sections.
swe_calc_pctr() calculates planetocentric positions of planets, i. e. positions as observed from some
different planet, e.g. Jupiter-centric ephemerides. The function can actually calculate any object as
observed from any other object, e.g. also the position of some asteroid as observed from another
asteroid or from a planetary moon. The function declaration is as follows:
int32 swe_calc_pctr(
double tjd, // input time in TT
int32 ipl, // target object
int32 iplctr, // center object
int32 iflag,
double *xxret,
char *serr);
To tell swe_calc() which celestial body or factor should be computed, a fixed set of body numbers is
used. The body numbers are defined in swephexp.h:
/* planet numbers for the ipl parameter in swe_calc() */
#define SE_ECL_NUT -1
#define SE_SUN 0
#define SE_MOON 1
#define SE_MERCURY 2
#define SE_VENUS 3
#define SE_MARS 4
#define SE_JUPITER 5
#define SE_SATURN 6
#define SE_URANUS 7
#define SE_NEPTUNE 8
#define SE_PLUTO 9
#define SE_MEAN_NODE 10
#define SE_TRUE_NODE 11
#define SE_MEAN_APOG 12
#define SE_OSCU_APOG 13
#define SE_EARTH 14
#define SE_CHIRON 15
#define SE_PHOLUS 16
#define SE_CERES 17
#define SE_PALLAS 18
#define SE_JUNO 19
#define SE_VESTA 20
swephprg.doc ~5~ i c
Swiss Ephemeris 2.10 Index
#define SE_INTP_APOG 21
#define SE_INTP_PERG 22
#define SE_NPLANETS 23
#define SE_FICT_OFFSET 40 // offset for fictitious objects
#define SE_NFICT_ELEM 15
#define SE_PLMOON_OFFSET 9000 // offset for planetary moons
#define SE_AST_OFFSET 10000 // offset for asteroids
/* Hamburger or Uranian "planets" */
#define SE_CUPIDO 40
#define SE_HADES 41
#define SE_ZEUS 42
#define SE_KRONOS 43
#define SE_APOLLON 44
#define SE_ADMETOS 45
#define SE_VULKANUS 46
#define SE_POSEIDON 47
/* other fictitious bodies */
#define SE_ISIS 48
#define SE_NIBIRU 49
#define SE_HARRINGTON 50
#define SE_NEPTUNE_LEVERRIER 51
#define SE_NEPTUNE_ADAMS 52
#define SE_PLUTO_LOWELL 53
#define SE_PLUTO_PICKERING 54
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 (= 10433)
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'
swephprg.doc ~6~ i c
Swiss Ephemeris 2.10 Index
1221 Amor
1387 Kama
1388 Aphrodite
1862 Apollo different from Witte's Apollon
3553 Damocles highly eccentric orbit between 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 - between Saturn and Pluto
There are two ephemeris files for each asteroid (except the main asteroids), a long one and a short
one:
se09999.se1 long-term ephemeris of asteroid number 9999, 3000 BCE – 3000 CE
se09999s.se1 short ephemeris of asteroid number 9999, 1500 – 2100 CE
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.
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 CE and after 4650 CE 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 BCE, and for many other asteroids, as e.g. 1862 Apollo. He
becomes chaotic before the year 1870 CE, when he approaches Venus very closely. Swiss Ephemeris
does not provide positions of Apollo for earlier centuries !
NOTE on asteroid names:
Asteroid names are listed in the file seasnam.txt. This file is in the ephemeris directory.
Ephemerides of planetary moons and centers of body (COB) were introduced with Swiss Ephemeris
version 2.10.
Their Swiss Ephemeris body numbers are between SE_PLMOON_OFFSET (= 9000) and SE_AST_OFFSET
(= 10000) and are constructed as follows:
ipl = SE_PLMOON_OFFSET + planet_number * 100 + moon number in JPL Horizons;
e.g., Jupiter moon Io: ipl = SE_PLMOON_OFFSET + SE_JUPITER (= 5) * 100 + 1 (= 9501).
Centers of body (COB) are calculated the same way, i.e. like a planetary moon but with the “moon
number” 99;
e.g. Jupiter center of body: ipl = SE_PLMOON_OFFSET + SE_JUPITER * 100 + 99 (= 9599)
Moons of Mars: 9401 – 9402
Moons of Jupiter: 9501 – 95xx; Center of body: 9599
Moons of Saturn: 9601 – 96xx; Center of body: 9699
Moons of Uranus: 9701 – 97xx; Center of body: 9799
Moons of Neptune: 9801 – 98xx; Center of body: 9899
Moons of Pluto: 9901 – 99xx; Center of body: 9999
A full list of existing planetary moons is found here:
https://en.wikipedia.org/wiki/List_of_natural_satellites .
The ephemeris files of the planetary moons and COB are in the subdirectory sat. Like the
subdirectories of asteroids, the directory sat must be created in the path which is defined using the
function swe_set_ephe_path().
The ephemeris files can be downloaded from here:
https://www.astro.com/ftp/swisseph/ephe/sat/.
The list of objects available in the Swiss Ephemeris is:
swephprg.doc ~7~ i c
Swiss Ephemeris 2.10 Index
9401 Phobos/Mars
9402 Deimos/Mars
9501 Io/Jupiter
9502 Europa/Jupiter
9503 Ganymede/Jupiter
9504 Callisto/Jupiter
9599 Jupiter/COB
9601 Mimas/Saturn
9602 Enceladus/Saturn
9603 Tethys/Saturn
9604 Dione/Saturn
9605 Rhea/Saturn
9606 Titan/Saturn
9607 Hyperion/Saturn
9608 Iapetus/Saturn
9699 Saturn/COB
9701 Ariel/Uranus
9702 Umbriel/Uranus
9703 Titania/Uranus
9704 Oberon/Uranus
9705 Miranda/Uranus
9799 Uranus/COB
9801 Triton/Neptune
9802 Triton/Nereid
9808 Proteus/Neptune
9899 Neptune/COB
9901 Charon/Pluto
9902 Nix/Pluto
9903 Hydra/Pluto
9904 Kerberos/Pluto
9905 Styx/Pluto
9999 Pluto/COB
The maximum differences between barycenter and center of body (COB) are:
Mars (0.2 m, irrelevant to us)
Jupiter 0.075 arcsec (jd 2468233.5)
Saturn 0.053 arcsec (jd 2463601.5)
Uranus 0.0032 arcsec (jd 2446650.5)
Neptune 0.0036 arcsec (jd 2449131.5)
Pluto 0.088 arcsec (jd 2437372.5)
(from one-day-step calculations over 150 years)
If you prefer using COB rather than barycenters, you should understand that:
- The performance is not as good for COB as for barycenters. With transit calculations you could run
into troubles.
- The ephemerides are limited to the time range 1900 to 2047.
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
swephprg.doc ~8~ i c
Swiss Ephemeris 2.10 Index
as
ipl = SE_FICT_OFFSET_1 + number_of_elements_set;
e.g. for Kronos: ipl = 39 + 4 = 43.
The file seorbel.txt has the following structure:
# Orbital elements of fictitious planets
# 27 Jan. 2000
#
# This file is part of the Swiss Ephemeris, from Version 1.60 on.
#
# Warning! These planets do not exist!
#
# The user can add his or her own elements.
# 960 is the maximum number of fictitious planets.
#
# The elements order is as follows:
# 1. epoch of elements (Julian day)
# 2. equinox (Julian day or "J1900" or "B1950" or "J2000" or “JDATE”)
# 3. mean anomaly at epoch
# 4. semi-axis
# 5. eccentricity
# 6. argument of perihelion (ang. distance of perihelion from node)
# 7. ascending node
# 8. inclination
# 9. name of planet
#
# use '#' for comments
# to compute a body with swe_calc(), use planet number
# ipl = SE_FICT_OFFSET_1 + number_of_elements_set,
# e.g. number of Kronos is ipl = 39 + 4 = 43
#
# Witte/Sieggruen planets, refined by James Neely
J1900, J1900, 163.7409, 40.99837, 0.00460, 171.4333, 129.8325, 1.0833, Cupido # 1
J1900, J1900, 27.6496, 50.66744, 0.00245, 148.1796, 161.3339, 1.0500, Hades # 2
J1900, J1900, 165.1232, 59.21436, 0.00120, 299.0440, 0.0000, 0.0000, Zeus # 3
J1900, J1900, 169.0193, 64.81960, 0.00305, 208.8801, 0.0000, 0.0000, Kronos # 4
J1900, J1900, 138.0533, 70.29949, 0.00000, 0.0000, 0.0000, 0.0000, Apollon # 5
J1900, J1900, 351.3350, 73.62765, 0.00000, 0.0000, 0.0000, 0.0000, Admetos # 6
J1900, J1900, 55.8983, 77.25568, 0.00000, 0.0000, 0.0000, 0.0000, Vulcanus # 7
J1900, J1900, 165.5163, 83.66907, 0.00000, 0.0000, 0.0000, 0.0000, Poseidon # 8
#
# Isis-Transpluto; elements from "Die Sterne" 3/1952, p. 70ff.
# Strubell does not give an equinox. 1945 is taken in order to
# reproduce the as best as ASTRON ephemeris. (This is a strange
# choice, though.)
# The epoch according to Strubell is 1772.76.
# 1772 is a leap year!
# The fraction is counted from 1 Jan. 1772
2368547.66, 2431456.5, 0.0, 77.775, 0.3, 0.7, 0, 0, Isis-Transpluto # 9
# Nibiru, elements from Christian Woeltge, Hannover
1856113.380954, 1856113.380954, 0.0, 234.8921, 0.981092, 103.966, -44.567, 158.708,
Nibiru # 10
# Harrington, elements from Astronomical Journal 96(4), Oct. 1988
swephprg.doc ~9~ i c
Swiss Ephemeris 2.10 Index
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.
iflgret = swe_calc(tjd_et, SE_ECL_NUT, 0, x, serr);
x is an array of 6 doubles as usual. They will be filled as follows:
x[0] = true obliquity of the Ecliptic (includes nutation)
x[1] = mean obliquity of the Ecliptic
x[2] = nutation in longitude
x[3] = nutation in obliquity
x[4] = x[5] = 0
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.
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.
swephprg.doc ~ 10 ~ i c
Swiss Ephemeris 2.10 Index
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.
swephprg.doc ~ 11 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 12 ~ i c
Swiss Ephemeris 2.10 Index
function.
5.8. 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.
5.9. JPL Horizons positions
For apparent positions of the planets, JPL Horizons follows a different approach from Astronomical
Almanac and from the IERS Conventions 2003 and 2010. It uses the old precession models IAU 1976
(Lieske) and nutation IAU 1980 (Wahr) and corrects the resulting positions by adding daily-measured
celestial pole offsets (delta_psi and delta_epsilon) to nutation. (IERS Conventions 1996, p. 22) While this
approach is more accurate in some respect, it is not referred to the same reference frame. For more
details see the general documentation of the Swiss Ephemeris in swisseph.doc or
http://www.astro.com/swisseph/swisseph.htm, ch. 2.1.2.2.
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.
swe_calc() returns the coordinates of position and velocity in the following order:
Ecliptic position Equatorial position (SEFLG_EQUATORIAL)
Longitude right ascension
Latitude declination
Distance in AU distance in AU
Speed in longitude (deg/day) speed in right ascension (deg/day)
Speed in latitude (deg/day) speed in declination (deg/day)
Speed in distance (AU/day) speed in distance (AU/day)
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.
swephprg.doc ~ 13 ~ i c
Swiss Ephemeris 2.10 Index
This function allows to find a planetary or asteroid name, when the planet number is given. The
function definition is:
char* swe_get_planet_name(
int32 ipl,
char *spname);
If an asteroid name is wanted, the function does the following:
The name is first looked for in the asteroid file.
Because many asteroids, especially the ones with high catalogue numbers, have no names yet (or
have only a preliminary designation like 1968 HB), and because the Minor Planet Center of the IAU
add new names quite often, it happens that there is no name in the asteroid file although the
asteroid has already been given a name. For this, we have the file seasnam.txt, a file that contains a
list of all named asteroid and is usually more up to date. If swe_calc() finds a preliminary
designation, it looks for a name in this file.
The file seasnam.txt can be updated by the user. To do this, download the names list from the Minor
Planet Center http://cfa-www.harvard.edu/iau/lists/MPNames.html, rename it as seasnam.txt and move
it into your ephemeris directory.
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.
Example:
(3192) A'Hearn
(3654) AAS
swephprg.doc ~ 14 ~ i c
Swiss Ephemeris 2.10 Index
(8721) AMOS
(3568) ASCII
(2848) ASP
(677) Aaltje
...
The function swe_fixstar_ut() does exactly the same as swe_fixstar() except that it expects
Universal Time rather than Terrestrial Time (Ephemeris Time) as an input value. (cf. swe_calc_ut()
and swe_calc()) For more details, see under 4.2 swe_fixstar().
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_fixstar() 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)
int32 swe_fixstar_ut(
char* star,
double tjd_ut,
int32 iflag,
double* xx,
char* serr);
int32 swe_fixstar(
char *star,
double tjd_et,
int32 iflag,
double* xx,
char* serr);
int32 swe_fixstar2_ut(
char* star,
double tjd_ut,
int32 iflag,
double* xx,
char* serr);
int32 swe_fixstar2(
char *star,
double tjd_et,
int32 iflag,
double* xx,
char* serr);
where:
swephprg.doc ~ 15 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 16 ~ i c
Swiss Ephemeris 2.10 Index
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 positions …
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:
# 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
# Great Attractor, near Galaxy Cluster ACO 3627, at gal. coordinates
# 325.3, -7.2, 4844 km s-1 according to Kraan-Korteweg et al. 1996,
# Woudt 1998
Great Attractor,GA,2000,16,15,02.836,-60,53,22.54,0.000,0.00,0.0,0.0000159,999.99, 0,
0
# Virgo Cluster, according to NED (Nasa Extragalactic Database)
Virgo Cluster,VC,2000,12,26,32.1,12,43,24,0.000, 0.00, 0.0,0.0000,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
# Galactic Pole acc. to Liu/Zhu/Zhang, „Reconsidering the galactic coordinate system“,
# Astronomy & Astrophysics No. AA2010, Oct. 2010, p. 8.
# It is defined relative to a plane that contains the galactic center and the Sun and
# approximates the galactic plane.
Gal.Pole,GPol,ICRS,12,51,36.7151981,27,06,11.193172,0.0,0.0,0.0,0.0,0.0,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
# Old Galactic Pole 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
# Pole of true galactic plane, calculated by DK
Gal.Plane Pole,GPPlan,ICRS,12,51,5.731104,27,10,39.554849,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.
swephprg.doc ~ 17 ~ i c
Swiss Ephemeris 2.10 Index
Attention:
With older versions of the Swiss Ephemeris, swe_fixstar() does not compute speeds of the fixed
stars. 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.
int32 swe_fixstar_mag(
char *star,
double* mag,
char* serr);
int32 swe_fixstar2_mag(
char *star,
double* mag,
char* serr);
Function calculates the magnitude of a fixed star. The function returns OK or ERR. The magnitude value
is returned in the parameter mag.
For the definition and use of the parameter star see function swe_fixstar(). The parameter serr and
is, as usually, an error string pointer.
The new function swe_fixstar2_mag() (since SE 2.07) is more efficient if great numbers of fixed stars
are calculated.
Strictly speaking, the magnitudes returned by this function are valid for the year 2000 only. Variations
in brightness due to the star’s variability or due to the increase or decrease of the star’s distance
cannot be taken into account. With stars of constant absolute magnitude, the change in brightness can
be ignored for the historical period. E.g. the current magnitude of Sirius is -1.46. In 3000 BCE it was -
1.44.
The functions swe_nod_aps_ut() and swe_nod_aps() compute planetary nodes and apsides (perihelia,
aphelia, second focal points of the orbital ellipses). Both functions do exactly the same except that they
expect a different time parameter (cf. swe_calc_ut() and swe_calc()).
The definitions are:
int32 swe_nod_aps_ut(
double tjd_ut,// Julian day number in UT
int32 ipl, // planet number
int32 iflag, // flag bits
int32 method, // method, see explanations below
double *xnasc,// array of 6 double for ascending node
double *xndsc,// array of 6 double for descending node
double *xperi,// array of 6 double for perihelion
double *xaphe, // array of 6 double for aphelion
char *serr); // character string to contain error messages, 256 chars
int32 swe_nod_aps(
double tjd_et,// Julian day number in TT
int32 ipl,
swephprg.doc ~ 18 ~ i c
Swiss Ephemeris 2.10 Index
int32 iflag,
int32 method,
double *xnasc,
double *xndsc,
double *xperi,
double *xaphe,
char *serr);
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.
#define SE_NODBIT_FOPOINT 256
The second focal point of the orbital ellipse is computed and returned in the array of the aphelion. This
bit can be combined with any other bit.
This function calculates osculating elements (Kepler elements) and orbital periods for a planet, the
Earth-Moon barycenter, or an asteroid. The elements are calculated relative to the mean ecliptic J2000.
The elements define the orbital ellipse under the premise that it is a two-body system and there are no
perturbations from other celestial bodies. The elements are particularly bad for the Moon, which is
strongly perturbed by the Sun. It is not recommended to calculate ephemerides using Kepler elements.
Important: This function should not be used for ephemerides of the perihelion or aphelion of a planet.
Note that when the position of a perihelion is calculated using swe_get_orbital_elements(), this position
is not measured on the ecliptic, but on the orbit of the planet itself, thus it is not an ecliptic position.
Also note that the positions of the nodes are always calculated relative to the mean equinox 2000 and
never precessed to the ecliptic or equator of date. For ecliptic positions of a perihelion or aphelion or a
node, you should use the function swe_nod_aps() or swe_nod_aps_ut().
int32 swe_get_orbital_elements(
double tjd_et,
int32 ipl,
int32 iflag,
double *dret,
char *serr);
/* Function calculates osculating orbital elements (Kepler elements) of a planet
* or asteroid or the EMB. The function returns error,
* if called for the Sun, the lunar nodes, or the apsides.
* Input parameters:
* tjd_et Julian day number, in TT (ET)
* ipl object number
* iflag can contain
* - ephemeris flag: SEFLG_JPLEPH, SEFLG_SWIEPH, SEFLG_MOSEPH
* - center:
* Sun: SEFLG_HELCTR (assumed as default) or
* SS Barycentre: SEFLG_BARYCTR (rel. to solar system barycentre)
swephprg.doc ~ 19 ~ i c
Swiss Ephemeris 2.10 Index
6.3. swe_orbit_max_min_true_distance()
This function 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..
int32 swe_orbit_max_min_true_distance(
double tjd_et,
int32 ipl,
int32 iflag,
double *dmax,
double *dmin,
double *dtrue,
char *serr);
/* Input:
* tjd_et epoch
* ipl planet number
* iflag ephemeris flag and optional heliocentric flag (SEFLG_HELCTR)
*
* output:
* dmax maximum distance (pointer to double)
* dmin minimum distance (pointer to double)
* dtrue true distance (pointer to double)
swephprg.doc ~ 20 ~ i c
Swiss Ephemeris 2.10 Index
There are the following functions for eclipse and occultation calculations.
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.
Occultations of planets by the moon:
These functions can also be used for solar eclipses. But they are slightly less efficient.
swe_lun_occult_when_loc(tjd...) finds the next occultation for a body and a given geographic
position;
swe_lun_occult_when_glob(tjd...) finds the next occultation of a given body globally;
swe_lun_occult_where() computes the geographic location of an occultation for a given tjd.
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.
Risings, settings, and meridian transits of planets and stars:
swe_rise_trans();
swe_rise_trans_true_hor() returns rising and setting times for a local horizon with altitude != 0.
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.
Find the next total eclipse, calculate the geographical position where it is maximal and the four
contacts for that position (for a detailed explanation of all eclipse functions see the next chapters):
double tret[10], attr[20], geopos[10];
char serr[255];
int32 whicheph = 0; /* default ephemeris */
double tjd_start = 2451545; /* Julian day number for 1 Jan 2000 */
int32 ifltype = SE_ECL_TOTAL ¦ SE_ECL_CENTRAL ¦ SE_ECL_NONCENTRAL;
/* find next eclipse anywhere on Earth */
eclflag = swe_sol_eclipse_when_glob(tjd_start, whicheph, ifltype, tret, 0, serr);
if (eclflag == ERR)
return ERR;
/* the time of the greatest eclipse has been returned in tret[0];
* now we can find geographical position of the eclipse maximum */
tjd_start = tret[0];
eclflag = swe_sol_eclipse_where(tjd_start, whicheph, geopos, attr, serr);
if (eclflag == ERR)
return ERR;
/* the geographical position of the eclipse maximum is in geopos[0] and geopos[1];
* now we can calculate the four contacts for this place. The start time is chosen
* a day before the maximum eclipse: */
tjd_start = tret[0] - 1;
eclflag = swe_sol_eclipse_when_loc(tjd_start, whicheph, geopos, tret, attr, 0, serr);
swephprg.doc ~ 21 ~ i c
Swiss Ephemeris 2.10 Index
if (eclflag == ERR)
return ERR;
/* now tret[] contains the following values:
* tret[0] = time of greatest eclipse (Julian day number)
* tret[1] = first contact
* tret[2] = second contact
* tret[3] = third contact
* tret[4] = fourth contact */
7.2. 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 */
The function returns:
/* retflag -1 (ERR) on error (e.g. if swe_calc() for sun or moon fails)
SE_ECL_TOTAL or SE_ECL_ANNULAR or SE_ECL_PARTIAL
SE_ECL_VISIBLE,
SE_ECL_MAX_VISIBLE,
SE_ECL_1ST_VISIBLE, SE_ECL_2ND_VISIBLE
SE_ECL_3ST_VISIBLE, SE_ECL_4ND_VISIBLE
tret[0] time of maximum eclipse
tret[1] time of first contact
tret[2] time of second contact
tret[3] time of third contact
tret[4] time of forth contact
tret[5] time of sunrise between first and forth contact
tret[6] time of sunset between first and forth contact
swephprg.doc ~ 22 ~ i c
Swiss Ephemeris 2.10 Index
7.3. swe_sol_eclipse_when_glob()
swephprg.doc ~ 23 ~ i c
Swiss Ephemeris 2.10 Index
tret[9] time when annular-total eclipse becomes annular again, not implemented so far
declare as tret[10] at least!
*/
7.4. 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 */
/* retflag -1 (ERR) on error (e.g. if swe_calc() for sun or moon fails)
SE_ECL_TOTAL or SE_ECL_ANNULAR or SE_ECL_PARTIAL
0, if no eclipse is visible at geogr. position.
attr[0] fraction of solar diameter covered by moon;
with total/annular eclipses, it results in magnitude acc. to IMCCE.
attr[1] ratio of lunar diameter to solar one
attr[2] fraction of solar disc covered by moon (obscuration)
attr[3] diameter of core shadow in km
attr[4] azimuth of sun at tjd
attr[5] true altitude of sun above horizon at tjd
attr[6] apparent altitude of sun above horizon at tjd
attr[7] elongation of moon in degrees
attr[8] magnitude acc. to NASA;
= attr[0] for partial and attr[1] for annular and total eclipses
attr[9] saros series number (if available; otherwise -99999999)
attr[10] saros series member number (if available; otherwise -99999999) */
7.5. 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.
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:
swephprg.doc ~ 24 ~ i c
Swiss Ephemeris 2.10 Index
7.6. 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.
/* Same declaration as swe_sol_eclipse_when_loc().
* In addition:
* int32 ipl planet number of occulted body
* char* starname name of occulted star. Must be NULL or "", if a planetary
* occultation is to be calculated. For use of this field, see
swe_fixstar().
* int32 ifl ephemeris flag. If you want to have only one conjunction
* of the moon with the body tested, add the following flag:
swephprg.doc ~ 25 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 26 ~ i c
Swiss Ephemeris 2.10 Index
7.7. 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.
/* Same declaration as swe_sol_eclipse_when_glob().
* In addition:
* int32 ipl planet number of occulted body
* char* starname name of occulted star. Must be NULL or "", if a planetary
* occultation is to be calculated. For use of this field,
* see swe_fixstar().
* int32 ifl ephemeris flag. If you want to have only one conjunction
* of the moon with the body tested, add the following flag:
* backward |= SE_ECL_ONE_TRY. If this flag is not set,
* the function will search for an occultation until it
* finds one. For bodies with ecliptical latitudes > 5,
* the function may search successlessly until it reaches
* the end of the ephemeris.
*/
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 *tret, /* return array, 10 doubles, see below */
AS_BOOL backward, /* TRUE, if backward search */
char *serr); /* return error string */
An explanation of the ifl |= SE_ECL_ONE_TRY is given above in paragraph about the function
swe_lun_occult_when_loc().
The function returns:
/* 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
tret[0] time of maximum eclipse
tret[1] time, when eclipse takes place at local apparent noon
tret[2] time of eclipse begin
tret[3] time of eclipse end
tret[4] time of totality begin
tret[5] time of totality end
tret[6] time of center line begin
swephprg.doc ~ 27 ~ i c
Swiss Ephemeris 2.10 Index
7.8. swe_lun_occult_where ()
Similar to 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. With
occultations, it tells us, at which geographic location the occulted body is in the middle of the lunar disc
or closest to it. Because occultations are always visible from a very large area, this is not very
interesting information. But it may become more interesting as soon as the limits of the umbra (and
penumbra) will be implemented.
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 */
The function returns:
/* -1 (ERR) on error (e.g. if swe_calc() for sun or moon fails)
0 if there is no solar eclipse (occultation) at tjd
SE_ECL_TOTAL
SE_ECL_ANNULAR
SE_ECL_TOTAL | SE_ECL_CENTRAL
SE_ECL_TOTAL | SE_ECL_NONCENTRAL
SE_ECL_ANNULAR | SE_ECL_CENTRAL
SE_ECL_ANNULAR | SE_ECL_NONCENTRAL
SE_ECL_PARTIAL
geopos[0]: geographic longitude of central line
geopos[1]: geographic latitude of central line
not implemented so far:
geopos[2]: geographic longitude of northern limit of umbra
geopos[3]: geographic latitude of northern limit of umbra
geopos[4]: geographic longitude of southern limit of umbra
geopos[5]: geographic latitude of southern limit of umbra
geopos[6]: geographic longitude of northern limit of penumbra
geopos[7]: geographic latitude of northern limit of penumbra
geopos[8]: geographic longitude of southern limit of penumbra
geopos[9]: geographic latitude of southern limit of penumbra
eastern longitudes are positive,
western longitudes are negative,
northern latitudes are positive,
southern latitudes are negative
attr[0] fraction of object's diameter covered by moon (magnitude)
attr[1] ratio of lunar diameter to object's diameter
swephprg.doc ~ 28 ~ i c
Swiss Ephemeris 2.10 Index
7.9. swe_lun_eclipse_when_loc ()
To find the next lunar eclipse observable from a given geographic position:
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.
The function returns:
/* retflag SE_ECL_TOTAL or SE_ECL_PENUMBRAL or SE_ECL_PARTIAL
*
* tret[0] time of maximum eclipse
* tret[1]
* tret[2] time of partial phase begin (indices consistent with solar eclipses)
* tret[3] time of partial phase end
* tret[4] time of totality begin
* tret[5] time of totality end
* tret[6] time of penumbral phase begin
* tret[7] time of penumbral phase end
* tret[8] time of moonrise, if it occurs during the eclipse
* tret[9] time of moonset, if it occurs during the eclipse
*
* attr[0] umbral magnitude at tjd
* attr[1] penumbral magnitude
* attr[4] azimuth of moon at tjd
* attr[5] true altitude of moon above horizon at tjd
* attr[6] apparent altitude of moon above horizon at tjd
* attr[7] distance of moon from opposition in degrees
* attr[8] umbral magnitude at tjd (= attr[0])
* attr[9] saros series number (if available; otherwise -99999999)
* attr[10] saros series member number (if available; otherwise -99999999) */
7.10. swe_lun_eclipse_when ()
swephprg.doc ~ 29 ~ i c
Swiss Ephemeris 2.10 Index
7.11. swe_lun_eclipse_how ()
swephprg.doc ~ 30 ~ i c
Swiss Ephemeris 2.10 Index
The function swe_rise_trans() computes the times of rising, setting and meridian transits for all
planets, asteroids, the moon, and the fixed stars. The function swe_rise_trans_true_hor() does the
same for a local horizon that has an altitude != 0.
The function returns a rising time of an object:
if at t0 the object is below the horizon and a rising takes place before the next culmination of the
object;
if at t0 the object is above the horizon and a rising takes place between the next lower and upper
culminations of the object.
And it returns a setting time of an object,
if at t0 the object is above the horizon and a setting takes place before the next lower culmination of
the object;
if at t0 the object is below the horizon and a setting takes place between the next upper and lower
culminations.
Note, “culmination” does not mean meridian transit, especially not with the Sun, Moon, and planets.
The culmination of a moving body with changing declination does not take place exactly on the
meridian but shortly before or after the meridian transit. In polar regions, it even happens that the
moon "rises" shortly after the culmination, on the west side of the meridian. I. e., the upper limb if its
disk will become visible for a short time. The function swe_rise_trans() should catch these cases.
Function definitions are as follows:
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, 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 horhgt, /* height of local horizon in deg at the point where the body
rises or sets */
swephprg.doc ~ 31 ~ i c
Swiss Ephemeris 2.10 Index
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 newspapers 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 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 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()
{
swephprg.doc ~ 32 ~ i c
Swiss Ephemeris 2.10 Index
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 sea 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);
// 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);
swephprg.doc ~ 33 ~ i c
Swiss Ephemeris 2.10 Index
// 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);
}
These functions compute phase, phase angle, elongation, apparent diameter, apparent magnitude for
the Sun, the Moon, all planets and asteroids. The two functions do exactly the same but expect a
different time parameter.
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 */
The function returns:
/*
attr[0] = phase angle (Earth-planet-sun)
attr[1] = phase (illumined fraction of disc)
attr[2] = elongation of planet
attr[3] = apparent diameter of disc
attr[4] = apparent magnitude
declare as attr[20] at least!
NOTE: the lunar magnitude is quite a complicated thing,
but our algorithm is very simple.
The phase of the moon, its distance from the Earth and
the sun is considered, but no other factors.
iflag also allows SEFLG_TRUEPOS, SEFLG_HELCTR
*/
swe_azalt() computes the horizontal coordinates (azimuth and altitude) of a planet or a star from
either ecliptical or equatorial coordinates.
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)
swephprg.doc ~ 34 ~ i c
Swiss Ephemeris 2.10 Index
7.15. 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
The refraction function swe_refrac() calculates either the true altitude from the apparent altitude or
the apparent altitude from the apparent altitude. Its definition is:
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 */
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
swephprg.doc ~ 35 ~ i c
Swiss Ephemeris 2.10 Index
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_refrac_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,
double *dret); /* array of 4 doubles; declare 20 ! */
* - dret[0] true altitude, if possible; otherwise input value
* - dret[1] apparent altitude, if possible; otherwise input
value
* - dret[2] refraction
* - dret[3] dip of the horizon
/* either SE_TRUE_TO_APP or SE_APP_TO_TRUE */
Function returns:
case 1, conversion from true altitude to apparent altitude:
o apparent altitude, if body appears above is observable above ideal horizon;
o 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:
o 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;
o the input altitude; otherwise in addition the array dret[] returns the following values:
dret[0] true altitude, if possible; otherwise input value;
dret[1] apparent altitude, if possible; otherwise input value;
dret[2] refraction;
dret[3] dip of the horizon.
The body is above the horizon if the dret[0] != dret[1].
The function swe_heliacal_ut() the Julian day of the next heliacal phenomenon after a given start
date. It works between geographic latitudes 60s – 60n.
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 */
Function returns OK or ERR.
Details for dgeo[] (array of doubles):
dgeo[0]: geographic longitude;
dgeo[1]: geographic latitude;
swephprg.doc ~ 36 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 37 ~ i c
Swiss Ephemeris 2.10 Index
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
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_vis_limit_mag().
The function swe_vis_limit_mag() determines the limiting visual magnitude in dark skies. If the visual
magnitude mag of an object is known for a given date (e. g. from a call of function swe_pheno_ut(),
and if mag is smaller than the value returned by swe_vis_limit_mag(), then it is visible.
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 “7.17. Heliacal
risings etc.: swe_heliacal_ut()”.
Details for return array dret[] (array of doubles):
dret[0]: limiting visual magnitude (if dret[0] > magnitude of object, then the object is visible);
dret[1]: altitude of object;
dret[2]: azimuth of object;
dret[3]: altitude of sun;
dret[4]: azimuth of sun;
dret[5]: altitude of moon;
dret[6]: azimuth of moon;
dret[7]: magnitude of object.
The function swe_heliacal_pheno_ut() provides data that are relevant for the calculation of heliacal
risings and settings. This function does not provide data of heliacal risings and settings, just some
additional data mostly used for test purposes. To calculate heliacal risings and settings, please use the
function swe_heliacal_ut() documented further above.
double swe_heliacal_pheno_ut(
double tjd_ut, /* Julian day number */
swephprg.doc ~ 38 ~ i c
Swiss Ephemeris 2.10 Index
These functions are needed to convert calendar dates to the astronomical time scale which measures
time in Julian days.
double swe_julday(
int year,
swephprg.doc ~ 39 ~ i c
Swiss Ephemeris 2.10 Index
int month,
int day,
double hour,
int gregflag);
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.
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.
The following functions, which were introduced with Swiss Ephemeris version 1.76, do a similar job as
the functions described under 7.1. The difference is that input and output times are Coordinated
Universal Time (UTC). For transformations between wall clock (or arm wrist) time and Julian Day
numbers, these functions are more correct. The difference is below 1 second, though.
Use these functions to convert:
local time to UTC and UTC to local time;
UTC to a Julian day number, and
a Julian day number to UTC.
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.
/* transform local time to UTC or UTC to local time
*
* input:
* iyear ... dsec date and time
* d_timezone timezone offset
* output:
* iyear_out ... dsec_out
*
* For time zones east of Greenwich, d_timezone is positive.
* For time zones west of Greenwich, d_timezone is negative.
swephprg.doc ~ 40 ~ i c
Swiss Ephemeris 2.10 Index
*
* For conversion from local time to utc, use +d_timezone.
* For conversion from utc to local time, use -d_timezone.
*/
void swe_utc_time_zone(
int32 iyear, int32 imonth, int32 iday,
int32 ihour, int32 imin, double dsec,
double d_timezone,
int32 *iyear_out, int32 *imonth_out, int32 *iday_out,
int32 *ihour_out, int32 *imin_out, double *dsec_out);
/* input: date and time (wall clock time), calendar flag.
* output: an array of doubles with Julian Day number in ET (TT) and UT (UT1)
* an error message (on error)
* The function returns OK or ERR.
*/
int32 swe_utc_to_jd(
int32 iyear, int32 imonth, int32 iday,
int32 ihour, int32 imin, double dsec, /* NOTE: second is a decimal */
gregflag, /* Gregorian calendar: 1, Julian calendar: 0 */
dret /* return array, two doubles:
* dret[0] = Julian day in ET (TT)
* dret[1] = Julian day in UT (UT1) */
serr); /* error string */
/* 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 */
/* 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 UT (UT1) */
gregflag, /* Gregorian calendar: 1, Julian calendar: 0 */
int32 *iyear, int32 *imonth, int32 *iday,
int32 *ihour, int32 *imin, double *dsec); /* NOTE: second is a decimal */
How do I get correct planetary positions, sidereal time, and house cusps, starting from a
wall clock date and time?
int32 iday, imonth, iyear, ihour, imin, retval;
int32 gregflag = SE_GREG_CAL;
double d_timezone = 5.5; /* time zone = Indian Standard Time; NOTE: east is
positive */
double dsec, tjd_et, tjd_ut;
double dret[2];
char serr[256];
…
/* if date and time is in time zone different from UTC,
* the time zone offset must be subtracted first in order to get UTC: */
swe_utc_time_zone(iyear, imonth, iday, ihour, imin, dsec, d_timezone,
&iyear_utc, &imonth_utc, &iday_utc, &ihour_utc, &imin_utc, &dsec_utc);
/* calculate Julian day number in UT (UT1) and ET (TT) from UTC */
swephprg.doc ~ 41 ~ i c
Swiss Ephemeris 2.10 Index
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
Before 1972, swe_utc_to_jd() treats its input time as UT1.
NOTE: UTC was introduced in 1961. From 1961 - 1971, the length of the UTC second was regularly
changed, so that UTC remained very close to UT1.
From 1972 on, input time is treated as UTC.
If delta_t - nleap - 32.184 > 1, the input time is treated as UT1.
NOTE: Like this we avoid errors greater than 1 second in case that the leap seconds table (or the Swiss
Ephemeris version) is not updated for a long time.
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
swephprg.doc ~ 42 ~ i c
Swiss Ephemeris 2.10 Index
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 conversions between Local Apparent Time and Local Mean Time, it is recommended to use the
following functions:
/* converts Local Mean Time (LMT) to Local Apparent Time (LAT) */
/* tjd_lmt and tjd_lat are a Julian day number
* geolon is geographic longitude, where eastern longitudes are positive,
* western ones negative */
int32 swe_lmt_to_lat(
double tjd_lmt,
double geolon,
double *tjd_lat,
char *serr);
/* converts Local Apparent Time (LAT) to Local Mean Time (LMT) */
int32 swe_lat_to_lmt(
double tjd_lat,
double geolon,
double *tjd_lmt,
char *serr);
swephprg.doc ~ 43 ~ i c
Swiss Ephemeris 2.10 Index
9.1. swe_deltat_ex()
9.2. swe_deltat()
With Swiss Ephemeris versions until 1.80, this function had always to be used, if a nonstandard
ephemeris like DE200 or DE421 was used.
Since Swiss Ephemeris version 2.00, this function is usually not needed, because the value is
automatically set according to the ephemeris files selected or available. However, under certain
circumstances that are described in the section “9.2 swe_deltat()”, the user may want to control the
tidal acceleration himself.
To find out the value of the tidal acceleration currently used, call the function
swephprg.doc ~ 44 ~ i c
Swiss Ephemeris 2.10 Index
acceleration = swe_get_tid_acc();
In order to set a different value, use the function
swe_set_tid_acc(acceleration);
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 automatic setting of tidal acceleration is
blocked. In order to unblock it again, call
swe_set_tid_acc(SE_TIDAL_AUTOMATIC);
9.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);
Delta T values for future years can only be estimated. Strictly speaking, the Swiss Ephemeris has to be
updated every year after the new Delta T value for the past year has been published by the IERS. We
will do our best and hope to update the Swiss Ephemeris every year. However, if the user does not
want to wait for our update or does not download a new version of the Swiss Ephemeris he can add
new Delta T values in the file swe_deltat.txt, which has to be located in the Swiss Ephemeris ephemeris
path.
# This file allows make new Delta T known to the Swiss Ephemeris.
# Note, these values override the values given in the internal Delta T
# table of the Swiss Ephemeris.
# Format: year and seconds (decimal)
2003 64.47
2004 65.80
2005 66.00
2006 67.00
2007 68.00
2008 68.00
2009 69.00
void swe_set_topo( /* 3 doubles for geogr. longitude, latitude, height above sea.
double geolon, * eastern longitude is positive,
double geolat, * western longitude is negative,
double altitude); * northern latitude is positive,
* southern latitude is negative */
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.:
swe_set_topo(geo_lon, geo_lat, altitude_above_sea);
iflag |= SEFLG_TOPOCTR;
for (i = 0; i < NPLANETS; i++)
{
iflgret = swe_calc(tjd, ipl, iflag, xp, serr);
swephprg.doc ~ 45 ~ i c
Swiss Ephemeris 2.10 Index
printf(”%f\n”, xp[0]);
}
The parameters set by swe_set_topo() survive swe_close().
11.1. swe_set_sid_mode()
swephprg.doc ~ 46 ~ i c
Swiss Ephemeris 2.10 Index
#define SE_SIDM_BABYL_BRITTON 38
#define SE_SIDM_TRUE_SHEORAN 39
#define SE_SIDM_GALCENT_COCHRANE 40
#define SE_SIDM_GALEQU_FIORENZA 41
#define SE_SIDM_VALENS_MOON 42
#define SE_SIDM_LAHIRI_1940 43
#define SE_SIDM_LAHIRI_VP285 44
#define SE_SIDM_KRISHNAMURTI_VP291 45
#define SE_SIDM_LAHIRI_ICRC 46
#define SE_SIDM_USER 255
The function swe_get_ayanamsa_name() returns the name of the ayanamsha.
const char *swe_get_ayanamsa_name(int32 isidmode)
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
swephprg.doc ~ 47 ~ i c
Swiss Ephemeris 2.10 Index
"\"Vedic\"/Sheoran 39 SE_SIDM_TRUE_SHEORAN
"Cochrane (Gal.Center = 0 Cap)" 40 SE_SIDM_GALCENT_COCHRANE
"Galactic Equator (Fiorenza)", 41 SE_SIDM_GALEQU_FIORENZA
"Vettius Valens", 42 SE_SIDM_VALENS_MOON
"Lahiri 1940", 43 SE_SIDM_LAHIRI_1940
"Lahiri VP285", 44 SE_SIDM_LAHIRI_VP285
"Krishnamurti-Senthilathiban", 45 SE_SIDM_KRISHNAMURTI_VP291
"Lahiri ICRC", 46 SE_SIDM_LAHIRI_ICRC
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:
Special uses of the sidereal functions:
swephprg.doc ~ 48 ~ i c
Swiss Ephemeris 2.10 Index
#define SE_SIDM_J1900 19
#define SE_SIDM_B1950 20
If a transformation to the ecliptic of date is required the following bit can be added (‘ored’) to the
value of the variable sid_mode:
/* for projection onto ecliptic of t0 */
#define SE_SIDBIT_ECL_DATE 2048
E.g.:
swe_set_sid_mode(SE_SIDM_J2000 + SE_SIDBIT_ECL_DATE, 0, 0);
iflag |= SEFLG_SIDEREAL;
for (i = 0; i < NPLANETS; i++) {
iflgret = swe_calc(tjd, ipl, iflag, xp, serr);
printf(”%f\n”, xp[0]);
}
These functions compute the ayanamsha, i.e. the distance of the tropical vernal point from the sidereal
zero point of the zodiac. The ayanamsha is used to compute sidereal planetary positions from tropical
ones:
pos_sid = pos_trop – ayanamsha
Important information concerning the values returned:
The functions swe_get_ayanamsa() and swe_get_ayanamsa_ut() provide the ayanamsha without
nutation.
The functions swe_get_ayanamsa_ex() and swe_get_ayanamsa_ex_ut() provide the ayanamsha
with or without nutation depending on the parameter iflag. If iflag contains (SEFLG_NONUT) the
ayanamsha value is calculated without nutation, otherwise it is calculated including nutation.
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
swephprg.doc ~ 49 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 50 ~ i c
Swiss Ephemeris 2.10 Index
There is a disagreement between American and European programmers whether eastern or western
geographical longitudes ought to be considered positive. Americans prefer to have West longitudes
positive, Europeans prefer the older tradition that considers East longitudes as positive and West
longitudes as negative.
The Astronomical Almanac still follows the European pattern. It gives the geographical coordinates of
observatories in "East longitude".
The Swiss Ephemeris also follows the European style. All Swiss Ephemeris functions that use
geographical coordinates consider positive geographical longitudes as East and negative ones
as West.
E.g. 87w39 = -87.65° (Chicago IL/USA) and 8e33 = +8.55° (Zurich, Switzerland).
There is no such controversy about northern and southern geographical latitudes. North is always
positive and south is negative.
There is some confusion among astrologers whether they should use geographic latitude (also called
geodetic latitude, which is a synonym) or geocentric latitude for house calculations, topocentric
positions of planets, eclipses, etc.
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.
14.1. swe_house_name()
14.2. swe_houses()
swephprg.doc ~ 51 ~ i c
Swiss Ephemeris 2.10 Index
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
documented below */
double *cusps, /* array for 13 (or 37 for hsys G) doubles, explained further
below */
double *ascmc); /* array for 10 doubles, explained further below */
int swe_houses_armc_ex2(
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
documented below */
double *cusps, /* array for 13 (or 37 for hsys G) doubles, explained further
below */
double *ascmc, /* array for 10 doubles, explained further below */
double *cusp_speed,
double *ascmc_speed,
char *serr):
swephprg.doc ~ 52 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 53 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 54 ~ i c
Swiss Ephemeris 2.10 Index
To compute the house position of a given body for a given ARMC, you may use:
double swe_house_pos(
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 *xpin, /* array of 2 doubles: ecl. longitude and latitude of the
planet */
char *serr); /* return area for error or warning message */
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.
With house system ‘G’ (Gauquelin sectors), a value between 1.0 and 36.9999999 is returned. Note that,
swephprg.doc ~ 55 ~ i c
Swiss Ephemeris 2.10 Index
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.
For general information on Gauquelin sectors, read chapter 6.5 in documentation file swisseph.doc.
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.
Function swe_gauquelin_sector() is declared as follows:
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
* geograph. long., lat., height of observer */
double atpress, /* atmospheric pressure, only useful with imeth = 3;
swephprg.doc ~ 56 ~ i c
Swiss Ephemeris 2.10 Index
The sidereal time is computed inside the houses() function and returned via the variable armc which
measures sidereal time in degrees. To get sidereal time in hours, divide armc by 15.
If the sidereal time is required separately from house calculation, two functions are available. The
second version requires obliquity and nutation to be given in the function call, the first function
computes them internally. Both return sidereal time at the Greenwich Meridian, measured in hours.
double swe_sidtime(
double tjd_ut); /* Julian day number, UT */
double swe_sidtime0(
double tjd_ut, /* Julian day number, UT */
double eps, /* obliquity of ecliptic, in degrees */
double nut); /* nutation in longitude, in degrees */
swephprg.doc ~ 57 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 58 ~ i c
Swiss Ephemeris 2.10 Index
double *xndsc, /* target address for 6 position values for descending node (cf.
swe_calc()*/
double *xperi, /* target address for 6 position values for perihelion (cf.
swe_calc()*/
double *xaphe, /* target address for 6 position values for aphelion (cf.
swe_calc()*/
char *serr);
// positions of fixed stars from UT, faster function if many stars are calculated
int32 swe_fixstar2_ut(
char *star, /* star name, returned star name 40 bytes */
double tjd_ut, /* Julian day number, Universal Time */
int32 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 */
// positions of fixed stars from TT, faster function if many stars are calculated
int32 swe_fixstar2(
char *star, /* star name, returned star name 40 bytes */
double tjd_et, /* Julian day number, Ephemeris Time */
int32 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 */
// positions of fixed stars from UT, faster function if single stars are calculated
int32 swe_fixstar_ut(
char *star, /* star name, returned star name 40 bytes */
double tjd_ut, /* Julian day number, Universal Time */
int32 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 */
// positions of fixed stars from TT, faster function if single stars are calculated
int32 swe_fixstar(
char *star, /* star name, returned star name 40 bytes */
double tjd_et, /* Julian day number, Ephemeris Time */
int32 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 */
// get the magnitude of a fixed star
int32 swe_fixstar2_mag(
char *star,
double* mag,
char* serr);
int32 swe_fixstar_mag(
char *star,
double* mag,
char* serr);
swephprg.doc ~ 59 ~ i c
Swiss Ephemeris 2.10 Index
void swe_set_topo(
double geolon, /* geographic longitude */
double geolat, /* geographic latitude
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
double altitude); /* altitude above sea */
void swe_set_sid_mode(
int32 sid_mode,
double t0, /* reference epoch */
double ayan_t0); /* initial ayanamsha at t0 */
/* The function calculates ayanamsha for a given date in UT.
* The return value is either the ephemeris flag used or ERR (-1) */
int32 swe_get_ayanamsa_ex_ut(
double tjd_ut, /* Julian day number in UT */
int32 ephe_flag, /* ephemeris flag, one of SEFLG_SWIEPH, SEFLG_JPLEPH,
SEFLG_MOSEPH */
double *daya, /* output: ayanamsha value (pointer to double) */
char *serr); /* output: error message or warning (pointer to string) */
/* The function calculates ayanamsha for a given date in ET/TT.
* The return value is either the ephemeris flag used or ERR (-1) */
int32 swe_get_ayanamsa_ex(
double tjd_ut, /* Julian day number in ET/TT */
int32 ephe_flag, /* ephemeris flag, one of SEFLG_SWIEPH, SEFLG_JPLEPH,
SEFLG_MOSEPH */
double *daya, /* output: ayanamsha value (pointer to double) */
char *serr); /* output: error message or warning (pointer to string) */
/* to get the ayanamsha for a date in UT, old function, better use
swe_get_ayanamsa_ex_ut() */
double swe_get_ayanamsa_ut(double tjd_ut);
/* to get the ayanamsha for a date in ET/TT, old function, better use
swe_get_ayanamsa_ex() */
double swe_get_ayanamsa(double tjd_et);
// find the name of an ayanamsha
const char *swe_get_ayanamsa_name(int32 isidmode)
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 geo. lon, lat, height */
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
swephprg.doc ~ 60 ~ i c
Swiss Ephemeris 2.10 Index
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. */
double *tret, /* return array, 10 doubles, see below */
AS_BOOL backward, /* TRUE, if backward search */
char *serr); /* return error string */
17.2.3. 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 */
17.2.4. 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 */
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,
swephprg.doc ~ 61 ~ i c
Swiss Ephemeris 2.10 Index
17.2.5. Find the next occultation of a body by the moon for a given
geographic position
17.2.7. Find the next lunar eclipse observable from a geographic location
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 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_eclipse_when(
swephprg.doc ~ 62 ~ i c
Swiss Ephemeris 2.10 Index
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 */
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 */
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 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 */
swephprg.doc ~ 63 ~ i c
Swiss Ephemeris 2.10 Index
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 */
// details of heliacal risings/settings
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()) */
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, declare array of 50 doubles */
char *serr); /* error string */
// magnitude limit for visibility
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 */
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()) */
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, declare array of 50 doubles */
char *serr); /* error string */
int32 swe_pheno_ut(
swephprg.doc ~ 64 ~ i c
Swiss Ephemeris 2.10 Index
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 */
double swe_refrac_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 */
double *dret); /* array of 4 doubles; declare 20 ! */
* - dret[0] true altitude, if possible; otherwise input value
* - dret[1] apparent altitude, if possible; otherwise input
value
swephprg.doc ~ 65 ~ i c
Swiss Ephemeris 2.10 Index
* - dret[2] refraction
* - dret[3] dip of the horizon
/* either SE_TRUE_TO_APP or SE_APP_TO_TRUE */
int32 swe_get_orbital_elements(
double tjd_et, // input date in TT (Julian day number)
int32 ipl, // planet number
int32 iflag, // flag bits, see detailed docu
double *dret, // return values, see detailed docu
char *serr);
int32 swe_orbit_max_min_true_distance(
double tjd_et, // input date in TT (Julian day number)
int32 ipl, // planet number
int32 iflag, // flag bits, see detailed docu
double *dmax, // return value: maximum distance based on osculating elements
double *dmin, // return value: minimum distance based on osculating elements
double *dtrue, // return value: current distance
char *serr);
17.3.2. Julian day number from year, month, day, hour, with check whether
date is legal
swephprg.doc ~ 66 ~ i c
Swiss Ephemeris 2.10 Index
double swe_julday(
int year,
int month,
int day,
double hour,
int gregflag); /* Gregorian calendar: 1, Julian calendar: 0 */
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);
swephprg.doc ~ 67 ~ i c
Swiss Ephemeris 2.10 Index
double swe_get_tid_acc(void);
/* 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);
/* converts Local Mean Time (LMT) to Local Apparent Time (LAT) */
/* tjd_lmt and tjd_lat are a Julian day number
* geolon is geographic longitude, where eastern
* longitudes are positive, western ones negative */
int32 swe_lmt_to_lat(
double tjd_lmt,
double geolon,
double *tjd_lat,
char *serr);
/* converts Local Apparent Time (LAT) to Local Mean Time (LMT) */
int32 swe_lat_to_lmt(
double tjd_lat,
double geolon,
double *tjd_lmt,
swephprg.doc ~ 68 ~ i c
Swiss Ephemeris 2.10 Index
char *serr);
char * swe_house_name(
int hsys); /* house method, ascii code of one of the letters PKORCAEVXHTBG
*/
int swe_houses(
double tjd_ut, /* Julian day number, UT */
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 of the letters PKRCAV */
swephprg.doc ~ 69 ~ i c
Swiss Ephemeris 2.10 Index
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 of the letters PKRCAV */
double* cusps, /* array for 13 doubles */
double* ascmc); /* array for 10 doubles */
int swe_houses_ex2(
double tjd_ut, /* Julian day number, UT */
int32 iflag, /* 0 or SEFLG_SIDEREAL or SEFLG_RADIANS or SEFLG_NONUT */
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, explained further
below */
double *ascmc, /* array for 10 doubles, explained further below */
double *cusp_speed, /* like cusps */
double *ascmc_speed, /* like ascmc */
char *serr);
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 */
int swe_houses_armc_ex2(
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
documented below */
double *cusps, /* array for 13 (or 37 for system G) doubles, explained further
below */
double *ascmc, /* array for 10 doubles, explained further below */
double *cusp_speed,
double *ascmc_speed,
char *serr):
swephprg.doc ~ 70 ~ i c
Swiss Ephemeris 2.10 Index
double swe_house_pos(
double armc, /* ARMC */
double geolat, /* geographic latitude, in degrees
* eastern longitude is positive,
* western longitude is negative,
* northern latitude is positive,
* southern latitude is negative */
double eps, /* ecliptic obliquity, in degrees */
int hsys, /* house method, one of the letters PKRCAV */
double *xpin, /* array of 2 doubles: ecl. longitude and latitude of the
planet */
char *serr); /* return area for error or warning message */
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 */
swephprg.doc ~ 71 ~ i c
Swiss Ephemeris 2.10 Index
double *xpo, /* 6 doubles, input: long., lat., dist. and speeds in long.,
lat and dist. */
double *xpn, /* 6 doubles, position and speed in new coordinate system */
double eps); /* obliquity of ecliptic, in degrees. */
char* swe_get_planet_name(
int ipl, /* planet number */
char* plan_name); /* address for planet name, at least 20 char */
This function takes a decimal degree number as input and provides sign or nakshatra, degree, minutes,
seconds and fraction of second. It can also round to seconds, minutes, degrees. For more details see
the specifications below.
double swe_split_deg(
double ddeg,
int32 roundflag,
int32 *ideg,
int32 *imin,
int32 *isec,
double *dsecfr,
int32 *isgn);
/* splitting decimal degrees into (zod. sign,) deg, min, sec. *
* input:
* ddeg decimal degrees, ecliptic longitude
* roundflag by default there is no rounding. if rounding is
* required, the following bits can be set:
# define SE_SPLIT_DEG_ROUND_SEC 1
# define SE_SPLIT_DEG_ROUND_MIN 2
# define SE_SPLIT_DEG_ROUND_DEG 4
# define SE_SPLIT_DEG_ZODIACAL 8 * split into zodiac signs
# define SE_SPLIT_DEG_NAKSHATRA 1024 * split into nakshatras *
# define SE_SPLIT_DEG_KEEP_SIGN 16 * don't round to next zodiac sign/nakshatra,
* e.g. 29.9999998 will be rounded
* to 29°59'59" (or 29°59' or 29°)
* or next nakshatra:
* e.g. 13.3333332 will be rounded
* to 13°19'59" (or 13°19' or 13°)
# define SE_SPLIT_DEG_KEEP_DEG 32 * don't round to next degree
* e.g. 10.9999999 will be rounded
* to 10d59'59" (or 10d59' or 10d)
* output:
* ideg degrees,
swephprg.doc ~ 72 ~ i c
Swiss Ephemeris 2.10 Index
* imin minutes,
* isec seconds,
* dsecfr fraction of seconds
* isgn zodiac sign number;
* or +/- sign
PLACALC, the predecessor of SWISSEPH, had included several functions that we do not need for
SWISSEPH anymore. Nevertheless we include them again in our DLL, because some users of our
software may have taken them over and use them in their applications. However, we gave them new
names that were more consistent with SWISSEPH.
PLACALC used angular measurements in centiseconds a lot; a centisecond is 1/100 of an arc second.
The C type CSEC or centisec is a 32-bit integer. CSEC was used because calculation with integer
variables was considerably faster than floating point calculation on most CPUs in 1988, when PLACALC
was written.
In the Swiss Ephemeris we have dropped the use of centiseconds and use double (64-bit floating point)
for all angular measurements.
swephprg.doc ~ 73 ~ i c
Swiss Ephemeris 2.10 Index
The 32-bit DLL contains the exported function under 'decorated names'. Each function has an
underscore before its name, and a suffix of the form @xx where xx is the number of stack bytes used by
the call.
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.
DLL functions returning a string:
Some DLL functions return a string, e.g.
char* swe_get_planet_name(int ipl, char *plname)
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
swephprg.doc ~ 74 ~ i c
Swiss Ephemeris 2.10 Index
20. Using the DLL with Borland Delphi and C++ Builder
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;
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';
A nearly complete set of declarations is in file \sweph\delphi2\swe_d32.pas.
A small sample project for Delphi 2.0 is also included in the same directory (starting with release 1.25
from June 1998). This sample requires the DLL to exist in the same directory as the sample.
Borland C++ Builder (BCB) does not understand the Microsoft format in the library file SWEDLL32.LIB; it
reports an OMF error when this file is used in a BCB project. The user must create his/her own LIB file
for BCB with the utility IMPLIB which is part of BCB.
With the following command you create a special lib file in the current directory:
IMPLIB –f –c swe32bor.lib \sweph\bin\swedll32.dll
In the C++ Builder project the following settings must be made:
Menu Options->Projects->Directories/Conditionals: add the conditional define USE_DLL;
Menu Project->Add_to_project: add the library file swe32bor.lib to your project;
In the project source, add the include file "swephexp.h".
In the header file swedll.h the declaration for Dllimport must be
#define DllImport extern "C" __declspec(dllimport)
This is provided automatically by the __cplusplus switch for release 1.24 and higher. For earlier
releases the change must be made manually.
swephprg.doc ~ 75 ~ i c
Swiss Ephemeris 2.10 Index
The Swiss Ephemeris can be run from Perl using the Perl module SwissEph.pm. The module
SwissEph.pm uses XSUB (“eXternal SUBroutine”), which calls the Swiss Ephemeris functions either from
a C library or a DLL.
In order to run the Swiss Ephemeris from Perl, you have to:
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.
Install the XS library:
Unpack the file PerlSwissEph-1.76.00.tar.gz (or whatever newest version there is);
Open the file Makefile.PL, and edit it according to your requirements. Then run it;
make install
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).
The distribution contains executables and C source code of sample programs which demonstrate the
use of the Swiss Ephemeris DLL and its functions.
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.
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.
Since version 2.08, all sample programs and DLLs were compiled with Microsoft Visual Studio 14.0.
Again, 64-bit programs contain a ‘64’ 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.dll32-bit DLL
sweph\src\swedll64.dll64-bit DLL
sweph\src\swedll32.lib
sweph\src\swedll64.lib
You can run the samples in the following environments:
Swetest.exe in Windows command line
Swetest64.exe in Windows command line
Swete32.exe in Windows command line
Swete64.exe in Windows command line
Swewin32.exe in Windows
Character mode executable that needs a DLL
Swete32.exe
The project files for Microsoft Visual C++ are in \sweph\src\swete32.
swetest.c
swedll32.lib
swephexp.h
swedll.h
swephprg.doc ~ 76 ~ i c
Swiss Ephemeris 2.10 Index
sweodef.h
define macros: USE_DLL DOS32 DOS_DEGREE
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.
How the sample programs search for the ephemeris files:
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.
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
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
173758 Nov 27 10:07 sweph.c
12136 Nov 27 10:06 sweph.h
55063 Nov 27 10:07 swephlib.c
swephprg.doc ~ 77 ~ i c
Swiss Ephemeris 2.10 Index
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
HPUX PA-Risc versus Intel Pentium gcc non-optimized
differences are smaller than 0.001 arcsec/day
Intel Pentium gss non-optimized versus -O9 optimized:
Mean Node, True node, Mean Apogee: difference smaller than 0.001 arcsec/day
Osculating Apogee: differences smaller than 0.03 arcsec
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 safely
ignored.
Besides the ordinary Swisseph function, there are two additional DLLs that allow you tracing your
Swisseph function calls:
swephprg.doc ~ 78 ~ i c
Swiss Ephemeris 2.10 Index
Swedlltrs32.dll and swedlltrs64.dll are for single task debugging, i.e. if only one application at a time
calls Swisseph functions.
Two output files are written:
a) swetrace.txt: reports all Swisseph functions that are being called.
b) swetrace.c: contains C code equivalent to the Swisseph calls that your application did.
The last bracket of the function main() at the end of the file is missing.
If you want to compile the code, you have to add it manually. Note that these files may grow very fast,
depending on what you are doing in your application. The output is limited to 10000 function calls per
run.
Swedlltrm32.dll and swedlltrm64.dll are for multitasking, i.e. if more than one application at a time are
calling Swisseph functions. If you used the single task DLL here, all applications would try to write their
trace output into the same file. Swedlltrm32.dll and swedlltrm64.dll generate output file names that
contain the process identification number of the application by which the DLL is called, e.g.
swetrace_192.c and swetrace_192.txt.
Keep in mind that every process creates its own output files and with time might fill your disk.
In order to use a trace DLL, you have to replace your Swisseph DLL by it:
a) save your Swisseph DLL;
b) rename the trace DLL as your Swisseph DLL (e.g. as swedll32.dll or swedll64.dll).
IMPORTANT: The Swisseph DLL will possibly not work properly if called from more than one thread.
(NOTE: This may not be true any longer for DLLs compiled with MVS version 14.0… (2015); it should be
tested again.)
Output samples swetrace.txt:
swe_deltat: 2451337.870000 0.000757
swe_set_ephe_path: path_in = path_set = \sweph\ephe\
swe_calc: 2451337.870757 -1 258 23.437404 23.439365 -0.003530 -0.001961 0.000000
0.000000
swe_deltat: 2451337.870000 0.000757
swe_sidtime0: 2451337.870000 sidt = 1.966683 eps = 23.437404 nut = -0.003530
swe_sidtime: 2451337.870000 1.966683
swe_calc: 2451337.870757 0 258 77.142261 -0.000071 1.014989 0.956743 -0.000022
0.000132
swe_get_planet_name: 0 Sun
swetrace.c:
#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();
Similar tracing is also possible if you compile the Swisseph source code into your application. Use the
preprocessor definitions TRACE = 1 for single task debugging, and TRACE = 2 for multitasking. In most
compilers this flag can be set with – DTRACE = 1 or / DTRACE = 1.
swephprg.doc ~ 79 ~ i c
Swiss Ephemeris 2.10 Index
28. Updates
Updated By
30-sep-1997 Alois added chapter 10 (sample programs)
7-oct-1997 Dieter inserted chapter 7 (house calculation)
8-oct-1997 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-1997 Dieter remarks concerning computation of asteroids, changes to version 1.04
8-jan-1998 Dieter changes from version 1.04 to 1.10.
12-jan-1998 Dieter changes from version 1.10 to 1.11.
21-jan-1998 Dieter calculation of topocentric planets and house positions (1.20)
28-jan-1998 Dieter Delphi 1.0 sample and declarations for 16- and 32-bit Delphi (1.21)
11-feb-1998 Dieter version 1.23
7-mar-1998 Alois version 1.24 support for Borland C++ Builder added
4-jun-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-1999 Dieter version 1.4
8-jun-1999 Dieter chapter 21 on tracing an debugging Swisseph
27-jul-1999 Dieter info about sidereal calculations
16-aug-1999 Dieter version 1.51, minor bug fixes
15-feb-2000 Dieter many things for version 1.60
19-mar-2000 Vic Ogi swephprg.doc re-edited
17-apr-2002 Dieter documentation for version 1.64
26-jun-2002 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
swephprg.doc ~ 80 ~ i c
Swiss Ephemeris 2.10 Index
Relea Date
se
1.00 30-sep-
1997
1.01 9-oct-1997 houses(), sidtime() made more convenient for developer, Vertex
added.
1.02 16-oct- houses() changed again, Visual Basic support, new numbers for
1997 fictitious planets This release was pushed to all existing licensees at
this date.
1.03 28-oct- minor bug fixes, improved swe_fixstar() functionality. This release
1997 was not 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- small improvements
1998
1.20 20-jan- new: topocentric planets and house positions; a minor bug fix
1998
1.21 28-jan- Delphi declarations and sample for Delphi 1.0
1998
1.22 2-feb-1998 asteroids moved to subdirectory. Swe_calc() finds them there.
swephprg.doc ~ 81 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 82 ~ i c
Swiss Ephemeris 2.10 Index
1.72 28-sep- new function swe_refrac_extended(), Delta T update, minor bug fixes
2007
1.73 29-may- new function swe_fixstars_mag(), Whole Sign houses
2008
1.74 18-jun- bug fixes
2008
1.75 27-aug- Swiss Ephemeris can read newer JPL ephemeris files; bug fixes
2008
1.76 7-apr-2009 heliacal risings, UTC and minor improvements/bug fixes
1.77 26-jan- swe_deltat(), swe_fixstar() improved, swe_utc_time_zone added
2010
1.78 3-aug-2012 new precession, improvement of some eclipse functions, some minor
bug fixes
1.79 18-apr- new precession, improvement of some eclipse functions, some minor
2013 bug fixes
1.80 3-sep-2013 security update, APC houses, bug fixes
2.00 11-feb- Swiss Ephemeris is now based on JPL Ephemeris DE431
2014
2.01 18-mar- udates for tidal acceleration of the Moon with DE431, Delta T, and
2015 leap seconds.
a number of bug fixes
2.02 11-aug- new functions swe_deltat_ex() and
2015 swe_get_ayanamsha_ex()/swe_get_ayanamsha_ex_ut()
a number of bug fixes
2.02.0 14-aug- small corrections to new code, for better backward compatibility
1 2015
2.03 16-oct- Swiss Ephemeris thread-safe (except DLL)
2015
2.04 21-oct- Swiss Ephemeris DLL based on calling convention __stdcall again, as
2015 used to be
2.05 27-may- bug fixes, new ayanamshas, new house methods, osculating
2015 elements
2.05.0 27-may- bug fix in new function swe_orbit_max_min_true_distance()
1 2015
2.06 10-jan- new Delta T calculation
2017
2.07 10-jan- better performance of swe_fixstar() and swe_rise_trans()
2018
2.07.0 1-feb-2018 compatibility with Microsoft Visual Studio, minor bugfixes (fixed star
1 functions, leap seconds).
2.08 13-jun- new Delta T and a number of minor bugfixes.
2019
2.09 23-jul-2020 improved Placidus houses, sidereal ephemerides, planetary
magnitudes; minor bug fixes.
2.09.0 23-jul-2020 bug fix for improved Placidus houses.
1
2.09.0 18-aug- new functions swe_houses_ex2(), swepeeds of house cusps.
2 2020
2.09.0 1-sep-2020 minor bug fixes.
3
2.10 3-dec-2020 center of body, planetary moons, and planetocentric ephemerides
2.10.0 5-may- Minor bug fixes and DE441 added to the list of usable JPL
1 2021 ephemerides
swephprg.doc ~ 83 ~ i c
Swiss Ephemeris 2.10 Index
1. An old bug in the lunar ephemeris with (iflag & SEFLG_SWIEPH) was fixed. It resulted from the fact
that a different ecliptic obliquity J2000 was used in the packing and unpacking of the ephemeris data
(function sweph.c:rot_back()). The difference between the two was 0.042". Many thanks to Hal Rollins
for finding and reporting this problem.
2. Correct handling of new JPL Ephemeris DE441, using the lunar tidal acceleration (deceleration) -
25.936 "/cent^2 (according to Jon Giorgini/JPL's Horizons System).
3. Deltat T was updated for current years.
4. A minor bug in swe_calc_pctr() was fixed: The function did not work correctly with asteroids and
(iflag & SEFLG_JPLEPH), resulting in the error message "Ephmeris file seas_18.se1 is damaged (2)".
5. Bug in swe_rise_set() with fixed stars reported by Ricardo Ric was fixed.
New features:
- ephemerides of center of body (COB) of planets
- ephemerides of some planetary moons
- planetocentric ephemerides using the function swe_calc_pctr()
- function swe_get_current_file_data() for time range of *.se1 ephemeris files.
New functions swe_houses_ex2() and swe_houses_armc_ex2() can calculate speeds (“daily motions”) of
house cusps and related points.
This release provides new values for Delta T in 2020 and 2021, an improved calculation of Placidus
house cusps near the polar circles, new magnitudes for the major planets, improved sidereal
ephemerides, and a few new ayanamshas.
1. Our calculation of Placidus house positions did not provide greatest possible precision with high
geographic latitudes (noticed by D. Senthilathiban). The improvement is documented in the
General Documentation under 6.7. "Improvement of the Placidus house calculation in SE 2.09".
2. New magnitudes according to Mallama 2018 were implemented. The new values agree with JPL
Horizons for all planets except Mars, Saturn, and Uranus. Deviations form Horizons are < 0.1m for
Mars, < 0.02m for Saturn and < 0.03m for Uranus.
3. New values for Delta T have been added for 2020 and 2021 (the latter estimated).
Sidereal astrology:
A lot of work has been done for more correct calculation of ayanamshas.
4. Improved general documentation:
- theory of ayanamsha in general
- about Lahiri ayanamsha
swephprg.doc ~ 84 ~ i c
Swiss Ephemeris 2.10 Index
This release provides a number minor bug fixes and cleanups, an update for current Delta T, a few little
swephprg.doc ~ 85 ~ i c
Swiss Ephemeris 2.10 Index
Changes for compatibility with Microsoft Visual C. Affected functions are: swe_fixstar2(),
swe_fixstar2_ut(), swe_fixstar2_mag().
Minor bugfixes in the functions swe_fixstar_ut(), swe_fixstar2_ut() and swe_fixstar2(). In particular,
calls of the _ut functions with sequential star numbers did not work properly. This was an older bug,
introduced with version 2.02.01 (where it appeared in function swe_fixstar_ut()).
Wrong leap second (20171231) removed from swedate.c. Affected functions were: swe_utc_to_jd(),
swe_jdet_to_utc(), swe_jdut1_to_utc().
swephprg.doc ~ 86 ~ i c
Swiss Ephemeris 2.10 Index
Greatly enhanced performance of swe_rise_trans() with calculations of risings and settings of planets
except for high geographic latitudes.
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.
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 behavior 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.
New ayanamsha added:
"Vedic" ayanamsha according to Sunil Sheoran (SE_SIDM_TRUE_SHEORAN)
It must be noted that in Sheoran's opinion 0 Aries = 3°20' Ashvini. The user has to carry the
responsibility to correctly handle this problem. For calculating a planet's nakshatra position correctly,
we recommend the use of the function swe_split_deg() with parameter roundflag |=
SE_SPLIT_DEG_NAKSHATRA or roundflag |= 1024. This will handle Sheoran’s ayanamsha correctly.
For more information about this and other ayanamshas, I refer to the general documentation chap. 2.7
or my article on ayanamshas here: https://www.astro.com/astrology/in_ayanamsha_e.htm
Function swe_rise_trans() has two new flags:
SE_BIT_GEOCTR_NO_ECL_LAT 128 /* use geocentric (rather than topocentric) position of object and
ignore its ecliptic latitude */
SE_BIT_HINDU_RISING /* calculate risings according to Hindu astrology */
Of course, as usual, leap seconds and Delta T have been updated.
Calculation of heliacal risings using swe_heliacal_ut() now also works with Bayer designations, with
an initial comma, e.g. “,alTau”.
Problem left undone:
Janez Križaj noticed that in the remote past the ephemeris of the Sun has some unusual ecliptic
latitude, which amounts to +-51 arcsec for the year -12998. This phenomenon is due to an intrinsic
inaccuracy of the precession theory Vondrak 2011 and therefore we do not try to fix it. While the
problem could be avoided by using some older precession theory such as Laskar 1986 or Owen 1990,
we give preference to Vondrak 2011 because it is in very good agreement with precession IAU2006 for
recent centuries. Also, the “problem” (a very small one) appears only in the very remote past, not in
historical epochs.
Important additional information on the new function swe_fixstar2() and its derivatives with increased
performance:
Some users had criticized 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 behavior is slightly different:
swephprg.doc ~ 87 ~ i c
Swiss Ephemeris 2.10 Index
Starting with release 2.05, the special unit test system setest designed and developed by Rüdiger
Plantiko is used by the developers. This improves the reliability of the code considerably and has led to
swephprg.doc ~ 88 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 89 ~ i c
Swiss Ephemeris 2.10 Index
Ephemeris.
Ayanamsha having Galactic Centre at 0 Sagittarius (No. 17) has been changed to a "true"
ayanamsha that has the GC always at 0 Sag.
In addition, the following ayanamshas have been added:
Galactic ayanamsha (Gil Brand) SE_SIDM_GALCENT_RGBRAND
Galactic alignment (Skydram/Mardyks) SE_SIDM_GALALIGN_MARDYKS
Galactic equator (IAU 1958) SE_SIDM_GALEQU_IAU1958
Galactic equator true/modern SE_SIDM_GALEQU_TRUE
Galactic equator in middle of Mula SE_SIDM_GALEQU_MULA
True Mula ayanamsha (Chandra Hari) SE_SIDM_TRUE_MULA
Galactic centre middle Mula (Wilhelm) SE_SIDM_GALCENT_MULA_WILHELM
Aryabhata 522 SE_SIDM_ARYABHATA_522
Babylonian Britton SE_SIDM_BABYL_BRITTON
More information about these ayanamshas is given in the General Documentation of the Swiss
Ephemeris.
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 position is exactly at 180°.
9) Occultation function swe_lun_occult_when_loc():
Function did not correctly detect daytime occurrence with partial occultations (a rare phenomenon).
Some rare occultation events were missed by the function.
As a result of the changes three are very small changes in the timings of the events.
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 apparent very often.
12) User-defined Delta T: For archeoastronomy (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.
The DLL of version 2.03 is not compatible with existing software. In all past versions, the
function names in the DLL were “decorated” (i.e. they had an initial ‘_’ and a final ‘@99’). However,
version 2.03 had the function names “undecorated”. This was a result of the removal of the PASCAL
keyword from the function declarations. Because of this, the DLL was created with the __cdecl calling
convention whereas with the PASCAL keyword it had been created with the __stdcall calling convention.
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.
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:
FAR, PASCAL, and EXP16 macros in function declarations were removed.
swephprg.doc ~ 90 ~ i c
Swiss Ephemeris 2.10 Index
For better backward-compatibility with 2.0x, the behavior of the old Delta T function swe_deltat() has
been modified as follows:
swe_deltat() assumes
SEFLG_JPLEPH, if a JPL file is open;
SEFLG_SWIEPH, otherwise.
Usually, this modification does not result in values different from those provided by former versions SE
2.00 and 2.01.
Note, SEFLG_MOSEPH is never assumed by swe_deltat(). For consistent handling of ephemeris-
dependent Delta T, please use the new Delta T function swe_deltat_ex(). Or if you understand the lunar
tidal acceleration problem, you can use swe_set_tid_acc() to define the value you want.
With version 2.02, software that does not use swe_set_ephe_path() or swe_set_jpl_file() to initialize
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.
Thanks to Thomas Mack for some contributions to this release.
Many thanks to all who have contributed bug reports, in particular Thomas Mack, Bernd Müller, and
Anner van Hardenbroek.
Swiss Ephemeris 2.02 contains the following updates:
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 (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.
swephprg.doc ~ 91 ~ i c
Swiss Ephemeris 2.10 Index
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.
Eclipse and occultation functions:
Searches for non-existing events looped through the whole ephemeris.
With version 2.02, an error is returned instead.
Simplified (less confusing) handling of search flag in functions swe_sol_eclipse_when_glob() and
swe_lun_occult_when_glob() (of course backward compatible).
fixed bug: swe_lun_occult_when_loc() has overlooked some eclipses in polar regions (bug introduced
in Swiss Ephemeris 2.01)
SEFLG_JPLHOR also works in combination with SEFLG_TOPOCTR
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.
swemptab.c was renamed swemptab.h.
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.
A general remark concerning Swiss Ephemeris 2.02:
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.
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 solar 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_fixstar_ut(), you
usually need not worry about Delta T and can avoid any such complications.
Many thanks to those who reported bugs or made valuable suggestions. And I apologize if I forgot to
mention some name.
Note: Still unsolved is the problem with the lunar node with SEFLG_SWIEPH, discovered recently by
swephprg.doc ~ 92 ~ i c
Swiss Ephemeris 2.10 Index
swephprg.doc ~ 93 ~ i c
Swiss Ephemeris 2.10 Index
This is a major release which makes the Swiss Ephemeris fully compatible with JPL Ephemeris
DE430/DE431.
A considerable number of functions were updated. That should not be a problem for existing
applications. However, the following notes must be made:
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 Delta 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.
New functionality and improvements:
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.
unused function swi_str_concat() was removed.
Security update: improved some places in code where buffer overflow could occur (thanks to Paul
Elliott)
APC house system
New function swe_house_name(), returns name of house method
Two new ayanamshas: Suryasiddhanta Revati (359’50 polar longitude) and Citra (180° polar
longitude)
Bug fix in swehel.c, handling of age of observer (thanks to Victor Reijs).
Bug fix in swe_lun_occult_when_loc(): correct handling of starting date (thanks to Olivier Beltrami)
swephprg.doc ~ 94 ~ i c
Swiss Ephemeris 2.10 Index
Improved precision in eclipse calculations: 2 nd and 3rd contact with solar eclipses, penumbral and
partial phases with lunar eclipses.
Bug fix in function swe_sol_eclipse_when_loc().If the local maximum eclipse occurs at sunset or
sunrise, tret[0] now gives the moment when the lower limb of the Sun touches the horizon. This was
not correctly implemented in former versions
Several changes to C code that had caused compiler warnings (as proposed by Torsten Förtsch).
Bug fix in Perl functions swe_house() etc. These functions had crashed with a segmentation violation
if called with the house parameter ‘G’.
Bug fix in Perl function swe_utc_to_jd(), where gregflag had been read from the 4 th instead of the 6th
parameter.
Bug fix in Perl functions to do with date conversion. The default mechanism for gregflag was buggy.
For Hindu astrologers, some more ayanamshas were added that are related to Suryasiddhanta and
Aryabhata and are of historical interest.
Delta T:
Current values were updated.
File sedeltat.txt understands doubles.
For the period before 1633, the new formulae by Espenak and Meeus (2006) are used. These
formulae were derived from Morrison & Stephenson (2004), as used by the Swiss Ephemeris until
version 1.76.02.
The tidal acceleration of the moon contained in LE405/6 was corrected according to
Chapront/Chapront-Touzé/Francou A&A 387 (2002), p. 705.
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_fixstar() does not find sefstars.txt, it will try 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
swephprg.doc ~ 95 ~ i c
Swiss Ephemeris 2.10 Index
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
New features:
Functions for the calculation of heliacal risings and related phenomena, s. chap. 6.15-6.17.
Functions for conversion between UTC and JD (TT/UT1), s. chap. 7.2 and 7.3.
File sedeltat.txt allows the user to update Delta T himself regularly, s. chap. 8.3
Function swe_rise_trans(): twilight calculations (civil, nautical, and astronomical) added
Function swe_version() returns version number of Swiss Ephemeris.
Swiss Ephemeris for Perl programmers using XSUB
Other updates:
Delta T updated (-2009).
Minor bug fixes:
swe_house_pos(): minor bug with Alcabitius houses fixed
swe_sol_eclipse_when_glob(): totality times for eclipses jd2456776 and jd2879654 fixed (tret[4],
tret[5])
The Swiss Ephemeris is now able to read ephemeris files of JPL ephemerides DE200 DE421. If JPL will
not change the file structure in future releases, the Swiss Ephemeris will be able to read them, as
well.
Function swe_fixstar() (and swe_fixstar_ut()) was made slightly more efficient.
Function swe_gauquelin_sector() was extended.
Minor bug fixes.
New features:
Whole Sign houses implemented (W)
swe_house_pos() now also handles Alcabitius house method
function swe_fixstars_mag() provides fixed stars magnitudes
swephprg.doc ~ 96 ~ i c
Swiss Ephemeris 2.10 Index
In September 2006, Pluto was introduced to the minor planet catalogue and given the catalogue
number 134340.
The numerical integrator we use to generate minor planet ephemerides would crash with 134340 Pluto,
because Pluto is one of those planets whose gravitational perturbations are used for the numerical
integration. Instead of fixing the numerical integrator for this special case, we changed the Swiss
Ephemeris functions in such a way that they treat minor planet 134340 Pluto
(ipl=SE_AST_OFFSET+134340) as our main body Pluto (ipl=SE_PLUTO=9). This also results in a slightly
better precision for 134340 Pluto.
Swiss Ephemeris versions prior to 1.71 are not able to do any calculations for minor planet number
134340.
Bug fixed (in swecl.c: swi_bias()): This bug sometimes resulted in a crash, if the DLL was used and the
SEFLG_SPEED was not set. It seems that the error happened only with the DLL and did not appear,
when the Swiss Ephemeris C code was directly linked to the application.
Code to do with (#define NO_MOSHIER) was removed.
Bug fixed in speed calculation for interpolated lunar apsides. With ephemeris positions close to 0 Aries,
speed calculations were completely wrong. E.g. swetest -pc -bj3670817.276275689 (speed = 1448042°
!)
Thanks, once more, to Thomas Mack, for testing the software so well.
Bug fixed in speed calculation for interpolated lunar apsides. Bug could result in program crashes if the
speed flag was set.
swephprg.doc ~ 97 ~ i c
Swiss Ephemeris 2.10 Index
Delta-T updated with new measured values for the years 2003 and 2004, and better estimates for 2005
and 2006.
Bug fixed #define SE_NFICT_ELEM 15
New features:
House system according to Morinus (system ‘M’).
Bug fixed in swe_fixstar(). Declinations between –1° and 0° were wrongly taken as positive.
Thanks to John Smith, Serbia, who found this bug.
Several minor bug fixes and cosmetic code improvements suggested by Thomas Mack, Germany.
swetest.c: options –po and –pn work now.
Sweph.c: speed of mean node and mean lunar apogee were wrong in rare cases, near 0 Aries.
New features:
1. Gauquelin sectors:
swe_houses() etc. can be called with house system character ‘G’ to calculate Gauquelin sector
boundaries.
swe_house_pos() can be called with house system ‘G’ to calculate sector positions of planets.
swe_gauquelin_sector() is new and calculates Gauquelin sector positions with three methods:
without ecl. latitude, with ecl. latitude, from rising and setting.
2. Waldemath Black Moon elements have been added in seorbel.txt (with thanks to Graham Dawson).
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.
6. new Delta T algorithms
New features:
The option –house was added to swetest.c so that swetest.exe can now be used to compute complete
horoscopes in textual mode.
Bug fix: a minor bug in function swe_co_trans was fixed. It never had an effect.
swephprg.doc ~ 98 ~ i c
Swiss Ephemeris 2.10 Index
New features:
1. Elements for hypothetical bodies that move around the Earth (e.g. Selena/White Moon) can be added
to the file seorbel.txt.
2. The software will be able to read asteroid files > 55535.
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)
New features:
1. swe_houses and swe_houses_armc now supports the Alcabitus house system. The function
swe_house_pos() does not yet, because we wanted to release quickly on user request.
New features:
1. Function swe_rise_trans(): Risings and settings also for disc center and without refraction
2. “topocentric” house system added to swe_houses() and other house-related functions
3. Hypothetical planets (seorbel.txt), orbital elements with t terms are possible now (e.g. for Vulcan
according to L.H. Weston)
New features:
1. Universal time functions swe_calc_ut(), swe_fixstar_ut(), etc.
2. Planetary nodes, perihelia, aphelia, focal points.
3. Risings, settings, and meridian transits of the Moon, planets, asteroids, and stars.
4. Horizontal coordinates (azimuth and altitude).
5. Refraction.
6. User-definable orbital elements.
7. Asteroid names can be updated by user.
8. Hitherto missing "Personal Sensitive Points" according to M. Munkasey.
Minor bug fixes:
Astrometric lunar positions (not relevant for astrology; swe_calc(tjd, SE_MOON,
SEFLG_NOABERR)) had a maximum error of about 20 arc sec).
Topocentric lunar positions (not relevant for common astrology): the ellipsoid shape of the Earth
was not correctly implemented. This resulted in an error of 2 - 3 arc seconds. The new precision is
0.2 - 0.3 arc seconds, corresponding to about 500 m in geographic location. This is also the precision
that Nasa's Horizon system provides for the topocentric moon. The planets are much better, of
course.
Solar eclipse functions: The correction of the topocentric moon and another small bug fix lead to
slightly different results of the solar eclipse functions. The improvement is within a few time
seconds.
swephprg.doc ~ 99 ~ i c
Swiss Ephemeris 2.10 Index
The time range of the Swiss Ephemeris has been extended by numerical integration. The Swiss
Ephemeris now covers the period 2 Jan 5401 BCE to 31 Dec 5399 CE. To use the extended time
range, the appropriate ephemeris files must be downloaded.
In the JPL mode and the Moshier mode the time range remains unchanged at 3000 BCE to 3000 CE.
IMPORTANT
Chiron’s ephemeris is now restricted to the time range 650 CE – 4650 CE; for explanations, see
swisseph.doc.
Outside this time range, Swiss Ephemeris returns an error code and a position value 0. You must handle
this situation in your application. There is a similar restriction with Pholus (as with some other
asteroids).
The environment variable SE_EPHE_PATH is now always overriding the call to swe_set_ephe_path() if it
is set and contains a value.
Both the environment variable and the function argument can now contain a list of directory names
where the ephemeris files are looked for. Before this release, they could contain only a single directory
name.
The asteroid subdirectory ephe/asteroid has been split into directories ast0, ast1,... with 1000
asteroid files per directory.
source code is included with the distribution under the new licensing model
the Placalc compatibility API (swepcalc.h) is now documented
There is a new function to compute the equation of time swe_time_equ().
Improvements of ephemerides:
ATTENTION: Ephemeris of 16 Psyche has been wrong so far ! By a mysterious mistake it has been
identical to 3 Juno.
swephprg.doc ~ 100 ~ i c
Swiss Ephemeris 2.10 Index
Ephemerides of Ceres, Pallas, Vesta, Juno, Chiron and Pholus have been reintegrated, with more
recent orbital elements and parameters (e.g. asteroid masses) that are more appropriate to Bowells
database of minor planets elements. The differences are small, though.
Note that the CHIRON ephemeris should not be used before 700 A.D.
Minor bug fix in computation of topocentric planet positions. Nutation has not been correctly
considered in observer’s position. This has led to an error of 1 milliarcsec with the planets and 0.1”
with the moon.
We have inactivated the coordinate transformation from IERS to FK5, because there is still no
generally accepted algorithm. This results in a difference of a few milliarcsec from former releases.
The topocentric flag now also works with the fixed stars. (The effect of diurnal aberration is a few 0.1
arc second.)
Bug fix: The return position of swe_cotrans_sp() has been 0, when the input distance was 0.
About 140 asteroids are on the CD.
New:
A flag bit SEFLG_TOPOCTR allows to compute topocentric planet positions. Before calling swe_calc(),
call swe_set_topo.
swe_house_pos for computation of the house position of a given planet. See description in
SWISSEPH.DOC, Chapter 3.1 ”Geocentric and topocentric positions”. A bug has been fixed that has
sometimes turned up, when the JPL ephemeris was closed. (An error in memory allocation and
freeing.)
Bug fix: swe_cotrans() did not work in former versions.
A bug has been fixed that sometimes occurred in swe_calc() when the user changed iflag between
calls, e.g. the speed flag. The first call for a planet which had been previously computed for the
swephprg.doc ~ 101 ~ i c
Swiss Ephemeris 2.10 Index
same time, but a different iflag, could return incorrect results, if Sun, Moon or Earth had been
computed for a different time in between these two calls.
More asteroids have been added in this release.
A bug has been fixed that has sometimes lead to a floating point exception when the speed flag was
not specified and an unusual sequence of planets was called.
Additional asteroid files have been included.
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.
swe_fixstar() has a better implementation for the search of a specific star. If a number is given, the
non-comment lines in the file fixstars.cat are now counted from 1; they were counted from zero in
earlier releases.
swe_fixstar() now also computes heliocentric and barycentric fixed stars positions. Former versions
Swiss Ephemeris always returned geocentric positions, even if the heliocentric or the barycentric flag
bit was set.
The Galactic Center has been included in fixstars.cat.
Two small bugs were fixed in the implementation of the barycentric Sun and planets. Under unusual
conditions, e.g. if the caller switched from JPL to Swiss Ephemeris or vice-versa, an error of an arc
second appeared with the barycentric sun and 0.001 arc sec with the barycentric planets. However,
this did not touch normal geocentric computations.
Some VB declarations in swedecl.txt contained errors and have been fixed. The VB sample has been
extended to show fixed star and house calculation. This fix is only in 1.03 releases from 29-oct-97 or
later, not in the two 1.03 CDROMs we burned on 28-oct-97.
The computation of the sidereal time is now much easier. The obliquity and nutation are now computed
inside the function. The structure of the function swe_sidtime() has been changed as follows:
/* sidereal time */
double swe_sidtime(double tjd_ut); /* Julian day number, UT */
The old functions swe_sidtime0() has been kept for backward compatibility.
28.61.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 */
swephprg.doc ~ 102 ~ i c
Swiss Ephemeris 2.10 Index
The new pseudo-body SE_ECL_NUT replaces the two separate pseudo-bodies SE_ECLIPTIC and
SE_NUTATION in the function swe_calc().
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;
which glyphs to use;
when a planet is stationary;
how to compute universal time from local time, i.e. what timezone a place is located in;
how to compute progressions, solar returns, composite charts, transit times and a lot more;
what the different calendars (Julian, Gregorian ...) mean and when they apply.
swephprg.doc ~ 103 ~ i c
Swiss Ephemeris 2.10 Index
30. Index
Variables Errors
ARMC ASTEROIDS
ASCMC[...] AVOIDING KOCH HOUSES
ATPRESS EPHEMERIS PATH LENGTH
ATTEMP ERRORS AND RETURN VALUES
AYAN_T0 FATAL ERROR
CUSPS[...] HOUSE CUSPS BEYOND THE POLAR CIRCLE
EPS KOCH HOUSES LIMITATIONS
GREGFLAG SPEEDS OF THE FIXED STARS
HSYS
IFLAG
IPL
METHOD
RSMI
SID_MODE
STAR
swephprg.doc ~ 104 ~ i c
Swiss Ephemeris 2.10 Index
Function Description
1 swe_azalt computes the horizontal coordinates (azimuth and altitude)
2 swe_azalt_rev computes either ecliptical or equatorial coordinates from azimuth
and true altitude
3 swe_calc computes the positions of planets, asteroids, lunar nodes and
apogees
4 swe_calc_ut modified version of swe_calc
5 swe_close releases most resources used by the Swiss Ephemeris
6 swe_cotrans coordinate transformation, from ecliptic to equator or vice-versa
7 swe_cotrans_sp coordinate transformation of position and speed, from ecliptic to
equator or vice-versa
8 swe_date_conversion computes a Julian day from year, month, day, time and checks
whether a date is legal
9 swe_degnorm normalization of any degree number to the range 0 ... 360
1 swe_deltat computes the difference between Universal Time (UT, GMT) and
0 Ephemeris time
1 swe_fixstar computes fixed stars
1
1 swe_fixstar_ut modified version of swe_fixstar
2
1 swe_get_ayanamsa computes the ayanamsha
3
1 swe_get_ayanamsa_ut modified version of swe_get_ayanamsa
4
1 swe_get_planet_name finds a planetary or asteroid name by given number
5
1 swe_get_tid_acc gets the tidal acceleration
6
1 swe_heliacal_ut compute heliacal risings etc. of a planet or star
7
1 swe_house_pos compute the house position of a given body for a given ARMC
8
1 swe_houses calculates houses for a given date and geographic position
9
2 swe_houses_armc computes houses from ARMC (e.g. with the composite horoscope
0 which has no date)
2 swe_houses_ex the same as swe_houses(). Has a parameter, which can be used, if
1 sidereal house positions are wanted
2 swe_jdet_to_utc converts JD (ET/TT) to UTC
2
2 swe_jdut1_to_utc converts JD (UT1) to UTC
3
2 swe_julday conversion from day, month, year, time to Julian date
4
2 swe_lat_to_lmt converts local apparent time (LAT) to local mean time (LMT)
5
2 swe_lmt_to_lat converts local mean time (LMT) to local apparent time (LAT)
6
2 swe_lun_eclipse_how computes the attributes of a lunar eclipse at a given time
7
2 swe_lun_eclipse_when finds the next lunar eclipse
8
2 swe_lun_eclipse_when_ finds the next lunar eclipse observable from a geographic location
9 loc
3 swe_nod_aps computes planetary nodes and apsides: perihelia, aphelia, second
0 focal points of the orbital ellipses
swephprg.doc ~ 105 ~ i c
Swiss Ephemeris 2.10 Index
PlaCalc Description
function
swe_csnorm normalize argument into interval [0..DEG360]
swe_cs2degstr centiseconds -> degrees string
swe_cs2lonlatstr centiseconds -> longitude or latitude string
swe_cs2timestr centiseconds -> time string
swe_csroundsec round second, but at 29.5959 always down
swe_d2l double to long with rounding, no overflow check
swephprg.doc ~ 106 ~ i c
Swiss Ephemeris 2.10 Index
End of SWEPHPRG.DOC
swephprg.doc ~ 107 ~ i c