Merge lp:~registry/stellarium/socis2015-de430 into lp:stellarium

Proposed by gzotti
Status: Merged
Merged at revision: 8132
Proposed branch: lp:~registry/stellarium/socis2015-de430
Merge into: lp:stellarium
Diff against target: 3100 lines (+2424/-282)
24 files modified
.bzrignore (+4/-1)
data/default_config.ini.cmake (+4/-0)
src/CMakeLists.txt (+12/-2)
src/StelMainView.cpp (+3/-0)
src/core/StelCore.cpp (+80/-0)
src/core/StelCore.hpp (+16/-0)
src/core/modules/SolarSystem.cpp (+1/-1)
src/core/planetsephems/EphemWrapper.cpp (+400/-0)
src/core/planetsephems/EphemWrapper.hpp (+92/-0)
src/core/planetsephems/README.txt (+54/-0)
src/core/planetsephems/de430.cpp (+120/-0)
src/core/planetsephems/de430.hpp (+44/-0)
src/core/planetsephems/de431.cpp (+119/-0)
src/core/planetsephems/de431.hpp (+44/-0)
src/core/planetsephems/jpl_int.h (+106/-0)
src/core/planetsephems/jpleph.cpp (+978/-0)
src/core/planetsephems/jpleph.h (+117/-0)
src/core/planetsephems/pluto.h (+11/-0)
src/core/planetsephems/stellplanet.c (+0/-136)
src/core/planetsephems/stellplanet.h (+0/-77)
src/core/planetsephems/vsop87.h (+0/-9)
src/gui/ConfigurationDialog.cpp (+120/-40)
src/gui/ConfigurationDialog.hpp (+18/-4)
src/gui/configurationDialog.ui (+81/-12)
To merge this branch: bzr merge lp:~registry/stellarium/socis2015-de430
Reviewer Review Type Date Requested Status
Alexander Wolf Approve
Review via email: mp+282847@code.launchpad.net

Description of the change

A nice new feature for (pre)historical sky simulation or people needing extra accuracy. Thanks to support by ESA SoCiS2015 we have now optional access to precomputed planetary positions from NASA/JPL.

DE430&431 currently require manual download of data files. If files are available already, it is possible to use files from configured directory. Downloading should be integrated to the coming download manager.

More info in the branch description.

To post a comment you must log in.
7760. By gzotti

cleanup a bit

Revision history for this message
Alexander Wolf (alexwolf) wrote :

I think GUI for VSOP/DE should be changed - using checkbox and chooser of the file for ephemeris files instead buttons seems better, IMHO.

Revision history for this message
Alexander Wolf (alexwolf) :
review: Approve
Revision history for this message
gzotti (georg-zotti) wrote :

I don't want to add a file chooser here. I describe how to install files in the guide, and with the download manager on its way this will be replaced anyway soon.
Maybe changing to checkbox is more like the rest of GUI, I will do that.

7761. By gzotti

replaced DE43x buttons by checkboxes, some more cleanup

7762. By gzotti

removed unneeded manifest file

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2016-01-10 23:15:27 +0000
3+++ .bzrignore 2016-01-16 17:00:50 +0000
4@@ -1,20 +1,22 @@
5 builds
6+build
7 installers
8 .DS_Store
9 CMakeLists.txt.user
10 Stellarium.bat
11 stellarium.iss
12 stellarium-patch.iss
13+stellarium.exe.manifest
14 ./doc/qt.tag
15 ./locale
16 ./util/locations-editor/Makefile
17 ./util/locations-editor/locations-editor
18 ./util/locations-editor/locations-editor.pro.user
19 ./util/copy-translations.bat
20-build
21 ./plugins/Observability/doc
22 default_config.ini
23 updates.json
24+data/Info.plist
25 guide/*.aux
26 guide/*.log
27 guide/*.idx
28@@ -24,4 +26,5 @@
29 guide/*.xml
30 guide/*.synctex.gz
31 * - Kopie.*
32+*.~
33
34
35=== modified file 'data/default_config.ini.cmake'
36--- data/default_config.ini.cmake 2015-12-07 23:46:23 +0000
37+++ data/default_config.ini.cmake 2016-01-16 17:00:50 +0000
38@@ -264,6 +264,10 @@
39 planet_magnitude_limit = 6.5
40 flag_nebula_magnitude_limit = false
41 nebula_magnitude_limit = 8.5
42+flag_use_de430 = false
43+flag_use_de431 = false
44+de430_path = ""
45+de431_path = ""
46
47 [init_location]
48 location = auto
49
50=== modified file 'src/CMakeLists.txt'
51--- src/CMakeLists.txt 2016-01-11 16:48:05 +0000
52+++ src/CMakeLists.txt 2016-01-16 17:00:50 +0000
53@@ -178,12 +178,22 @@
54 core/planetsephems/precession.h
55 core/planetsephems/sidereal_time.c
56 core/planetsephems/sidereal_time.h
57- core/planetsephems/stellplanet.c
58- core/planetsephems/stellplanet.h
59+ #core/planetsephems/stellplanet.c # replaced by EphemWrapper during de430 work
60+ #core/planetsephems/stellplanet.h
61+ core/planetsephems/jpl_int.h
62+ core/planetsephems/jpleph.h
63+ core/planetsephems/jpleph.cpp
64+ core/planetsephems/EphemWrapper.cpp
65+ core/planetsephems/EphemWrapper.hpp
66+
67 core/planetsephems/tass17.c
68 core/planetsephems/tass17.h
69 core/planetsephems/vsop87.c
70 core/planetsephems/vsop87.h
71+ core/planetsephems/de430.cpp
72+ core/planetsephems/de430.hpp
73+ core/planetsephems/de431.cpp
74+ core/planetsephems/de431.hpp
75
76 core/modules/Atmosphere.cpp
77 core/modules/Atmosphere.hpp
78
79=== modified file 'src/StelMainView.cpp'
80--- src/StelMainView.cpp 2015-11-22 00:16:28 +0000
81+++ src/StelMainView.cpp 2016-01-16 17:00:50 +0000
82@@ -620,6 +620,9 @@
83 // plugins, because the gui create the QActions needed by some plugins.
84 StelApp::getInstance().initPlugIns();
85
86+ // activate DE430/431
87+ StelApp::getInstance().getCore()->initEphemeridesFunctions();
88+
89 // The script manager can only be fully initialized after the plugins have loaded.
90 StelApp::getInstance().initScriptMgr();
91
92
93=== modified file 'src/core/StelCore.cpp'
94--- src/core/StelCore.cpp 2016-01-06 15:10:45 +0000
95+++ src/core/StelCore.cpp 2016-01-16 17:00:50 +0000
96@@ -37,12 +37,17 @@
97 #include "LandscapeMgr.hpp"
98 #include "StelTranslator.hpp"
99 #include "StelActionMgr.hpp"
100+#include "StelFileMgr.hpp"
101+#include "EphemWrapper.hpp"
102 #include "precession.h"
103
104 #include <QSettings>
105 #include <QDebug>
106 #include <QMetaEnum>
107
108+#include <iostream>
109+#include <fstream>
110+
111 // Init statics transfo matrices
112 // See vsop87.doc:
113 const Mat4d StelCore::matJ2000ToVsop87(Mat4d::xrotation(-23.4392803055555555556*(M_PI/180)) * Mat4d::zrotation(0.0000275*(M_PI/180)));
114@@ -73,6 +78,10 @@
115 , jdOfLastJDUpdate(0.)
116 , deltaTCustomNDot(-26.0)
117 , deltaTCustomYear(1820.0)
118+ , de430Available(false)
119+ , de431Available(false)
120+ , de430Active(false)
121+ , de431Active(false)
122 {
123 toneReproducer = new StelToneReproducer();
124
125@@ -1928,3 +1937,74 @@
126 {
127 return 2000.0 + (getJD() - 2451545.0)/365.25;
128 }
129+
130+// DE430/DE431 handling
131+
132+bool StelCore::de430IsAvailable()
133+{
134+ return de430Available;
135+}
136+
137+bool StelCore::de431IsAvailable()
138+{
139+ return de431Available;
140+}
141+
142+bool StelCore::de430IsActive()
143+{
144+ return de430Active;
145+}
146+
147+bool StelCore::de431IsActive()
148+{
149+ return de431Active;
150+}
151+
152+void StelCore::setDe430Active(bool status)
153+{
154+ de430Active = de430Available && status;
155+}
156+
157+void StelCore::setDe431Active(bool status)
158+{
159+ de431Active = de431Available && status;
160+}
161+
162+void StelCore::initEphemeridesFunctions()
163+{
164+ QSettings* conf = StelApp::getInstance().getSettings();
165+
166+ QString de430ConfigPath = conf->value("astro/de430_path").toString();
167+ QString de431ConfigPath = conf->value("astro/de431_path").toString();
168+
169+ QString de430FilePath;
170+ QString de431FilePath;
171+
172+ //<-- DE430 -->
173+ if(de430ConfigPath.remove(QChar('"')).isEmpty())
174+ de430FilePath = StelFileMgr::findFile("ephem/" + QString(DE430_FILENAME), StelFileMgr::File);
175+ else
176+ de430FilePath = StelFileMgr::findFile(de430ConfigPath, StelFileMgr::File);
177+
178+ de430Available=!de430FilePath.isEmpty();
179+ if(de430Available)
180+ {
181+ qDebug() << "DE430 at: " << de430FilePath;
182+ EphemWrapper::init_de430(de430FilePath.toStdString().c_str());
183+ }
184+ setDe430Active(de430Available && conf->value("astro/flag_use_de430").toBool());
185+
186+ //<-- DE431 -->
187+ if(de431ConfigPath.remove(QChar('"')).isEmpty())
188+ de431FilePath = StelFileMgr::findFile("ephem/" + QString(DE431_FILENAME), StelFileMgr::File);
189+ else
190+ de431FilePath = StelFileMgr::findFile(de431ConfigPath, StelFileMgr::File);
191+
192+ de431Available=!de431FilePath.isEmpty();
193+ if(de431Available)
194+ {
195+ qDebug() << "DE431 at: " << de431FilePath;
196+ EphemWrapper::init_de431(de431FilePath.toStdString().c_str());
197+ }
198+ setDe431Active(de431Available && conf->value("astro/flag_use_de431").toBool());
199+}
200
201=== modified file 'src/core/StelCore.hpp'
202--- src/core/StelCore.hpp 2015-12-29 12:14:13 +0000
203+++ src/core/StelCore.hpp 2016-01-16 17:00:50 +0000
204@@ -584,6 +584,16 @@
205 //! Get coefficients for custom equation for calculation of Delta-T
206 Vec3f getDeltaTCustomEquationCoefficients() const { return deltaTCustomEquationCoeff; }
207
208+ //! initialize ephemerides calculation functions
209+ void initEphemeridesFunctions();
210+
211+ bool de430IsAvailable(); //!< true if DE430 ephemeris file has been found
212+ bool de431IsAvailable(); //!< true if DE431 ephemeris file has been found
213+ bool de430IsActive(); //!< true if DE430 ephemeris is in use
214+ bool de431IsActive(); //!< true if DE431 ephemeris is in use
215+ void setDe430Active(bool status); //!< switch DE430 use to @param status (if de430IsAvailable()) DE430 is only used if date is within range of DE430.
216+ void setDe431Active(bool status); //!< switch DE431 use to @param status (if de431IsAvailable()). DE431 is only used if DE430 is not used and the date is within range of DE431.
217+
218 signals:
219 //! This signal is emitted when the observer location has changed.
220 void locationChanged(StelLocation);
221@@ -653,6 +663,12 @@
222 float deltaTCustomNDot;
223 float deltaTCustomYear;
224
225+ // Variables for DE430/431 ephem calculation
226+ bool de430Available; // ephem file found
227+ bool de431Available; // ephem file found
228+ bool de430Active; // available and user-activated.
229+ bool de431Active; // available and user-activated.
230+
231 };
232
233 #endif // _STELCORE_HPP_
234
235=== modified file 'src/core/modules/SolarSystem.cpp'
236--- src/core/modules/SolarSystem.cpp 2015-12-09 11:01:21 +0000
237+++ src/core/modules/SolarSystem.cpp 2016-01-16 17:00:50 +0000
238@@ -21,7 +21,7 @@
239
240 #include "SolarSystem.hpp"
241 #include "StelTexture.hpp"
242-#include "stellplanet.h"
243+#include "EphemWrapper.hpp"
244 #include "Orbit.hpp"
245
246 #include "StelProjector.hpp"
247
248=== added file 'src/core/planetsephems/EphemWrapper.cpp'
249--- src/core/planetsephems/EphemWrapper.cpp 1970-01-01 00:00:00 +0000
250+++ src/core/planetsephems/EphemWrapper.cpp 2016-01-16 17:00:50 +0000
251@@ -0,0 +1,400 @@
252+/*
253+Copyright (C) 2003 Fabien Chereau
254+Copyright (C) 2015 Holger Niessner
255+Copyright (C) 2015 Georg Zotti
256+
257+This program is free software; you can redistribute it and/or modify
258+it under the terms of the GNU Library General Public License as published by
259+the Free Software Foundation; either version 2 of the License, or
260+(at your option) any later version.
261+
262+This program is distributed in the hope that it will be useful,
263+but WITHOUT ANY WARRANTY; without even the implied warranty of
264+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
265+GNU General Public License for more details.
266+
267+You should have received a copy of the GNU General Public License
268+along with this program; if not, write to the Free Software
269+Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
270+*/
271+
272+#include "EphemWrapper.hpp"
273+#include "StelApp.hpp"
274+#include "StelCore.hpp"
275+#include "vsop87.h"
276+#include "elp82b.h"
277+#include "marssat.h"
278+#include "l1.h"
279+#include "tass17.h"
280+#include "gust86.h"
281+#include "de431.hpp"
282+#include "de430.hpp"
283+#include "pluto.h"
284+
285+#define EPHEM_MERCURY_ID 0
286+#define EPHEM_VENUS_ID 1
287+#define EPHEM_EMB_ID 2
288+#define EPHEM_MARS_ID 3
289+#define EPHEM_JUPITER_ID 4
290+#define EPHEM_SATURN_ID 5
291+#define EPHEM_URANUS_ID 6
292+#define EPHEM_NEPTUNE_ID 7
293+#define EPHEM_PLUTO_ID 8
294+
295+// GZ No idea what IMD stands for?
296+//#define EPHEM_IMD_EARTH_ID 2
297+#define EPHEM_JPL_EARTH_ID 3
298+#define EPHEM_JPL_PLUTO_ID 9
299+#define EPHEM_JPL_MOON_ID 10
300+#define EPHEM_JPL_SUN_ID 11
301+
302+/** JPL PLANET ID LIST
303+** 1 = mercury 8 = neptune **
304+** 2 = venus 9 = pluto **
305+** 3 = earth 10 = moon **
306+** 4 = mars 11 = sun **
307+** 5 = jupiter 12 = solar-system barycenter **
308+** 6 = saturn 13 = earth-moon barycenter **
309+** 7 = uranus
310+**/
311+
312+void EphemWrapper::init_de430(const char* filepath)
313+{
314+ InitDE430(filepath);
315+}
316+
317+void EphemWrapper::init_de431(const char* filepath)
318+{
319+ InitDE431(filepath);
320+}
321+
322+bool jd_fits_de431(const double jd)
323+{
324+ //Correct limits found via jpl_get_double(). Limits hardcoded to avoid calls each time.
325+ //return !(jd < -3027215.5 || jd > 7930192.5);
326+ //This limits inside those where sun can jump between ecliptic of date and ecliptic2000.
327+ // We lose a month in -13000 and a few months in +17000, this should not matter.
328+ return ((jd > -3027188.25 ) && (jd < 7930056.87916));
329+}
330+
331+bool jd_fits_de430(const double jd)
332+{
333+ //return !(jd < 2287184.5 || jd > 2688974.5);
334+ //return !(jd < 2287184.5 || jd > 2688976.5);
335+ return ((jd > 2287184.5) && (jd < 2688976.5));
336+}
337+
338+bool use_de430(const double jd)
339+{
340+ return StelApp::getInstance().getCore()->de430IsActive() &&
341+ jd_fits_de430(jd);
342+}
343+
344+bool use_de431(const double jd)
345+{
346+ return StelApp::getInstance().getCore()->de431IsActive() &&
347+ jd_fits_de431(jd);
348+}
349+
350+// planet_id is ONLY one of the #defined values 0..8 above.
351+void get_planet_helio_coordsv(const double jd, double xyz[3], const int planet_id)
352+{
353+ bool deOk=false;
354+ if(!std::isfinite(jd))
355+ {
356+ qDebug() << "get_planet_helio_coordsv(): SKIPPED CoordCalc, jd is infinite/nan: " << jd;
357+ return;
358+ }
359+
360+ if(use_de430(jd))
361+ {
362+ deOk=GetDe430Coor(jd, planet_id + 1, xyz);
363+ }
364+ else if(use_de431(jd))
365+ {
366+ deOk=GetDe431Coor(jd, planet_id + 1, xyz);
367+ }
368+ if (!deOk) //VSOP87 as fallback
369+ {
370+ GetVsop87Coor(jd, planet_id, xyz);
371+ }
372+}
373+
374+// Osculating positions for time JDE in elements for JDE0, if possible by the theory used (e.g. VSOP87).
375+// For ephemerides like DE4xx, JDE0 is irrelevant.
376+void get_planet_helio_osculating_coordsv(double jd0, double jd, double xyz[3], int planet_id)
377+{
378+ bool deOk=false;
379+ if(!(std::isfinite(jd) && std::isfinite(jd0)))
380+ {
381+ qDebug() << "get_planet_helio_osculating_coordsv(): SKIPPED CoordCalc, jd0 or jd is infinite/nan. jd0:" << jd0 << "jd: "<< jd;
382+ return;
383+ }
384+
385+ if(use_de430(jd))
386+ {
387+ deOk=GetDe430Coor(jd, planet_id + 1, xyz);
388+ }
389+ else if(use_de431(jd))
390+ {
391+ deOk=GetDe431Coor(jd, planet_id + 1, xyz);
392+ }
393+ if (!deOk) //VSOP87 as fallback
394+ {
395+ GetVsop87OsculatingCoor(jd0, jd, planet_id, xyz);
396+ }
397+}
398+
399+/* Chapter 31 Pg 206-207 Equ 31.1 31.2, 31.3 using VSOP 87
400+ * Calculate Pluto's rectangular heliocentric ecliptical coordinates
401+ * for given Julian Day. Values are in AU.
402+ * params : Julian day, rect coords */
403+
404+void get_pluto_helio_coordsv(double jd,double xyz[3], void* unused)
405+{
406+ Q_UNUSED(unused);
407+ bool deOk=false;
408+ if(!std::isfinite(jd))
409+ {
410+ qDebug() << "get_pluto_helio_coordsv(): SKIPPED PlutoCoordCalc, jd is infinite/nan:" << jd;
411+ return;
412+ }
413+
414+ if(use_de430(jd))
415+ {
416+ deOk=GetDe430Coor(jd, EPHEM_JPL_PLUTO_ID, xyz);
417+ }
418+ else if(use_de431(jd))
419+ {
420+ deOk=GetDe431Coor(jd, EPHEM_JPL_PLUTO_ID, xyz);
421+ }
422+ if (!deOk) // fallback to previous solution
423+ {
424+ get_pluto_helio_coords(jd, &xyz[0], &xyz[1], &xyz[2]);
425+ }
426+}
427+
428+/* Return 0 for the sun */
429+void get_sun_helio_coordsv(double jd,double xyz[3], void* unused)
430+{
431+ xyz[0]=0.; xyz[1]=0.; xyz[2]=0.;
432+}
433+
434+void get_mercury_helio_coordsv(double jd,double xyz[3], void* unused)
435+{
436+ get_planet_helio_coordsv(jd, xyz, EPHEM_MERCURY_ID);
437+}
438+void get_venus_helio_coordsv(double jd,double xyz[3], void* unused)
439+{
440+ get_planet_helio_coordsv(jd, xyz, EPHEM_VENUS_ID);
441+}
442+
443+void get_earth_helio_coordsv(const double jd,double xyz[3], void* unused)
444+{
445+ bool deOk=false;
446+ if(!std::isfinite(jd))
447+ {
448+ qDebug() << "get_earth_helio_coordsv(): SKIPPED EarthCoordCalc, jd is infinite/nan:" << jd;
449+ return;
450+ }
451+
452+ if(use_de430(jd))
453+ {
454+ deOk=GetDe430Coor(jd, EPHEM_JPL_EARTH_ID, xyz);
455+ }
456+ else if(use_de431(jd))
457+ {
458+ deOk=GetDe431Coor(jd, EPHEM_JPL_EARTH_ID, xyz);
459+ }
460+ if (!deOk) //VSOP87 as fallback
461+ {
462+ double moon[3];
463+ GetVsop87Coor(jd,EPHEM_EMB_ID,xyz);
464+ GetElp82bCoor(jd,moon);
465+ /* Earth != EMB:
466+ 0.0121505677733761 = mu_m/(1+mu_m),
467+ mu_m = mass(moon)/mass(earth) = 0.01230002 */
468+ xyz[0] -= 0.0121505677733761 * moon[0];
469+ xyz[1] -= 0.0121505677733761 * moon[1];
470+ xyz[2] -= 0.0121505677733761 * moon[2];
471+ }
472+}
473+
474+void get_mars_helio_coordsv(double jd,double xyz[3], void* unused)
475+{
476+ get_planet_helio_coordsv(jd, xyz, EPHEM_MARS_ID);
477+}
478+
479+void get_jupiter_helio_coordsv(double jd,double xyz[3], void* unused)
480+{
481+ get_planet_helio_coordsv(jd, xyz, EPHEM_JUPITER_ID);
482+}
483+
484+void get_saturn_helio_coordsv(double jd,double xyz[3], void* unused)
485+{
486+ get_planet_helio_coordsv(jd, xyz, EPHEM_SATURN_ID);
487+}
488+
489+void get_uranus_helio_coordsv(double jd,double xyz[3], void* unused)
490+{
491+ get_planet_helio_coordsv(jd, xyz, EPHEM_URANUS_ID);
492+}
493+
494+void get_neptune_helio_coordsv(double jd,double xyz[3], void* unused)
495+{
496+ get_planet_helio_coordsv(jd, xyz, EPHEM_NEPTUNE_ID);
497+}
498+
499+void get_mercury_helio_osculating_coords(double jd0,double jd,double xyz[3])
500+{
501+ get_planet_helio_osculating_coordsv(jd0, jd, xyz, EPHEM_MERCURY_ID);
502+}
503+
504+void get_venus_helio_osculating_coords(double jd0,double jd,double xyz[3])
505+{
506+ get_planet_helio_osculating_coordsv(jd0, jd, xyz, EPHEM_VENUS_ID);
507+}
508+
509+void get_earth_helio_osculating_coords(double jd0,double jd,double xyz[3])
510+{
511+ get_planet_helio_osculating_coordsv(jd0, jd, xyz, EPHEM_EMB_ID);
512+}
513+
514+void get_mars_helio_osculating_coords(double jd0,double jd,double xyz[3])
515+{
516+ get_planet_helio_osculating_coordsv(jd0, jd, xyz, EPHEM_MARS_ID);
517+}
518+
519+void get_jupiter_helio_osculating_coords(double jd0,double jd,double xyz[3])
520+{
521+ get_planet_helio_osculating_coordsv(jd0, jd, xyz, EPHEM_JUPITER_ID);
522+}
523+
524+void get_saturn_helio_osculating_coords(double jd0,double jd,double xyz[3])
525+{
526+ get_planet_helio_osculating_coordsv(jd0, jd, xyz, EPHEM_SATURN_ID);
527+}
528+
529+void get_uranus_helio_osculating_coords(double jd0,double jd,double xyz[3])
530+{
531+ get_planet_helio_osculating_coordsv(jd0, jd, xyz, EPHEM_URANUS_ID);
532+}
533+
534+void get_neptune_helio_osculating_coords(double jd0,double jd,double xyz[3])
535+{
536+ get_planet_helio_osculating_coordsv(jd0, jd, xyz, EPHEM_NEPTUNE_ID);
537+}
538+
539+/* Calculate the rectangular geocentric lunar coordinates to the inertial mean
540+ * ecliptic and equinox of J2000.
541+ * The geocentric coordinates returned are in units of AU.
542+ * This function is based upon the Lunar Solution ELP2000-82B by
543+ * Michelle Chapront-Touze and Jean Chapront of the Bureau des Longitudes,
544+ * Paris. ELP 2000-82B theory
545+ * param jd Julian day, rect pos */
546+void get_lunar_parent_coordsv(double jde,double xyz[3], void* unused)
547+{
548+ bool deOk=false;
549+ if(use_de430(jde))
550+ deOk=GetDe430Coor(jde, EPHEM_JPL_MOON_ID, xyz, EPHEM_JPL_EARTH_ID);
551+ else if(use_de431(jde))
552+ deOk=GetDe431Coor(jde, EPHEM_JPL_MOON_ID, xyz, EPHEM_JPL_EARTH_ID);
553+ if (!deOk) // fallback...
554+ GetElp82bCoor(jde,xyz);
555+}
556+
557+void get_phobos_parent_coordsv(double jd,double xyz[3], void* unused)
558+{
559+ GetMarsSatCoor(jd,MARS_SAT_PHOBOS,xyz);
560+}
561+
562+void get_deimos_parent_coordsv(double jd,double xyz[3], void* unused)
563+{
564+ GetMarsSatCoor(jd,MARS_SAT_DEIMOS,xyz);
565+}
566+
567+void get_io_parent_coordsv(double jd,double xyz[3], void* unused)
568+{
569+ GetL1Coor(jd,L1_IO,xyz);
570+}
571+
572+void get_europa_parent_coordsv(double jd,double xyz[3], void* unused)
573+{
574+ GetL1Coor(jd,L1_EUROPA,xyz);
575+}
576+
577+void get_ganymede_parent_coordsv(double jd,double xyz[3], void* unused)
578+{
579+ GetL1Coor(jd,L1_GANYMEDE,xyz);
580+}
581+
582+void get_callisto_parent_coordsv(double jd,double xyz[3], void* unused)
583+{
584+ GetL1Coor(jd,L1_CALLISTO,xyz);
585+}
586+
587+void get_mimas_parent_coordsv(double jd,double xyz[3], void* unused)
588+{
589+ GetTass17Coor(jd,TASS17_MIMAS,xyz);
590+}
591+
592+void get_enceladus_parent_coordsv(double jd,double xyz[3], void* unused)
593+{
594+ GetTass17Coor(jd,TASS17_ENCELADUS,xyz);
595+}
596+
597+void get_tethys_parent_coordsv(double jd,double xyz[3], void* unused)
598+{
599+ GetTass17Coor(jd,TASS17_TETHYS,xyz);
600+}
601+
602+void get_dione_parent_coordsv(double jd,double xyz[3], void* unused)
603+{
604+ GetTass17Coor(jd,TASS17_DIONE,xyz);
605+}
606+
607+void get_rhea_parent_coordsv(double jd,double xyz[3], void* unused)
608+{
609+ GetTass17Coor(jd,TASS17_RHEA,xyz);
610+}
611+
612+void get_titan_parent_coordsv(double jd,double xyz[3], void* unused)
613+{
614+ GetTass17Coor(jd,TASS17_TITAN,xyz);
615+}
616+
617+void get_hyperion_parent_coordsv(double jd,double xyz[3], void* unused)
618+{
619+ GetTass17Coor(jd,TASS17_HYPERION,xyz);
620+}
621+
622+void get_iapetus_parent_coordsv(double jd,double xyz[3], void* unused)
623+{
624+ GetTass17Coor(jd,TASS17_IAPETUS,xyz);
625+}
626+
627+void get_miranda_parent_coordsv(double jd,double xyz[3], void* unused)
628+{
629+ GetGust86Coor(jd,GUST86_MIRANDA,xyz);
630+}
631+
632+void get_ariel_parent_coordsv(double jd,double xyz[3], void* unused)
633+{
634+ GetGust86Coor(jd,GUST86_ARIEL,xyz);
635+}
636+
637+void get_umbriel_parent_coordsv(double jd,double xyz[3], void* unused)
638+{
639+ GetGust86Coor(jd,GUST86_UMBRIEL,xyz);
640+}
641+
642+void get_titania_parent_coordsv(double jd,double xyz[3], void* unused)
643+{
644+ GetGust86Coor(jd,GUST86_TITANIA,xyz);
645+}
646+
647+void get_oberon_parent_coordsv(double jd,double xyz[3], void* unused)
648+{
649+ GetGust86Coor(jd,GUST86_OBERON,xyz);
650+}
651+
652
653=== added file 'src/core/planetsephems/EphemWrapper.hpp'
654--- src/core/planetsephems/EphemWrapper.hpp 1970-01-01 00:00:00 +0000
655+++ src/core/planetsephems/EphemWrapper.hpp 2016-01-16 17:00:50 +0000
656@@ -0,0 +1,92 @@
657+/*
658+Copyright (C) 2003 Fabien Chereau
659+Copyright (C) 2015 Holger Niessner
660+Copyright (C) 2015 Georg Zotti
661+
662+This program is free software; you can redistribute it and/or modify
663+it under the terms of the GNU Library General Public License as published by
664+the Free Software Foundation; either version 2 of the License, or
665+(at your option) any later version.
666+
667+This program is distributed in the hope that it will be useful,
668+but WITHOUT ANY WARRANTY; without even the implied warranty of
669+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
670+GNU General Public License for more details.
671+
672+You should have received a copy of the GNU General Public License
673+along with this program; if not, write to the Free Software
674+Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
675+*/
676+
677+/*
678+ * This class provides a wrapper to multiple methods to calculate ephemerides.
679+ * Depending on availability of extra data files, the class uses:
680+ * - VSOP87 and ELP82B
681+ * - DE430
682+ * - DE431
683+ *
684+ * Extending the old stellplanet-class, this updated version now
685+ * includes access to DE430 and DE431 for a more precise, yet storage-space intensive solution.
686+ */
687+
688+#ifndef _EPHEMWRAPPER_HPP_
689+#define _EPHEMWRAPPER_HPP_
690+
691+#define DE430_FILENAME "linux_p1550p2650.430"
692+#define DE431_FILENAME "lnxm13000p17000.431"
693+
694+class EphemWrapper{
695+public:
696+ static void init_de430(const char* filepath);
697+ static void init_de431(const char* filepath);
698+};
699+
700+void get_sun_helio_coordsv(double jd,double xyz[3], void*);
701+void get_mercury_helio_coordsv(double jd,double xyz[3], void*);
702+void get_venus_helio_coordsv(double jd,double xyz[3], void*);
703+void get_earth_helio_coordsv(double jd,double xyz[3], void*);
704+void get_mars_helio_coordsv(double jd,double xyz[3], void*);
705+void get_jupiter_helio_coordsv(double jd,double xyz[3], void*);
706+void get_saturn_helio_coordsv(double jd,double xyz[3], void*);
707+void get_uranus_helio_coordsv(double jd,double xyz[3], void*);
708+void get_neptune_helio_coordsv(double jd,double xyz[3], void*);
709+void get_pluto_helio_coordsv(double jd,double xyz[3], void*);
710+
711+void get_mercury_helio_osculating_coords(double jd0,double jd,double xyz[3]);
712+void get_venus_helio_osculating_coords(double jd0,double jd,double xyz[3]);
713+void get_earth_helio_osculating_coords(double jd0,double jd,double xyz[3]);
714+void get_mars_helio_osculating_coords(double jd0,double jd,double xyz[3]);
715+void get_jupiter_helio_osculating_coords(double jd0,double jd,double xyz[3]);
716+void get_saturn_helio_osculating_coords(double jd0,double jd,double xyz[3]);
717+void get_uranus_helio_osculating_coords(double jd0,double jd,double xyz[3]);
718+void get_neptune_helio_osculating_coords(double jd0,double jd,double xyz[3]);
719+void get_pluto_helio_osculating_coords(double jd0,double jd,double xyz[3]);
720+
721+void get_lunar_parent_coordsv(double jde, double xyz[3], void*);
722+
723+void get_phobos_parent_coordsv(double jd,double xyz[3], void*);
724+void get_deimos_parent_coordsv(double jd,double xyz[3], void*);
725+
726+void get_io_parent_coordsv(double jd,double xyz[3], void*);
727+void get_europa_parent_coordsv(double jd,double xyz[3], void*);
728+void get_ganymede_parent_coordsv(double jd,double xyz[3], void*);
729+void get_callisto_parent_coordsv(double jd,double xyz[3], void*);
730+
731+void get_mimas_parent_coordsv(double jd,double xyz[3], void*);
732+void get_enceladus_parent_coordsv(double jd,double xyz[3], void*);
733+void get_tethys_parent_coordsv(double jd,double xyz[3], void*);
734+void get_dione_parent_coordsv(double jd,double xyz[3], void*);
735+void get_rhea_parent_coordsv(double jd,double xyz[3], void*);
736+void get_titan_parent_coordsv(double jd,double xyz[3], void*);
737+void get_hyperion_parent_coordsv(double jd,double xyz[3], void*);
738+void get_iapetus_parent_coordsv(double jd,double xyz[3], void*);
739+
740+void get_miranda_parent_coordsv(double jd,double xyz[3], void*);
741+void get_ariel_parent_coordsv(double jd,double xyz[3], void*);
742+void get_umbriel_parent_coordsv(double jd,double xyz[3], void*);
743+void get_titania_parent_coordsv(double jd,double xyz[3], void*);
744+void get_oberon_parent_coordsv(double jd,double xyz[3], void*);
745+
746+#endif // _EPHEMWRAPPER_HPP_
747+
748+
749
750=== added file 'src/core/planetsephems/README.txt'
751--- src/core/planetsephems/README.txt 1970-01-01 00:00:00 +0000
752+++ src/core/planetsephems/README.txt 2016-01-16 17:00:50 +0000
753@@ -0,0 +1,54 @@
754+README
755+=======
756+This Readme gives instructions on how to enable DE430 and/or DE431 for Stellarium for
757+more accurate planetary positions.
758+
759+DE430 covers the dates from 1.Jan 1550 to 22. Jan 2650 with higher precision, whereas
760+DE431 covers a longer period of time, from 13201 BC to AD 17191.
761+Both are more precise than the standard VSOP87 algorithm used in Stellarium.
762+
763+When one or both files are used as described below,
764+the algorithm will switch according to the current time displayed in Stellarium and
765+calculate the planetary positions using the preferred method.
766+
767+Instructions
768+============
769+
770+File description
771+================
772+The following files, which can be obtained from
773+ftp://ssd.jpl.nasa.gov/pub/eph/planets/Linux/, have to be used:
774+
775+DE430: linux_p1550p2650.430 (md5 hash 707c4262533d52d59abaaaa5e69c5738)
776+DE431: lnxm13000p17000.431 (md5 hash fad0f432ae18c330f9e14915fbf8960a)
777+
778+File Placement
779+==============
780+The above mentioned files have to be placed in a folder named 'ephem' inside the
781+'Installation Data Directory' (see http://www.stellarium.org/doc/head/fileStructure.html).
782+
783+This is directory is different on the supported operating systems:
784+ - On Linux / BSD / other POSIX:
785+ It depends on the installation prefix used when building Stellarium.
786+ If you built from source, and didn't explicitly specify an install prefix,
787+ the prefix will be /usr/local. Typically, pre-built packages for distros will use
788+ the /usr prefix. The Installation Data Directory is $PREFIX/share/stellarium
789+
790+ - On Windows:
791+ It depends on where Stellarium is installed.
792+ The main Stellarium installation directory is the Installation Data Directory.
793+ Typically this will be C:\Program Files\Stellarium\
794+
795+ - On MacOS X:
796+ The Installation Data Directory is found inside the application bundle.
797+
798+Already placed in the 'Installation Data Directory' should be folders such as 'data',
799+'landscapes', 'stars', 'textures',...
800+
801+_ IDD
802+ \_ data
803+ \_ landscapes
804+ \_ stars
805+ \_ ephem
806+ \_ linux_p1550p2650.430
807+ \_ lnxm13000p17000.431
808
809=== added file 'src/core/planetsephems/de430.cpp'
810--- src/core/planetsephems/de430.cpp 1970-01-01 00:00:00 +0000
811+++ src/core/planetsephems/de430.cpp 2016-01-16 17:00:50 +0000
812@@ -0,0 +1,120 @@
813+/*
814+Copyright (c) 2015 Holger Niessner
815+Copyright (c) 2016 Georg Zotti
816+
817+Permission is hereby granted, free of charge, to any person obtaining a copy
818+of this software and associated documentation files (the "Software"), to deal
819+in the Software without restriction, including without limitation the rights
820+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
821+copies of the Software, and to permit persons to whom the Software is
822+furnished to do so, subject to the following conditions:
823+
824+The above copyright notice and this permission notice shall be included in
825+all copies or substantial portions of the Software.
826+
827+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
828+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
829+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
830+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
831+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
832+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
833+THE SOFTWARE.
834+*/
835+
836+#include "de430.hpp"
837+#include "StelUtils.hpp"
838+#include "StelCore.hpp"
839+#include "StelApp.hpp"
840+
841+#ifdef __cplusplus
842+ extern "C" {
843+#endif
844+
845+static void * ephem;
846+
847+static Vec3d tempECL = Vec3d(0,0,0);
848+static Vec3d tempICRF = Vec3d(0,0,0);
849+static char nams[JPL_MAX_N_CONSTANTS][6];
850+static double vals[JPL_MAX_N_CONSTANTS];
851+static double tempXYZ[6];
852+
853+static bool initDone = false;
854+
855+void InitDE430(const char* filepath)
856+{
857+ ephem = jpl_init_ephemeris(filepath, nams, vals);
858+
859+ if(jpl_init_error_code() != 0)
860+ {
861+ StelApp::getInstance().getCore()->setDe430Active(false);
862+ qDebug() << "Error "<< jpl_init_error_code() << "at DE430 init:" << jpl_init_error_message();
863+ }
864+ else
865+ {
866+ initDone = true;
867+ double jd1, jd2;
868+ jd1=jpl_get_double(ephem, JPL_EPHEM_START_JD);
869+ jd2=jpl_get_double(ephem, JPL_EPHEM_END_JD);
870+ qDebug() << "DE430 init successful. startJD=" << QString::number(jd1, 'f', 4) << "endJD=" << QString::number(jd2, 'f', 4);
871+ }
872+}
873+
874+void TerminateDE430()
875+{
876+ jpl_close_ephemeris(ephem);
877+}
878+
879+bool GetDe430Coor(const double jde, const int planet_id, double * xyz, const int centralBody_id)
880+{
881+ if(initDone)
882+ {
883+ // This may return some error code!
884+ int jplresult=jpl_pleph(ephem, jde, planet_id, centralBody_id, tempXYZ, 0);
885+
886+ switch (jplresult)
887+ {
888+ case 0: // all OK.
889+ break;
890+ case JPL_EPH_OUTSIDE_RANGE:
891+ qDebug() << "GetDe430Coor: JPL_EPH_OUTSIDE_RANGE at jde" << jde << "for planet" << planet_id;
892+ return false;
893+ break;
894+ case JPL_EPH_READ_ERROR:
895+ qDebug() << "GetDe430Coor: JPL_EPH_READ_ERROR at jde" << jde << "for planet" << planet_id;
896+ return false;
897+ break;
898+ case JPL_EPH_QUANTITY_NOT_IN_EPHEMERIS:
899+ qDebug() << "GetDe430Coor: JPL_EPH_QUANTITY_NOT_IN_EPHEMERIS at jde" << jde << "for planet" << planet_id;
900+ return false;
901+ break;
902+ case JPL_EPH_INVALID_INDEX:
903+ qDebug() << "GetDe430Coor: JPL_EPH_INVALID_INDEX at jde" << jde << "for planet" << planet_id;
904+ return false;
905+ break;
906+ case JPL_EPH_FSEEK_ERROR:
907+ qDebug() << "GetDe430Coor: JPL_EPH_FSEEK_ERROR at jde" << jde << "for planet" << planet_id;
908+ return false;
909+ break;
910+ default: // Should never happen...
911+ qDebug() << "GetDe430Coor: unknown error" << jplresult << "at jde" << jde << "for planet" << planet_id;
912+ return false;
913+ break;
914+ }
915+
916+ jpl_pleph(ephem, jde, planet_id, centralBody_id, tempXYZ, 0);
917+
918+ tempICRF = Vec3d(tempXYZ[0], tempXYZ[1], tempXYZ[2]);
919+ tempECL = StelCore::matJ2000ToVsop87 * tempICRF;
920+
921+ xyz[0] = tempECL[0];
922+ xyz[1] = tempECL[1];
923+ xyz[2] = tempECL[2];
924+ return true;
925+ }
926+ return false;
927+}
928+
929+
930+#ifdef __cplusplus
931+ }
932+#endif
933
934=== added file 'src/core/planetsephems/de430.hpp'
935--- src/core/planetsephems/de430.hpp 1970-01-01 00:00:00 +0000
936+++ src/core/planetsephems/de430.hpp 2016-01-16 17:00:50 +0000
937@@ -0,0 +1,44 @@
938+/*
939+Copyright (c) 2015 Holger Niessner
940+Copyright (c) 2016 Georg Zotti
941+
942+Permission is hereby granted, free of charge, to any person obtaining a copy
943+of this software and associated documentation files (the "Software"), to deal
944+in the Software without restriction, including without limitation the rights
945+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
946+copies of the Software, and to permit persons to whom the Software is
947+furnished to do so, subject to the following conditions:
948+
949+The above copyright notice and this permission notice shall be included in
950+all copies or substantial portions of the Software.
951+
952+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
953+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
954+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
955+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
956+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
957+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
958+THE SOFTWARE.
959+*/
960+
961+#ifndef _DE430_HPP_
962+#define _DE430_HPP_
963+
964+#include "jpleph.h"
965+
966+#ifdef __cplusplus
967+ extern "C" {
968+#endif
969+
970+void InitDE430(const char* filepath);
971+// most of the time centralBody_id likely is the Sun. However, for Moon, use centralBody_id=EPHEM_JPL_EARTH_ID=3
972+// return true if OK, false if something was wrong with the JPL functions. In this case, see log for details.
973+bool GetDe430Coor(const double jde, const int planet_id, double * xyz, const int centralBody_id=CENTRAL_PLANET_ID);
974+// Not possible for a DE.
975+//void GetDe430OsculatingCoor(double jd0, double jd, int planet_id, double *xyz, const int centralBody_id=CENTRAL_PLANET_ID);
976+
977+#ifdef __cplusplus
978+ }
979+#endif
980+
981+#endif
982
983=== added file 'src/core/planetsephems/de431.cpp'
984--- src/core/planetsephems/de431.cpp 1970-01-01 00:00:00 +0000
985+++ src/core/planetsephems/de431.cpp 2016-01-16 17:00:50 +0000
986@@ -0,0 +1,119 @@
987+/*
988+Copyright (c) 2015 Holger Niessner
989+Copyright (c) 2016 Georg Zotti
990+
991+Permission is hereby granted, free of charge, to any person obtaining a copy
992+of this software and associated documentation files (the "Software"), to deal
993+in the Software without restriction, including without limitation the rights
994+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
995+copies of the Software, and to permit persons to whom the Software is
996+furnished to do so, subject to the following conditions:
997+
998+The above copyright notice and this permission notice shall be included in
999+all copies or substantial portions of the Software.
1000+
1001+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1002+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1003+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1004+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1005+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1006+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1007+THE SOFTWARE.
1008+*/
1009+
1010+#include "de431.hpp"
1011+#include "jpleph.h"
1012+#include "StelUtils.hpp"
1013+#include "StelCore.hpp"
1014+#include "StelApp.hpp"
1015+
1016+#ifdef __cplusplus
1017+ extern "C" {
1018+#endif
1019+
1020+static void * ephem;
1021+
1022+static Vec3d tempECL = Vec3d(0,0,0);
1023+static Vec3d tempICRF = Vec3d(0,0,0);
1024+static char nams[JPL_MAX_N_CONSTANTS][6];
1025+static double vals[JPL_MAX_N_CONSTANTS];
1026+static double tempXYZ[6];
1027+
1028+static bool initDone = false;
1029+
1030+void InitDE431(const char* filepath)
1031+{
1032+ ephem = jpl_init_ephemeris(filepath, nams, vals);
1033+
1034+ if(jpl_init_error_code() != 0)
1035+ {
1036+ StelApp::getInstance().getCore()->setDe431Active(false);
1037+ qDebug() << "Error "<< jpl_init_error_code() << "at DE431 init:" << jpl_init_error_message();
1038+ }
1039+ else
1040+ {
1041+ initDone = true;
1042+ double jd1, jd2;
1043+ jd1=jpl_get_double(ephem, JPL_EPHEM_START_JD);
1044+ jd2=jpl_get_double(ephem, JPL_EPHEM_END_JD);
1045+ qDebug() << "DE431 init successful. startJD=" << QString::number(jd1, 'f', 4) << "endJD=" << QString::number(jd2, 'f', 4);
1046+ }
1047+}
1048+
1049+void TerminateDE431()
1050+{
1051+ jpl_close_ephemeris(ephem);
1052+}
1053+
1054+bool GetDe431Coor(const double jde, const int planet_id, double * xyz, const int centralBody_id)
1055+{
1056+ if(initDone)
1057+ {
1058+ // This may return some error code!
1059+ int jplresult=jpl_pleph(ephem, jde, planet_id, centralBody_id, tempXYZ, 0);
1060+
1061+ switch (jplresult)
1062+ {
1063+ case 0: // all OK.
1064+ break;
1065+ case JPL_EPH_OUTSIDE_RANGE:
1066+ qDebug() << "GetDe431Coor: JPL_EPH_OUTSIDE_RANGE at jde" << jde << "for planet" << planet_id;
1067+ return false;
1068+ break;
1069+ case JPL_EPH_READ_ERROR:
1070+ qDebug() << "GetDe431Coor: JPL_EPH_READ_ERROR at jde" << jde << "for planet" << planet_id;
1071+ return false;
1072+ break;
1073+ case JPL_EPH_QUANTITY_NOT_IN_EPHEMERIS:
1074+ qDebug() << "GetDe431Coor: JPL_EPH_QUANTITY_NOT_IN_EPHEMERIS at jde" << jde << "for planet" << planet_id;
1075+ return false;
1076+ break;
1077+ case JPL_EPH_INVALID_INDEX:
1078+ qDebug() << "GetDe431Coor: JPL_EPH_INVALID_INDEX at jde" << jde << "for planet" << planet_id;
1079+ return false;
1080+ break;
1081+ case JPL_EPH_FSEEK_ERROR:
1082+ qDebug() << "GetDe431Coor: JPL_EPH_FSEEK_ERROR at jde" << jde << "for planet" << planet_id;
1083+ return false;
1084+ break;
1085+ default: // Should never happen...
1086+ qDebug() << "GetDe431Coor: unknown error" << jplresult << "at jde" << jde << "for planet" << planet_id;
1087+ return false;
1088+ break;
1089+ }
1090+
1091+ tempICRF = Vec3d(tempXYZ[0], tempXYZ[1], tempXYZ[2]);
1092+ tempECL = StelCore::matJ2000ToVsop87 * tempICRF;
1093+
1094+ xyz[0] = tempECL[0];
1095+ xyz[1] = tempECL[1];
1096+ xyz[2] = tempECL[2];
1097+ return true;
1098+ }
1099+ return false;
1100+}
1101+
1102+
1103+#ifdef __cplusplus
1104+ }
1105+#endif
1106
1107=== added file 'src/core/planetsephems/de431.hpp'
1108--- src/core/planetsephems/de431.hpp 1970-01-01 00:00:00 +0000
1109+++ src/core/planetsephems/de431.hpp 2016-01-16 17:00:50 +0000
1110@@ -0,0 +1,44 @@
1111+/*
1112+Copyright (c) 2015 Holger Niessner
1113+Copyright (c) 2016 Georg Zotti
1114+
1115+Permission is hereby granted, free of charge, to any person obtaining a copy
1116+of this software and associated documentation files (the "Software"), to deal
1117+in the Software without restriction, including without limitation the rights
1118+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1119+copies of the Software, and to permit persons to whom the Software is
1120+furnished to do so, subject to the following conditions:
1121+
1122+The above copyright notice and this permission notice shall be included in
1123+all copies or substantial portions of the Software.
1124+
1125+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1126+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1127+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1128+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1129+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1130+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1131+THE SOFTWARE.
1132+*/
1133+
1134+#ifndef _DE431_HPP_
1135+#define _DE431_HPP_
1136+
1137+#include "jpleph.h"
1138+
1139+#ifdef __cplusplus
1140+ extern "C" {
1141+#endif
1142+
1143+void InitDE431(const char* filepath);
1144+// most of the time centralBody_id likely is the Sun. However, for Moon, use centralBody_id=EPHEM_JPL_EARTH_ID=3
1145+// return true if OK, false if something was wrong with the JPL functions. In this case, see log for details.
1146+bool GetDe431Coor(const double jde, const int planet_id, double * xyz, const int centralBody_id=CENTRAL_PLANET_ID);
1147+// Not possible for a DE.
1148+//void GetDe431OsculatingCoor(double jd0, double jd, int planet_id, double *xyz, const int centralBody_id=CENTRAL_PLANET_ID);
1149+
1150+#ifdef __cplusplus
1151+ }
1152+#endif
1153+
1154+#endif
1155
1156=== added file 'src/core/planetsephems/jpl_int.h'
1157--- src/core/planetsephems/jpl_int.h 1970-01-01 00:00:00 +0000
1158+++ src/core/planetsephems/jpl_int.h 2016-01-16 17:00:50 +0000
1159@@ -0,0 +1,106 @@
1160+/* jpl_int.cpp: internal definitions for JPL ephemeris functions
1161+
1162+Copyright (C) 2011, Project Pluto
1163+
1164+This program is free software; you can redistribute it and/or
1165+modify it under the terms of the GNU General Public License
1166+as published by the Free Software Foundation; either version 2
1167+of the License, or (at your option) any later version.
1168+
1169+This program is distributed in the hope that it will be useful,
1170+but WITHOUT ANY WARRANTY; without even the implied warranty of
1171+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1172+GNU General Public License for more details.
1173+
1174+You should have received a copy of the GNU General Public License
1175+along with this program; if not, write to the Free Software
1176+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1177+02110-1301, USA. */
1178+
1179+ /* A JPL binary ephemeris header contains five doubles and */
1180+ /* (up to) 41 int32_t integers, so: */
1181+#define JPL_HEADER_SIZE (5 * sizeof( double) + 41 * sizeof( int32_t))
1182+ /* ...also known as 5 * 8 + 41 * 4 = 204 bytes. */
1183+
1184+
1185+ /* Thus far, no DE ephems use eighteen terms in the Chebyshev */
1186+ /* expansion. There's an assert to catch it if this changes.. */
1187+#define MAX_CHEBY 18
1188+
1189+#pragma pack(1)
1190+
1191+struct interpolation_info
1192+ {
1193+ double posn_coeff[MAX_CHEBY], vel_coeff[MAX_CHEBY], twot;
1194+ unsigned n_posn_avail, n_vel_avail;
1195+ };
1196+
1197+struct jpl_eph_data {
1198+ double ephem_start, ephem_end, ephem_step;
1199+ uint32_t ncon;
1200+ double au;
1201+ double emrat;
1202+ uint32_t ipt[15][3];
1203+ uint32_t ephemeris_version;
1204+ /* This is the end of the file header. Following are */
1205+ /* items computed within my code. */
1206+ uint32_t kernel_size, recsize, ncoeff;
1207+ uint32_t swap_bytes;
1208+ uint32_t curr_cache_loc;
1209+ double pvsun[9];
1210+ double pvsun_t;
1211+ double *cache;
1212+ struct interpolation_info iinfo;
1213+ FILE *ifile;
1214+ };
1215+#pragma pack()
1216+
1217+/* 2014 Mar 25: notes about the file structure :
1218+
1219+Bytes 0- 83: first line ("JPL Planetary Ephemeris DExxx/LExxx")
1220+ 84-167: second line ("Start Epoch: JED = ttttttt.t yyyy-MMM-dd 00:00:00")
1221+ 168-251: third line ("Final Epoch: JED = ttttttt.t yyyy-MMM-dd 00:00:00")
1222+ 252-257: first constant name ("DENUM ")
1223+ 252+6n to 257+6n: nth constant name (0 <= n < 399)
1224+ 2646-2651: 400th constant name
1225+ 2652-2659: ephem_start
1226+ 2660-2667: ephem_end
1227+ 2668-2675: ephem_step
1228+ 2676-2679: ncon
1229+ 2680-2687: AU in km: close to 149597870.700000
1230+ 2688-2695: Earth/moon mass ratio: about 81.300569
1231+ ...followed by 36 32-bit ints for the above 'ipt' array [12][3]...
1232+ 2840-2843: ephemeris version (405, 430, etc.)
1233+ ...followed by three 32-bit ints for ipt[12][0...2].
1234+ 2844-2855: ipt[12][0], ipt[12][1], ipt[12][2]
1235+ Note that in the JPL FORTRAN code,
1236+ ipt[12][0..2] become lpt[0..2] (the lunar libration offsets);
1237+ ipt[13][0..2] become rpt[0..2] (the lunar euler angle rate offsets);
1238+ ipt[14][0..2] become tpt[0..2] (the TT-TDB offsets)
1239+ Further note that ipt[13] and [14] are new to DE-430t. In older
1240+ versions, they're just zeroes.
1241+ 2856-2861: name of 401th constant
1242+ 2862-2867: name of 402st constant
1243+ ...and after the last constant, ipt[13][0..2] and ipt[14][0..2].
1244+ If n_constants <= 400, these will occupy bytes 2856-2879. Otherwise,
1245+ add (n_constants - 400) * 6 to get the byte offset.
1246+
1247+ Notice that _most_ of the data in the jpl_eph_data struct is stored
1248+ between bytes 2652 to 2839. That gets us up to ipt[11][2]. In a
1249+ sensible world, this would be followed by ipt[12][0]. However, it
1250+ used to be that DE just gave eleven variables; librations and
1251+ TT-TDB are sort of an afterthought. And furthermore, having more
1252+ than 400 constants was something of an afterthought, too. So you
1253+ have ipts[0] to [11] stored contiguously; then four bytes for the
1254+ ephemeris version are stuck in there; then twelve bytes for ipt[12],
1255+ which may be zero; then any "extra" (past 400) constant names;
1256+ and _then_ 24 bytes for ipt[13] and ipt[14].
1257+
1258+ recsize-recsize+8*ncon: actual values of the constants.
1259+ recsize = 8 * ncoeff; ncoeff, thus far, has been...
1260+ ncoeff = 773 for DE-102
1261+ ncoeff = 826 for DE-200 & 202
1262+ ncoeff = 1018 for DE-403, 405, 406, 410, 414, 421, 422, 423, 424, 430, 431,
1263+ ncoeff = 728 for DE-406
1264+ ncoeff = 982 for DE-432, DE-432t
1265+*/
1266
1267=== added file 'src/core/planetsephems/jpleph.cpp'
1268--- src/core/planetsephems/jpleph.cpp 1970-01-01 00:00:00 +0000
1269+++ src/core/planetsephems/jpleph.cpp 2016-01-16 17:00:50 +0000
1270@@ -0,0 +1,978 @@
1271+/* jpleph.cpp: JPL ephemeris functions
1272+
1273+Copyright (C) 2011, Project Pluto
1274+
1275+This program is free software; you can redistribute it and/or
1276+modify it under the terms of the GNU General Public License
1277+as published by the Free Software Foundation; either version 2
1278+of the License, or (at your option) any later version.
1279+
1280+This program is distributed in the hope that it will be useful,
1281+but WITHOUT ANY WARRANTY; without even the implied warranty of
1282+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1283+GNU General Public License for more details.
1284+
1285+You should have received a copy of the GNU General Public License
1286+along with this program; if not, write to the Free Software
1287+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
1288+02110-1301, USA. */
1289+
1290+/*****************************************************************************
1291+* ***** jpl planetary and lunar ephemerides ***** C ver.1.2 *
1292+******************************************************************************
1293+* *
1294+* This program was written in standard fortran-77 and it was manually *
1295+* translated to C language by Piotr A. Dybczynski (dybol@phys.amu.edu.pl), *
1296+* subsequently revised heavily by Bill J Gray (pluto@gwi.net), just short *
1297+* of a total re-write. *
1298+* *
1299+******************************************************************************
1300+* Last modified: July 23, 1997 by PAD *
1301+******************************************************************************
1302+21 Apr 2010: Revised by Bill J. Gray. The code now determines the kernel
1303+size, then allocates memory accordingly. This should 'future-proof' us in
1304+case JPL (or someone else) creates kernels that are larger than the previously
1305+arbitrary MAX_KERNEL_SIZE parameter. 'swap_long' and 'swap_double' have
1306+been replaced with 'swap_32_bit_val' and 'swap_64_bit_val'. It also works
1307+on 64-bit compiles now.
1308+
1309+16 Mar 2001: Revised by Bill J. Gray. You can now use binary
1310+ephemerides with either byte order ('big-endian' or 'small-endian');
1311+the code checks to see if the data is in the "wrong" order for the
1312+current platform, and swaps bytes on-the-fly if needed. (Yes, this
1313+can result in a slowdown... sometimes as much as 1%. The function is
1314+so mathematically intensive that the byte-swapping is the least of our
1315+troubles.) You can also use DE-200, 403, 404, 405, or 406 without
1316+recompiling (the constan() function now determines which ephemeris is
1317+in use and its byte order).
1318+
1319+Also, I did some minor optimization of the interp() (Chebyshev
1320+interpolation) function, resulting in a bit of a speedup.
1321+
1322+The code has been modified to be a separately linkable component, with
1323+details of the implementation encapsulated.
1324+*****************************************************************************/
1325+
1326+#include <stdio.h>
1327+#include <assert.h>
1328+#include <math.h>
1329+#include <string.h>
1330+#include <stdlib.h>
1331+#include <stdint.h>
1332+
1333+#include "StelUtils.hpp"
1334+/**** include variable and type definitions, specific for this C version */
1335+
1336+#include "jpleph.h"
1337+#include "jpl_int.h"
1338+
1339+#define TRUE 1
1340+#define FALSE 0
1341+
1342+
1343+// GZ patches for Large File Support for DE431 past AD10100...
1344+#if defined(Q_OS_WIN)
1345+#define FSeek(__FILE, __OFFSET, _MODE) _fseeki64(__FILE, __OFFSET, _MODE)
1346+#else
1347+#define FSeek(__FILE, __OFFSET, _MODE) fseeko(__FILE, __OFFSET, _MODE)
1348+#endif
1349+
1350+
1351+double DLL_FUNC jpl_get_double(const void *ephem, const int value)
1352+{
1353+ return(*(double *)((char *)ephem + value));
1354+}
1355+
1356+long DLL_FUNC jpl_get_long(const void *ephem, const int value)
1357+{
1358+ return(*(int32_t *)((char *)ephem + value));
1359+}
1360+
1361+
1362+/*****************************************************************************
1363+** jpl_pleph(ephem,et,ntar,ncent,rrd,calc_velocity) **
1364+******************************************************************************
1365+** **
1366+** This subroutine reads the jpl planetary ephemeris **
1367+** and gives the position and velocity of the point 'ntarg' **
1368+** with respect to 'ncent'. **
1369+** **
1370+** Calling sequence parameters: **
1371+** **
1372+** et = (double) julian ephemeris date at which interpolation **
1373+** is wanted. **
1374+** **
1375+** ntarg = integer number of 'target' point. **
1376+** **
1377+** ncent = integer number of center point. **
1378+** **
1379+** The numbering convention for 'ntarg' and 'ncent' is: **
1380+** **
1381+** 1 = mercury 8 = neptune **
1382+** 2 = venus 9 = pluto **
1383+** 3 = earth 10 = moon **
1384+** 4 = mars 11 = sun **
1385+** 5 = jupiter 12 = solar-system barycenter **
1386+** 6 = saturn 13 = earth-moon barycenter **
1387+** 7 = uranus 14 = nutations (longitude and obliq) **
1388+** 15 = librations, if on eph. file **
1389+** 16 = lunar mantle omega_x,omega_y,omega_z**
1390+** 17 = TT-TDB, if on eph. file **
1391+** **
1392+** (If nutations are wanted, set ntarg = 14. **
1393+** For librations, set ntarg = 15. set ncent= 0. **
1394+** For TT-TDB, set ntarg = 17. I've not actually **
1395+** seen an ntarg = 16 case yet.) **
1396+** **
1397+** rrd = output 6-element, double array of position and velocity **
1398+** of point 'ntarg' relative to 'ncent'. The units are au and **
1399+** au/day. For librations the units are radians and radians **
1400+** per day. In the case of nutations the first four words of **
1401+** rrd will be set to nutations and rates, having units of **
1402+** radians and radians/day. **
1403+** **
1404+** The option is available to have the units in km and km/sec. **
1405+** for this, set km=TRUE at the beginning of the program. **
1406+** **
1407+** calc_velocity = integer flag; if nonzero, velocities will be **
1408+** computed, otherwise not. **
1409+** **
1410+*****************************************************************************/
1411+int DLL_FUNC jpl_pleph(void *ephem, const double et, const int ntarg,
1412+ const int ncent, double rrd[], const int calc_velocity)
1413+{
1414+ struct jpl_eph_data *eph = (struct jpl_eph_data *)ephem;
1415+ double pv[13][6];/* pv is the position/velocity array
1416+ NUMBERED FROM ZERO: 0=Mercury,1=Venus,...
1417+ 8=Pluto,9=Moon,10=Sun,11=SSBary,12=EMBary
1418+ First 10 elements (0-9) are affected by
1419+ jpl_state(), all are adjusted here. */
1420+
1421+
1422+ int rval = 0;
1423+ const int list_val = (calc_velocity ? 2 : 1);
1424+ unsigned i;
1425+ int list[14]; /* list is a vector denoting, for which "body"
1426+ ephemeris values should be calculated by
1427+ jpl_state(): 0=Mercury,1=Venus,2=EMBary,...,
1428+ 8=Pluto, 9=geocentric Moon, 10=nutations in
1429+ long. & obliq. 11= lunar librations;
1430+ 12 = TT-TDB, 13=lunar mantle omegas */
1431+
1432+ for(i = 0; i < 6; ++i) rrd[i] = 0.0;
1433+
1434+ if(ntarg == ncent) return(0);
1435+
1436+ for(i = 0; i < sizeof(list) / sizeof(list[0]); i++)
1437+ list[i] = 0;
1438+
1439+ /* Because of the whacko indexing in JPL ephemerides, we need */
1440+ /* to work out way through the following indexing schemes : */
1441+ /* ntarg ipt list */
1442+ /* 14 11 10 Nutations */
1443+ /* 15 12 11 Librations */
1444+ /* 16 13 12 Lunar mantle angular vel */
1445+ /* 17 14 13 TT - TDB */
1446+
1447+ for(i = 0; i < 4; i++)
1448+ if(ntarg == (int)i + 14)
1449+ {
1450+ if(eph->ipt[i + 11][1] > 0) /* quantity is in ephemeris */
1451+ {
1452+ list[i + 10] = list_val;
1453+ rval = jpl_state(ephem, et, list, pv, rrd, 0);
1454+ }
1455+ else /* quantity doesn't exist in the ephemeris file */
1456+ rval = JPL_EPH_QUANTITY_NOT_IN_EPHEMERIS;
1457+ return(rval);
1458+ }
1459+ if(ntarg > 13 || ncent > 13 || ntarg < 1 || ncent < 1)
1460+ return(JPL_EPH_INVALID_INDEX);
1461+
1462+/* force barycentric output by 'state' */
1463+
1464+/* set up proper entries in 'list' array for state call */
1465+
1466+ for(i = 0; i < 2; i++) /* list[] IS NUMBERED FROM ZERO ! */
1467+ {
1468+ const unsigned k = (i ? ncent : ntarg) - 1;
1469+
1470+ if(k <= 9) list[k] = list_val; /* Major planets */
1471+ if(k == 9) list[2] = list_val; /* for moon, earth state is needed */
1472+ if(k == 2) list[9] = list_val; /* for earth, moon state is needed */
1473+ if(k == 12) list[2] = list_val; /* EMBary state additionally */
1474+ }
1475+
1476+ /* make call to state */
1477+ rval = jpl_state(eph, et, list, pv, rrd, 1);
1478+ /* Solar System barycentric Sun state goes to pv[10][] */
1479+ if(ntarg == 11 || ncent == 11)
1480+ for(i = 0; i < 6; i++)
1481+ pv[10][i] = eph->pvsun[i];
1482+
1483+ /* Solar System Barycenter coordinates & velocities equal to zero */
1484+ if(ntarg == 12 || ncent == 12)
1485+ for(i = 0; i < 6; i++)
1486+ pv[11][i] = 0.0;
1487+
1488+ /* Solar System barycentric EMBary state: */
1489+ if(ntarg == 13 || ncent == 13)
1490+ for(i = 0; i < 6; i++)
1491+ pv[12][i] = pv[2][i];
1492+
1493+ /* if moon from earth or earth from moon ..... */
1494+ if((ntarg*ncent) == 30 && (ntarg+ncent) == 13)
1495+ for(i = 0; i < 6; ++i) pv[2][i]=0.0;
1496+ else
1497+ {
1498+ if(list[2]) /* calculate earth state from EMBary */
1499+ for(i = 0; i < list[2] * 3u; ++i)
1500+ pv[2][i] -= pv[9][i]/(1.0+eph->emrat);
1501+
1502+ if(list[9]) /* calculate Solar System barycentric moon state */
1503+ for(i = 0; i < list[9] * 3u; ++i)
1504+ pv[9][i] += pv[2][i];
1505+ }
1506+
1507+ for(i = 0; i < list_val * 3u; ++i)
1508+ rrd[i] = pv[ntarg-1][i] - pv[ncent-1][i];
1509+
1510+ return(rval);
1511+}
1512+
1513+/* Some notes about the information stored in 'iinfo': the posn_coeff[]
1514+array contains the Chebyshev polynomials for tc,
1515+
1516+posn_coeff[i]=T (tc).
1517+ i
1518+
1519+The vel_coeff[] array contains the derivatives of the same polynomials,
1520+
1521+vel_coeff[i]=T'(tc).
1522+ i
1523+
1524+ Evaluating these polynomials is a little expensive, and we don't want
1525+to evaluate any more than we have to. (Some planets require many more
1526+Chebyshev polynomials than others.) So if 'tc' is unchanged, we can
1527+rest assured that 'n_posn_avail' Chebyshev polynomials, and 'n_vel_avail'
1528+derivatives of Chebyshev polynomials, have already been evaluated, and
1529+we start from there, using the recurrence formulae
1530+
1531+T (x) = 1 T (x) = x T (x) = 2xT (x) - T (x)
1532+ 0 1 n+1 n n-1
1533+
1534+T'(x) = 0 T'(x) = 1 T' (x) = 2xT'(x) + 2T (x) - T' (x)
1535+ 0 1 n+1 n n n-1
1536+
1537+ (the second set being just the derivatives of the first). To get the
1538+_acceleration_ of an object, we just keep going and get the second
1539+derivatives as
1540+
1541+T"(x) = 0 T"(x) = 1 T" (x) = 2xT"(x) + 4T'(x) - T" (x)
1542+ 0 1 n+1 n n n-1
1543+
1544+ At present, i can range from 0 to 17. If future JPL ephems require
1545+Chebyshev polynomials beyond T , those arrays may need to be expanded.
1546+ 17 */
1547+
1548+/*****************************************************************************
1549+** interp(buf,t,ncf,ncm,na,ifl,pv) **
1550+******************************************************************************
1551+** **
1552+** this subroutine differentiates and interpolates a **
1553+** set of chebyshev coefficients to give position and velocity **
1554+** **
1555+** calling sequence parameters: **
1556+** **
1557+** input: **
1558+** **
1559+** iinfo stores certain chunks of interpolation info, in hopes **
1560+** that if you call again with similar parameters, the **
1561+** function won't have to re-compute all coefficients/data. **
1562+** **
1563+** coef 1st location of array of d.p. chebyshev coefficients **
1564+** of position **
1565+** **
1566+** t t[0] is double fractional time in interval covered by **
1567+** coefficients at which interpolation is wanted **
1568+** (0 <= t[0] <= 1). t[1] is dp length of whole **
1569+** interval in input time units. **
1570+** **
1571+** ncf # of coefficients per component **
1572+** **
1573+** ncm # of components per set of coefficients **
1574+** **
1575+** na # of sets of coefficients in full array **
1576+** (i.e., # of sub-intervals in full interval) **
1577+** **
1578+** ifl integer flag: =1 for positions only **
1579+** =2 for pos and vel **
1580+** =3 for pos, vel, accel (currently used for **
1581+** pvsun only) **
1582+** **
1583+** output: **
1584+** **
1585+** posvel interpolated quantities requested. dimension **
1586+** expected is posvel[ncm*ifl], double precision. **
1587+** **
1588+*****************************************************************************/
1589+static void interp(struct interpolation_info *iinfo,
1590+ const double coef[], const double t[2], const unsigned ncf, const unsigned ncm,
1591+ const unsigned na, const int velocity_flag, double posvel[])
1592+{
1593+ const double dna = (double)na;
1594+ const double temp = dna * t[0];
1595+ unsigned l = (unsigned)temp;
1596+ double vfac, unused_temp1;
1597+ double tc = 2.0 * modf(temp, &unused_temp1) - 1.0;
1598+ unsigned i, j;
1599+
1600+ assert(ncf < MAX_CHEBY);
1601+ if(l == na)
1602+ {
1603+ l--;
1604+ tc = 1.;
1605+ }
1606+ assert(tc >= -1.);
1607+ assert(tc <= 1.);
1608+
1609+/* check to see whether chebyshev time has changed, and compute new
1610+ polynomial values if it has.
1611+ (the element iinfo->posn_coeff[1] is the value of t1[tc] and hence
1612+ contains the value of tc on the previous call.) */
1613+
1614+
1615+ if(tc != iinfo->posn_coeff[1])
1616+ {
1617+ iinfo->n_posn_avail = 2;
1618+ iinfo->n_vel_avail = 2;
1619+ iinfo->posn_coeff[1] = tc;
1620+ iinfo->twot = tc+tc;
1621+ }
1622+
1623+/* be sure that at least 'ncf' polynomials have been evaluated and are
1624+ stored in the array 'iinfo->posn_coeff'. Note that we start out with
1625+ posn_coeff[0] = 1. and posn_coeff[1] = tc (see 'jpl_init_ephemeris'
1626+ below), and vel_coeff[0] and [1] are similarly preset. We do that
1627+ because you need the first two coeffs of those series to start the
1628+ Chebyshev recurrence; see the comments above this function. */
1629+
1630+ if(iinfo->n_posn_avail < ncf)
1631+ {
1632+ double *pc_ptr = iinfo->posn_coeff + iinfo->n_posn_avail;
1633+
1634+ for(i=ncf - iinfo->n_posn_avail; i; i--, pc_ptr++)
1635+ *pc_ptr = iinfo->twot * pc_ptr[-1] - pc_ptr[-2];
1636+ iinfo->n_posn_avail=ncf;
1637+ }
1638+
1639+/* interpolate to get position for each component */
1640+
1641+ for(i = 0; i < ncm; ++i) /* ncm is a number of coordinates */
1642+ {
1643+ const double *coeff_ptr = coef + ncf * (i + l * ncm + 1);
1644+ const double *pc_ptr = iinfo->posn_coeff + ncf;
1645+
1646+ *posvel = 0.0;
1647+ for(j = ncf; j; j--)
1648+ *posvel += (*--pc_ptr) * (*--coeff_ptr);
1649+ posvel++;
1650+ }
1651+
1652+ if(velocity_flag <= 1) return;
1653+
1654+/* if velocity interpolation is wanted, be sure enough
1655+ derivative polynomials have been generated and stored. */
1656+
1657+ if(iinfo->n_vel_avail < ncf)
1658+ {
1659+ double *vc_ptr = iinfo->vel_coeff + iinfo->n_vel_avail;
1660+ const double *pc_ptr = iinfo->posn_coeff + iinfo->n_vel_avail - 1;
1661+
1662+ for(i = ncf - iinfo->n_vel_avail; i; i--, vc_ptr++, pc_ptr++)
1663+ *vc_ptr = iinfo->twot * vc_ptr[-1] + *pc_ptr + *pc_ptr - vc_ptr[-2];
1664+ iinfo->n_vel_avail = ncf;
1665+ }
1666+
1667+/* interpolate to get velocity for each component */
1668+
1669+ vfac = (dna + dna) / t[1];
1670+ for(i = 0; i < ncm; ++i)
1671+ {
1672+ double tval = 0.;
1673+ const double *coeff_ptr = coef + ncf * (i + l * ncm + 1);
1674+ const double *vc_ptr = iinfo->vel_coeff + ncf;
1675+
1676+ for(j = ncf - 1; j; j--)
1677+ tval += (*--vc_ptr) * (*--coeff_ptr);
1678+ *posvel++ = tval * vfac;
1679+ }
1680+
1681+ /* Accelerations are rarely computed -- at present, only */
1682+ /* for pvsun -- so we don't get so tricky in optimizing. */
1683+ /* The accel_coeffs (the second derivative of the Chebyshev */
1684+ /* polynomials) are not stored for repeated use, for example. */
1685+ if(velocity_flag == 3)
1686+ {
1687+
1688+ double accel_coeffs[MAX_CHEBY];
1689+
1690+ accel_coeffs[0] = accel_coeffs[1] = 0.;
1691+ for(i = 2; i < ncf; i++) /* recurrence for T"(x) */
1692+ accel_coeffs[i] = 4. * iinfo->vel_coeff[i - 1]
1693+ + iinfo->twot * accel_coeffs[i - 1]
1694+ - accel_coeffs[i - 2];
1695+
1696+ for(i = 0; i < ncm; ++i) /* ncm is a number of coordinates */
1697+ {
1698+ double tval = 0.;
1699+ const double *coeff_ptr = coef + ncf * (i + l * ncm + 1);
1700+ const double *ac_ptr = accel_coeffs + ncf;
1701+
1702+ for(j = ncf; j; j--)
1703+ tval += (*--ac_ptr) * (*--coeff_ptr);
1704+ *posvel++ = tval * vfac * vfac;
1705+ }
1706+ }
1707+
1708+ return;
1709+}
1710+
1711+/* swap_32_bit_val() and swap_64_bit_val() are used when reading a binary
1712+ephemeris that was created on a machine with 'opposite' byte order to
1713+the currently-used machine (signalled by the 'swap_bytes' flag in the
1714+jpl_eph_data structure). In such cases, every double and integer
1715+value read from the ephemeris must be byte-swapped by these two functions. */
1716+
1717+#define SWAP_MACRO(A, B, TEMP) { TEMP = A; A = B; B = TEMP; }
1718+
1719+static void swap_32_bit_val(void *ptr)
1720+{
1721+ char *tptr = (char *)ptr, tchar;
1722+
1723+ SWAP_MACRO(tptr[0], tptr[3], tchar);
1724+ SWAP_MACRO(tptr[1], tptr[2], tchar);
1725+}
1726+
1727+static void swap_64_bit_val(void *ptr, long count)
1728+{
1729+ char *tptr = (char *)ptr, tchar;
1730+
1731+ while(count--)
1732+ {
1733+ SWAP_MACRO(tptr[0], tptr[7], tchar);
1734+ SWAP_MACRO(tptr[1], tptr[6], tchar);
1735+ SWAP_MACRO(tptr[2], tptr[5], tchar);
1736+ SWAP_MACRO(tptr[3], tptr[4], tchar);
1737+
1738+ tptr += 8;
1739+ }
1740+}
1741+
1742+/* Most ephemeris quantities have a dimension of three. Planet positions
1743+have an x, y, and z; librations and lunar mantle angles have three Euler
1744+angles. But TDT-TT is a single quantity, and nutation is expressed as
1745+two angles. */
1746+
1747+static int dimension(const int idx)
1748+{
1749+ int rval;
1750+
1751+ if(idx == 11) /* Nutations */
1752+ rval = 2;
1753+ else if(idx == 14) /* TDT - TT */
1754+ rval = 1;
1755+ else /* planets, lunar mantle angles, librations */
1756+ rval = 3;
1757+ return(rval);
1758+}
1759+
1760+/*****************************************************************************
1761+** jpl_state(ephem,et2,list,pv,nut,bary) **
1762+******************************************************************************
1763+** This subroutine reads and interpolates the jpl planetary ephemeris file **
1764+** **
1765+** Calling sequence parameters: **
1766+** **
1767+** Input: **
1768+** **
1769+** et2[] double, 2-element JED epoch at which interpolation **
1770+** is wanted. Any combination of et2[0]+et2[1] which falls **
1771+** within the time span on the file is a permissible epoch. **
1772+** **
1773+** a. for ease in programming, the user may put the **
1774+** entire epoch in et2[0] and set et2[1]=0.0 **
1775+** **
1776+** b. for maximum interpolation accuracy, set et2[0] = **
1777+** the most recent midnight at or before interpolation **
1778+** epoch and set et2[1] = fractional part of a day **
1779+** elapsed between et2[0] and epoch. **
1780+** **
1781+** c. as an alternative, it may prove convenient to set **
1782+** et2[0] = some fixed epoch, such as start of integration,**
1783+** and et2[1] = elapsed interval between then and epoch. **
1784+** **
1785+** list 13-element integer array specifying what interpolation **
1786+** is wanted for each of the "bodies" on the file. **
1787+** **
1788+** list[i]=0, no interpolation for body i **
1789+** =1, position only **
1790+** =2, position and velocity **
1791+** **
1792+** the designation of the astronomical bodies by i is: **
1793+** **
1794+** i = 0: mercury **
1795+** = 1: venus **
1796+** = 2: earth-moon barycenter **
1797+** = 3: mars **
1798+** = 4: jupiter **
1799+** = 5: saturn **
1800+** = 6: uranus **
1801+** = 7: neptune **
1802+** = 8: pluto **
1803+** = 9: geocentric moon **
1804+** =10: nutations in lon & obliq (if on file) **
1805+** =11: lunar librations (if on file) **
1806+** =12: lunar mantle omegas **
1807+** =13: TT-TDB (if on file) **
1808+** **
1809+** Note that I've not actually seen case 12 yet. It probably doesn't work. **
1810+** **
1811+** output: **
1812+** **
1813+** pv[][6] double array that will contain requested interpolated **
1814+** quantities. The body specified by list[i] will have its **
1815+** state in the array starting at pv[i][0] (on any given **
1816+** call, only those words in 'pv' which are affected by the **
1817+** first 10 'list' entries (and by list(11) if librations are **
1818+** on the file) are set. The rest of the 'pv' array **
1819+** is untouched.) The order of components in pv[][] is: **
1820+** pv[][0]=x,....pv[][5]=dz. **
1821+** **
1822+** All output vectors are referenced to the earth mean **
1823+** equator and equinox of epoch. The moon state is always **
1824+** geocentric; the other nine states are either heliocentric **
1825+** or solar-system barycentric, depending on the setting of **
1826+** global variables (see below). **
1827+** **
1828+** Lunar librations, if on file, are put into pv[10][k] if **
1829+** list[11] is 1 or 2. **
1830+** **
1831+** nut dp 4-word array that will contain nutations and rates, **
1832+** depending on the setting of list[10]. the order of **
1833+** quantities in nut is: **
1834+** **
1835+** d psi (nutation in longitude) **
1836+** d epsilon (nutation in obliquity) **
1837+** d psi dot **
1838+** d epsilon dot **
1839+** **
1840+*****************************************************************************/
1841+int DLL_FUNC jpl_state(void *ephem, const double et, const int list[14],
1842+ double pv[][6], double nut[4], const int bary)
1843+{
1844+ struct jpl_eph_data *eph = (struct jpl_eph_data *)ephem;
1845+ unsigned i, j, n_intervals;
1846+ uint32_t nr;
1847+ double *buf = eph->cache;
1848+ double t[2];
1849+ const double block_loc = (et - eph->ephem_start) / eph->ephem_step;
1850+ bool recompute_pvsun;
1851+ const double aufac = 1.0 / eph->au;
1852+
1853+/* error return for epoch out of range */
1854+ if(et < eph->ephem_start || et > eph->ephem_end)
1855+ return(JPL_EPH_OUTSIDE_RANGE);
1856+
1857+/* calculate record # and relative time in interval */
1858+
1859+ nr = (uint32_t)block_loc;
1860+ t[0] = block_loc - (double)nr;
1861+ if(!t[0] && nr)
1862+ {
1863+ t[0] = 1.;
1864+ nr--;
1865+ }
1866+
1867+/* read correct record if not in core (static vector buf[]) */
1868+ if(nr != eph->curr_cache_loc)
1869+ {
1870+ eph->curr_cache_loc = nr;
1871+ /* Read two blocks ahead to account for header: */
1872+ if(FSeek(eph->ifile, (nr + 2) * eph->recsize, SEEK_SET))
1873+ {
1874+ // GZ: Make sure we will try again on next call...
1875+ eph->curr_cache_loc=0;
1876+ return(JPL_EPH_FSEEK_ERROR);
1877+ }
1878+ if(fread(buf, sizeof(double), (size_t)eph->ncoeff, eph->ifile)
1879+ != (size_t)eph->ncoeff)
1880+ return(JPL_EPH_READ_ERROR);
1881+
1882+ if(eph->swap_bytes)
1883+ swap_64_bit_val(buf, eph->ncoeff);
1884+ }
1885+ t[1] = eph->ephem_step;
1886+
1887+ if(eph->pvsun_t != et) /* If several calls are made for the same et, */
1888+ { /* don't recompute pvsun each time... only on */
1889+ recompute_pvsun = true; /* the first run through. */
1890+ eph->pvsun_t = et;
1891+ }
1892+ else
1893+ recompute_pvsun = false;
1894+
1895+ /* Here, i loops through the "traditional" 14 listed items -- 10
1896+ solar system objects, nutations, librations, lunar mantle angles,
1897+ and TT-TDT -- plus a fifteenth: the solar system barycenter. That
1898+ last is quite different: it's computed 'as needed', rather than
1899+ from list[]; the output goes to pvsun rather than the pv array;
1900+ and three quantities (position, velocity, acceleration) are
1901+ computed (nobody else gets accelerations at present.) */
1902+ for(n_intervals = 1; n_intervals <= 8; n_intervals *= 2)
1903+ for(i = 0; i < 15; i++)
1904+ {
1905+ unsigned quantities;
1906+ uint32_t *iptr = &eph->ipt[i + 1][0];
1907+
1908+ if(i == 14)
1909+ {
1910+ quantities = (recompute_pvsun ? 3 : 0);
1911+ iptr = &eph->ipt[10][0];
1912+ }
1913+ else
1914+ {
1915+ quantities = list[i];
1916+ iptr = &eph->ipt[i < 10 ? i : i + 1][0];
1917+ }
1918+ if(n_intervals == iptr[2] && quantities)
1919+ {
1920+ double *dest = ((i == 10) ? eph->pvsun : pv[i]);
1921+
1922+ if(i < 10)
1923+ dest = pv[i];
1924+ else if(i == 14)
1925+ dest = eph->pvsun;
1926+ else
1927+ dest = nut;
1928+ interp(&eph->iinfo, &buf[iptr[0]-1], t, (int)iptr[1],
1929+ dimension(i + 1),
1930+ n_intervals, quantities, dest);
1931+
1932+ if(i < 10 || i == 14) /* convert km to AU */
1933+ for(j = 0; j < quantities * 3; j++)
1934+ dest[j] *= aufac;
1935+ }
1936+ }
1937+ if(!bary) /* gotta correct everybody for */
1938+ for(i = 0; i < 9; i++) /* the solar system barycenter */
1939+ for(j = 0; j < (unsigned)list[i] * 3; j++)
1940+ pv[i][j] -= eph->pvsun[j];
1941+ return(0);
1942+}
1943+
1944+static int init_err_code = JPL_INIT_NOT_CALLED;
1945+
1946+int DLL_FUNC jpl_init_error_code(void)
1947+{
1948+ return(init_err_code);
1949+}
1950+
1951+const char * jpl_init_error_message(void)
1952+{
1953+ switch(init_err_code)
1954+ {
1955+ case 0:
1956+ return (const char *)("JPL_INIT_NO_ERROR");
1957+ case -1:
1958+ return (const char *)("JPL_INIT_FILE_NOT_FOUND");
1959+ case -2:
1960+ return (const char *)("JPL_INIT_FSEEK_FAILED");
1961+ case -3:
1962+ return (const char *)("JPL_INIT_FREAD_FAILED");
1963+ case -4:
1964+ return (const char *)("JPL_INIT_FREAD2_FAILED");
1965+ case -5:
1966+ return (const char *)("JPL_INIT_FILE_CORRUPT");
1967+ case -6:
1968+ return (const char *)("JPL_INIT_MEMORY_FAILURE");
1969+ case -7:
1970+ return (const char *)("JPL_INIT_FREAD3_FAILED");
1971+ case -8:
1972+ return (const char *)("JPL_INIT_FREAD4_FAILED");
1973+ case -9:
1974+ return (const char *)("JPL_INIT_NOT_CALLED");
1975+ case -10:
1976+ return (const char *)("JPL_INIT_FREAD5_FAILED");
1977+ default:
1978+ return (const char *)("ERROR_NOT_RECOGNIZED");
1979+ }
1980+}
1981+
1982+ /* DE-430 has 572 constants. That's more than the 400 constants */
1983+ /* originally expected. The remaining 172 are stored after the */
1984+ /* other header data : */
1985+
1986+#define START_400TH_CONSTANT_NAME (84 * 3 + 400 * 6 + 5 * sizeof(double) \
1987+ + 41 * sizeof(int32_t))
1988+
1989+ /* ...which comes out to 2856. See comments in 'jpl_int.h'. */
1990+
1991+/****************************************************************************
1992+** jpl_init_ephemeris(ephemeris_filename, nam, val, n_constants) **
1993+*****************************************************************************
1994+** **
1995+** this function does the initial prep work for use of binary JPL **
1996+** ephemerides. **
1997+** const char *ephemeris_filename = full path/filename of the binary **
1998+** ephemeris (on the Willmann-Bell CDs, this is UNIX.200, 405, **
1999+** or 406) **
2000+** char nam[][6] = array of constant names (max 6 characters each) **
2001+** You can pass nam=NULL if you don't care about the names **
2002+** double *val = array of values of constants **
2003+** You can pass val=NULL if you don't care about the constants **
2004+** Return value is a pointer to the jpl_eph_data structure **
2005+** NULL is returned if the file isn't opened or memory isn't alloced **
2006+** Errors can be determined with the above jpl_init_error_code() **
2007+****************************************************************************/
2008+
2009+void * DLL_FUNC jpl_init_ephemeris(const char *ephemeris_filename,
2010+ char nam[][6], double *val)
2011+{
2012+ unsigned i, j;
2013+ long de_version;
2014+ char title[84];
2015+ FILE *ifile = fopen(ephemeris_filename, "rb");
2016+
2017+ struct jpl_eph_data *rval;
2018+ struct jpl_eph_data temp_data;
2019+
2020+ init_err_code = 0;
2021+ temp_data.ifile = ifile;
2022+ if(!ifile)
2023+ init_err_code = JPL_INIT_FILE_NOT_FOUND;
2024+ else if(fread(title, 84, 1, ifile) != 1)
2025+ init_err_code = JPL_INIT_FREAD_FAILED;
2026+ else if(FSeek(ifile, 2652L, SEEK_SET))
2027+ init_err_code = JPL_INIT_FSEEK_FAILED;
2028+ else if(fread(&temp_data, JPL_HEADER_SIZE, 1, ifile) != 1)
2029+ init_err_code = JPL_INIT_FREAD2_FAILED;
2030+
2031+ if(init_err_code)
2032+ {
2033+ if(ifile)
2034+ fclose(ifile);
2035+ return(NULL);
2036+ }
2037+
2038+ de_version = atoi(title + 26);
2039+
2040+ /* A small piece of trickery: in the binary file, data is stored */
2041+ /* for ipt[0...11], then the ephemeris version, then the */
2042+ /* remaining ipt[12] data. A little switching is required to get */
2043+ /* the correct order. */
2044+ temp_data.ipt[12][0] = temp_data.ipt[12][1];
2045+ temp_data.ipt[12][1] = temp_data.ipt[12][2];
2046+ temp_data.ipt[12][2] = temp_data.ipt[13][0];
2047+ temp_data.ephemeris_version = de_version;
2048+
2049+ //qDebug() << "DE_Version: " << de_version;
2050+
2051+
2052+ temp_data.swap_bytes = (temp_data.ncon > 65536L);
2053+ if(temp_data.swap_bytes) /* byte order is wrong for current platform */
2054+ {
2055+ qDebug() << "Byte order is wrong for current platform";
2056+
2057+ swap_64_bit_val(&temp_data.ephem_start, 1);
2058+ swap_64_bit_val(&temp_data.ephem_end, 1);
2059+ swap_64_bit_val(&temp_data.ephem_step, 1);
2060+ swap_32_bit_val(&temp_data.ncon);
2061+ swap_64_bit_val(&temp_data.au, 1);
2062+ swap_64_bit_val(&temp_data.emrat, 1);
2063+ }
2064+
2065+ /* It's a little tricky to tell if an ephemeris really has */
2066+ /* TT-TDB data (with offsets in ipt[13][] and ipt[14][]). */
2067+ /* Essentially, we read the data and sanity-check it, and */
2068+ /* zero it if it "doesn't add up" correctly. */
2069+ /* Also: certain ephems I've generated with ncon capped */
2070+ /* at 400 have no TT-TDB data. So if ncon == 400, don't */
2071+ /* try to read such data; you may get garbage. */
2072+ if(de_version >= 430 && temp_data.ncon != 400)
2073+ {
2074+ /* If there are 400 or fewer constants, data for ipt[13][0...2] */
2075+ /* immediately follows that for ipt[12][0..2]; i.e., we don't */
2076+ /* need to fseek(). Otherwise, we gotta skip 6*(n_constants-400) */
2077+ /* bytes. */
2078+ if(temp_data.ncon > 400)
2079+ FSeek(ifile, (size_t)(temp_data.ncon - 400) * 6, SEEK_CUR);
2080+ if(fread(&temp_data.ipt[13][0], sizeof(int32_t), 6, ifile) != 6)
2081+ init_err_code = JPL_INIT_FREAD5_FAILED;
2082+ }
2083+ else /* mark header data as invalid */
2084+ temp_data.ipt[13][0] = (uint32_t)-1;
2085+
2086+ if(temp_data.swap_bytes) /* byte order is wrong for current platform */
2087+ {
2088+ for(j = 0; j < 3; j++)
2089+ {
2090+ for(i = 0; i < 15; i++)
2091+ {
2092+ swap_32_bit_val(&temp_data.ipt[i][j]);
2093+ }
2094+ }
2095+ }
2096+
2097+ if(temp_data.ipt[13][0] != /* if these don't add up correctly, */
2098+ temp_data.ipt[12][0] + temp_data.ipt[12][1] * temp_data.ipt[12][2] * 3
2099+ || temp_data.ipt[14][0] != /* zero them out (they've garbage data) */
2100+ temp_data.ipt[13][0] + temp_data.ipt[13][1] * temp_data.ipt[13][2] * 3)
2101+ { /* not valid pointers to TT-TDB data */
2102+ memset(&temp_data.ipt[13][0], 0, 6 * sizeof(int32_t));
2103+ }
2104+
2105+ /* A sanity check: if the earth-moon ratio is outside reasonable */
2106+ /* bounds, we must be looking at a wrong or corrupted file. */
2107+ /* In DE-102, emrat = 81.3007; in DE-405/406, emrat = 81.30056. */
2108+ /* Those are the low and high ranges. We'll allow some slop in */
2109+ /* case the earth/moon mass ratio changes: */
2110+ if(temp_data.emrat > 81.3008 || temp_data.emrat < 81.30055)
2111+ {
2112+ init_err_code = JPL_INIT_FILE_CORRUPT;
2113+ qWarning() << "temp_data: " << temp_data.emrat << "(should have been =~81). JPL_INIT_FILE_CORRUPT!";
2114+ }
2115+
2116+ if(init_err_code)
2117+ {
2118+ fclose(ifile);
2119+ return(NULL);
2120+ }
2121+
2122+ /* Once upon a time, the kernel size was determined from the */
2123+ /* DE version. This was not a terrible idea, except that it */
2124+ /* meant that when the code faced a new version, it broke. */
2125+ /* Now we use some logic to compute the kernel size. */
2126+ temp_data.kernel_size = 4;
2127+ for(i = 0; i < 15; i++)
2128+ temp_data.kernel_size +=
2129+ 2 * temp_data.ipt[i][1] * temp_data.ipt[i][2] * dimension(i);
2130+// for(i = 0; i < 13; i++)
2131+// temp_data.kernel_size +=
2132+// temp_data.ipt[i][1] * temp_data.ipt[i][2] * ((i == 11) ? 4 : 6);
2133+// /* ...and then add in space required for the TT-TDB data : */
2134+// temp_data.kernel_size += temp_data.ipt[14][1] * temp_data.ipt[14][2] * 2;
2135+ temp_data.recsize = temp_data.kernel_size * 4L;
2136+ temp_data.ncoeff = temp_data.kernel_size / 2L;
2137+
2138+ /* Rather than do two separate allocations, everything */
2139+ /* we need is allocated in _one_ chunk, then parceled out. */
2140+ /* This looks a little weird, but it simplifies error */
2141+ /* handling and cleanup. */
2142+ rval = (struct jpl_eph_data *)calloc(sizeof(struct jpl_eph_data)
2143+ + temp_data.recsize, 1);
2144+ if(!rval)
2145+ {
2146+ init_err_code = JPL_INIT_MEMORY_FAILURE;
2147+ fclose(ifile);
2148+ return(NULL);
2149+ }
2150+ memcpy(rval, &temp_data, sizeof(struct jpl_eph_data));
2151+ rval->iinfo.posn_coeff[0] = 1.0;
2152+ /* Seed a bogus value here. The first and subsequent calls to */
2153+ /* 'interp' will correct it to a value between -1 and +1. */
2154+ rval->iinfo.posn_coeff[1] = -2.0;
2155+ rval->iinfo.vel_coeff[0] = 0.0;
2156+ rval->iinfo.vel_coeff[1] = 1.0;
2157+ rval->curr_cache_loc = (uint32_t)-1;
2158+
2159+ /* The 'cache' data is right after the 'jpl_eph_data' struct: */
2160+ rval->cache = (double *)(rval + 1);
2161+ /* If there are more than 400 constants, the names of */
2162+ /* the extra constants are stored in what would normally */
2163+ /* be zero-padding after the header record. However, */
2164+ /* older ephemeris-reading software won't know about that. */
2165+ /* So we store ncon=400, then actually check the names to */
2166+ /* see how many constants there _really_ are. Older readers */
2167+ /* will just see 400 names and won't know about the others. */
2168+ /* But on the upside, they won't crash. */
2169+
2170+ if(rval->ncon == 400)
2171+ {
2172+ char buff[7];
2173+
2174+ buff[6] = '\0';
2175+ FSeek(ifile, START_400TH_CONSTANT_NAME, SEEK_SET);
2176+ while(fread(buff, 6, 1, ifile) && strlen(buff) == 6)
2177+ {
2178+ rval->ncon++;
2179+ }
2180+ }
2181+
2182+ if(val)
2183+ {
2184+ FSeek(ifile, rval->recsize, SEEK_SET);
2185+ if(fread(val, sizeof(double), (size_t)rval->ncon, ifile)
2186+ != (size_t)rval->ncon)
2187+ init_err_code = JPL_INIT_FREAD3_FAILED;
2188+ else if(rval->swap_bytes) /* gotta swap the constants, too */
2189+ swap_64_bit_val(val, rval->ncon);
2190+ }
2191+
2192+ if(!init_err_code && nam)
2193+ {
2194+ FSeek(ifile, 84L * 3L, SEEK_SET); /* just after the 3 'title' lines */
2195+ for(i = 0; i < rval->ncon && !init_err_code; i++)
2196+ {
2197+ if(i == 400)
2198+ FSeek(ifile, START_400TH_CONSTANT_NAME, SEEK_SET);
2199+ if(fread(nam[i], 6, 1, ifile) != 1)
2200+ init_err_code = JPL_INIT_FREAD4_FAILED;
2201+ }
2202+ }
2203+ return(rval);
2204+}
2205+
2206+/****************************************************************************
2207+** jpl_close_ephemeris(ephem) **
2208+*****************************************************************************
2209+** **
2210+** this function closes files and frees up memory allocated by the **
2211+** jpl_init_ephemeris() function. **
2212+****************************************************************************/
2213+void DLL_FUNC jpl_close_ephemeris(void *ephem)
2214+{
2215+ struct jpl_eph_data *eph = (struct jpl_eph_data *)ephem;
2216+
2217+ fclose(eph->ifile);
2218+ free(ephem);
2219+}
2220+
2221+/* Added 2011 Jan 18: random access to any desired JPL constant */
2222+
2223+
2224+double DLL_FUNC jpl_get_constant(const int idx, void *ephem, char *constant_name)
2225+{
2226+ struct jpl_eph_data *eph = (struct jpl_eph_data *)ephem;
2227+ double rval = 0.;
2228+
2229+ *constant_name = '\0';
2230+ if(idx >= 0 && idx < (int)eph->ncon)
2231+ {
2232+ // GZ extended from const long to const long long
2233+ const long long seek_loc = (idx < 400 ? 84L * 3L + (long)idx * 6 :
2234+ START_400TH_CONSTANT_NAME + (idx - 400) * 6);
2235+
2236+ FSeek(eph->ifile, seek_loc, SEEK_SET);
2237+ if(fread(constant_name, 1, 6, eph->ifile))
2238+ {
2239+ constant_name[6] = '\0';
2240+ FSeek(eph->ifile, eph->recsize + (long)idx * sizeof(double), SEEK_SET);
2241+ if(fread(&rval, 1, sizeof(double), eph->ifile))
2242+ if(eph->swap_bytes) /* gotta swap the constants, too */
2243+ swap_64_bit_val(&rval, 1);
2244+ }
2245+ }
2246+ return(rval);
2247+}
2248+/*************************** THE END ***************************************/
2249
2250=== added file 'src/core/planetsephems/jpleph.h'
2251--- src/core/planetsephems/jpleph.h 1970-01-01 00:00:00 +0000
2252+++ src/core/planetsephems/jpleph.h 2016-01-16 17:00:50 +0000
2253@@ -0,0 +1,117 @@
2254+/* jpleph.h: header for JPL ephemeris functions
2255+
2256+Copyright (C) 2011, Project Pluto
2257+
2258+This program is free software; you can redistribute it and/or
2259+modify it under the terms of the GNU General Public License
2260+as published by the Free Software Foundation; either version 2
2261+of the License, or (at your option) any later version.
2262+
2263+This program is distributed in the hope that it will be useful,
2264+but WITHOUT ANY WARRANTY; without even the implied warranty of
2265+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2266+GNU General Public License for more details.
2267+
2268+You should have received a copy of the GNU General Public License
2269+along with this program; if not, write to the Free Software
2270+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2271+02110-1301, USA. */
2272+
2273+/***************************************************************************
2274+******* JPLEPH.H *********
2275+****************************************************************************
2276+** This header file is used both by ASC2EPH and TESTEPH programs. **
2277+****************************************************************************
2278+** Written: May 28, 1997 by PAD ** Last modified: June 23,1997 by PAD **
2279+** Modified further by Bill Gray, Jun-Aug 2001 **
2280+****************************************************************************
2281+** PAD: dr. Piotr A. Dybczynski, e-mail: dybol@phys.amu.edu.pl **
2282+** Astronomical Observatory of the A.Mickiewicz Univ., Poznan, Poland **
2283+***************************************************************************/
2284+
2285+/* By default, in Windoze 32, the JPL ephemeris functions are compiled
2286+ into a DLL. This is not really all that helpful at present, but may
2287+ be useful to people who want to use the functions from languages other
2288+ than C. */
2289+
2290+#ifdef _WIN32
2291+#define DLL_FUNC __stdcall
2292+#else
2293+#define DLL_FUNC
2294+#endif
2295+
2296+#ifdef __WATCOMC__
2297+ #include <stdbool.h>
2298+#endif
2299+
2300+#ifdef __cplusplus
2301+extern "C" {
2302+#endif
2303+
2304+void * DLL_FUNC jpl_init_ephemeris( const char *ephemeris_filename,
2305+ char nam[][6], double *val);
2306+void DLL_FUNC jpl_close_ephemeris( void *ephem);
2307+int DLL_FUNC jpl_state( void *ephem, const double et, const int list[14],
2308+ double pv[][6], double nut[4], const int bary);
2309+int DLL_FUNC jpl_pleph( void *ephem, const double et, const int ntarg,
2310+ const int ncent, double rrd[], const int calc_velocity);
2311+double DLL_FUNC jpl_get_double( const void *ephem, const int value);
2312+long DLL_FUNC jpl_get_long( const void *ephem, const int value);
2313+int DLL_FUNC make_sub_ephem( void *ephem, const char *sub_filename,
2314+ const double start_jd, const double end_jd);
2315+double DLL_FUNC jpl_get_constant( const int idx, void *ephem, char *constant_name);
2316+
2317+#ifdef __cplusplus
2318+}
2319+#endif
2320+
2321+ /* Following are constants used in */
2322+ /* jpl_get_double( ) and jpl_get_long( ): */
2323+
2324+#define JPL_EPHEM_START_JD 0
2325+#define JPL_EPHEM_END_JD 8
2326+#define JPL_EPHEM_STEP 16
2327+#define JPL_EPHEM_N_CONSTANTS 24
2328+#define JPL_EPHEM_AU_IN_KM 28
2329+#define JPL_EPHEM_EARTH_MOON_RATIO 36
2330+#define JPL_EPHEM_IPT_ARRAY 44
2331+#define JPL_EPHEM_EPHEMERIS_VERSION 224
2332+#define JPL_EPHEM_KERNEL_SIZE 228
2333+#define JPL_EPHEM_KERNEL_RECORD_SIZE 232
2334+#define JPL_EPHEM_KERNEL_NCOEFF 236
2335+#define JPL_EPHEM_KERNEL_SWAP_BYTES 240
2336+
2337+ /* The following error codes may be returned by */
2338+ /* jpl_state() and jpl_pleph(): */
2339+#define JPL_EPH_OUTSIDE_RANGE (-1)
2340+#define JPL_EPH_READ_ERROR (-2)
2341+#define JPL_EPH_QUANTITY_NOT_IN_EPHEMERIS (-3)
2342+#define JPL_EPH_INVALID_INDEX (-5)
2343+#define JPL_EPH_FSEEK_ERROR (-6)
2344+
2345+int DLL_FUNC jpl_init_error_code( void);
2346+
2347+ /* The following error codes may be returned by */
2348+ /* jpl_init_error_code( ) after jpl_init_ephemeris( ) */
2349+ /* has been called: */
2350+
2351+#define JPL_INIT_NO_ERROR 0
2352+#define JPL_INIT_FILE_NOT_FOUND -1
2353+#define JPL_INIT_FSEEK_FAILED -2
2354+#define JPL_INIT_FREAD_FAILED -3
2355+#define JPL_INIT_FREAD2_FAILED -4
2356+#define JPL_INIT_FREAD5_FAILED -10
2357+#define JPL_INIT_FILE_CORRUPT -5
2358+#define JPL_INIT_MEMORY_FAILURE -6
2359+#define JPL_INIT_FREAD3_FAILED -7
2360+#define JPL_INIT_FREAD4_FAILED -8
2361+#define JPL_INIT_NOT_CALLED -9
2362+
2363+#define jpl_get_pvsun( ephem) ((double *)((char *)ephem + 248))
2364+
2365+/* addition for use in stellarium */
2366+#define JPL_MAX_N_CONSTANTS 1018
2367+#define CALC_VELOCITY 0
2368+#define CENTRAL_PLANET_ID 11 //ID of sun in JPL enumeration
2369+
2370+const char * jpl_init_error_message(void);
2371
2372=== modified file 'src/core/planetsephems/pluto.h'
2373--- src/core/planetsephems/pluto.h 2013-08-04 14:59:29 +0000
2374+++ src/core/planetsephems/pluto.h 2016-01-16 17:00:50 +0000
2375@@ -20,6 +20,11 @@
2376 #ifndef LN_PLUTO_H
2377 #define LN_PLUTO_H
2378
2379+#ifdef __cplusplus
2380+extern "C" {
2381+#endif
2382+
2383+
2384 struct pluto_argument
2385 {
2386 double J, S, P;
2387@@ -40,5 +45,11 @@
2388 double A,B;
2389 };
2390
2391+void get_pluto_helio_coords (double JD, double * X, double * Y, double * Z);
2392+
2393+#ifdef __cplusplus
2394+}
2395+#endif
2396+
2397
2398 #endif
2399
2400=== removed file 'src/core/planetsephems/stellplanet.c'
2401--- src/core/planetsephems/stellplanet.c 2013-08-04 14:59:29 +0000
2402+++ src/core/planetsephems/stellplanet.c 1970-01-01 00:00:00 +0000
2403@@ -1,136 +0,0 @@
2404-/*
2405-Copyright (C) 2003 Fabien Chereau
2406-
2407-This program is free software; you can redistribute it and/or modify
2408-it under the terms of the GNU Library General Public License as published by
2409-the Free Software Foundation; either version 2 of the License, or
2410-(at your option) any later version.
2411-
2412-This program is distributed in the hope that it will be useful,
2413-but WITHOUT ANY WARRANTY; without even the implied warranty of
2414-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2415-GNU General Public License for more details.
2416-
2417-You should have received a copy of the GNU General Public License
2418-along with this program; if not, write to the Free Software
2419-Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
2420-*/
2421-
2422-#include "vsop87.h"
2423-#include "elp82b.h"
2424-#include "marssat.h"
2425-#include "l1.h"
2426-#include "tass17.h"
2427-#include "gust86.h"
2428-
2429-/* Chapter 31 Pg 206-207 Equ 31.1 31.2 , 31.3 using VSOP 87
2430- * Calculate planets rectangular heliocentric ecliptical coordinates
2431- * for given julian day. Values are in AU.
2432- * params : Julian day, rect coords */
2433-void get_pluto_helio_coords(double jd, double * X, double * Y, double * Z);
2434-
2435-void get_pluto_helio_coordsv(double jd,double xyz[3], void* unused)
2436- {get_pluto_helio_coords(jd, &xyz[0], &xyz[1], &xyz[2]);}
2437-
2438-
2439-/* Return 0 of course... */
2440-void get_sun_helio_coordsv(double jd,double xyz[3], void* unused)
2441- {xyz[0]=0.; xyz[1]=0.; xyz[2]=0.;}
2442-
2443-void get_mercury_helio_coordsv(double jd,double xyz[3], void* unused)
2444- {GetVsop87Coor(jd,VSOP87_MERCURY,xyz);}
2445-void get_venus_helio_coordsv(double jd,double xyz[3], void* unused)
2446- {GetVsop87Coor(jd,VSOP87_VENUS,xyz);}
2447-
2448-void get_earth_helio_coordsv(const double jd,double xyz[3]) {
2449- double moon[3];
2450- GetVsop87Coor(jd,VSOP87_EMB,xyz);
2451- GetElp82bCoor(jd,moon);
2452- /* Earth != EMB:
2453- 0.0121505677733761 = mu_m/(1+mu_m),
2454- mu_m = mass(moon)/mass(earth) = 0.01230002 */
2455- xyz[0] -= 0.0121505677733761 * moon[0];
2456- xyz[1] -= 0.0121505677733761 * moon[1];
2457- xyz[2] -= 0.0121505677733761 * moon[2];
2458-}
2459-
2460-void get_mars_helio_coordsv(double jd,double xyz[3], void* unused)
2461- {GetVsop87Coor(jd,VSOP87_MARS,xyz);}
2462-void get_jupiter_helio_coordsv(double jd,double xyz[3], void* unused)
2463- {GetVsop87Coor(jd,VSOP87_JUPITER,xyz);}
2464-void get_saturn_helio_coordsv(double jd,double xyz[3], void* unused)
2465- {GetVsop87Coor(jd,VSOP87_SATURN,xyz);}
2466-void get_uranus_helio_coordsv(double jd,double xyz[3], void* unused)
2467- {GetVsop87Coor(jd,VSOP87_URANUS,xyz);}
2468-void get_neptune_helio_coordsv(double jd,double xyz[3], void* unused)
2469- {GetVsop87Coor(jd,VSOP87_NEPTUNE,xyz);}
2470-
2471-void get_mercury_helio_osculating_coords(double jd0,double jd,double xyz[3])
2472- {GetVsop87OsculatingCoor(jd0,jd,VSOP87_MERCURY,xyz);}
2473-void get_venus_helio_osculating_coords(double jd0,double jd,double xyz[3])
2474- {GetVsop87OsculatingCoor(jd0,jd,VSOP87_VENUS,xyz);}
2475-void get_earth_helio_osculating_coords(double jd0,double jd,double xyz[3])
2476- {GetVsop87OsculatingCoor(jd0,jd,VSOP87_EMB,xyz);}
2477-void get_mars_helio_osculating_coords(double jd0,double jd,double xyz[3])
2478- {GetVsop87OsculatingCoor(jd0,jd,VSOP87_MARS,xyz);}
2479-void get_jupiter_helio_osculating_coords(double jd0,double jd,double xyz[3])
2480- {GetVsop87OsculatingCoor(jd0,jd,VSOP87_JUPITER,xyz);}
2481-void get_saturn_helio_osculating_coords(double jd0,double jd,double xyz[3])
2482- {GetVsop87OsculatingCoor(jd0,jd,VSOP87_SATURN,xyz);}
2483-void get_uranus_helio_osculating_coords(double jd0,double jd,double xyz[3])
2484- {GetVsop87OsculatingCoor(jd0,jd,VSOP87_URANUS,xyz);}
2485-void get_neptune_helio_osculating_coords(double jd0,double jd,double xyz[3])
2486- {GetVsop87OsculatingCoor(jd0,jd,VSOP87_NEPTUNE,xyz);}
2487-
2488-/* Calculate the rectangular geocentric lunar coordinates to the inertial mean
2489- * ecliptic and equinox of J2000.
2490- * The geocentric coordinates returned are in units of AU.
2491- * This function is based upon the Lunar Solution ELP2000-82B by
2492- * Michelle Chapront-Touze and Jean Chapront of the Bureau des Longitudes,
2493- * Paris. ELP 2000-82B theory
2494- * param jd Julian day, rect pos */
2495-void get_lunar_parent_coordsv(double jd,double xyz[3], void* unused)
2496- {GetElp82bCoor(jd,xyz);}
2497-
2498-void get_phobos_parent_coordsv(double jd,double xyz[3], void* unused)
2499- {GetMarsSatCoor(jd,MARS_SAT_PHOBOS,xyz);}
2500-void get_deimos_parent_coordsv(double jd,double xyz[3], void* unused)
2501- {GetMarsSatCoor(jd,MARS_SAT_DEIMOS,xyz);}
2502-
2503-void get_io_parent_coordsv(double jd,double xyz[3], void* unused)
2504- {GetL1Coor(jd,L1_IO,xyz);}
2505-void get_europa_parent_coordsv(double jd,double xyz[3], void* unused)
2506- {GetL1Coor(jd,L1_EUROPA,xyz);}
2507-void get_ganymede_parent_coordsv(double jd,double xyz[3], void* unused)
2508- {GetL1Coor(jd,L1_GANYMEDE,xyz);}
2509-void get_callisto_parent_coordsv(double jd,double xyz[3], void* unused)
2510- {GetL1Coor(jd,L1_CALLISTO,xyz);}
2511-
2512-void get_mimas_parent_coordsv(double jd,double xyz[3], void* unused)
2513- {GetTass17Coor(jd,TASS17_MIMAS,xyz);}
2514-void get_enceladus_parent_coordsv(double jd,double xyz[3], void* unused)
2515- {GetTass17Coor(jd,TASS17_ENCELADUS,xyz);}
2516-void get_tethys_parent_coordsv(double jd,double xyz[3], void* unused)
2517- {GetTass17Coor(jd,TASS17_TETHYS,xyz);}
2518-void get_dione_parent_coordsv(double jd,double xyz[3], void* unused)
2519- {GetTass17Coor(jd,TASS17_DIONE,xyz);}
2520-void get_rhea_parent_coordsv(double jd,double xyz[3], void* unused)
2521- {GetTass17Coor(jd,TASS17_RHEA,xyz);}
2522-void get_titan_parent_coordsv(double jd,double xyz[3], void* unused)
2523- {GetTass17Coor(jd,TASS17_TITAN,xyz);}
2524-void get_hyperion_parent_coordsv(double jd,double xyz[3], void* unused)
2525- {GetTass17Coor(jd,TASS17_HYPERION,xyz);}
2526-void get_iapetus_parent_coordsv(double jd,double xyz[3], void* unused)
2527- {GetTass17Coor(jd,TASS17_IAPETUS,xyz);}
2528-
2529-void get_miranda_parent_coordsv(double jd,double xyz[3], void* unused)
2530- {GetGust86Coor(jd,GUST86_MIRANDA,xyz);}
2531-void get_ariel_parent_coordsv(double jd,double xyz[3], void* unused)
2532- {GetGust86Coor(jd,GUST86_ARIEL,xyz);}
2533-void get_umbriel_parent_coordsv(double jd,double xyz[3], void* unused)
2534- {GetGust86Coor(jd,GUST86_UMBRIEL,xyz);}
2535-void get_titania_parent_coordsv(double jd,double xyz[3], void* unused)
2536- {GetGust86Coor(jd,GUST86_TITANIA,xyz);}
2537-void get_oberon_parent_coordsv(double jd,double xyz[3], void* unused)
2538- {GetGust86Coor(jd,GUST86_OBERON,xyz);}
2539-
2540
2541=== removed file 'src/core/planetsephems/stellplanet.h'
2542--- src/core/planetsephems/stellplanet.h 2013-08-04 14:59:29 +0000
2543+++ src/core/planetsephems/stellplanet.h 1970-01-01 00:00:00 +0000
2544@@ -1,77 +0,0 @@
2545-/*
2546-Copyright (C) 2003 Fabien Chereau
2547-
2548-This program is free software; you can redistribute it and/or modify
2549-it under the terms of the GNU Library General Public License as published by
2550-the Free Software Foundation; either version 2 of the License, or
2551-(at your option) any later version.
2552-
2553-This program is distributed in the hope that it will be useful,
2554-but WITHOUT ANY WARRANTY; without even the implied warranty of
2555-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2556-GNU General Public License for more details.
2557-
2558-You should have received a copy of the GNU General Public License
2559-along with this program; if not, write to the Free Software
2560-Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
2561-*/
2562-
2563-#ifndef _STELLPLANET_H_
2564-#define _STELLPLANET_H_
2565-
2566-#ifdef __cplusplus
2567-extern "C" {
2568-#endif
2569-
2570-void get_sun_helio_coordsv(double jd,double xyz[3], void*);
2571-void get_mercury_helio_coordsv(double jd,double xyz[3], void*);
2572-void get_venus_helio_coordsv(double jd,double xyz[3], void*);
2573-void get_earth_helio_coordsv(double jd,double xyz[3], void*);
2574-void get_mars_helio_coordsv(double jd,double xyz[3], void*);
2575-void get_jupiter_helio_coordsv(double jd,double xyz[3], void*);
2576-void get_saturn_helio_coordsv(double jd,double xyz[3], void*);
2577-void get_uranus_helio_coordsv(double jd,double xyz[3], void*);
2578-void get_neptune_helio_coordsv(double jd,double xyz[3], void*);
2579-void get_pluto_helio_coordsv(double jd,double xyz[3], void*);
2580-
2581-void get_mercury_helio_osculating_coords(double jd0,double jd,double xyz[3]);
2582-void get_venus_helio_osculating_coords(double jd0,double jd,double xyz[3]);
2583-void get_earth_helio_osculating_coords(double jd0,double jd,double xyz[3]);
2584-void get_mars_helio_osculating_coords(double jd0,double jd,double xyz[3]);
2585-void get_jupiter_helio_osculating_coords(double jd0,double jd,double xyz[3]);
2586-void get_saturn_helio_osculating_coords(double jd0,double jd,double xyz[3]);
2587-void get_uranus_helio_osculating_coords(double jd0,double jd,double xyz[3]);
2588-void get_neptune_helio_osculating_coords(double jd0,double jd,double xyz[3]);
2589-void get_pluto_helio_osculating_coords(double jd0,double jd,double xyz[3]);
2590-
2591-void get_lunar_parent_coordsv(double jd,double xyz[3], void*);
2592-
2593-void get_phobos_parent_coordsv(double jd,double xyz[3], void*);
2594-void get_deimos_parent_coordsv(double jd,double xyz[3], void*);
2595-
2596-void get_io_parent_coordsv(double jd,double xyz[3], void*);
2597-void get_europa_parent_coordsv(double jd,double xyz[3], void*);
2598-void get_ganymede_parent_coordsv(double jd,double xyz[3], void*);
2599-void get_callisto_parent_coordsv(double jd,double xyz[3], void*);
2600-
2601-void get_mimas_parent_coordsv(double jd,double xyz[3], void*);
2602-void get_enceladus_parent_coordsv(double jd,double xyz[3], void*);
2603-void get_tethys_parent_coordsv(double jd,double xyz[3], void*);
2604-void get_dione_parent_coordsv(double jd,double xyz[3], void*);
2605-void get_rhea_parent_coordsv(double jd,double xyz[3], void*);
2606-void get_titan_parent_coordsv(double jd,double xyz[3], void*);
2607-void get_hyperion_parent_coordsv(double jd,double xyz[3], void*);
2608-void get_iapetus_parent_coordsv(double jd,double xyz[3], void*);
2609-
2610-void get_miranda_parent_coordsv(double jd,double xyz[3], void*);
2611-void get_ariel_parent_coordsv(double jd,double xyz[3], void*);
2612-void get_umbriel_parent_coordsv(double jd,double xyz[3], void*);
2613-void get_titania_parent_coordsv(double jd,double xyz[3], void*);
2614-void get_oberon_parent_coordsv(double jd,double xyz[3], void*);
2615-
2616-#ifdef __cplusplus
2617-}
2618-#endif
2619-
2620-
2621-#endif /* _STELLPLANET_H_ */
2622
2623=== modified file 'src/core/planetsephems/vsop87.h'
2624--- src/core/planetsephems/vsop87.h 2015-07-20 15:56:19 +0000
2625+++ src/core/planetsephems/vsop87.h 2016-01-16 17:00:50 +0000
2626@@ -51,15 +51,6 @@
2627 extern "C" {
2628 #endif
2629
2630-#define VSOP87_MERCURY 0
2631-#define VSOP87_VENUS 1
2632-#define VSOP87_EMB 2
2633-#define VSOP87_MARS 3
2634-#define VSOP87_JUPITER 4
2635-#define VSOP87_SATURN 5
2636-#define VSOP87_URANUS 6
2637-#define VSOP87_NEPTUNE 7
2638-
2639 void GetVsop87Coor(double jd,int body,double *xyz);
2640 /* Return the rectangular coordinates of the given planet
2641 and the given julian date jd expressed in dynamical time (TAI+32.184s).
2642
2643=== modified file 'src/gui/ConfigurationDialog.cpp'
2644--- src/gui/ConfigurationDialog.cpp 2015-11-29 14:05:01 +0000
2645+++ src/gui/ConfigurationDialog.cpp 2016-01-16 17:00:50 +0000
2646@@ -59,6 +59,7 @@
2647 #include "SkyGui.hpp"
2648 #include "StelJsonParser.hpp"
2649 #include "StelTranslator.hpp"
2650+#include "EphemWrapper.hpp"
2651
2652 #include <QSettings>
2653 #include <QDebug>
2654@@ -72,15 +73,17 @@
2655 : StelDialog(parent)
2656 , nextStarCatalogToDownloadIndex(0)
2657 , starCatalogsCount(0)
2658- , starCatalogDownloadReply(NULL)
2659+ , downloadReply(NULL)
2660 , currentDownloadFile(NULL)
2661 , progressBar(NULL)
2662 , gui(agui)
2663+ , hasDownloadedStarCatalog(false)
2664+ , isDownloadingStarCatalog(false)
2665+ , isDownloadingEphemData(false)
2666+ , customDeltaTEquationDialog(NULL)
2667 {
2668 ui = new Ui_configurationDialogForm;
2669- customDeltaTEquationDialog = NULL;
2670- hasDownloadedStarCatalog = false;
2671- isDownloadingStarCatalog = false;
2672+
2673 savedProjectionType = StelApp::getInstance().getCore()->getCurrentProjectionType();
2674 // Get info about operating system
2675 QString platform = StelUtils::getOperatingSystemInfo();
2676@@ -170,11 +173,18 @@
2677 connect(ui->getStarsButton, SIGNAL(clicked()), this, SLOT(downloadStars()));
2678 connect(ui->downloadCancelButton, SIGNAL(clicked()), this, SLOT(cancelDownload()));
2679 connect(ui->downloadRetryButton, SIGNAL(clicked()), this, SLOT(downloadStars()));
2680- resetStarCatalogControls();
2681+
2682 ui->nutationCheckBox->setChecked(core->getUseNutation());
2683 connect(ui->nutationCheckBox, SIGNAL(toggled(bool)), core, SLOT(setUseNutation(bool)));
2684 ui->topocentricCheckBox->setChecked(core->getUseTopocentricCoordinates());
2685 connect(ui->topocentricCheckBox, SIGNAL(toggled(bool)), core, SLOT(setUseTopocentricCoordinates(bool)));
2686+
2687+ connect(ui->de430checkBox, SIGNAL(clicked()), this, SLOT(de430ButtonClicked()));
2688+ connect(ui->de431checkBox, SIGNAL(clicked()), this, SLOT(de431ButtonClicked()));
2689+
2690+ resetStarCatalogControls();
2691+ resetEphemControls();
2692+
2693 #ifdef Q_OS_WIN
2694 //Kinetic scrolling for tablet pc and pc
2695 QList<QWidget *> addscroll;
2696@@ -1077,27 +1087,27 @@
2697 void ConfigurationDialog::cancelDownload(void)
2698 {
2699 Q_ASSERT(currentDownloadFile);
2700- Q_ASSERT(starCatalogDownloadReply);
2701+ Q_ASSERT(downloadReply);
2702 qWarning() << "Aborting download";
2703- starCatalogDownloadReply->abort();
2704+ downloadReply->abort();
2705 }
2706
2707 void ConfigurationDialog::newStarCatalogData()
2708 {
2709 Q_ASSERT(currentDownloadFile);
2710- Q_ASSERT(starCatalogDownloadReply);
2711+ Q_ASSERT(downloadReply);
2712 Q_ASSERT(progressBar);
2713
2714- int size = starCatalogDownloadReply->bytesAvailable();
2715+ int size = downloadReply->bytesAvailable();
2716 progressBar->setValue((float)progressBar->getValue()+(float)size/1024);
2717- currentDownloadFile->write(starCatalogDownloadReply->read(size));
2718+ currentDownloadFile->write(downloadReply->read(size));
2719 }
2720
2721 void ConfigurationDialog::downloadStars()
2722 {
2723 Q_ASSERT(!nextStarCatalogToDownload.isEmpty());
2724 Q_ASSERT(!isDownloadingStarCatalog);
2725- Q_ASSERT(starCatalogDownloadReply==NULL);
2726+ Q_ASSERT(downloadReply==NULL);
2727 Q_ASSERT(currentDownloadFile==NULL);
2728 Q_ASSERT(progressBar==NULL);
2729
2730@@ -1112,7 +1122,7 @@
2731 ui->downloadRetryButton->setVisible(true);
2732 return;
2733 }
2734-
2735+ isDownloading = true;
2736 isDownloadingStarCatalog = true;
2737 updateStarCatalogControlsText();
2738 ui->downloadCancelButton->setVisible(true);
2739@@ -1124,10 +1134,10 @@
2740 req.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
2741 req.setAttribute(QNetworkRequest::RedirectionTargetAttribute, false);
2742 req.setRawHeader("User-Agent", userAgent.toLatin1());
2743- starCatalogDownloadReply = StelApp::getInstance().getNetworkAccessManager()->get(req);
2744- starCatalogDownloadReply->setReadBufferSize(1024*1024*2);
2745- connect(starCatalogDownloadReply, SIGNAL(finished()), this, SLOT(downloadFinished()));
2746- connect(starCatalogDownloadReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
2747+ downloadReply = StelApp::getInstance().getNetworkAccessManager()->get(req);
2748+ downloadReply->setReadBufferSize(1024*1024*2);
2749+ connect(downloadReply, SIGNAL(finished()), this, SLOT(starsDownloadFinished()));
2750+ connect(downloadReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
2751
2752 progressBar = StelApp::getInstance().addProgressBar();
2753 progressBar->setValue(0);
2754@@ -1137,30 +1147,97 @@
2755 qDebug() << "Downloading file" << nextStarCatalogToDownload.value("url").toString();
2756 }
2757
2758+void ConfigurationDialog::de430ButtonClicked()
2759+{
2760+ QSettings* conf = StelApp::getInstance().getSettings();
2761+ Q_ASSERT(conf);
2762+
2763+ StelApp::getInstance().getCore()->setDe430Active(!StelApp::getInstance().getCore()->de430IsActive());
2764+ conf->setValue("astro/flag_use_de430", StelApp::getInstance().getCore()->de430IsActive());
2765+
2766+ resetEphemControls(); //refresh labels
2767+}
2768+
2769+void ConfigurationDialog::de431ButtonClicked()
2770+{
2771+ QSettings* conf = StelApp::getInstance().getSettings();
2772+ Q_ASSERT(conf);
2773+
2774+ StelApp::getInstance().getCore()->setDe431Active(!StelApp::getInstance().getCore()->de431IsActive());
2775+ conf->setValue("astro/flag_use_de431", StelApp::getInstance().getCore()->de431IsActive());
2776+
2777+ resetEphemControls(); //refresh labels
2778+}
2779+
2780+void ConfigurationDialog::resetEphemControls()
2781+{
2782+ ui->de430checkBox->setEnabled(StelApp::getInstance().getCore()->de430IsAvailable());
2783+ ui->de431checkBox->setEnabled(StelApp::getInstance().getCore()->de431IsAvailable());
2784+ ui->de430checkBox->setChecked(StelApp::getInstance().getCore()->de430IsActive());
2785+ ui->de431checkBox->setChecked(StelApp::getInstance().getCore()->de431IsActive());
2786+
2787+ if(StelApp::getInstance().getCore()->de430IsActive())
2788+ ui->de430label->setText(q_("1550...2650"));
2789+ else
2790+ {
2791+ if (StelApp::getInstance().getCore()->de430IsAvailable())
2792+ ui->de430label->setText(q_("Available"));
2793+ else
2794+ ui->de430label->setText(q_("Not Available"));
2795+ }
2796+ if(StelApp::getInstance().getCore()->de431IsActive())
2797+ ui->de431label->setText(q_("-13.000...17.000"));
2798+ else
2799+ {
2800+ if (StelApp::getInstance().getCore()->de431IsAvailable())
2801+ ui->de431label->setText(q_("Available"));
2802+ else
2803+ ui->de431label->setText(q_("Not Available"));
2804+ }
2805+}
2806+
2807+void ConfigurationDialog::downloadEphemData()
2808+{
2809+ // TODO in connection with the download manager!
2810+ resetEphemControls();
2811+}
2812+
2813 void ConfigurationDialog::downloadError(QNetworkReply::NetworkError)
2814 {
2815 Q_ASSERT(currentDownloadFile);
2816- Q_ASSERT(starCatalogDownloadReply);
2817-
2818- isDownloadingStarCatalog = false;
2819- qWarning() << "Error downloading file" << starCatalogDownloadReply->url() << ": " << starCatalogDownloadReply->errorString();
2820- ui->downloadLabel->setText(q_("Error downloading %1:\n%2").arg(nextStarCatalogToDownload.value("id").toString()).arg(starCatalogDownloadReply->errorString()));
2821+ Q_ASSERT(downloadReply);
2822+
2823+ isDownloading = false;
2824+ if(isDownloadingStarCatalog)
2825+ {
2826+ isDownloadingStarCatalog = false;
2827+ ui->getStarsButton->setVisible(false);
2828+ ui->getStarsButton->setEnabled(true);
2829+ }
2830+
2831+ qWarning() << "Error downloading file" << downloadReply->url() << ": " << downloadReply->errorString();
2832+ ui->downloadLabel->setText(q_("Error downloading %1:\n%2").arg(nextStarCatalogToDownload.value("id").toString()).arg(downloadReply->errorString()));
2833 ui->downloadCancelButton->setVisible(false);
2834 ui->downloadRetryButton->setVisible(true);
2835- ui->getStarsButton->setVisible(false);
2836- ui->getStarsButton->setEnabled(true);
2837-}
2838-
2839-void ConfigurationDialog::downloadFinished()
2840+
2841+}
2842+
2843+void ConfigurationDialog::ephemDataDownloadFinished()
2844+{
2845+ // TODO in connection with the download manager!
2846+
2847+}
2848+
2849+void ConfigurationDialog::starsDownloadFinished()
2850 {
2851 Q_ASSERT(currentDownloadFile);
2852- Q_ASSERT(starCatalogDownloadReply);
2853+ Q_ASSERT(downloadReply);
2854 Q_ASSERT(progressBar);
2855
2856- if (starCatalogDownloadReply->error()!=QNetworkReply::NoError)
2857+ if (downloadReply->error()!=QNetworkReply::NoError)
2858 {
2859- starCatalogDownloadReply->deleteLater();
2860- starCatalogDownloadReply = NULL;
2861+ downloadReply->deleteLater();
2862+ downloadReply = NULL;
2863 currentDownloadFile->close();
2864 currentDownloadFile->deleteLater();
2865 currentDownloadFile = NULL;
2866@@ -1169,31 +1246,34 @@
2867 return;
2868 }
2869
2870- const QVariant& redirect = starCatalogDownloadReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
2871+ Q_ASSERT(downloadReply->bytesAvailable()==0);
2872+
2873+ const QVariant& redirect = downloadReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
2874 if (!redirect.isNull())
2875 {
2876 // We got a redirection, we need to follow
2877- starCatalogDownloadReply->deleteLater();
2878+ downloadReply->deleteLater();
2879 QNetworkRequest req(redirect.toUrl());
2880 req.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
2881 req.setAttribute(QNetworkRequest::RedirectionTargetAttribute, false);
2882 req.setRawHeader("User-Agent", userAgent.toLatin1());
2883- starCatalogDownloadReply = StelApp::getInstance().getNetworkAccessManager()->get(req);
2884- starCatalogDownloadReply->setReadBufferSize(1024*1024*2);
2885- connect(starCatalogDownloadReply, SIGNAL(readyRead()), this, SLOT(newStarCatalogData()));
2886- connect(starCatalogDownloadReply, SIGNAL(finished()), this, SLOT(downloadFinished()));
2887- connect(starCatalogDownloadReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
2888+ downloadReply = StelApp::getInstance().getNetworkAccessManager()->get(req);
2889+ downloadReply->setReadBufferSize(1024*1024*2);
2890+ connect(downloadReply, SIGNAL(readyRead()), this, SLOT(newStarCatalogData()));
2891+ connect(downloadReply, SIGNAL(finished()), this, SLOT(starsDownloadFinished()));
2892+ connect(downloadReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
2893 return;
2894 }
2895
2896- Q_ASSERT(starCatalogDownloadReply->bytesAvailable()==0);
2897+ Q_ASSERT(downloadReply->bytesAvailable()==0);
2898
2899 isDownloadingStarCatalog = false;
2900+ isDownloading = false;
2901 currentDownloadFile->close();
2902 currentDownloadFile->deleteLater();
2903 currentDownloadFile = NULL;
2904- starCatalogDownloadReply->deleteLater();
2905- starCatalogDownloadReply = NULL;
2906+ downloadReply->deleteLater();
2907+ downloadReply = NULL;
2908 StelApp::getInstance().removeProgressBar(progressBar);
2909 progressBar=NULL;
2910
2911
2912=== modified file 'src/gui/ConfigurationDialog.hpp'
2913--- src/gui/ConfigurationDialog.hpp 2015-08-19 11:23:26 +0000
2914+++ src/gui/ConfigurationDialog.hpp 2016-01-16 17:00:50 +0000
2915@@ -60,20 +60,26 @@
2916 //! Re-translate the contents of the "Star calalogs" box.
2917 //! Update the strings according to the state.
2918 void updateStarCatalogControlsText();
2919- //! True if a star catalog download is in progress.
2920- bool isDownloadingStarCatalog;
2921 //! Value set by resetStarCatalogControls().
2922 int nextStarCatalogToDownloadIndex;
2923 //! Value set by resetStarCatalogControls().
2924 int starCatalogsCount;
2925 //! True when at least one star catalog has been downloaded successfully this session
2926 bool hasDownloadedStarCatalog;
2927- QNetworkReply* starCatalogDownloadReply;
2928+ QNetworkReply* downloadReply;
2929 QFile* currentDownloadFile;
2930 class StelProgressController* progressBar;
2931
2932 QString userAgent;
2933
2934+ //! True if a star catalog download is in progress.
2935+ bool isDownloadingStarCatalog;
2936+ //! True if a ephemData download is in progress.
2937+ bool isDownloadingEphemData;
2938+ //! True if any download is in progress
2939+ bool isDownloading;
2940+
2941+
2942 private slots:
2943 void setNoSelectedInfo();
2944 void setAllSelectedInfo();
2945@@ -100,7 +106,9 @@
2946 void newStarCatalogData();
2947 void downloadStars();
2948 void cancelDownload();
2949- void downloadFinished();
2950+ void starsDownloadFinished();
2951+ void ephemDataDownloadFinished();
2952+ void resetEphemControls();
2953 void downloadError(QNetworkReply::NetworkError);
2954
2955 //! Update the labels displaying the current default state
2956@@ -148,6 +156,12 @@
2957 #endif
2958 void setFixedDateTimeToCurrent();
2959
2960+ //! downloads DE430/DE431 ephemData from SourceForge
2961+ void downloadEphemData();
2962+
2963+ void de430ButtonClicked();
2964+ void de431ButtonClicked();
2965+
2966 private:
2967 StelGui* gui;
2968
2969
2970=== modified file 'src/gui/configurationDialog.ui'
2971--- src/gui/configurationDialog.ui 2015-11-08 09:52:30 +0000
2972+++ src/gui/configurationDialog.ui 2016-01-16 17:00:50 +0000
2973@@ -6,7 +6,7 @@
2974 <rect>
2975 <x>0</x>
2976 <y>0</y>
2977- <width>497</width>
2978+ <width>509</width>
2979 <height>538</height>
2980 </rect>
2981 </property>
2982@@ -168,7 +168,7 @@
2983 <number>0</number>
2984 </property>
2985 <item>
2986- <widget class="QGroupBox" name="groupBox_2">
2987+ <widget class="QGroupBox" name="groupBox_LanguageSettings">
2988 <property name="title">
2989 <string>Language settings</string>
2990 </property>
2991@@ -269,6 +269,75 @@
2992 </widget>
2993 </item>
2994 <item>
2995+ <widget class="QGroupBox" name="groupBox_EphemerisSettings">
2996+ <property name="title">
2997+ <string>Ephemeris settings</string>
2998+ </property>
2999+ <layout class="QGridLayout" name="gridLayout_ephemeris">
3000+ <property name="leftMargin">
3001+ <number>0</number>
3002+ </property>
3003+ <property name="topMargin">
3004+ <number>0</number>
3005+ </property>
3006+ <property name="rightMargin">
3007+ <number>0</number>
3008+ </property>
3009+ <property name="bottomMargin">
3010+ <number>0</number>
3011+ </property>
3012+ <item row="0" column="0">
3013+ <layout class="QGridLayout" name="EphemerisGridLayout">
3014+ <item row="1" column="1">
3015+ <widget class="QLabel" name="de431label">
3016+ <property name="text">
3017+ <string>Not installed</string>
3018+ </property>
3019+ </widget>
3020+ </item>
3021+ <item row="0" column="1">
3022+ <widget class="QLabel" name="de430label">
3023+ <property name="text">
3024+ <string>Not installed</string>
3025+ </property>
3026+ </widget>
3027+ </item>
3028+ <item row="1" column="0">
3029+ <widget class="QCheckBox" name="de431checkBox">
3030+ <property name="toolTip">
3031+ <string>DE431 provides position data for years -13000...+17000. For special applications only.</string>
3032+ </property>
3033+ <property name="text">
3034+ <string>Use DE431 (long-time data)</string>
3035+ </property>
3036+ </widget>
3037+ </item>
3038+ <item row="0" column="0">
3039+ <widget class="QCheckBox" name="de430checkBox">
3040+ <property name="toolTip">
3041+ <string>DE430 provides highest accuracy, only for years 1550...2650.</string>
3042+ </property>
3043+ <property name="text">
3044+ <string>Use DE430 (high accuracy)</string>
3045+ </property>
3046+ </widget>
3047+ </item>
3048+ <item row="2" column="0" colspan="2">
3049+ <widget class="QLabel" name="label_VSOP87used">
3050+ <property name="toolTip">
3051+ <string>Using VSOP87 is recommended for years -4000...+8000 only, but delivers useful positions outside this range.</string>
3052+ </property>
3053+ <property name="text">
3054+ <string>VSOP87/ELP2000-82B is used when these are not installed or not activated.</string>
3055+ </property>
3056+ </widget>
3057+ </item>
3058+ </layout>
3059+ </item>
3060+ </layout>
3061+ </widget>
3062+ </item>
3063+ <item>
3064 <widget class="QGroupBox" name="groupBox_6">
3065 <property name="title">
3066 <string>Default options</string>
3067@@ -1143,16 +1212,6 @@
3068 </property>
3069 </widget>
3070 </item>
3071- <item row="7" column="0" colspan="2">
3072- <widget class="QCheckBox" name="autoZoomResetsDirectionCheckbox">
3073- <property name="toolTip">
3074- <string>When enabled, the &quot;auto zoom out&quot; key will also set the initial viewing direction</string>
3075- </property>
3076- <property name="text">
3077- <string>Auto zoom out returns to initial direction of view</string>
3078- </property>
3079- </widget>
3080- </item>
3081 <item row="3" column="1">
3082 <widget class="QCheckBox" name="decimalDegreeCheckBox">
3083 <property name="toolTip">
3084@@ -1193,6 +1252,16 @@
3085 </property>
3086 </widget>
3087 </item>
3088+ <item row="6" column="0" colspan="2">
3089+ <widget class="QCheckBox" name="autoZoomResetsDirectionCheckbox">
3090+ <property name="toolTip">
3091+ <string>When enabled, the &quot;auto zoom out&quot; key will also set the initial viewing direction</string>
3092+ </property>
3093+ <property name="text">
3094+ <string>Auto zoom out returns to initial direction of view</string>
3095+ </property>
3096+ </widget>
3097+ </item>
3098 </layout>
3099 </widget>
3100 </item>