Commit 029e05f2 authored by timcera's avatar timcera

Initial revision

parents
#AUTHORS
Tim Cera timcera@earthlink.net
initial development
#CHANGES
See also doc/deshist (design history)
2005-06-13:
This diff is collapsed.
#INSTALL
This is a standard distutils install, e.g.:
mkdir workdir
mv xyz-0.1.tar.gz workdir
cd workdir
gzip -cd xyz-0.1.tar.gz | tar xvf -
cd xyz-0.1
python setup.py build
python setup.py install (possibly as root)
include AUTHORS CHANGES COPYING INSTALL MANIFEST.in README VERSION *.py
recursive-include tappy *
recursive-include doc go* *.py *.pdx *.help *.html
recursive-include test *
global-exclude *~ *.pyc *.pyo
#README
See doc/index.html
This diff is collapsed.
/* Copyright 2000, 2001 William McClain
This file is part of Astrolabe.
Astrolabe is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Astrolabe is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Astrolabe; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Check the accuracy of the equinox approximation routines over
4000 years.
Usage:
./check_equinox
Meeus provides formulae for appromimate solstices and equinoxes for
the years -1000 to 3000. How accurate are they over the whole range
of years?
The test below compares the approximate values with the exact
values as determined by the VSOP87d theory.
Result: The maximum differences is 0.0015 days, or about 2.16 minutes. The
maximum occurred for the summer solstice in -408.
*/
#include <cmath>
#include <ctime>
#include <iostream>
#include "astrolabe.hpp"
using std::string;
using std::cout;
using std::endl;
using std::map;
using std::exception;
using astrolabe::calendar::cal_to_jd;
using astrolabe::constants::days_per_second;
using astrolabe::dicts::seasonToString;
using astrolabe::equinox::equinox_approx;
using astrolabe::equinox::equinox_exact;
using astrolabe::Error;
using astrolabe::kAutumn;
using astrolabe::kSpring;
using astrolabe::kSummer;
using astrolabe::kWinter;
using astrolabe::Season;
using astrolabe::util::int_to_string;
using astrolabe::util::load_params;
class SeasonToMonth {
public:
SeasonToMonth() {
class Data {
public:
Data(Season season, int month) : season(season), month(month) {};
Season season;
int month;
};
const Data tbl[] = {
Data(kSpring, 3),
Data(kSummer, 6),
Data(kAutumn, 9),
Data(kWinter, 12)
};
for (const Data *p = tbl; p != tbl + ARRAY_SIZE(tbl); p++)
pmap[p->season] = p->month;
};
const int &operator[](Season season) const {
std::map<Season, int>::const_iterator p = pmap.find(season);
if (p == pmap.end())
throw Error("SeasonToMonth::const int &operator[]: season out of range = " + int_to_string(season));
return p->second;
};
private:
map<Season, int> pmap;
};
const SeasonToMonth seasonToMonth;
void _main() {
const string tab = " ";
load_params();
const time_t t0 = time(NULL);
double delta = 0.0;
for (int yr = -1000; yr < 3000; yr++) {
if (yr % 100 == 0)
cout << yr << endl; // just someting to watch while it runs
for (int season = kSpring; season <= kWinter; season++) {
const double approx_jd = equinox_approx(yr, static_cast<Season>(season));
//
// We use the 21st of the month as our guess, just in case the
// approx_jd is wildly off.
//
const double jd = equinox_exact(cal_to_jd(yr, seasonToMonth[static_cast<Season>(season)], 21), static_cast<Season>(season), days_per_second);
const double val = fabs(approx_jd - jd);
if (val > delta) {
delta = val;
cout << tab << "new maximum " << yr << " " << seasonToString[static_cast<Season>(season)] << " " << delta << endl;
}
}
}
cout << "maximum difference = " << delta << " days" << endl;
cout << "run time = " << difftime(time(NULL), t0) << " seconds" << endl;
}
int main() {
try {
_main();
}
catch(const exception &e) {
cout << e.what() << endl;
}
return 0;
}
/* Copyright 2000, 2001 William McClain
This file is part of Astrolabe.
Astrolabe is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Astrolabe is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Astrolabe; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Test the VSOP87d calculations against the check document.
Usage:
./check_vsop87d vsop87.chk
where "vsop87.chk" has been fetched from the ftp directory referenced
at:
http://cdsweb.u-strasbg.fr/cgi-bin/Cat?VI/81
The program scans through the file and selects those 80 tests which
apply to VSOP87d. We calculate results for each test and compare
with the given value.
Result: all calculations match within 1e-10 radians or au.
*/
#include "astrolabe.hpp"
#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
using std::string;
using std::vector;
using std::ifstream;
using std::list;
using std::cout;
using std::endl;
using std::getline;
using std::exception;
using astrolabe::vPlanets;
using astrolabe::util::load_params;
using astrolabe::vsop87d::VSOP87d;
using astrolabe::Error;
using astrolabe::util::split;
using astrolabe::util::lower;
using astrolabe::util::string_to_double;
using astrolabe::dicts::stringToPlanet;
void report(double computed, double reference, double delta) {
if (fabs(computed - reference) > delta) {
cout << "\tERROR:" << endl;
cout << "\t\tcomputed = " << computed << endl;
cout << "\t\treference = " << reference << endl;
cout << "\t\tdifference = " << fabs(computed - reference) << endl;
}
}
class Refs {
public:
Refs(const string &name, vPlanets planet, double jd, double l, double b, double r) :
name(name),
planet(planet),
jd(jd),
l(l),
b(b),
r(r) {};
const string name;
const vPlanets planet;
const double jd;
const double l;
const double b;
const double r;
};
void usage() {
cout << "Test the VSOP87d calculations against the check document." << endl;
cout << endl;
cout << "Usage:" << endl;
cout << endl;
cout << " ./check_vsop87d vsop87.chk" << endl;
cout << endl;
cout << "where 'vsop87.chk' has been fetched from the ftp directory referenced" << endl;
cout << "at:" << endl;
cout << endl;
cout << " http://cdsweb.u-strasbg.fr/cgi-bin/Cat?VI/81" << endl;
};
void _main(int argc, char *argv[]) {
if (argc != 2) {
usage();
exit(EXIT_FAILURE);
}
//
// a list of tuples of the form (planet_name, julian_day, longitude, latitude, radius)
//
list<Refs> refs;
load_params();
ifstream infile(argv[1]);
if (!infile)
throw Error("_main: unable to open input file = " + string(argv[1]));
string line;
getline(infile, line);
while (infile) {
vector<string> fields = split(line);
if (!fields.empty())
if (fields[0] == "VSOP87D") {
string planet = fields[1];
planet = planet[0] + lower(planet.substr(1));
string jdstr = fields[2];
jdstr = jdstr.substr(2);
const double jd = string_to_double(jdstr);
getline(infile, line);
fields = split(line);
const double l = string_to_double(fields[1]);
const double b = string_to_double(fields[4]);
const double r = string_to_double(fields[7]);
refs.push_back(Refs(planet, stringToPlanet[planet], jd, l, b, r));
}
getline(infile, line);
}
infile.close();
cout << refs.size() << " tests" << endl;
VSOP87d vsop;
for (std::list<Refs>::const_iterator p = refs.begin(); p != refs.end(); p++) {
double L, B, R;
vsop.dimension3(p->jd, p->planet, L, B, R);
cout << p->name << " " << (long)p->jd << " L" << endl;
report(L, p->l, 1e-10);
cout << p->name << " " << (long)p->jd << " B" << endl;
report(B, p->b, 1e-10);
cout << p->name << " " << (long)p->jd << " R" << endl;
report(R, p->r, 1e-10);
cout << endl;
}
}
int main(int argc, char *argv[]) {
try {
_main(argc, argv);
}
catch(const exception &e) {
cout << e.what() << endl;
}
return 0;
}
/* Copyright 2000, 2001 William McClain
This file is part of Astrolabe.
Astrolabe is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Astrolabe is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Astrolabe; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*Create a text version of the VSOP87d database.
Usage:
./create_text_vsop_db > vsop87d.txt # or whatever path/file.
IMPORTANT: A text version of the database is provided with the Astrolabe
package. You need to run this program ONLY if for some reason you want
to recreate that file.
Run the program from a directory containing these files:
VSOP87D.ear
VSOP87D.jup
VSOP87D.mar
VSOP87D.mer
VSOP87D.nep
VSOP87D.sat
VSOP87D.ura
VSOP87D.ven
...which have been fetched from the ftp directory referenced at:
http://cdsweb.u-strasbg.fr/cgi-bin/Cat?VI/81
The program will read each file, select the data required and combine all
of them into a format expected by the Astrolabe vsop87d module.
Results are written to standard output; redirect them into a file in your
data directory and enter that path/file name into the astrolabe_params.txt
file as the value of "vsop87d_text_path".
*/
/*
#
# Here are file format notes from the original VSOP distribution.
#
#HEADER RECORD
#=============
#Specifications :
#- iv : code of VSOP87 version integer i1 col.18
#- bo : name of body character a7 col.23-29
#- ic : index of coordinate integer i1 col.42
#- it : degree alpha of time variable T integer i1 col.60
#- in : number of terms of series integer i7 col.61-67
#
#The code iv of the version is :
#iv = 4 for the version VSOP87D
#
#The names bo of the bodies are :
#MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE, SUN,
#and EMB for the Earth-Moon Barycenter.
#
#The index ic of the coordinates are :
#- for the spherical coordinates (versions B,D) :
# 1 : Longitude
# 2 : Latitude
# 3 : Radius
#
#The degree alpha of the time variable is equal to :
#0 for periodic series, 1 to 5 for Poisson series.
#TERM RECORD
#===========
#Specifications :
#iv : code of VSOP87 version integer i1 col.02
#ic : index of coordinate integer i1 col.04
#it : degree alpha of time variable T integer i1 col.05
#n : rank of the term in a serie integer i5 col.06-10
#A : amplitude A real dp f18.11 col.80-97
#B : phase B real dp f14.11 col.98-111
#C : frequency C read dp f20.11 col.112-131
*/
#include "astrolabe.hpp"
#include <cassert>
#include <fstream>
#include <iostream>
using std::string;
using std::vector;
using std::getline;
using std::ifstream;
using std::cout;
using std::endl;
using std::exception;
using astrolabe::util::string_to_int;
using astrolabe::util::strip;
using astrolabe::util::upper;
using astrolabe::util::lower;
using astrolabe::Error;
const string _planets[] = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"};
const VECTOR(planets, string);
const string _coords[] = {"L","B","R"};
const VECTOR(coords, string);
void _main() {
// each planet file...
for (std::vector<string>::const_iterator p = planets.begin(); p != planets.end(); p++) {
const string planet = *p;
const string fname = "VSOP87D." + lower(planet.substr(0,3));
ifstream infile(fname.c_str());
if (!infile)
throw Error("_main: cannot open file = " + fname);
string line;
getline(infile, line);
// header records...
while (infile) {
assert(line[17] == '4'); // model "d"
assert(strip(line.substr(22 ,7)) == upper(planet)); // planet name
const int ic = string_to_int(line.substr(41, 1)); // coord type
assert(ic >= 0 && ic <= 2);
const int it = string_to_int(line.substr(59, 1)); // time degree
const int nt = string_to_int(line.substr(60, 7)); // number of terms
cout << planet << " " << coords[ic - 1] << " " << it << " " << nt << endl;
// term records
for (int i = 0; i < nt; i++) {
getline(infile, line);
assert(line[1] == '4'); // model "d"
const int ict = string_to_int(line.substr(3, 1)); // coord type
assert(ict == ic);
const int itt = string_to_int(line.substr(4, 1)); // time degree
assert(itt == it);
const string A = strip(line.substr(79, 18));
const string B = strip(line.substr(97, 14));
const string C = strip(line.substr(111, 20));
cout << A << " " << B << " " << C << endl;
}
getline(infile, line);
}
infile.close();
}
//
// that's all
//
}
int main(int argc, char *argv[]) {
try {
_main();
}
catch(const exception &e) {
cout << e.what() << endl;
}
return 0;
}
This diff is collapsed.
LIB = ../../lib/cpp
CXXFLAGS = -Wall -I../../lib/cpp -O
objects = \
$(LIB)/calendar.o \
$(LIB)/dicts.o \
$(LIB)/dynamical.o \
$(LIB)/elp2000.o \
$(LIB)/equinox.o \
$(LIB)/globals.o \
$(LIB)/nutation.o \
$(LIB)/riseset.o \
$(LIB)/sun.o \
$(LIB)/util.o \
$(LIB)/vsop87d.o
apps = \
check_equinox \
check_vsop87d \
create_text_vsop_db \
cronus \
solstice \
time_vsop_db_loads \
validate_meeus
check_vsop87d : check_vsop87d.o
check_equinox : check_equinox.o
create_text_vsop_db : create_text_vsop_db.o
cronus : cronus.o
solstice : solstice.o
time_vsop_db_loads : time_vsop_db_loads.o
validate_meeus : validate_meeus.o
$(objects) : $(LIB)/astrolabe.hpp
$(apps) : $(LIB)/astrolabe.a($(objects)) $(LIB)/astrolabe.hpp
g++ -o $@ $@.o -Wall -O -I$(LIB) $(LIB)/astrolabe.a
.PHONY : all
all : $(apps)
/* Copyright 2000, 2001 William McClain
This file is part of Astrolabe.
Astrolabe is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Astrolabe is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Astrolabe; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Usage:
./solstice start_year [stop_year]
Displays the instants of equinoxes and solstices for a range of years.
Times are accurate to one second.
The arguments must be integers.
If one argument is given, the display is for that year.
If two arguments are given, the display is for that range of
years.
*/
#include "astrolabe.hpp"
#include <cstdlib>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
using std::exception;
using astrolabe::calendar::lt_to_str;
using astrolabe::calendar::ut_to_lt;
using astrolabe::constants::days_per_second;
using astrolabe::dicts::seasonToString;
using astrolabe::dynamical::dt_to_ut;
using astrolabe::equinox::equinox_approx;
using astrolabe::equinox::equinox_exact;
using astrolabe::kSpring;
using astrolabe::kWinter;
using astrolabe::Season;
using astrolabe::util::load_params;
const string tab = " ";
void usage() {
cout << "Usage:" << endl;
cout << endl;
cout << " ./solstice start_year [stop_year]" << endl;
cout << endl;
cout << "Displays the instants of equinoxes and solstices for a range of years." << endl;
cout << "Times are accurate to one second." << endl;
cout << endl;
cout << "The arguments must be integers." << endl;
cout << endl;
cout << "If one argument is given, the display is for that year." << endl;
cout << endl;
cout << "If two arguments are given, the display is for that range of" << endl;
cout << "years." << endl;
}
void _main(int argc, char *argv[]) {
int start, stop;
if (argc < 2) {
usage();
exit(EXIT_FAILURE);
}
else if (argc < 3) {
start = atoi(argv[1]);
stop = start;
}
else if (argc < 4) {
start = atoi(argv[1]);
stop = atoi(argv[2]);
}
else {
usage();
exit(EXIT_FAILURE);
}
load_params();
for (int yr = start; yr <= stop; yr++) {
cout << yr << endl;
for (int season = kSpring; season <= kWinter; season++) {
const double approx_jd = equinox_approx(yr, static_cast<Season>(season));
const double jd = equinox_exact(approx_jd, static_cast<Season>(season), days_per_second);
const double ut = dt_to_ut(jd);
double lt;
string zone;
ut_to_lt(ut, lt, zone);
cout << tab << seasonToString[static_cast<Season>(season)] << " " << lt_to_str(lt, zone) << endl;
}
}
}
int main(int argc, char *argv[]) {
try {
_main(argc, argv);
}
catch(const exception &e) {
cout << e.what() << endl;
}
return 0;
}
/* Copyright 2000, 2001 William McClain
This file is part of Astrolabe.
Astrolabe is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Astrolabe is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. </