From 0f626c6f786325ed335ac07e644574c942a72b38 Mon Sep 17 00:00:00 2001 From: Sergio Poppi <s.poppi@gmail.com> Date: Mon, 3 Mar 2025 16:46:21 +0100 Subject: [PATCH] Solar system bodies tracking (#912) * First skeleton issue #002 * SolarSystemBody.midl interface and makefile patched * Xephem Astro lib added to Common Libraries * Patched Makefile XEphem libastro * Xephem libastro wrapper to solarsystem comp * Patched makefile in astrolib * inclded dynamic comp in cdb * added build.log to gitignore * Git ignored solarsystem body * Xephemlib added to System Make * Modified xephemAstrilib wrappe. implemented SolarSystemBodyImpl::execute. * Site implementation * Removed handy shortcuts from astro.h in astrolib * Refactored libastrowrapper to opimize handling solar system body names with static methods. * Unresolved symbols due to missing linking objects in SolarSystem makefile * Implemented Method body position * getAttribute method implemented. * Implemented getCoordinates and getAllCoordinates * patch to allow test component with python * test_solarsystembody.py added az el calculation * Testing output Solar System Body output * patched libastrowrapper. Added getJ2000EquatorialMethod. * unittest setup * patched test planet jupiter * SolarSystemBody comp. test apparant equatorial and horizontal * SolarSystemBody:added test for setting offsets. * Add to git new tests * test on Sun and offsets * test Sun added * Implemented distance * Test jupiter distance * Patched getAttributes * Implemented SUN in Antenna boss component * Sun tracking:implemented in scheduler * SolarSystem module added to SystemMake * Error handling if a wrong planet is chosen * Included functinality for planet tracking. Typos patched. * Bug fixed Mercury planet code. Planet not found i NOBJ code * Wrong planet name gives correct exception * planet tracking with schedule, first draft * Patched schedule subscan to allow planet tracking in schedule file * Otimized logging of the SolarSystemBody component * Generator showed in antennaBoss TUI * typos fixes * patche logs --------- Co-authored-by: Giuseppe Carboni <giuseppecarboni89@live.com> --- .gitignore | 9 + .../include/UpdateGenerator.i | 45 +- .../src/AntennaBossTextClient.cpp | 5 +- .../AntennaBossTextClient/src/Makefile | 2 +- .../AntennaInterface/idl/SolarSystemBody.midl | 93 + .../Interfaces/AntennaInterface/src/Makefile | 4 +- .../idl/AntennaDefinitions.midl | 2 +- .../idl/ManagmentDefinitions.midl | 7 +- .../include/ManagementModule.h | 4 + .../ManagmentInterface/idl/Scheduler.idl | 19 + .../Libraries/XEphemAstroLib/include/astro.h | 825 ++ Common/Libraries/XEphemAstroLib/include/bdl.h | 6 + .../Libraries/XEphemAstroLib/include/chap95.h | 68 + .../XEphemAstroLib/include/deepconst.h | 34 + .../XEphemAstroLib/include/preferences.h | 41 + .../Libraries/XEphemAstroLib/include/satlib.h | 206 + .../XEphemAstroLib/include/satspec.h | 43 + .../XEphemAstroLib/include/sattypes.h | 28 + .../Libraries/XEphemAstroLib/include/vector.h | 19 + .../Libraries/XEphemAstroLib/include/vsop87.h | 93 + Common/Libraries/XEphemAstroLib/src/Makefile | 253 + Common/Libraries/XEphemAstroLib/src/a.out | Bin 0 -> 409952 bytes .../Libraries/XEphemAstroLib/src/aa_hadec.c | 77 + .../Libraries/XEphemAstroLib/src/aberration.c | 161 + Common/Libraries/XEphemAstroLib/src/actan.c | 67 + Common/Libraries/XEphemAstroLib/src/airmass.c | 26 + Common/Libraries/XEphemAstroLib/src/anomaly.c | 63 + Common/Libraries/XEphemAstroLib/src/ap_as.c | 68 + Common/Libraries/XEphemAstroLib/src/astro.h | 824 ++ Common/Libraries/XEphemAstroLib/src/atlas.c | 196 + Common/Libraries/XEphemAstroLib/src/auxil.c | 42 + Common/Libraries/XEphemAstroLib/src/bdl.c | 238 + Common/Libraries/XEphemAstroLib/src/bdl.h | 6 + Common/Libraries/XEphemAstroLib/src/chap95.c | 174 + Common/Libraries/XEphemAstroLib/src/chap95.h | 68 + .../XEphemAstroLib/src/chap95_data.c | 783 ++ Common/Libraries/XEphemAstroLib/src/circum.c | 861 ++ Common/Libraries/XEphemAstroLib/src/comet.c | 83 + Common/Libraries/XEphemAstroLib/src/constel.c | 1803 +++++ Common/Libraries/XEphemAstroLib/src/dbfmt.c | 1029 +++ Common/Libraries/XEphemAstroLib/src/deep.c | 790 ++ .../Libraries/XEphemAstroLib/src/deepconst.h | 34 + Common/Libraries/XEphemAstroLib/src/deltat.c | 334 + .../Libraries/XEphemAstroLib/src/descrip.mms | 92 + .../Libraries/XEphemAstroLib/src/earthsat.c | 792 ++ Common/Libraries/XEphemAstroLib/src/eq_ecl.c | 72 + Common/Libraries/XEphemAstroLib/src/eq_gal.c | 99 + Common/Libraries/XEphemAstroLib/src/formats.c | 212 + Common/Libraries/XEphemAstroLib/src/helio.c | 51 + Common/Libraries/XEphemAstroLib/src/jupmoon.c | 391 + .../Libraries/XEphemAstroLib/src/libration.c | 2213 ++++++ Common/Libraries/XEphemAstroLib/src/magdecl.c | 381 + .../Libraries/XEphemAstroLib/src/marsmoon.c | 265 + Common/Libraries/XEphemAstroLib/src/misc.c | 503 ++ Common/Libraries/XEphemAstroLib/src/mjd.c | 256 + Common/Libraries/XEphemAstroLib/src/moon.c | 3467 ++++++++ .../Libraries/XEphemAstroLib/src/mooncolong.c | 236 + Common/Libraries/XEphemAstroLib/src/moonnf.c | 69 + .../Libraries/XEphemAstroLib/src/nutation.c | 441 ++ Common/Libraries/XEphemAstroLib/src/obliq.c | 27 + .../XEphemAstroLib/src/parallactic.c | 54 + .../Libraries/XEphemAstroLib/src/parallax.c | 42 + Common/Libraries/XEphemAstroLib/src/plans.c | 227 + Common/Libraries/XEphemAstroLib/src/plmoon.c | 284 + .../Libraries/XEphemAstroLib/src/plshadow.c | 50 + Common/Libraries/XEphemAstroLib/src/precess.c | 146 + .../XEphemAstroLib/src/preferences.h | 41 + Common/Libraries/XEphemAstroLib/src/reduce.c | 78 + Common/Libraries/XEphemAstroLib/src/refract.c | 96 + Common/Libraries/XEphemAstroLib/src/rings.c | 45 + Common/Libraries/XEphemAstroLib/src/riset.c | 100 + .../Libraries/XEphemAstroLib/src/riset_cir.c | 426 + Common/Libraries/XEphemAstroLib/src/satlib.h | 206 + Common/Libraries/XEphemAstroLib/src/satmoon.c | 510 ++ Common/Libraries/XEphemAstroLib/src/satspec.h | 43 + .../Libraries/XEphemAstroLib/src/sattypes.h | 28 + Common/Libraries/XEphemAstroLib/src/sdp4.c | 430 + Common/Libraries/XEphemAstroLib/src/sgp4.c | 401 + Common/Libraries/XEphemAstroLib/src/sphcart.c | 43 + Common/Libraries/XEphemAstroLib/src/sun.c | 44 + Common/Libraries/XEphemAstroLib/src/thetag.c | 90 + Common/Libraries/XEphemAstroLib/src/twobody.c | 243 + Common/Libraries/XEphemAstroLib/src/umoon.c | 270 + Common/Libraries/XEphemAstroLib/src/utc_gst.c | 95 + Common/Libraries/XEphemAstroLib/src/vector.h | 19 + Common/Libraries/XEphemAstroLib/src/vsop87.c | 209 + Common/Libraries/XEphemAstroLib/src/vsop87.h | 93 + .../XEphemAstroLib/src/vsop87_data.c | 6988 +++++++++++++++++ Common/Servers/AntennaBoss/include/BossCore.h | 1 + Common/Servers/AntennaBoss/src/BossCore.cpp | 6 +- .../AntennaBoss/src/BossCore_prepareScan.i | 97 +- Common/Servers/AntennaBoss/src/Makefile | 2 +- Common/Servers/Moon/src/MoonImpl.cpp | 2 +- .../Scheduler/include/Core_Operations.h | 18 + Common/Servers/Scheduler/include/Schedule.h | 23 + .../Servers/Scheduler/include/SchedulerImpl.h | 25 + Common/Servers/Scheduler/src/Core.cpp | 2 + Common/Servers/Scheduler/src/Core_Common.i | 1 + .../Servers/Scheduler/src/Core_Operations.i | 36 + .../Scheduler/src/Schedule_ScanList.cpp | 195 +- .../Servers/Scheduler/src/SchedulerImpl.cpp | 35 + .../Servers/Scheduler/src/SubScanBinder.cpp | 42 + .../Scheduler/templates/MapJupiter1x1.bck | 2 + .../Scheduler/templates/MapJupiter1x1.cfg | 13 + .../Scheduler/templates/MapJupiter1x1.lis | 208 + .../Scheduler/templates/MapJupiter1x1.scd | 85 + Common/Servers/Scheduler/templates/calib.lis | 2 +- Common/Servers/SolarSystem/ChangeLog | 1 + .../SolarSystem/include/SolarSystemBodyImpl.h | 222 + .../SolarSystem/include/libastrowrapper.h | 104 + Common/Servers/SolarSystem/src/Makefile | 113 + Common/Servers/SolarSystem/src/MyMake | 22 + .../SolarSystem/src/SolarSystemBodyImpl.cpp | 424 + .../SolarSystem/src/libastrowrapper.cpp | 281 + Common/Servers/SolarSystem/src/mainastro.cpp | 22 + Common/Servers/SolarSystem/src/test.cpp | 86 + .../SolarSystem/src/test_SolarSystemBody.py | 130 + Common/Servers/SolarSystem/test/Makefile | 3 + Common/Servers/SolarSystem/test/__init__.py | 0 .../Servers/SolarSystem/test/test_jupiter.py | 54 + .../SolarSystem/test/test_jupiter_distance.py | 44 + .../Servers/SolarSystem/test/test_offset.py | 54 + Common/Servers/SolarSystem/test/test_sun.py | 55 + .../Components/ANTENNA/IncludeDynamic.xml | 5 + .../AntennaBossContainer.xml | 6 +- .../AntennaContainer/AntennaContainer.xml | 4 +- .../ManagementContainer.xml | 4 +- SRT/CDB/alma/ANTENNA/Boss/Boss.xml | 18 +- .../Components/ANTENNA/IncludeDynamic.xml | 5 + .../CDB/alma/ANTENNA/Boss/Boss.xml | 8 +- SystemMake/Makefile | 4 +- 131 files changed, 32826 insertions(+), 39 deletions(-) create mode 100644 Common/Interfaces/AntennaInterface/idl/SolarSystemBody.midl create mode 100644 Common/Libraries/XEphemAstroLib/include/astro.h create mode 100644 Common/Libraries/XEphemAstroLib/include/bdl.h create mode 100644 Common/Libraries/XEphemAstroLib/include/chap95.h create mode 100644 Common/Libraries/XEphemAstroLib/include/deepconst.h create mode 100644 Common/Libraries/XEphemAstroLib/include/preferences.h create mode 100644 Common/Libraries/XEphemAstroLib/include/satlib.h create mode 100644 Common/Libraries/XEphemAstroLib/include/satspec.h create mode 100644 Common/Libraries/XEphemAstroLib/include/sattypes.h create mode 100644 Common/Libraries/XEphemAstroLib/include/vector.h create mode 100644 Common/Libraries/XEphemAstroLib/include/vsop87.h create mode 100644 Common/Libraries/XEphemAstroLib/src/Makefile create mode 100644 Common/Libraries/XEphemAstroLib/src/a.out create mode 100644 Common/Libraries/XEphemAstroLib/src/aa_hadec.c create mode 100644 Common/Libraries/XEphemAstroLib/src/aberration.c create mode 100644 Common/Libraries/XEphemAstroLib/src/actan.c create mode 100644 Common/Libraries/XEphemAstroLib/src/airmass.c create mode 100644 Common/Libraries/XEphemAstroLib/src/anomaly.c create mode 100644 Common/Libraries/XEphemAstroLib/src/ap_as.c create mode 100644 Common/Libraries/XEphemAstroLib/src/astro.h create mode 100644 Common/Libraries/XEphemAstroLib/src/atlas.c create mode 100644 Common/Libraries/XEphemAstroLib/src/auxil.c create mode 100644 Common/Libraries/XEphemAstroLib/src/bdl.c create mode 100644 Common/Libraries/XEphemAstroLib/src/bdl.h create mode 100644 Common/Libraries/XEphemAstroLib/src/chap95.c create mode 100644 Common/Libraries/XEphemAstroLib/src/chap95.h create mode 100644 Common/Libraries/XEphemAstroLib/src/chap95_data.c create mode 100644 Common/Libraries/XEphemAstroLib/src/circum.c create mode 100644 Common/Libraries/XEphemAstroLib/src/comet.c create mode 100644 Common/Libraries/XEphemAstroLib/src/constel.c create mode 100644 Common/Libraries/XEphemAstroLib/src/dbfmt.c create mode 100644 Common/Libraries/XEphemAstroLib/src/deep.c create mode 100644 Common/Libraries/XEphemAstroLib/src/deepconst.h create mode 100644 Common/Libraries/XEphemAstroLib/src/deltat.c create mode 100644 Common/Libraries/XEphemAstroLib/src/descrip.mms create mode 100644 Common/Libraries/XEphemAstroLib/src/earthsat.c create mode 100644 Common/Libraries/XEphemAstroLib/src/eq_ecl.c create mode 100644 Common/Libraries/XEphemAstroLib/src/eq_gal.c create mode 100644 Common/Libraries/XEphemAstroLib/src/formats.c create mode 100644 Common/Libraries/XEphemAstroLib/src/helio.c create mode 100644 Common/Libraries/XEphemAstroLib/src/jupmoon.c create mode 100644 Common/Libraries/XEphemAstroLib/src/libration.c create mode 100644 Common/Libraries/XEphemAstroLib/src/magdecl.c create mode 100644 Common/Libraries/XEphemAstroLib/src/marsmoon.c create mode 100644 Common/Libraries/XEphemAstroLib/src/misc.c create mode 100644 Common/Libraries/XEphemAstroLib/src/mjd.c create mode 100644 Common/Libraries/XEphemAstroLib/src/moon.c create mode 100644 Common/Libraries/XEphemAstroLib/src/mooncolong.c create mode 100644 Common/Libraries/XEphemAstroLib/src/moonnf.c create mode 100644 Common/Libraries/XEphemAstroLib/src/nutation.c create mode 100644 Common/Libraries/XEphemAstroLib/src/obliq.c create mode 100644 Common/Libraries/XEphemAstroLib/src/parallactic.c create mode 100644 Common/Libraries/XEphemAstroLib/src/parallax.c create mode 100644 Common/Libraries/XEphemAstroLib/src/plans.c create mode 100644 Common/Libraries/XEphemAstroLib/src/plmoon.c create mode 100644 Common/Libraries/XEphemAstroLib/src/plshadow.c create mode 100644 Common/Libraries/XEphemAstroLib/src/precess.c create mode 100644 Common/Libraries/XEphemAstroLib/src/preferences.h create mode 100644 Common/Libraries/XEphemAstroLib/src/reduce.c create mode 100644 Common/Libraries/XEphemAstroLib/src/refract.c create mode 100644 Common/Libraries/XEphemAstroLib/src/rings.c create mode 100644 Common/Libraries/XEphemAstroLib/src/riset.c create mode 100644 Common/Libraries/XEphemAstroLib/src/riset_cir.c create mode 100644 Common/Libraries/XEphemAstroLib/src/satlib.h create mode 100644 Common/Libraries/XEphemAstroLib/src/satmoon.c create mode 100644 Common/Libraries/XEphemAstroLib/src/satspec.h create mode 100644 Common/Libraries/XEphemAstroLib/src/sattypes.h create mode 100644 Common/Libraries/XEphemAstroLib/src/sdp4.c create mode 100644 Common/Libraries/XEphemAstroLib/src/sgp4.c create mode 100644 Common/Libraries/XEphemAstroLib/src/sphcart.c create mode 100644 Common/Libraries/XEphemAstroLib/src/sun.c create mode 100644 Common/Libraries/XEphemAstroLib/src/thetag.c create mode 100644 Common/Libraries/XEphemAstroLib/src/twobody.c create mode 100644 Common/Libraries/XEphemAstroLib/src/umoon.c create mode 100644 Common/Libraries/XEphemAstroLib/src/utc_gst.c create mode 100644 Common/Libraries/XEphemAstroLib/src/vector.h create mode 100644 Common/Libraries/XEphemAstroLib/src/vsop87.c create mode 100644 Common/Libraries/XEphemAstroLib/src/vsop87.h create mode 100644 Common/Libraries/XEphemAstroLib/src/vsop87_data.c create mode 100644 Common/Servers/Scheduler/templates/MapJupiter1x1.bck create mode 100644 Common/Servers/Scheduler/templates/MapJupiter1x1.cfg create mode 100644 Common/Servers/Scheduler/templates/MapJupiter1x1.lis create mode 100644 Common/Servers/Scheduler/templates/MapJupiter1x1.scd create mode 100644 Common/Servers/SolarSystem/ChangeLog create mode 100644 Common/Servers/SolarSystem/include/SolarSystemBodyImpl.h create mode 100644 Common/Servers/SolarSystem/include/libastrowrapper.h create mode 100644 Common/Servers/SolarSystem/src/Makefile create mode 100644 Common/Servers/SolarSystem/src/MyMake create mode 100644 Common/Servers/SolarSystem/src/SolarSystemBodyImpl.cpp create mode 100644 Common/Servers/SolarSystem/src/libastrowrapper.cpp create mode 100644 Common/Servers/SolarSystem/src/mainastro.cpp create mode 100644 Common/Servers/SolarSystem/src/test.cpp create mode 100644 Common/Servers/SolarSystem/src/test_SolarSystemBody.py create mode 100644 Common/Servers/SolarSystem/test/Makefile create mode 100644 Common/Servers/SolarSystem/test/__init__.py create mode 100644 Common/Servers/SolarSystem/test/test_jupiter.py create mode 100644 Common/Servers/SolarSystem/test/test_jupiter_distance.py create mode 100644 Common/Servers/SolarSystem/test/test_offset.py create mode 100644 Common/Servers/SolarSystem/test/test_sun.py diff --git a/.gitignore b/.gitignore index 12abadff6..d7349f20e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,11 +6,13 @@ object/ *~ *.swp *.pyc +.project* # Ignore the SliLibrary directory Common/Libraries/SlaLibrary # Files generated by the building process +Common/Interfaces/build.log Common/Clients/CaltoolClient/src/calibrationtool_ui.py Common/Clients/CaltoolClient/src/calibrationtool_ui.pye Common/Errors/AntennaErrors/idl/AntennaErrors.idl @@ -26,12 +28,16 @@ Common/Errors/ParserErrors/idl/ParserErrors.idl Common/Errors/ReceiversErrors/idl/DerotatorErrors.idl Common/Errors/ReceiversErrors/idl/ReceiversErrors.idl Common/Errors/XBackendErrors/idl/XBackendsErrors.idl +Common/Errors/ActiveSurfaceErrors/idl/ASErrors.idl +Common/Interfaces/ActiveSurfaceInterface/idl/ActiveSurfaceCommon.idl +Common/Interfaces/AntennaInterface/idl/SolarSystemBody.idl Common/Interfaces/AntennaInterface/idl/AntennaBoss.idl Common/Interfaces/AntennaInterface/idl/Moon.idl Common/Interfaces/AntennaInterface/idl/Mount.idl Common/Interfaces/AntennaInterface/idl/OTF.idl Common/Interfaces/AntennaInterface/idl/Observatory.idl Common/Interfaces/AntennaInterface/idl/SkySource.idl +Common/Interfaces/AntennaInterface/idl/SolarSystemBody.idl Common/Interfaces/ActiveSurfaceInterface/idl/ActiveSurfaceCommon.idl Common/Interfaces/CommonInterface/idl/AntennaDefinitions.idl Common/Interfaces/CommonInterface/idl/BackendsDefinitions.idl @@ -50,4 +56,7 @@ SRT/Clients/SRTActiveSurfaceGUIClient/include/SRTActiveSurfaceGUI.h SRT/Clients/SRTActiveSurfaceGUIClient/src/moc_SRTActiveSurfaceCore.cpp SRT/Clients/SRTActiveSurfaceGUIClient/src/moc_SRTActiveSurfaceGUIui.cpp SRT/Interfaces/SRTActiveSurfaceInterface/idl/SRTActiveSurfaceBoss.idl +Common/Libraries/build.log +SRT/Interfaces/SRTActiveSurfaceInterface/idl/SRTActiveSurfaceCommon.idl +.DS_Store .vscode/settings.json diff --git a/Common/Clients/AntennaBossTextClient/include/UpdateGenerator.i b/Common/Clients/AntennaBossTextClient/include/UpdateGenerator.i index 395214319..c4007114f 100644 --- a/Common/Clients/AntennaBossTextClient/include/UpdateGenerator.i +++ b/Common/Clients/AntennaBossTextClient/include/UpdateGenerator.i @@ -162,6 +162,49 @@ void updateGenerator(maci::SimpleClient& client,Antenna::TGeneratorType& lastGen extraLabel6->Refresh(); break; } + case Antenna::ANT_SOLARSYSTEMBODY : { + IRA::CString str1,str2; + + Antenna::SolarSystemBodyAttributes_var att; + Antenna::SolarSystemBody_var ssbody; + try { + ssbody=Antenna::SolarSystemBody::_narrow(lastGenerator); + if (!CORBA::is_nil(ssbody)) { + ssbody->getAttributes(att); + } + } + catch (...) { + _EXCPT(ClientErrors::UnknownExImpl,impl,"::Main()"); + _IRA_LOGGUARD_LOG_EXCEPTION(guard,impl,LM_ERROR); + return; + } + tmpString=(const char*)att->sourceID; + outString="Source name : "+tmpString; + extraLabel1->setValue(outString); + extraLabel1->Refresh(); + IRA::CIRATools::radToHourAngle(att->rightAscension,str1); + IRA::CIRATools::radToSexagesimalAngle(att->declination,str2); + outString="Apparent Eq. : "+str1+"/"+str2+"/"; + str1.Format("%.5lf",att->julianEpoch); + outString+=str1; + extraLabel2->setValue(outString); + extraLabel2->Refresh(); + IRA::CIRATools::radToAngle(att->gLongitude,str1); + IRA::CIRATools::radToAngle(att->gLatitude,str2); + outString="Galactic : "+str1+"/"+str2; + extraLabel3->setValue(outString); + extraLabel4->Refresh(); + IRA::CIRATools::radToAngle(att->azimuth,str1); + IRA::CIRATools::radToAngle(att->elevation,str2); + outString="Horizontal : "+str1+"/"+str2; + extraLabel4->setValue(outString); + extraLabel4->Refresh(); + extraLabel5->setValue(""); + extraLabel5->Refresh(); + extraLabel6->setValue(""); + extraLabel6->Refresh(); + break; + } case Antenna::ANT_OTF: { Antenna::OTFAttributes_var att; Antenna::OTF_var otf; @@ -175,7 +218,7 @@ void updateGenerator(maci::SimpleClient& client,Antenna::TGeneratorType& lastGen catch (...) { _EXCPT(ClientErrors::UnknownExImpl,impl,"::Main()"); _IRA_LOGGUARD_LOG_EXCEPTION(guard,impl,LM_ERROR); - return; + return; } IRA::CIRATools::radToAngle(att->startLon,str1); IRA::CIRATools::radToAngle(att->startLat,str2); diff --git a/Common/Clients/AntennaBossTextClient/src/AntennaBossTextClient.cpp b/Common/Clients/AntennaBossTextClient/src/AntennaBossTextClient.cpp index 616ab7337..cd1820bbd 100644 --- a/Common/Clients/AntennaBossTextClient/src/AntennaBossTextClient.cpp +++ b/Common/Clients/AntennaBossTextClient/src/AntennaBossTextClient.cpp @@ -6,6 +6,7 @@ #include <SkySourceC.h> #include <OTFC.h> #include <MoonC.h> +#include <SolarSystemBodyC.h> #include <ManagementErrors.h> #include <acsncSimpleConsumer.h> #include <fstream> @@ -396,7 +397,7 @@ int main(int argc, char *argv[]) { generatorType_box->setStatusLook(Antenna::ANT_SIDEREAL); generatorType_box->setStatusLook(Antenna::ANT_MOON); generatorType_box->setStatusLook(Antenna::ANT_SUN); - generatorType_box->setStatusLook(Antenna::ANT_SOLARSYTEMBODY); + generatorType_box->setStatusLook(Antenna::ANT_SOLARSYSTEMBODY); generatorType_box->setStatusLook(Antenna::ANT_SATELLITE); generatorType_box->setStatusLook(Antenna::ANT_OTF); @@ -434,6 +435,8 @@ int main(int argc, char *argv[]) { _TW_SET_COMPONENT(output_label,0,WINDOW_HEIGHT-(OUTPUT_FIELD_HEIGHT+1),WINDOW_WIDTH-1,OUTPUT_FIELD_HEIGHT,OUTPUT_FIELD_COLOR_PAIR,OUTPUT_FIELD_STYLE,NULL); #endif + + // Monitors ACS_LOG(LM_FULL_INFO,MODULE_NAME"::Main()",(LM_INFO,MODULE_NAME"::MONITORS_INSTALLATION")); /** Add all required monitor installation here */ diff --git a/Common/Clients/AntennaBossTextClient/src/Makefile b/Common/Clients/AntennaBossTextClient/src/Makefile index 61ae88472..ec223f759 100644 --- a/Common/Clients/AntennaBossTextClient/src/Makefile +++ b/Common/Clients/AntennaBossTextClient/src/Makefile @@ -66,7 +66,7 @@ EXECUTABLES_L = _tui_AntennaBossTextClient_OBJECTS = AntennaBossTextClient _tui_AntennaBossTextClient_LIBS = AntennaBossStubs IRALibrary \ ManagmentDefinitionsStubs TextWindowLibrary ClientErrors ComponentErrors ManagementErrors \ - AntennaErrors AntennaDefinitionsStubs EphemGeneratorStubs SkySourceStubs OTFStubs MoonStubs acsnc + AntennaErrors AntennaDefinitionsStubs EphemGeneratorStubs SkySourceStubs OTFStubs MoonStubs SolarSystemBodyStubs acsnc SCRIPTS = antennaBossTui diff --git a/Common/Interfaces/AntennaInterface/idl/SolarSystemBody.midl b/Common/Interfaces/AntennaInterface/idl/SolarSystemBody.midl new file mode 100644 index 000000000..d0d856e20 --- /dev/null +++ b/Common/Interfaces/AntennaInterface/idl/SolarSystemBody.midl @@ -0,0 +1,93 @@ +/* ************************************************************************************/ +/* INAF DISCOS +/* */ +/* $Id: SolarSystemBody.midl,v 1.3 2010-09-24 15:42:03 a.orlati Exp $ */ +/* */ +/* This code is under GNU General Public Licence (GPL) */ +/* */ +/* Who when What */ +/* S.Poppi, S.Righini 09/May/2017 created */ + +#ifndef _SSB_IDL +#define _SSB_IDL + +#include "baci.idl" +#include <enumpropMACRO.idl> +#include <EphemGenerator.idl> + +#pragma prefix "alma" + +module Antenna { + /* + * Here we have defined a struct "SolarSystemBody structure" that contains all the properties of the component. + * Since EphemGenerator defines all the properties of the component and we have inherited the SolarSystemBody component from EphemGenerator. + * This Interface will be mapped into the ACS dynamic component so it can't expose properties in their classic definations. + * Component attributes are read via their accesor method (<i>getAttributes()</i>). * +*/ + DEFATTRIBUTES (SolarSystemBodyAttributes) + double angularSize; /** apparent angular diameter of the body degrees**/ + double distance; /**body distance AU **/ + double radialVelocity; /**body radial velocity km/s**/ + Antenna::TReferenceFrame vradFrame; /** reference frame of the radial velocity */ + Antenna::TVradDefinition vradDefinition; /** definition of the radial velocity */ + + ENDDEFATTRIBUTES; + + + interface SolarSystemBody: EphemGenerator { + /*This is the Interface of the component Moon and this is inherited from EphemGenerator + * all the properties metioned below are inherited by the interface SolarSystemBody + * # input Source ID:SolarSystemBody, the name of the source + * # double right Ascension of the body in radians + * # double decination of the body in radians + * # double azimuth in radians + * # double elevation in radians + * # Julian Epoch the current time as a julian epoch + * # double userAzimuthOffset in radians + * # double userElevationOffset in radians + * # double userRightAscensionOffset in radians + * # double userDeclinationOffset in radians + * # double parallacticAngle in radians + */ + void getAttributes(out SolarSystemBodyAttributes att); /*this method is the attribute accessor*/ + + /** + * This method is only for control software internal use. It used, given a timestamp, to retrive the apparent + * J2000 Equatorial coordiantes coordinates in one shot. + * @throw CORBA::SystemException + * @param timestamp this parameter is used to pass the exact time the caller wants to know the topocentric coordinates. + * @param ra that's the returned value in radians of the right ascension for the requested time. + * @param re that's the returned value in radians of the declination for the requested time. + */ + void getJ2000EquatorialCoordinate(in ACS::Time timestamp, out double ra,out double dec); + + + /** + @param bodyName of the target + + */ + + void setBodyName(in string bodyName) raises (AntennaErrors::AntennaErrorsEx); + + /** + * This method is only for control software internal use. It used, given a timestamp, to retrive the distance of the body + * @param timestamp this parameter is used to pass the exact time the caller wants to know the topocentric coordinates. + * @param distance body distance in AU. + + * J2000 Equatorial coordiantes coordinates in one shot. + + */ + void getDistance(in ACS::Time timestamp, out double distance); + + + }; + +}; + + + + + + +#endif + diff --git a/Common/Interfaces/AntennaInterface/src/Makefile b/Common/Interfaces/AntennaInterface/src/Makefile index e486056f0..3115b17e5 100644 --- a/Common/Interfaces/AntennaInterface/src/Makefile +++ b/Common/Interfaces/AntennaInterface/src/Makefile @@ -30,7 +30,7 @@ CDB_SCHEMAS = Mount Station PointingModel # IDL Files and flags # IDL_FILES = Observatory Mount PointingModel EphemGeneratorMACRO_include \ -EphemGenerator SkySource OTF Refraction AntennaBoss Moon +EphemGenerator SkySource OTF Refraction AntennaBoss Moon SolarSystemBody IDL_TAO_FLAGS = USER_IDL = ObservatoryStubs_LIBS = baciStubs maciStubs AntennaDefinitionsStubs ComponentErrorsStubs @@ -48,7 +48,7 @@ AntennaBossStubs_LIBS = baciStubs maciStubs ManagmentDefinitionsStubs Management EphemGeneratorStubs ComponentErrorsStubs AntennaErrorsStubs \ AntennaDefinitionsStubs MoonStubs_LIBS = baciStubs maciStubs EphemGeneratorStubs - +SolarSystemBodyStubs_LIBS = baciStubs maciStubs EphemGeneratorStubs # # list of all possible C-sources (used to create automatic dependencies) diff --git a/Common/Interfaces/CommonInterface/idl/AntennaDefinitions.midl b/Common/Interfaces/CommonInterface/idl/AntennaDefinitions.midl index c80421b74..972eaf596 100644 --- a/Common/Interfaces/CommonInterface/idl/AntennaDefinitions.midl +++ b/Common/Interfaces/CommonInterface/idl/AntennaDefinitions.midl @@ -105,7 +105,7 @@ module Antenna { ANT_SUN, /*!< tracks the sun */ ANT_MOON, /*!< tracks the moon */ ANT_SATELLITE, /*!< tracks an artificial sattelite */ - ANT_SOLARSYTEMBODY, /*!< tracks a body of the solar system */ + ANT_SOLARSYSTEMBODY, /*!< tracks a body of the solar system */ ANT_OTF, /*!< perform a On the Fly Scan */ ANT_NONE /*!< no generator */ }; diff --git a/Common/Interfaces/CommonInterface/idl/ManagmentDefinitions.midl b/Common/Interfaces/CommonInterface/idl/ManagmentDefinitions.midl index 3eaf865d5..75a79d126 100644 --- a/Common/Interfaces/CommonInterface/idl/ManagmentDefinitions.midl +++ b/Common/Interfaces/CommonInterface/idl/ManagmentDefinitions.midl @@ -62,11 +62,12 @@ module Management { MNG_SUN, /*!< tracks the sun */ MNG_MOON, /*!< tracks the moon */ MNG_SATELLITE, /*!< tracks an artificial sattelite */ + MNG_PLANET, /*!< tracks a planet */ MNG_SOLARSYTEMBODY, /*!< tracks a body of the solar system */ - MNG_OTF, /*!< perform a On the Fly Scan */ + MNG_OTF, /*!< perform a On the Fly Scan */ MNG_OTFC, /*!< this is a wrapper of the otf, it allows the system to compute the center of the on-the-fly */ - MNG_PEAKER, /*!< perform a peaker measurement, involving the subreflector or minor servo systems */ - MNG_SKYDIP, /*!< perform a skydip scan */ + MNG_PEAKER, /*!< perform a peaker measurement, involving the subreflector or minor servo systems */ + MNG_SKYDIP, /*!< perform a skydip scan */ MNG_NONE /*!< no action */ }; diff --git a/Common/Interfaces/CommonInterface/include/ManagementModule.h b/Common/Interfaces/CommonInterface/include/ManagementModule.h index bb2bd2801..6725d43ac 100644 --- a/Common/Interfaces/CommonInterface/include/ManagementModule.h +++ b/Common/Interfaces/CommonInterface/include/ManagementModule.h @@ -40,6 +40,10 @@ public: mode=Management::MNG_SOLARSYTEMBODY; return true; } + else if (strcasecmp(strScan,"PLANET")==0) { + mode=Management::MNG_PLANET; + return true; + } else if (strcasecmp(strScan,"OTF")==0) { mode=Management::MNG_OTF; return true; diff --git a/Common/Interfaces/ManagmentInterface/idl/Scheduler.idl b/Common/Interfaces/ManagmentInterface/idl/Scheduler.idl index 4b7b30dbc..080fc150a 100644 --- a/Common/Interfaces/ManagmentInterface/idl/Scheduler.idl +++ b/Common/Interfaces/ManagmentInterface/idl/Scheduler.idl @@ -293,6 +293,25 @@ module Management { */ void moon() raises (ComponentErrors::ComponentErrorsEx,ManagementErrors::ManagementErrorsEx); + /** + * It allows to immediately start a tracking of the Sun. + * @throw CORBA::SystemExcpetion + * @throw ComponentErrors::ComponentErrorsEx + * @throw ManagementErrors::ManagementErrorsEx + */ + void sun() raises (ComponentErrors::ComponentErrorsEx,ManagementErrors::ManagementErrorsEx); + + /** + * It allows to immediately start a tracking of the Sun. + * @throw CORBA::SystemExcpetion + * @throw ComponentErrors::ComponentErrorsEx + * @throw ManagementErrors::ManagementErrorsEx + */ + + + void planet(in string name) raises (ComponentErrors::ComponentErrorsEx,ManagementErrors::ManagementErrorsEx); + + /** * It allows to immediately go to a fixed horizontal position (beampark). * @param az azimuth in radians. It could be -1, in that case the current position is taken diff --git a/Common/Libraries/XEphemAstroLib/include/astro.h b/Common/Libraries/XEphemAstroLib/include/astro.h new file mode 100644 index 000000000..614b3125e --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/astro.h @@ -0,0 +1,825 @@ +#ifndef _ASTRO_H +#define _ASTRO_H + +#include <stdio.h> + +#ifndef PI +#define PI 3.141592653589793 +#endif + +/* conversions among hours (of ra), degrees and radians. */ +#define degrad(x) ((x)*PI/180.) +#define raddeg(x) ((x)*180./PI) +#define hrdeg(x) ((x)*15.) +#define deghr(x) ((x)/15.) +#define hrrad(x) degrad(hrdeg(x)) +#define radhr(x) deghr(raddeg(x)) + +/* ratio of from synodic (solar) to sidereal (stellar) rate */ +#define SIDRATE .9972695677 + +/* manifest names for planets. + * N.B. must coincide with usage in pelement.c and plans.c. + * N.B. only the first 8 are valid for use with plans(). + */ + +#ifdef __cplusplus +extern "C" { +#endif + +// all of your legacy C code here + + + + +typedef enum { + MERCURY, + VENUS, + MARS, + JUPITER, + SATURN, + URANUS, + NEPTUNE, + PLUTO, + SUN, + MOON, + NOBJ /* total number of basic objects */ +} PLCode; + +/* moon constants for pl_moon */ +typedef enum { + X_PLANET = 0, /* use to mean planet itself */ + PHOBOS = NOBJ, DEIMOS, + IO, EUROPA, GANYMEDE, CALLISTO, + MIMAS, ENCELADUS, TETHYS, DIONE, RHEA, TITAN, HYPERION, IAPETUS, + ARIEL, UMBRIEL, TITANIA, OBERON, MIRANDA, + NBUILTIN +} MCode; + +/* starting point for MJD calculations + */ +#define MJD0 2415020.0 +#define J2000 (2451545.0 - MJD0) /* yes, 2000 January 1 at 12h */ + +/* the Now and Obj typedefs. + * also, a few miscellaneous constants and declarations. + */ + +#define SPD (24.0*3600.0) /* seconds per day */ +#define MAU (1.4959787e11) /* m / au */ +#define LTAU 499.005 /* seconds light takes to travel 1 AU */ +#define ERAD (6.37816e6) /* earth equitorial radius, m */ +#define MRAD (1.740e6) /* moon equitorial radius, m */ +#define SRAD (6.95e8) /* sun equitorial radius, m */ +#define FTPM 3.28084 /* ft per m */ +#define ESAT_MAG 2 /* default satellite magnitude */ +#define FAST_SAT_RPD 0.25 /* max earth sat rev/day considered "fast" */ + +#define EOD (-9786) /* special epoch flag: use epoch of date */ + +/* info about the local observing circumstances and misc preferences */ +typedef struct { + double n_mjd; /* modified Julian date, ie, days since + * Jan 0.5 1900 (== 12 noon, Dec 30, 1899), utc. + * enough precision to get well better than 1 second. + * N.B. if not first member, must move NOMJD inits. + */ + double n_lat; /* geographic (surface-normal) lt, >0 north, rads */ + double n_lng; /* longitude, >0 east, rads */ + double n_tz; /* time zone, hrs behind UTC */ + double n_temp; /* atmospheric temp, degrees C */ + double n_pressure; /* atmospheric pressure, mBar */ + double n_elev; /* elevation above sea level, earth radii */ + double n_dip; /* dip of sun below hzn at twilight, >0 below, rads */ + double n_epoch; /* desired precession display ep as an mjd, or EOD */ + char n_tznm[8]; /* time zone name; 7 chars or less, always 0 at end */ +} Now; + +/* handy shorthands for fields in a Now pointer, np */ +/* +#define mjd np->n_mjd +#define lat np->n_lat +#define lng np->n_lng +#define tz np->n_tz +#define temp np->n_temp +#define pressure np->n_pressure +#define elev np->n_elev +#define dip np->n_dip +#define epoch np->n_epoch +#define tznm np->n_tznm +#define mjed mm_mjed(np) +*/ +/* structures to describe objects of various types. + */ + +/* magnitude values in two different systems */ +typedef struct { + float m1, m2; /* either g/k or H/G, depending on... */ + int whichm; /* one of MAG_gk or MAG_HG */ +} Mag; + +/* whichm */ +#define MAG_HG 0 /* using 0 makes HG the initial default */ +#define MAG_gk 1 + +/* we actually store magnitudes times this scale factor in a short int */ +#define MAGSCALE 100.0 +#define set_smag(op,m) ((op)->s_mag = (short)floor((m)*MAGSCALE + 0.5)) +#define set_fmag(op,m) ((op)->f_mag = (short)floor((m)*MAGSCALE + 0.5)) +#define get_mag(op) ((op)->s_mag / MAGSCALE) +#define get_fmag(op) ((op)->f_mag / MAGSCALE) + +/* longest object name, including trailing '\0' */ +#define MAXNM 21 + +typedef unsigned char ObjType_t; +typedef unsigned char ObjAge_t; +typedef unsigned char byte; + +/* Obj is a massive union. + * many fields are in common so we use macros to make things a little easier. + */ + +/* fields common to *all* structs in the Obj union */ +#define OBJ_COMMON_FLDS \ + ObjType_t co_type; /* current object type; see flags, below */ \ + byte co_flags; /* FUSER*... used by others */ \ + ObjAge_t co_age; /* update aging code; see db.c */ \ + char co_name[MAXNM];/* name, including \0 */ \ + float co_ra; /* geo/topo app/mean ra, rads */ \ + float co_dec; /* geo/topo app/mean dec, rads */ \ + float co_gaera; /* geo apparent ra, rads */ \ + float co_gaedec; /* geo apparent dec, rads */ \ + float co_az; /* azimuth, >0 e of n, rads */ \ + float co_alt; /* altitude above topocentric horizon, rads */ \ + float co_elong; /* angular sep btwen obj and sun, >0 E, degs */ \ + float co_size; /* angular size, arc secs */ \ + short co_mag /* visual magnitude * MAGSCALE */ + +/* fields common to all solar system objects in the Obj union */ +#define OBJ_SOLSYS_FLDS \ + OBJ_COMMON_FLDS; /* all the fixed ones plus ... */ \ + float so_sdist; /* dist from object to sun, au */ \ + float so_edist; /* dist from object to earth, au */ \ + float so_hlong; /* heliocentric longitude, rads */ \ + float so_hlat; /* heliocentric latitude, rads */ \ + float so_phase /* phase, % */ + +/* fields common to all fixed objects in the Obj union */ +#define OBJ_FIXED_FLDS \ + char fo_spect[2]; /* spectral codes, if appropriate */ \ + float fo_epoch; /* eq of ra/dec and time when pm=0; mjd */ \ + float fo_ra; /* ra, rads, in epoch frame */ \ + float fo_dec; /* dec, rads, in epoch frame */ \ + float fo_pmra; /* ra proper motion, rads/day/cos(dec) */ \ + float fo_pmdec; /* dec proper motion, rads/day */ \ + char fo_class /* object class */ + +/* a generic object */ +typedef struct { + OBJ_COMMON_FLDS; +} ObjAny; + +/* a generic sol system object */ +typedef struct { + OBJ_SOLSYS_FLDS; +} ObjSS; + +/* basic Fixed object info. + */ +typedef struct { + OBJ_COMMON_FLDS; + OBJ_FIXED_FLDS; + + /* following are for galaxies */ + byte fo_ratio; /* minor/major diameter ratio. use s/get_ratio() */ + byte fo_pa; /* position angle, E of N, rads. use s/get_pa() */ +} ObjF; + +/* true-orbit parameters of binary-star object type */ +typedef struct { + float bo_T; /* epoch of periastron, years */ + float bo_e; /* eccentricity */ + float bo_o; /* argument of periastron, degress */ + float bo_O; /* longitude of node, degrees */ + float bo_i; /* inclination to plane of sky, degrees */ + float bo_a; /* semi major axis, arc secs */ + float bo_P; /* period, years */ + + /* companion position, computed by obj_cir() iff b_2compute */ + float bo_pa; /* position angle @ ep, rads E of N */ + float bo_sep; /* separation @ ep, arc secs */ + float bo_ra; /* geo/topo app/mean ra, rads */ + float bo_dec; /* geo/topo app/mean dec, rads */ +} BinOrbit; +typedef struct { + float bp_ep; /* epoch of pa/sep, year */ + float bp_pa; /* position angle @ ep, rads E of N */ + float bp_sep; /* separation @ ep, arc secs */ + + /* companion position, computed by obj_cir() iff b_2compute */ + float bp_ra; /* geo/topo app/mean ra, rads */ + float bp_dec; /* geo/topo app/mean dec, rads */ +} BinPos; +#define MAXBINPOS 2 /* max discrete epochs to store when no elements */ +typedef struct { + OBJ_COMMON_FLDS; + OBJ_FIXED_FLDS; + + byte b_2compute; /* whether to compute secondary positions */ + byte b_nbp; /* number of b_bp[] or 0 to use b_bo */ + short b_2mag; /* secondary's magnitude * MAGSCALE */ + char b_2spect[2]; /* secondary's spectrum */ + + /* either a real orbit or a set of discrete pa/sep */ + union { + BinOrbit b_bo; /* orbital elements */ + BinPos b_bp[MAXBINPOS]; /* table of discrete positions */ + } u; +} ObjB; + +#define fo_mag co_mag /* pseudonym for so_mag since it is not computed */ +#define fo_size co_size /* pseudonym for so_size since it is not computed */ + +/* macros to pack/unpack some fields */ +#define SRSCALE 255.0 /* galaxy size ratio scale */ +#define PASCALE (255.0/(2*PI)) /* pos angle scale factor */ +#define get_ratio(op) (((int)(op)->f_ratio)/SRSCALE) +#define set_ratio(op,maj,min) ((op)->f_ratio = (byte)(((maj) > 0) \ + ? ((min)*SRSCALE/(double)(maj)+0.5) \ + : 0)) +#define get_pa(op) ((double)(op)->f_pa/PASCALE) +#define set_pa(op,s) ((op)->f_pa = (byte)((s)*PASCALE + 0.5)) + +#define NCLASSES 128 /* n potential fo_classes -- allow for all ASCII */ + +/* basic planet object info */ +typedef struct { + OBJ_SOLSYS_FLDS; + PLCode plo_code; /* which planet */ + MCode plo_moon; /* which moon, or X_PLANET if planet */ + char plo_evis, plo_svis; /* if moon: whether visible from earth, sun */ + double plo_x, plo_y, plo_z; /* if moon: eq dist from center, planet radii */ + double plo_aux1, plo_aux2; /* various values, depending on type */ +} ObjPl; + +/* basic info about an object in elliptical heliocentric orbit */ +typedef struct { + OBJ_SOLSYS_FLDS; + float eo_inc; /* inclination, degrees */ + float eo_Om; /* longitude of ascending node, degrees */ + float eo_om; /* argument of perihelion, degress */ + float eo_a; /* mean distance, aka,semi-maj axis,AU */ + float eo_M; /* mean anomaly, ie, degrees from perihelion at cepoch*/ + float eo_size; /* angular size, in arc seconds at 1 AU */ + float eo_startok; /* nominal first mjd this set is ok, else 0 */ + float eo_endok; /* nominal last mjd this set is ok, else 0 */ + double eo_e; /* eccentricity (double for when near 1 computing q) */ + double eo_cepoch; /* epoch date (M reference), as an mjd */ + double eo_epoch; /* equinox year (inc/Om/om reference), as an mjd. */ + Mag eo_mag; /* magnitude */ +} ObjE; + +/* basic info about an object in hyperbolic heliocentric orbit */ +typedef struct { + OBJ_SOLSYS_FLDS; + double ho_epoch; /* equinox year (inc/Om/om reference), as an mjd */ + double ho_ep; /* epoch of perihelion, as an mjd */ + float ho_startok; /* nominal first mjd this set is ok, else 0 */ + float ho_endok; /* nominal last mjd this set is ok, else 0 */ + float ho_inc; /* inclination, degs */ + float ho_Om; /* longitude of ascending node, degs */ + float ho_om; /* argument of perihelion, degs. */ + float ho_e; /* eccentricity */ + float ho_qp; /* perihelion distance, AU */ + float ho_g, ho_k; /* magnitude model coefficients */ + float ho_size; /* angular size, in arc seconds at 1 AU */ +} ObjH; + +/* basic info about an object in parabolic heliocentric orbit */ +typedef struct { + OBJ_SOLSYS_FLDS; + double po_epoch; /* reference epoch, as an mjd */ + double po_ep; /* epoch of perihelion, as an mjd */ + float po_startok; /* nominal first mjd this set is ok, else 0 */ + float po_endok; /* nominal last mjd this set is ok, else 0 */ + float po_inc; /* inclination, degs */ + float po_qp; /* perihelion distance, AU */ + float po_om; /* argument of perihelion, degs. */ + float po_Om; /* longitude of ascending node, degs */ + float po_g, po_k; /* magnitude model coefficients */ + float po_size; /* angular size, in arc seconds at 1 AU */ +} ObjP; + +/* basic earth satellite object info */ +typedef struct { + OBJ_COMMON_FLDS; + double eso_epoch; /* reference epoch, as an mjd */ + double eso_n; /* mean motion, rev/day + * N.B. we need double due to a sensitive differencing + * operation used to compute MeanAnomaly in + * esat_main()/satellite.c. + */ + float eso_startok; /* nominal first mjd this set is ok, else 0 */ + float eso_endok; /* nominal last mjd this set is ok, else 0 */ + float eso_inc; /* inclination, degs */ + float eso_raan; /* RA of ascending node, degs */ + float eso_e; /* eccentricity */ + float eso_ap; /* argument of perigee at epoch, degs */ + float eso_M; /* mean anomaly, ie, degrees from perigee at epoch */ + float eso_decay; /* orbit decay rate, rev/day^2 */ + float eso_drag; /* object drag coefficient, (earth radii)^-1 */ + int eso_orbit; /* integer orbit number of epoch */ + + /* computed "sky" results unique to earth satellites */ + float ess_elev; /* height of satellite above sea level, m */ + float ess_range; /* line-of-site distance from observer to satellite, m*/ + float ess_rangev; /* rate-of-change of range, m/s */ + float ess_sublat; /* latitude below satellite, >0 north, rads */ + float ess_sublng; /* longitude below satellite, >0 east, rads */ + int ess_eclipsed;/* 1 if satellite is in earth's shadow, else 0 */ +} ObjES; + +typedef union { + ObjAny any; /* these fields valid for all types */ + ObjSS anyss; /* these fields valid for all solar system types */ + ObjPl pl; /* planet */ + ObjF f; /* fixed object, plus proper motion */ + ObjB b; /* bona fide binary stars (doubles are stored in f) */ + ObjE e; /* object in heliocentric elliptical orbit */ + ObjH h; /* object in heliocentric hyperbolic trajectory */ + ObjP p; /* object in heliocentric parabolic trajectory */ + ObjES es; /* earth satellite */ +} Obj; + + +/* for o_flags -- everybody must agree */ +#define FUSER0 0x01 +#define FUSER1 0x02 +#define FUSER2 0x04 +#define FUSER3 0x08 +#define FUSER4 0x10 +#define FUSER5 0x20 +#define FUSER6 0x40 +#define FUSER7 0x80 + +/* mark an object as being a "field star" */ +#define FLDSTAR FUSER3 +/* mark an object as circum calculation failed */ +#define NOCIRCUM FUSER7 + +/* Obj shorthands: */ +#define o_type any.co_type +#define o_name any.co_name +#define o_flags any.co_flags +#define o_age any.co_age +#define s_ra any.co_ra +#define s_dec any.co_dec +#define s_gaera any.co_gaera +#define s_gaedec any.co_gaedec +#define s_az any.co_az +#define s_alt any.co_alt +#define s_elong any.co_elong +#define s_size any.co_size +#define s_mag any.co_mag + +#define s_sdist anyss.so_sdist +#define s_edist anyss.so_edist +#define s_hlong anyss.so_hlong +#define s_hlat anyss.so_hlat +#define s_phase anyss.so_phase + +#define s_elev es.ess_elev +#define s_range es.ess_range +#define s_rangev es.ess_rangev +#define s_sublat es.ess_sublat +#define s_sublng es.ess_sublng +#define s_eclipsed es.ess_eclipsed + +#define f_class f.fo_class +#define f_spect f.fo_spect +#define f_ratio f.fo_ratio +#define f_pa f.fo_pa +#define f_epoch f.fo_epoch +#define f_RA f.fo_ra +#define f_pmRA f.fo_pmra +#define f_dec f.fo_dec +#define f_pmdec f.fo_pmdec +#define f_mag f.fo_mag +#define f_size f.fo_size + +#define e_cepoch e.eo_cepoch +#define e_epoch e.eo_epoch +#define e_startok e.eo_startok +#define e_endok e.eo_endok +#define e_inc e.eo_inc +#define e_Om e.eo_Om +#define e_om e.eo_om +#define e_a e.eo_a +#define e_e e.eo_e +#define e_M e.eo_M +#define e_size e.eo_size +#define e_mag e.eo_mag + +#define h_epoch h.ho_epoch +#define h_startok h.ho_startok +#define h_endok h.ho_endok +#define h_ep h.ho_ep +#define h_inc h.ho_inc +#define h_Om h.ho_Om +#define h_om h.ho_om +#define h_e h.ho_e +#define h_qp h.ho_qp +#define h_g h.ho_g +#define h_k h.ho_k +#define h_size h.ho_size + +#define p_epoch p.po_epoch +#define p_startok p.po_startok +#define p_endok p.po_endok +#define p_ep p.po_ep +#define p_inc p.po_inc +#define p_qp p.po_qp +#define p_om p.po_om +#define p_Om p.po_Om +#define p_g p.po_g +#define p_k p.po_k +#define p_size p.po_size + +#define es_epoch es.eso_epoch +#define es_startok es.eso_startok +#define es_endok es.eso_endok +#define es_inc es.eso_inc +#define es_raan es.eso_raan +#define es_e es.eso_e +#define es_ap es.eso_ap +#define es_M es.eso_M +#define es_n es.eso_n +#define es_decay es.eso_decay +#define es_drag es.eso_drag +#define es_orbit es.eso_orbit + +#define pl_code pl.plo_code +#define pl_moon pl.plo_moon +#define pl_evis pl.plo_evis +#define pl_svis pl.plo_svis +#define pl_x pl.plo_x +#define pl_y pl.plo_y +#define pl_z pl.plo_z +#define pl_aux1 pl.plo_aux1 +#define pl_aux2 pl.plo_aux2 + +#define b_2compute b.b_2compute +#define b_2spect b.b_2spect +#define b_2mag b.b_2mag +#define b_bo b.u.b_bo +#define b_bp b.u.b_bp +#define b_nbp b.b_nbp + +/* insure we always refer to the fields and no monkey business */ +#undef OBJ_COMMON_FLDS +#undef OBJ_SOLSYS_FLDS + +/* o_type code. + * N.B. names are assigned in order in objmenu.c + * N.B. if add one add switch in obj_cir(). + * N.B. UNDEFOBJ must be zero so new objects are undefinied by being zeroed. + * N.B. maintain the bitmasks too. + */ +enum ObjType { + UNDEFOBJ=0, + FIXED, BINARYSTAR, ELLIPTICAL, HYPERBOLIC, PARABOLIC, EARTHSAT, PLANET, + NOBJTYPES +}; + +/* types as handy bitmasks too */ +#define OBJTYPE2MASK(t) (1<<(t)) +#define FIXEDM OBJTYPE2MASK(FIXED) +#define BINARYSTARM OBJTYPE2MASK(BINARYSTAR) +#define ELLIPTICALM OBJTYPE2MASK(ELLIPTICAL) +#define HYPERBOLICM OBJTYPE2MASK(HYPERBOLIC) +#define PARABOLICM OBJTYPE2MASK(PARABOLIC) +#define EARTHSATM OBJTYPE2MASK(EARTHSAT) +#define PLANETM OBJTYPE2MASK(PLANET) +#define ALLM (~0) + +/* rise, set and transit information. + */ +typedef struct { + int rs_flags; /* info about what has been computed and any + * special conditions; see flags, below. + */ + double rs_risetm; /* mjd time of rise today */ + double rs_riseaz; /* azimuth of rise, rads E of N */ + double rs_trantm; /* mjd time of transit today */ + double rs_tranalt; /* altitude of transit, rads up from horizon */ + double rs_tranaz; /* azimuth of transit, rads E of N */ + double rs_settm; /* mjd time of set today */ + double rs_setaz; /* azimuth of set, rads E of N */ +} RiseSet; + +/* RiseSet flags */ +#define RS_NORISE 0x0001 /* object does not rise as such today */ +#define RS_NOSET 0x0002 /* object does not set as such today */ +#define RS_NOTRANS 0x0004 /* object does not transit as such today */ +#define RS_CIRCUMPOLAR 0x0010 /* object stays up all day today */ +#define RS_NEVERUP 0x0020 /* object never up at all today */ +#define RS_ERROR 0x1000 /* can't figure out anything! */ +#define RS_RISERR (0x0100|RS_ERROR) /* error computing rise */ +#define RS_SETERR (0x0200|RS_ERROR) /* error computing set */ +#define RS_TRANSERR (0x0400|RS_ERROR) /* error computing transit */ + +#define is_type(op,m) (OBJTYPE2MASK((op)->o_type) & (m)) + +/* any planet or its moons */ +#define is_planet(op,p) (is_type(op,PLANETM) && op->pl_code == (p)) + +/* any solar system object */ +#define is_ssobj(op) is_type(op,PLANETM|HYPERBOLICM|PARABOLICM|ELLIPTICALM) + + +/* natural satellite support */ + +typedef struct { + char *full; /* full name */ + char *tag; /* Roman numeral tag */ + float x, y, z; /* sky loc in planet radii: +x:east +y:south +z:front */ + float ra, dec; /* sky location in ra/dec */ + float mag; /* magnitude */ + int evis; /* whether geometrically visible from earth */ + int svis; /* whether in sun light */ + int pshad; /* whether moon is casting shadow on planet */ + int trans; /* whether moon is transiting */ + float sx, sy; /* shadow sky loc in planet radii: +x:east +y:south */ +} MoonData; + +/* separate set for each planet -- use in pl_moon */ + + +enum _marsmoons { + M_MARS = 0, /* == X_PLANET */ + M_PHOBOS, M_DEIMOS, + M_NMOONS /* including planet at 0 */ +}; + +enum _jupmoons { + J_JUPITER = 0, /* == X_PLANET */ + J_IO, J_EUROPA, J_GANYMEDE, J_CALLISTO, + J_NMOONS /* including planet */ +}; + +enum _satmoons { + S_SATURN = 0, /* == X_PLANET */ + S_MIMAS, S_ENCELADUS, S_TETHYS, S_DIONE, + S_RHEA, S_TITAN, S_HYPERION, S_IAPETUS, + S_NMOONS /* including planet */ +}; + +enum _uramoons { + U_URANUS = 0, /* == X_PLANET */ + U_ARIEL, U_UMBRIEL, U_TITANIA, U_OBERON, U_MIRANDA, + U_NMOONS /* including planet */ +}; + +#define X_MAXNMOONS S_NMOONS /* N.B. chosen by hand */ + + +/* global function declarations */ + + +/* aa_hadec.c */ +extern void aa_hadec (double lt, double alt, double az, double *ha, + double *dec); +extern void hadec_aa (double lt, double ha, double dec, double *alt, + double *az); + +/* aberration.c */ +extern void ab_ecl (double m, double lsn, double *lam, double *bet); +extern void ab_eq (double m, double lsn, double *ra, double *dec); + +/* airmass.c */ +extern void airmass (double aa, double *Xp); + +/* anomaly.c */ +extern void anomaly (double ma, double s, double *nu, double *ea); + +/* ap_as.c */ +extern void ap_as ( Now *np, double Mjd, double *rap, double *decp); +extern void as_ap ( Now *np, double Mjd, double *rap, double *decp); + +/* atlas.c */ +extern char *um_atlas (double ra, double dec); +extern char *u2k_atlas (double ra, double dec); +extern char *msa_atlas (double ra, double dec); + +/* aux.c */ +extern double mm_mjed (Now *np); + +/* chap95.c */ +extern int chap95 (double m, int obj, double prec, double *ret); + +/* chap95_data.c */ + +/* circum.c */ +extern int obj_cir (Now *np, Obj *op); + +/* comet.c */ +extern void comet (double m, double ep, double inc, double ap, double qp, + double om, double *lpd, double *psi, double *rp, double *rho, double *lam, + double *bet); + +/* constel.c */ +#define NCNS 89 +extern int cns_pick (double r, double d, double e); +extern int cns_id (char *abbrev); +extern char *cns_name (int id); +extern int cns_edges (double e, double **ra0p, double **dec0p, double **ra1p, + double **dec1p); +extern int cns_list (double ra, double dec, double e, double rad, int ids[]); +extern int cns_figure (int id, double e, double ra[],double dec[],int dcodes[]); +extern int cns_loadfigs (FILE *fp, char msg[]); + +/* dbfmt.c */ +extern int db_crack_line (char s[], Obj *op, char nm[][MAXNM], int nnm, + char whynot[]); +extern void db_write_line (Obj *op, char *lp); +extern int dbline_candidate (char line[]); +extern int get_fields (char *s, int delim, char *fields[]); +extern int db_tle (char *name, char *l1, char *l2, Obj *op); +extern int dateRangeOK (Now *np, Obj *op); + +/* deltat.c */ +extern double deltat (double m); + +/* earthsat.c */ +extern int obj_earthsat (Now *np, Obj *op); + +/* eq_ecl.c */ +extern void eq_ecl (double m, double ra, double dec, double *lt,double *lg); +extern void ecl_eq (double m, double lt, double lg, double *ra,double *dec); + +/* eq_gal.c */ +extern void eq_gal (double m, double ra, double dec, double *lt,double *lg); +extern void gal_eq (double m, double lt, double lg, double *ra,double *dec); + +/* formats.c */ +extern int fs_sexa (char *out, double a, int w, int fracbase); +extern int fs_date (char out[], int format, double jd); +extern int f_scansexa (const char *str, double *dp); +extern void f_sscandate (char *bp, int pref, int *m, double *d, int *y); + +/* helio.c */ +extern void heliocorr (double jd, double ra, double dec, double *hcp); + +/* jupmoon.c */ +extern void jupiter_data (double Mjd, char dir[], Obj *sop, Obj *jop, + double *jupsize, double *cmlI, double *cmlII, double *polera, + double *poledec, MoonData md[J_NMOONS]); + +/* libration.c */ +extern void llibration (double JD, double *llatp, double *llonp); + +/* magdecl.c */ +extern int magdecl (double l, double L, double e, double y, char *dir, + double *dp, char *err); + +/* marsmoon.c */ +extern void marsm_data (double Mjd, char dir[], Obj *sop, Obj *mop, + double *marssize, double *polera, double *poledec, MoonData md[M_NMOONS]); + +/* misc.c */ +extern void zero_mem (void *loc, unsigned len); +extern int tickmarks (double min, double max, int numdiv, double ticks[]); +extern int lc (int cx, int cy, int cw, int x1, int y1, int x2, int y2, + int *sx1, int *sy1, int *sx2, int *sy2); +extern void hg_mag (double h, double g, double rp, double rho, double rsn, + double *mp); +extern int magdiam (int fmag, int magstp, double scale, double mag, + double size); +extern void gk_mag (double g, double k, double rp, double rho, double *mp); +extern double atod (char *buf); +extern void solve_sphere (double A, double b, double cc, double sc, + double *cap, double *Bp); +extern double delra (double dra); +extern void now_lst (Now *np, double *lstp); +extern void radec2ha (Now *np, double ra, double dec, double *hap); +extern void gha (Now *np, Obj *op, double *ghap); +extern char *obj_description (Obj *op); +extern int is_deepsky (Obj *op); + +/* mjd.c */ +extern void cal_mjd (int mn, double dy, int yr, double *m); +extern void mjd_cal (double m, int *mn, double *dy, int *yr); +extern int mjd_dow (double m, int *dow); +extern int isleapyear (int year); +extern void mjd_dpm (double m, int *ndays); +extern void mjd_year (double m, double *yr); +extern void year_mjd (double y, double *m); +extern void rnd_second (double *t); +extern void mjd_dayno (double jd, int *yr, double *dy); +extern double mjd_day (double jd); +extern double mjd_hr (double jd); +extern void range (double *v, double r); +extern void radecrange (double *ra, double *dec); + +/* moon.c */ +extern void moon (double m, double *lam, double *bet, double *rho, + double *msp, double *mdp); + +/* mooncolong.c */ +extern void moon_colong (double jd, double lt, double lg, double *cp, + double *kp, double *ap, double *sp); + +/* moonnf.c */ +extern void moonnf (double mj, double *mjn, double *mjf); + +/* nutation.c */ +extern void nutation (double m, double *deps, double *dpsi); +extern void nut_eq (double m, double *ra, double *dec); + +/* obliq.c */ +extern void obliquity (double m, double *eps); + +/* parallax.c */ +extern void ta_par (double tha, double tdec, double phi, double ht, + double *rho, double *aha, double *adec); + +/* parallactic.c */ +extern double parallacticLDA (double lt, double dec, double alt); +extern double parallacticLHD (double lt, double ha, double dec); + +/* plans.c */ +extern void plans (double m, PLCode p, double *lpd0, double *psi0, + double *rp0, double *rho0, double *lam, double *bet, double *dia, + double *mag); + +/* plshadow.c */ +extern int plshadow (Obj *op, Obj *sop, double polera, + double poledec, double x, double y, double z, float *sxp, float *syp); + +/* plmoon_cir.c */ +extern int plmoon_cir (Now *np, Obj *moonop); +extern int getBuiltInObjs (Obj **opp); +extern void setMoonDir (char *dir); + +/* precess.c */ +extern void precess (double mjd1, double mjd2, double *ra, double *dec); + +/* reduce.c */ +extern void reduce_elements (double mjd0, double m, double inc0, + double ap0, double om0, double *inc, double *ap, double *om); + +/* refract.c */ +extern void unrefract (double pr, double tr, double aa, double *ta); +extern void refract (double pr, double tr, double ta, double *aa); + +/* rings.c */ +extern void satrings (double sb, double sl, double sr, double el, double er, + double JD, double *etiltp, double *stiltp); + +/* riset.c */ +extern void riset (double ra, double dec, double lt, double dis, + double *lstr, double *lsts, double *azr, double *azs, int *status); + +/* riset_cir.c */ +extern void riset_cir (Now *np, Obj *op, double dis, RiseSet *rp); +extern void twilight_cir (Now *np, double dis, double *dawn, double *dusk, + int *status); + +/* satmoon.c */ +extern void saturn_data (double Mjd, char dir[], Obj *eop, Obj *sop, + double *satsize, double *etilt, double *stlit, double *polera, + double *poledec, MoonData md[S_NMOONS]); + +/* sphcart.c */ +extern void sphcart (double l, double b, double r, double *x, double *y, + double *z); +extern void cartsph (double x, double y, double z, double *l, double *b, + double *r); + +/* sun.c */ +extern void sunpos (double m, double *lsn, double *rsn, double *bsn); + +/* twobody.c */ +extern int vrc (double *v, double *r, double tp, double e, double q); + +/* umoon.c */ +extern void uranus_data (double Mjd, char dir[], Obj *sop, Obj *uop, + double *usize, double *polera, double *poledec, MoonData md[U_NMOONS]); + +/* utc_gst.c */ +extern void utc_gst (double m, double utc, double *gst); +extern void gst_utc (double m, double gst, double *utc); + +/* vsop87.c */ +extern int vsop87 (double m, int obj, double prec, double *ret); + +#ifdef __cplusplus +} +#endif + +#endif /* _ASTRO_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: astro.h,v $ $Date: 2013/01/06 01:12:57 $ $Revision: 1.33 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/include/bdl.h b/Common/Libraries/XEphemAstroLib/include/bdl.h new file mode 100644 index 000000000..3b4d0ea33 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/bdl.h @@ -0,0 +1,6 @@ +extern int read_bdl (FILE *fp, double jd, double *xp, double *yp, double *zp, + char ynot[]); + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: bdl.h,v $ $Date: 2003/03/20 08:56:31 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/include/chap95.h b/Common/Libraries/XEphemAstroLib/include/chap95.h new file mode 100644 index 000000000..fff8acdd7 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/chap95.h @@ -0,0 +1,68 @@ +/* Position of outer planets; straightforward from: +ftp://adc.gsfc.nasa.gov/pub/adc/archives/journal_tables/A+AS/109/181: + +J/A+AS/109/181 Planetary ephemerides (Chapront, 1995) +=============================================================================== +Representation of planetary ephemerides by frequency analysis. Application to +the five outer planets. + CHAPRONT J. + <Astron. Astrophys. Suppl. Ser. 109, 181 (1995)> + =1995A&AS..109..181C (SIMBAD/NED Reference) +=============================================================================== + +Keywords: ephemerides - planets and satellites: general - methods: numerical + +Contents: + Heliocentric equatorial rectangular coordinates of the five outer planets + (X, Y and Z). The source is based on DE200 (tables 4 to 7) or a reconstruction + of DE200 by numerical integration (tables 9 to 13). The reference frame is + the mean equator and equinox J2000 of DE200. + + The general formulation of the series X is: + X = SUM[i=1,Records] T**n_i*(CX_i*cos(Nu_k*t)+SX_i*sin(Nu_k*t)) + The formulation is identical for Y and Z. + T is the time (TDB) in Julian centuries from J2000: + T = (JulianDate - 2451545.0)/36525 + t is the time (TDB) in Julian years from J2000: + t = (JulianDate - 2451545.0)/365.25 + Nu is the frequency. Frequencies are identical for all terms of rank k: + Nu_k = Nu_i when n_i = 0 + For purely secular terms k = 0 and Nu_0 = 0 + +=============================================================================== +(End) Patricia Bauer [CDS] 03-Oct-1994 +*/ + +#define CHAP_SCALE 1e10 + +/* JDs of validity period */ +#define CHAP_BEGIN (2338032.5 - MJD0) /* 1689/3/19 */ +#define CHAP_END (2542032.5 - MJD0) /* 2247/10/1 */ + +/* coding flags */ +/* calculating rates increases time by about 10% + * + * On an HP715/75, for pluto the times per step are 0.00049 s and 0.00057 s + * This method is quite fast. + */ +#define CHAP_GETRATE 1 + +typedef struct { + short n; /* order of time; "-1" marks end of list */ + double amp[6]; /* amplitudes of cosine and sine terms for x,y,z */ + /* in original order [CX,SX,CY,SY,CZ,SZ] */ + double Nu; /* Frequency Nu_k; given only at n=0 */ +} chap95_rec; + +extern chap95_rec chap95_jupiter[]; +extern chap95_rec chap95_saturn[]; +extern chap95_rec chap95_uranus[]; +extern chap95_rec chap95_neptune[]; +extern chap95_rec chap95_pluto[]; + +extern int chap95 (double m, int obj, double prec, double *ret); + + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: chap95.h,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.2 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/include/deepconst.h b/Common/Libraries/XEphemAstroLib/include/deepconst.h new file mode 100644 index 000000000..8c715676a --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/deepconst.h @@ -0,0 +1,34 @@ +#ifndef _CONST_H +#define _CONST_H + +/* $Id: deepconst.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + + +#define GE (3.986005E14) + +#define PI (3.1415926535897932385) + +#define XKE (7.43669161E-2) +#define CK2 (5.413080E-4) +#define CK4 (6.2098875E-7) +#define E6A (10E6) +#define QOMS2T (1.88027916E-9) +#define S (1.01222928) +#define TOTHRD (2.0/3.0) /* 6.6666666666666666667E-1 */ +#define XJ3 (-2.53881E-6) +/* #define XKE KE */ +#define XKMPER (6378.135) +#define XMNPDA (1440.0) +#define AE (1.0) +#define DE2RA (1.7453292519943295769E-2) +#define PIO2 (1.57079632679489661925) /* PI/2 */ +#define TWOPI (6.2831853071795864770) +#define X3PIO2 (4.7123889803846898578) /* 3*PI/2 */ + +#define RHO (0.15696590235) + +#endif /* _CONST_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: deepconst.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/include/preferences.h b/Common/Libraries/XEphemAstroLib/include/preferences.h new file mode 100644 index 000000000..c5786611f --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/preferences.h @@ -0,0 +1,41 @@ +/* global info for the preferences facility. + * N.B. many of these enums are used as indexes -- don't change without + * checking where they are used! + */ +#ifndef _PREFERENCES_H +#define _PREFERENCES_H + +#ifdef __cplusplus +extern "C" { +#endif + +// all of your legacy C code here + + +typedef enum { + PREF_EQUATORIAL, PREF_UNITS, PREF_DATE_FORMAT, PREF_ZONE, PREF_DPYPREC, + PREF_MSG_BELL, PREF_PRE_FILL, PREF_TIPS, PREF_CONFIRM, PREF_WEEKSTART, + NPREFS +} Preferences; + +typedef enum {PREF_GEO, PREF_TOPO} PrefEquatorial; +typedef enum {PREF_ENGLISH, PREF_METRIC} PrefUnits; +typedef enum {PREF_MDY, PREF_YMD, PREF_DMY} PrefDateFormat; +typedef enum {PREF_LOCALTZ, PREF_UTCTZ} PrefStampZone; +typedef enum {PREF_LOPREC, PREF_HIPREC} PrefDpyPrec; +typedef enum {PREF_NOMSGBELL, PREF_MSGBELL} PrefMsgBell; +typedef enum {PREF_PREFILL, PREF_NOPREFILL} PrefPreFill; +typedef enum {PREF_TIPSON, PREF_NOTIPS} PrefTips; +typedef enum {PREF_CONFIRMON, PREF_NOCONFIRM} PrefConfirm; +typedef enum {PREF_SAT, PREF_SUN, PREF_MON} PrefWeekStart; + +extern int pref_get (Preferences p); +extern int pref_set (Preferences p, int newp); +#ifdef __cplusplus +} +#endif +#endif /* _PREFERENCES_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: preferences.h,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.6 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/include/satlib.h b/Common/Libraries/XEphemAstroLib/include/satlib.h new file mode 100644 index 000000000..31c34675c --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/satlib.h @@ -0,0 +1,206 @@ +#ifndef __SATLIB_H +#define __SATLIB_H + +/* $Id: satlib.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + +typedef struct _SatElem { + float se_XMO; + float se_XNODEO; + float se_OMEGAO; + float se_EO; + float se_XINCL; + float se_XNDD60; + float se_BSTAR; + float pad1; + double se_XNO; + double se_XNDT20; + double se_EPOCH; + struct { + unsigned int catno : 21; + unsigned int classif : 5; + unsigned int elnum : 10; + unsigned int year : 14; + unsigned int launch : 10; + unsigned int piece : 15; + unsigned int ephtype : 4; + unsigned int orbit : 17; + } se_id; +} SatElem; + +#if 0 +struct sat_loc { + double sl_X; + double sl_XDOT; + double sl_Y; + double sl_YDOT; + double sl_Z; + double sl_ZDOT; +}; +#endif + +struct sgp4_data { + unsigned int sgp4_flags; + unsigned int pad; + double sgp4_AODP; + double sgp4_AYCOF; + double sgp4_C1; + double sgp4_C4; + double sgp4_C5; + double sgp4_COSIO; + double sgp4_D2; + double sgp4_D3; + double sgp4_D4; + double sgp4_DELMO; + double sgp4_ETA; + double sgp4_OMGCOF; + double sgp4_OMGDOT; + double sgp4_SINIO; + double sgp4_SINMO; + double sgp4_T2COF; + double sgp4_T3COF; + double sgp4_T4COF; + double sgp4_T5COF; + double sgp4_X1MTH2; + double sgp4_X3THM1; + double sgp4_X7THM1; + double sgp4_XLCOF; + double sgp4_XMCOF; + double sgp4_XMDOT; + double sgp4_XNODCF; + double sgp4_XNODOT; + double sgp4_XNODP; +}; + +struct deep_data { + struct { + unsigned int IRESFL : 1; + unsigned int ISYNFL : 1; + } deep_flags; + double deep_s_SINIQ; + double deep_s_COSIQ; + double deep_s_OMGDT; + double deep_ATIME; + double deep_D2201; + double deep_D2211; + double deep_D3210; + double deep_D3222; + double deep_D4410; + double deep_D4422; + double deep_D5220; + double deep_D5232; + double deep_D5421; + double deep_D5433; + double deep_DEL1; + double deep_DEL2; + double deep_DEL3; + double deep_E3; + double deep_EE2; + double deep_FASX2; + double deep_FASX4; + double deep_FASX6; + double deep_OMEGAQ; + double deep_PE; + double deep_PINC; + double deep_PL; + double deep_SAVTSN; + double deep_SE2; + double deep_SE3; + double deep_SGH2; + double deep_SGH3; + double deep_SGH4; + double deep_SGHL; + double deep_SGHS; + double deep_SH2; + double deep_SH3; + double deep_SHS; + double deep_SHL; + double deep_SI2; + double deep_SI3; + double deep_SL2; + double deep_SL3; + double deep_SL4; + double deep_SSE; + double deep_SSG; + double deep_SSH; + double deep_SSI; + double deep_SSL; + double deep_STEP2; + double deep_STEPN; + double deep_STEPP; + double deep_THGR; + double deep_XFACT; + double deep_XGH2; + double deep_XGH3; + double deep_XGH4; + double deep_XH2; + double deep_XH3; + double deep_XI2; + double deep_XI3; + double deep_XL2; + double deep_XL3; + double deep_XL4; + double deep_XLAMO; + double deep_XLI; + double deep_XNI; + double deep_XNQ; + double deep_XQNCL; + double deep_ZMOL; + double deep_ZMOS; +}; + +struct sdp4_data { + double sdp4_AODP; /* dpa */ + double sdp4_AYCOF; + double sdp4_BETAO; /* dpa */ + double sdp4_BETAO2; /* dpa */ + double sdp4_C1; + double sdp4_C4; + double sdp4_COSG; /* dpa */ + double sdp4_COSIO; /* dpa */ + double sdp4_EOSQ; /* dpa */ + double sdp4_OMGDOT; /* dpa */ + double sdp4_SING; /* dpa */ + double sdp4_SINIO; /* dpa */ + double sdp4_T2COF; + double sdp4_THETA2; /* dpa */ + double sdp4_X1MTH2; + double sdp4_X3THM1; + double sdp4_X7THM1; + double sdp4_XLCOF; + double sdp4_XMDOT; /* dpa */ + double sdp4_XNODCF; + double sdp4_XNODOT; /* dpa */ + double sdp4_XNODP; /* dpa */ + + double sdp4_XMDF_seco; + double sdp4_OMGADF_seco; + double sdp4_XNODE_seco; + double sdp4_EM_seco; + double sdp4_XINC_seco; + double sdp4_XN_seco; + + double sdp4_E_pero; + double sdp4_XINC_pero; + double sdp4_OMGADF_pero; + double sdp4_XNODE_pero; + double sdp4_XMAM_pero; +}; + +typedef struct _SatData { + struct _SatElem *elem; + union { + struct sgp4_data *sgp4; + struct sdp4_data *sdp4; + } prop; + struct deep_data *deep; +} SatData; + +void sgp4(SatData *sat, Vec3 *pos, Vec3 *dpos, double t); + +void sdp4(SatData *sat, Vec3 *pos, Vec3 *dpos, double TSINCE); + +#endif /* __SATLIB_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: satlib.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/include/satspec.h b/Common/Libraries/XEphemAstroLib/include/satspec.h new file mode 100644 index 000000000..0986dd789 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/satspec.h @@ -0,0 +1,43 @@ +#ifndef __SATSPEC_H +#define __SATSPEC_H + +/* $Id: satspec.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + +#include "sattypes.h" +#include "satlib.h" + +#define SGP4_SIMPLE 0x00000001 + +extern void init_deep(struct deep_data *deep); +void init_sdp4(struct sdp4_data *sdp); +char *tleerr(int); +int readtle(char *, char *, SatElem *); + +double current_jd(); + +double ut1_to_gha(double); + +void smallsleep(double t); + +double epoch_jd(double); + +double actan(double sinx, double cosx); + +double thetag(double EP, double *DS50); + +void dpinit(SatData *sat, double EQSQ, double SINIQ, double COSIQ, + double RTEQSQ, double AO, double COSQ2, double SINOMO, + double COSOMO, double BSQ, double XLLDOT, double OMGDT, + double XNODOT, double XNODP); + +void dpsec(SatData *sat, double *XLL, double *OMGASM, double *XNODES, + double *EM, double *XINC, double *XN, double T); + +void dpper(SatData *sat, double *EM, double *XINC, double *OMGASM, + double *XNODES, double *XLL, double T); + +#endif /* __SATSPEC_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: satspec.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/include/sattypes.h b/Common/Libraries/XEphemAstroLib/include/sattypes.h new file mode 100644 index 000000000..61891ff03 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/sattypes.h @@ -0,0 +1,28 @@ +#ifndef __SATTYPES_H +#define __SATTYPES_H + +/* $Id: sattypes.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + +typedef struct _Vec3 { + double x, y, z; +} Vec3; + + +typedef struct _LookAngle { + double az; + double el; + double r; +} LookAngle; + + +typedef struct _Geoloc { + double lt; + double ln; + double h; +} GeoLoc; + +#endif /* __SATTYPES_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: sattypes.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/include/vector.h b/Common/Libraries/XEphemAstroLib/include/vector.h new file mode 100644 index 000000000..be1ec56c2 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/vector.h @@ -0,0 +1,19 @@ +#ifndef __SATVECTOR_H +#define __SATVECTOR_H + +/* $Id: vector.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + +#define dotp(A,B) ((A).x*(B).x+(A).y*(B).y+(A).z*(B).z) + +#define crossp(A,B,C) {(C).x=(A).y*(B).z-(A).z*(B).y;(C).y=(A).z*(B).x-(A).x*(B).z;(C).z=(A).x*(B).y-(A).y*(B).x;} + +#define vecabs(V) (sqrt((V).x*(V).x+(V).y*(V).y+(V).z*(V).z)) +#define vecsq(V) ((V).x*(V).x+(V).y*(V).y+(V).z*(V).z) +#define vecsub(A,B,C) {(C).x=(A).x-(B).x;(C).y=(A).y-(B).y;(C).z=(A).z-(B).z;} +#define vecscale(A,k) {(A).x*=(k);(A).y*=(k);(A).z*=(k);} + +#endif /* __SATVECTOR_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: vector.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/include/vsop87.h b/Common/Libraries/XEphemAstroLib/include/vsop87.h new file mode 100644 index 000000000..b5cb958f5 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/include/vsop87.h @@ -0,0 +1,93 @@ +/* Position of planets mercury to neptune; from: +ftp://ftp.bdl.fr/pub/ephem/planets/vsop87/ +from README: + +========================== =========================== + BUREAU DES LONGITUDES + PLANETARY SOLUTION VSOP87 + 1996, January +========================== =========================== + +These files and programs are associated to : + +Planetary Theories in rectangular and spherical variables: VSOP87 solution. + Bretagnon P., Francou G. + Astron. Astrophys. 202, 309 (1988). + +Theorie du mouvement de l'ensemble des planetes (VSOP82). + Bretagnon P. + Astron. Astrophys. 114, 278 (1982). + +============================================================================== + +Description: + The Planetary solutions VSOP87 (Variations Seculaires des Orbites + Planetaires) are analytical solutions of the motion of the planets in + different versions. The main version VSOP87 consists of the series in + elliptic elements as in the case of VSOP82 solution and the other + versions VSOP87 (A-B-C-D-E) are built in rectangular and spherical + variables. + +Authors' Address: + P. Bretagnon, G. Francou + Bureau des Longitudes, CNRS URA 707 + 77, Avenue Denfert-Rochereau + 75014, Paris, France + Tel : (33) 1 40 51 22 69 (33) 1 40 51 22 60 + Fax : (33) 1 46 33 28 34 + E-mail : pierre@bdl.fr francou@bdl.fr + +Contents: + The main version of VSOP87 is similar to the previous theory VSOP82. + In the both cases the constants of integration have been determined by + fitting to the numerical integration DE200 of the Jet Propulsion + Laboratory. The various versions of VSOP87 are different from one to + another in the type of coordinates and the reference frame. + VSOP87 : heliocentric elliptic variables; equinox and ecliptic J2000. + VSOP87A : heliocentric rectangular variables; equinox and ecliptic J2000. + VSOP87B : heliocentric spherical variables; equinox and ecliptic J2000. + VSOP87C : heliocentric rectangular variables; equinox and ecliptic of date. + VSOP87D : heliocentric spherical variables; equinox and ecliptic of date. + VSOP87E : barycentric rectangular variables; equinox and ecliptic J2000. +... +============================================================================== +User feed-back is encouraged. Unless otherwise specified, send comments and bug +reports to: E-mail : comments@bdl.fr + Fax : (33) 1 46 33 28 34 + Postal mail: Bureau des longitudes + 77 avenue Denfert Rochereau + F-75014 PARIS +============================================================================== + implemented for C: stern +*/ + +#define VSOP_ASCALE 1e8 /* amplitude factor as stored */ + +/* coding flags */ +#define VSOP_SPHERICAL 1 /* version in data.c uses spherical coords */ +#define VSOP_GETRATE 0 /* calculate time derivatives of coordinates */ + +/* data tables */ +extern double vx_mercury[][3]; +extern int vn_mercury[][3]; +extern double vx_venus[][3]; +extern int vn_venus[][3]; +extern double vx_earth[][3]; +extern int vn_earth[][3]; +extern double vx_mars[][3]; +extern int vn_mars[][3]; +extern double vx_jupiter[][3]; +extern int vn_jupiter[][3]; +extern double vx_saturn[][3]; +extern int vn_saturn[][3]; +extern double vx_uranus[][3]; +extern int vn_uranus[][3]; +extern double vx_neptune[][3]; +extern int vn_neptune[][3]; + +extern int vsop87 (double mj, int obj, double prec, double *ret); + + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: vsop87.h,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.2 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/Makefile b/Common/Libraries/XEphemAstroLib/src/Makefile new file mode 100644 index 000000000..0e1eb839e --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/Makefile @@ -0,0 +1,253 @@ + +#******************************************************************************* +# ALMA - Atacama Large Millimiter Array +# Copyright (c) UNSPECIFIED - FILL IN, 2021 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# "@(#) $Id$" +# +# Makefile of ........ +# +# who when what +# -------- -------- ---------------------------------------------- +# SPOPPI 2021-06-29 created +# + +# ALMA - Atacama Large Millimeter Array +# Copyright (c) ESO - European Southern Observatory, 2014 +# (in the framework of the ALMA collaboration). +# All rights reserved. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#******************************************************************************* + +#******************************************************************************* +# This Makefile follows ALMA/ACS Standards (see Makefile(5) for more). +#******************************************************************************* +# REMARKS +# None +#------------------------------------------------------------------------ + +# +# user definable C-compilation flags +USER_CFLAGS = -c -pedantic -Wall + +# +# additional include and library search paths +#USER_INC = +USER_LIB = -lm + +# +# MODULE CODE DESCRIPTION: +# ------------------------ +# As a general rule: public file are "cleaned" and "installed" +# local (_L) are not "installed". + +# +# C programs (public and local) +# ----------------------------- +EXECUTABLES = +EXECUTABLES_L = + +# +# <brief description of xxxxx program> +astro_OBJECTS = aa_hadec aberration actan \ + airmass anomaly ap_as atlas auxil \ + bdl chap95 chap95_data circum comet constel \ + dbfmt deep deltat earthsat eq_ecl eq_gal \ + formats helio jupmoon libration magdecl marsmoon \ + misc mjd moon mooncolong moonnf nutation obliq \ + parallactic parallax plans plmoon plshadow precess \ + reduce refract rings riset riset_cir satmoon sdp4\ + sgp4 sphcart sun thetag twobody umoon utc_gst vsop87 vsop87_data + +# +# special compilation flags for single c sources +#yyyyy_CFLAGS = + +# +# Includes (.h) files (public only) +# --------------------------------- +INCLUDES = astro.h chap95.h preferences.h satspec.h vector.h \ + bdl.h deepconst.h satlib.h sattypes.h vsop87.h + + +# +# Libraries (public and local) +# ---------------------------- +LIBRARIES = astro +LIBRARIES_L = + +# +# <brief description of lllll library> +lllll_OBJECTS = + +# +# Scripts (public and local) +# ---------------------------- +SCRIPTS = +SCRIPTS_L = + +# +# TCL scripts (public and local) +# ------------------------------ +TCL_SCRIPTS = +TCL_SCRIPTS_L = + +# +# Python stuff (public and local) +# ---------------------------- +PY_SCRIPTS = +PY_SCRIPTS_L = + +PY_MODULES = +PY_MODULES_L = + +PY_PACKAGES = +PY_PACKAGES_L = +pppppp_MODULES = + +# +# <brief description of tttttt tcl-script> +tttttt_OBJECTS = +tttttt_TCLSH = +tttttt_LIBS = + +# +# TCL libraries (public and local) +# ------------------------------ +TCL_LIBRARIES = +TCL_LIBRARIES_L = + +# +# <brief description of tttlll library> +tttlll_OBJECTS = + +# +# Configuration Database Files +# ---------------------------- +CDB_SCHEMAS = + +# +# IDL Files and flags +# +IDL_FILES = +TAO_IDLFLAGS = +USER_IDL = +# +# Jarfiles and their directories +# +JARFILES= +jjj_DIRS= +jjj_EXTRAS= +# For expressing dependencies between jarfiles (parallel builds) +jjj_JLIBS= +# +# java sources in Jarfile on/off +DEBUG= +# +# ACS XmlIdl generation on/off +# +XML_IDL= +# +# Java Component Helper Classes generation on/off +# +COMPONENT_HELPERS= +# +# Java Entity Classes generation on/off +# +XSDBIND= +# +# Schema Config files for the above +# +XSDBIND_INCLUDE= +# man pages to be done +# -------------------- +MANSECTIONS = +MAN1 = +MAN3 = +MAN5 = +MAN7 = +MAN8 = + +# +# local man pages +# --------------- +MANl = + +# +# ASCII file to be converted into Framemaker-MIF +# -------------------- +ASCII_TO_MIF = + +# +# other files to be installed +#---------------------------- +INSTALL_FILES = + +# +# list of all possible C-sources (used to create automatic dependencies) +# ------------------------------ +CSOURCENAMES = \ + $(foreach exe, $(EXECUTABLES) $(EXECUTABLES_L), $($(exe)_OBJECTS)) \ + $(foreach rtos, $(RTAI_MODULES) , $($(rtos)_OBJECTS)) \ + $(foreach lib, $(LIBRARIES) $(LIBRARIES_L), $($(lib)_OBJECTS)) + +# +#>>>>> END OF standard rules + +# +# INCLUDE STANDARDS +# ----------------- + +MAKEDIRTMP := $(shell searchFile include/acsMakefile) +ifneq ($(MAKEDIRTMP),\#error\#) + MAKEDIR := $(MAKEDIRTMP)/include + include $(MAKEDIR)/acsMakefile +endif + +# +# TARGETS +# ------- +all: do_all + @echo " . . . 'all' done" + +clean : clean_all + @echo " . . . clean done" + +clean_dist : clean_all clean_dist_all + @echo " . . . clean_dist done" + +man : do_man + @echo " . . . man page(s) done" + +install : install_all + @echo " . . . installation done" + + +#___oOo___ diff --git a/Common/Libraries/XEphemAstroLib/src/a.out b/Common/Libraries/XEphemAstroLib/src/a.out new file mode 100644 index 0000000000000000000000000000000000000000..b53e559fff301498abe59a1e4864ec5d0bdf55de GIT binary patch literal 409952 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	`s^08QKks{RF< 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�<!&>LBAkf}kpyKk^s2GZg@G0_%w>AnlQ$ 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�)?Jdh6_P^?~_JG<y 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	v!1g7SO3VP6lcFm-2_&AtaWMfzGkkpO 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 literal 0 HcmV?d00001 diff --git a/Common/Libraries/XEphemAstroLib/src/aa_hadec.c b/Common/Libraries/XEphemAstroLib/src/aa_hadec.c new file mode 100644 index 000000000..29a2b6e24 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/aa_hadec.c @@ -0,0 +1,77 @@ +/* function to convert between alt/az and ha/dec. + */ + +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +static void aaha_aux (double lt, double x, double y, double *p, double *q); + +/* given geographical latitude (n+, radians), lt, altitude (up+, radians), + * alt, and azimuth (angle round to the east from north+, radians), + * return hour angle (radians), ha, and declination (radians), dec. + */ +void +aa_hadec ( +double lt, +double alt, double az, +double *ha, double *dec) +{ + aaha_aux (lt, az, alt, ha, dec); + if (*ha > PI) + *ha -= 2*PI; +} + +/* given geographical (n+, radians), lt, hour angle (radians), ha, and + * declination (radians), dec, return altitude (up+, radians), alt, and + * azimuth (angle round to the east from north+, radians), + */ +void +hadec_aa ( +double lt, +double ha, double dec, +double *alt, double *az) +{ + aaha_aux (lt, ha, dec, az, alt); +} + +#ifdef NEED_GEOC +/* given a geographic (surface-normal) latitude, phi, return the geocentric + * latitude, psi. + */ +double +geoc_lat ( +double phi) +{ +#define MAXLAT degrad(89.9999) /* avoid tan() greater than this */ + return (fabs(phi)>MAXLAT ? phi : atan(tan(phi)/1.00674)); +} +#endif + +/* the actual formula is the same for both transformation directions so + * do it here once for each way. + * N.B. all arguments are in radians. + */ +static void +aaha_aux ( +double lt, +double x, double y, +double *p, double *q) +{ + static double last_lt = -3434, slt, clt; + double cap, B; + + if (lt != last_lt) { + slt = sin(lt); + clt = cos(lt); + last_lt = lt; + } + + solve_sphere (-x, PI/2-y, slt, clt, &cap, &B); + *p = B; + *q = PI/2 - acos(cap); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: aa_hadec.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/aberration.c b/Common/Libraries/XEphemAstroLib/src/aberration.c new file mode 100644 index 000000000..af55df382 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/aberration.c @@ -0,0 +1,161 @@ +/* aberration, Jean Meeus, "Astronomical Algorithms", Willman-Bell, 1995; + * based on secular unperturbed Kepler orbit + * + * the corrections should be applied to ra/dec and lam/beta at the + * epoch of date. + */ + +#include <stdio.h> +#include <math.h> +#include <stdlib.h> + +#include "astro.h" + +#define ABERR_CONST (20.49552/3600./180.*PI) /* aberr const in rad */ +#define AB_ECL_EOD 0 +#define AB_EQ_EOD 1 + +static void ab_aux (double mj, double *x, double *y, double lsn, int mode); + +/* apply aberration correction to ecliptical coordinates *lam and *bet + * (in radians) for a given time m and handily supplied longitude of sun, + * lsn (in radians) + */ +void +ab_ecl (double mj, double lsn, double *lam, double *bet) +{ + ab_aux(mj, lam, bet, lsn, AB_ECL_EOD); +} + +/* apply aberration correction to equatoreal coordinates *ra and *dec + * (in radians) for a given time m and handily supplied longitude of sun, + * lsn (in radians) + */ +void +ab_eq (double mj, double lsn, double *ra, double *dec) +{ +#if defined(USE_MEEUS_AB_EQ) + + /* this claims to account for earth orbit excentricity and is also + * smooth clear to dec=90 but it does not work well backwards with + * ap_as() + */ + ab_aux(mj, ra, dec, lsn, AB_EQ_EOD); + +#else /* use Montenbruck */ + + /* this agrees with Meeus to within 0.2 arcsec until dec gets larger + * than about 89.9, then grows to 1as at 89.97. but it works very + * smoothly with ap_as + */ + double x, y, z; /* equatorial rectangular coords */ + double vx, vy, vz; /* aberration velocity in rectangular coords */ + double L; /* helio long of earth */ + double cL; + double r; + + + sphcart (*ra, *dec, 1.0, &x, &y, &z); + + L = 2*PI*(0.27908 + 100.00214*(mj-J2000)/36525.0); + cL = cos(L); + vx = -0.994e-4*sin(L); + vy = 0.912e-4*cL; + vz = 0.395e-4*cL; + x += vx; + y += vy; + z += vz; + + cartsph (x, y, z, ra, dec, &r); + +#endif +} + +/* because the e-terms are secular, keep the real transformation for both + * coordinate systems in here with the secular variables cached. + * mode == AB_ECL_EOD: x = lam, y = bet (ecliptical) + * mode == AB_EQ_EOD: x = ra, y = dec (equatoreal) + */ +static void +ab_aux (double mj, double *x, double *y, double lsn, int mode) +{ + static double lastmj = -10000; + static double eexc; /* earth orbit excentricity */ + static double leperi; /* ... and longitude of perihelion */ + static char dirty = 1; /* flag for cached trig terms */ + + if (mj != lastmj) { + double T; /* centuries since J2000 */ + + T = (mj - J2000)/36525.; + eexc = 0.016708617 - (42.037e-6 + 0.1236e-6 * T) * T; + leperi = degrad(102.93735 + (0.71953 + 0.00046 * T) * T); + lastmj = mj; + dirty = 1; + } + + switch (mode) { + case AB_ECL_EOD: /* ecliptical coords */ + { + double *lam = x, *bet = y; + double dlsun, dlperi; + + dlsun = lsn - *lam; + dlperi = leperi - *lam; + + /* valid only for *bet != +-PI/2 */ + *lam -= ABERR_CONST/cos(*bet) * (cos(dlsun) - + eexc*cos(dlperi)); + *bet -= ABERR_CONST*sin(*bet) * (sin(dlsun) - + eexc*sin(dlperi)); + } + break; + + case AB_EQ_EOD: /* equatoreal coords */ + { + double *ra = x, *dec = y; + double sr, cr, sd, cd, sls, cls;/* trig values coords */ + static double cp, sp, ce, se; /* .. and perihel/eclipic */ + double dra, ddec; /* changes in ra and dec */ + + if (dirty) { + double eps; + + cp = cos(leperi); + sp = sin(leperi); + obliquity(mj, &eps); + se = sin(eps); + ce = cos(eps); + dirty = 0; + } + + sr = sin(*ra); + cr = cos(*ra); + sd = sin(*dec); + cd = cos(*dec); + sls = sin(lsn); + cls = cos(lsn); + + dra = ABERR_CONST/cd * ( -(cr * cls * ce + sr * sls) + + eexc * (cr * cp * ce + sr * sp)); + + ddec = se/ce * cd - sr * sd; /* tmp use */ + ddec = ABERR_CONST * ( -(cls * ce * ddec + cr * sd * sls) + + eexc * (cp * ce * ddec + cr * sd * sp) ); + + *ra += dra; + *dec += ddec; + radecrange (ra, dec); + } + break; + + default: + printf ("ab_aux: bad mode: %d\n", mode); + abort(); + break; + + } /* switch (mode) */ +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: aberration.c,v $ $Date: 2006/08/28 00:22:26 $ $Revision: 1.6 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/actan.c b/Common/Libraries/XEphemAstroLib/src/actan.c new file mode 100644 index 000000000..a04725ba1 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/actan.c @@ -0,0 +1,67 @@ +#include <math.h> + +/* @(#) $Id: actan.c,v 1.3 2001/01/10 16:32:21 ecdowney Exp $ */ + +/* commonly in math.h, but not in strict ANSI C */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#define M_PI_2 1.57079632679489661923 +#endif + +double +actan(double sinx, double cosx) +{ + double ret; + + ret = 0.0; + if(cosx < 0.0) { + ret = M_PI; + } else if(cosx == 0.0) { + if(sinx < 0.0) { + return 3.0 * M_PI_2; + } else if(sinx == 0.0) { + return ret; + } else /* sinx > 0.0 */ { + return M_PI_2; + } + } else /* cosx > 0.0 */ { + if(sinx < 0.0) { + ret = 2.0 * M_PI; + } else if(sinx == 0.0) { + return ret; + } + } + + return ret + atan(sinx / cosx); +} + + +#if 0 + +#define D(X) (180.0 * (X) / M_PI) + +void main() { + double a, b; + + a = 0.0; b = 2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = 1.0; b = 2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = 2.0; b = 2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = 2.0; b = 1.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = 2.0; b = 0.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = 2.0; b = -1.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = 2.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = 1.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = 0.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = -1.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = -2.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = -2.0; b = -1.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = -2.0; b = 0.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = -2.0; b = 1.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = -2.0; b = 2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); + a = -1.0; b = 2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b))); +} + +#endif /* 0 */ + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: actan.c,v $ $Date: 2001/01/10 16:32:21 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/airmass.c b/Common/Libraries/XEphemAstroLib/src/airmass.c new file mode 100644 index 000000000..a5d046fe6 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/airmass.c @@ -0,0 +1,26 @@ +#include <math.h> + +#include "astro.h" + +/* given apparent altitude find airmass. + * R.H. Hardie, 1962, `Photoelectric Reductions', Chapter 8 of Astronomical + * Techniques, W.A. Hiltner (Ed), Stars and Stellar Systems, II (University + * of Chicago Press: Chicago), pp178-208. + */ +void +airmass ( +double aa, /* apparent altitude, rads */ +double *Xp) /* airmasses */ +{ + double sm1; /* secant zenith angle, minus 1 */ + + /* degenerate near or below horizon */ + if (aa < degrad(3.0)) + aa = degrad(3.0); + + sm1 = 1.0/sin(aa) - 1.0; + *Xp = 1.0 + sm1*(0.9981833 - sm1*(0.002875 + 0.0008083*sm1)); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: airmass.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/anomaly.c b/Common/Libraries/XEphemAstroLib/src/anomaly.c new file mode 100644 index 000000000..c6bc8ebe5 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/anomaly.c @@ -0,0 +1,63 @@ +/* improved by rclark@lpl.arizona.edu (Richard Clark) */ + +#include <stdio.h> +#include <math.h> + +#include "astro.h" + + +#define TWOPI (2*PI) +#define STOPERR (1e-8) + +/* given the mean anomaly, ma, and the eccentricity, s, of elliptical motion, + * find the true anomaly, *nu, and the eccentric anomaly, *ea. + * all angles in radians. + */ +void +anomaly (double ma, double s, double *nu, double *ea) +{ + double m, fea, corr; + + if (s < 1.0) { + /* elliptical */ + double dla; + + m = ma-TWOPI*(long)(ma/TWOPI); + if (m > PI) m -= TWOPI; + if (m < -PI) m += TWOPI; + fea = m; + + for (;;) { + dla = fea-(s*sin(fea))-m; + if (fabs(dla)<STOPERR) + break; + /* avoid runnaway corrections for e>.97 and M near 0*/ + corr = 1-(s*cos(fea)); + if (corr < .1) corr = .1; + dla /= corr; + fea -= dla; + } + *nu = 2*atan(sqrt((1+s)/(1-s))*tan(fea/2)); + } else { + /* hyperbolic */ + double fea1; + + m = fabs(ma); + fea = m / (s-1.); + fea1 = pow(6*m/(s*s),1./3.); + /* whichever is smaller is the better initial guess */ + if (fea1 < fea) fea = fea1; + + corr = 1; + while (fabs(corr) > STOPERR) { + corr = (m - s * sinh(fea) + fea) / (s*cosh(fea) - 1); + fea += corr; + } + if (ma < 0.) fea = -fea; + *nu = 2*atan(sqrt((s+1)/(s-1))*tanh(fea/2)); + } + *ea = fea; +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: anomaly.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/ap_as.c b/Common/Libraries/XEphemAstroLib/src/ap_as.c new file mode 100644 index 000000000..64619fec9 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/ap_as.c @@ -0,0 +1,68 @@ +#include <string.h> +#include <math.h> + +#include "astro.h" + +/* convert the given apparent RA/Dec to astrometric precessed to Mjd IN PLACE. + * we have no un-abberation etc so to find the correction: assume + * *rap and *decp are astrometric@EOD, convert to apparent and back out + * the difference; then precess to Mjd. + */ +void +ap_as (Now *np, double Mjd, double *rap, double *decp) +{ + double r0 = *rap, d0 = *decp; + Obj o; + Now n; + + /* as -> ap */ + zero_mem ((void *)&o, sizeof(o)); + o.o_type = FIXED; + o.f_RA = (float)*rap; + o.f_dec = (float)*decp; + o.f_epoch = (float)mjd; + memcpy ((void *)&n, (void *)np, sizeof(Now)); + n.n_epoch = EOD; + obj_cir (&n, &o); + *rap -= o.s_ra - *rap; + *decp -= o.s_dec - *decp; + + /* then back to start for second order correction */ + o.o_type = FIXED; + o.f_RA = (float)*rap; + o.f_dec = (float)*decp; + o.f_epoch = (float)mjd; + memcpy ((void *)&n, (void *)np, sizeof(Now)); + n.n_epoch = EOD; + obj_cir (&n, &o); + *rap -= o.s_ra - r0; + *decp -= o.s_dec - d0; + + radecrange (rap, decp); + precess (mjd, Mjd, rap, decp); + radecrange (rap, decp); +} + +/* convert the given astrometric RA/Dec which are precessed to Mjd into + * apparent @ EOD IN PLACE. + */ +void +as_ap (Now *np, double Mjd, double *rap, double *decp) +{ + Obj o; + Now n; + + zero_mem ((void *)&o, sizeof(o)); + o.o_type = FIXED; + o.f_RA = (float)*rap; + o.f_dec = (float)*decp; + o.f_epoch = (float)Mjd; + memcpy ((void *)&n, (void *)np, sizeof(Now)); + n.n_epoch = EOD; + obj_cir (&n, &o); + *rap = o.s_ra; + *decp = o.s_dec; +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: ap_as.c,v $ $Date: 2006/08/28 00:20:58 $ $Revision: 1.8 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/astro.h b/Common/Libraries/XEphemAstroLib/src/astro.h new file mode 100644 index 000000000..a060b683e --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/astro.h @@ -0,0 +1,824 @@ +#ifndef _ASTRO_H +#define _ASTRO_H + +#include <stdio.h> + +#ifndef PI +#define PI 3.141592653589793 +#endif + +/* conversions among hours (of ra), degrees and radians. */ +#define degrad(x) ((x)*PI/180.) +#define raddeg(x) ((x)*180./PI) +#define hrdeg(x) ((x)*15.) +#define deghr(x) ((x)/15.) +#define hrrad(x) degrad(hrdeg(x)) +#define radhr(x) deghr(raddeg(x)) + +/* ratio of from synodic (solar) to sidereal (stellar) rate */ +#define SIDRATE .9972695677 + +/* manifest names for planets. + * N.B. must coincide with usage in pelement.c and plans.c. + * N.B. only the first 8 are valid for use with plans(). + */ + +#ifdef __cplusplus +extern "C" { +#endif + +// all of your legacy C code here + + + + +typedef enum { + MERCURY, + VENUS, + MARS, + JUPITER, + SATURN, + URANUS, + NEPTUNE, + PLUTO, + SUN, + MOON, + NOBJ /* total number of basic objects */ +} PLCode; + +/* moon constants for pl_moon */ +typedef enum { + X_PLANET = 0, /* use to mean planet itself */ + PHOBOS = NOBJ, DEIMOS, + IO, EUROPA, GANYMEDE, CALLISTO, + MIMAS, ENCELADUS, TETHYS, DIONE, RHEA, TITAN, HYPERION, IAPETUS, + ARIEL, UMBRIEL, TITANIA, OBERON, MIRANDA, + NBUILTIN +} MCode; + +/* starting point for MJD calculations + */ +#define MJD0 2415020.0 +#define J2000 (2451545.0 - MJD0) /* yes, 2000 January 1 at 12h */ + +/* the Now and Obj typedefs. + * also, a few miscellaneous constants and declarations. + */ + +#define SPD (24.0*3600.0) /* seconds per day */ +#define MAU (1.4959787e11) /* m / au */ +#define LTAU 499.005 /* seconds light takes to travel 1 AU */ +#define ERAD (6.37816e6) /* earth equitorial radius, m */ +#define MRAD (1.740e6) /* moon equitorial radius, m */ +#define SRAD (6.95e8) /* sun equitorial radius, m */ +#define FTPM 3.28084 /* ft per m */ +#define ESAT_MAG 2 /* default satellite magnitude */ +#define FAST_SAT_RPD 0.25 /* max earth sat rev/day considered "fast" */ + +#define EOD (-9786) /* special epoch flag: use epoch of date */ + +/* info about the local observing circumstances and misc preferences */ +typedef struct { + double n_mjd; /* modified Julian date, ie, days since + * Jan 0.5 1900 (== 12 noon, Dec 30, 1899), utc. + * enough precision to get well better than 1 second. + * N.B. if not first member, must move NOMJD inits. + */ + double n_lat; /* geographic (surface-normal) lt, >0 north, rads */ + double n_lng; /* longitude, >0 east, rads */ + double n_tz; /* time zone, hrs behind UTC */ + double n_temp; /* atmospheric temp, degrees C */ + double n_pressure; /* atmospheric pressure, mBar */ + double n_elev; /* elevation above sea level, earth radii */ + double n_dip; /* dip of sun below hzn at twilight, >0 below, rads */ + double n_epoch; /* desired precession display ep as an mjd, or EOD */ + char n_tznm[8]; /* time zone name; 7 chars or less, always 0 at end */ +} Now; + +/* handy shorthands for fields in a Now pointer, np */ +#define mjd np->n_mjd +#define lat np->n_lat +#define lng np->n_lng +#define tz np->n_tz +#define temp np->n_temp +#define pressure np->n_pressure +#define elev np->n_elev +#define dip np->n_dip +#define epoch np->n_epoch +#define tznm np->n_tznm +#define mjed mm_mjed(np) + +/* structures to describe objects of various types. + */ + +/* magnitude values in two different systems */ +typedef struct { + float m1, m2; /* either g/k or H/G, depending on... */ + int whichm; /* one of MAG_gk or MAG_HG */ +} Mag; + +/* whichm */ +#define MAG_HG 0 /* using 0 makes HG the initial default */ +#define MAG_gk 1 + +/* we actually store magnitudes times this scale factor in a short int */ +#define MAGSCALE 100.0 +#define set_smag(op,m) ((op)->s_mag = (short)floor((m)*MAGSCALE + 0.5)) +#define set_fmag(op,m) ((op)->f_mag = (short)floor((m)*MAGSCALE + 0.5)) +#define get_mag(op) ((op)->s_mag / MAGSCALE) +#define get_fmag(op) ((op)->f_mag / MAGSCALE) + +/* longest object name, including trailing '\0' */ +#define MAXNM 21 + +typedef unsigned char ObjType_t; +typedef unsigned char ObjAge_t; +typedef unsigned char byte; + +/* Obj is a massive union. + * many fields are in common so we use macros to make things a little easier. + */ + +/* fields common to *all* structs in the Obj union */ +#define OBJ_COMMON_FLDS \ + ObjType_t co_type; /* current object type; see flags, below */ \ + byte co_flags; /* FUSER*... used by others */ \ + ObjAge_t co_age; /* update aging code; see db.c */ \ + char co_name[MAXNM];/* name, including \0 */ \ + float co_ra; /* geo/topo app/mean ra, rads */ \ + float co_dec; /* geo/topo app/mean dec, rads */ \ + float co_gaera; /* geo apparent ra, rads */ \ + float co_gaedec; /* geo apparent dec, rads */ \ + float co_az; /* azimuth, >0 e of n, rads */ \ + float co_alt; /* altitude above topocentric horizon, rads */ \ + float co_elong; /* angular sep btwen obj and sun, >0 E, degs */ \ + float co_size; /* angular size, arc secs */ \ + short co_mag /* visual magnitude * MAGSCALE */ + +/* fields common to all solar system objects in the Obj union */ +#define OBJ_SOLSYS_FLDS \ + OBJ_COMMON_FLDS; /* all the fixed ones plus ... */ \ + float so_sdist; /* dist from object to sun, au */ \ + float so_edist; /* dist from object to earth, au */ \ + float so_hlong; /* heliocentric longitude, rads */ \ + float so_hlat; /* heliocentric latitude, rads */ \ + float so_phase /* phase, % */ + +/* fields common to all fixed objects in the Obj union */ +#define OBJ_FIXED_FLDS \ + char fo_spect[2]; /* spectral codes, if appropriate */ \ + float fo_epoch; /* eq of ra/dec and time when pm=0; mjd */ \ + float fo_ra; /* ra, rads, in epoch frame */ \ + float fo_dec; /* dec, rads, in epoch frame */ \ + float fo_pmra; /* ra proper motion, rads/day/cos(dec) */ \ + float fo_pmdec; /* dec proper motion, rads/day */ \ + char fo_class /* object class */ + +/* a generic object */ +typedef struct { + OBJ_COMMON_FLDS; +} ObjAny; + +/* a generic sol system object */ +typedef struct { + OBJ_SOLSYS_FLDS; +} ObjSS; + +/* basic Fixed object info. + */ +typedef struct { + OBJ_COMMON_FLDS; + OBJ_FIXED_FLDS; + + /* following are for galaxies */ + byte fo_ratio; /* minor/major diameter ratio. use s/get_ratio() */ + byte fo_pa; /* position angle, E of N, rads. use s/get_pa() */ +} ObjF; + +/* true-orbit parameters of binary-star object type */ +typedef struct { + float bo_T; /* epoch of periastron, years */ + float bo_e; /* eccentricity */ + float bo_o; /* argument of periastron, degress */ + float bo_O; /* longitude of node, degrees */ + float bo_i; /* inclination to plane of sky, degrees */ + float bo_a; /* semi major axis, arc secs */ + float bo_P; /* period, years */ + + /* companion position, computed by obj_cir() iff b_2compute */ + float bo_pa; /* position angle @ ep, rads E of N */ + float bo_sep; /* separation @ ep, arc secs */ + float bo_ra; /* geo/topo app/mean ra, rads */ + float bo_dec; /* geo/topo app/mean dec, rads */ +} BinOrbit; +typedef struct { + float bp_ep; /* epoch of pa/sep, year */ + float bp_pa; /* position angle @ ep, rads E of N */ + float bp_sep; /* separation @ ep, arc secs */ + + /* companion position, computed by obj_cir() iff b_2compute */ + float bp_ra; /* geo/topo app/mean ra, rads */ + float bp_dec; /* geo/topo app/mean dec, rads */ +} BinPos; +#define MAXBINPOS 2 /* max discrete epochs to store when no elements */ +typedef struct { + OBJ_COMMON_FLDS; + OBJ_FIXED_FLDS; + + byte b_2compute; /* whether to compute secondary positions */ + byte b_nbp; /* number of b_bp[] or 0 to use b_bo */ + short b_2mag; /* secondary's magnitude * MAGSCALE */ + char b_2spect[2]; /* secondary's spectrum */ + + /* either a real orbit or a set of discrete pa/sep */ + union { + BinOrbit b_bo; /* orbital elements */ + BinPos b_bp[MAXBINPOS]; /* table of discrete positions */ + } u; +} ObjB; + +#define fo_mag co_mag /* pseudonym for so_mag since it is not computed */ +#define fo_size co_size /* pseudonym for so_size since it is not computed */ + +/* macros to pack/unpack some fields */ +#define SRSCALE 255.0 /* galaxy size ratio scale */ +#define PASCALE (255.0/(2*PI)) /* pos angle scale factor */ +#define get_ratio(op) (((int)(op)->f_ratio)/SRSCALE) +#define set_ratio(op,maj,min) ((op)->f_ratio = (byte)(((maj) > 0) \ + ? ((min)*SRSCALE/(double)(maj)+0.5) \ + : 0)) +#define get_pa(op) ((double)(op)->f_pa/PASCALE) +#define set_pa(op,s) ((op)->f_pa = (byte)((s)*PASCALE + 0.5)) + +#define NCLASSES 128 /* n potential fo_classes -- allow for all ASCII */ + +/* basic planet object info */ +typedef struct { + OBJ_SOLSYS_FLDS; + PLCode plo_code; /* which planet */ + MCode plo_moon; /* which moon, or X_PLANET if planet */ + char plo_evis, plo_svis; /* if moon: whether visible from earth, sun */ + double plo_x, plo_y, plo_z; /* if moon: eq dist from center, planet radii */ + double plo_aux1, plo_aux2; /* various values, depending on type */ +} ObjPl; + +/* basic info about an object in elliptical heliocentric orbit */ +typedef struct { + OBJ_SOLSYS_FLDS; + float eo_inc; /* inclination, degrees */ + float eo_Om; /* longitude of ascending node, degrees */ + float eo_om; /* argument of perihelion, degress */ + float eo_a; /* mean distance, aka,semi-maj axis,AU */ + float eo_M; /* mean anomaly, ie, degrees from perihelion at cepoch*/ + float eo_size; /* angular size, in arc seconds at 1 AU */ + float eo_startok; /* nominal first mjd this set is ok, else 0 */ + float eo_endok; /* nominal last mjd this set is ok, else 0 */ + double eo_e; /* eccentricity (double for when near 1 computing q) */ + double eo_cepoch; /* epoch date (M reference), as an mjd */ + double eo_epoch; /* equinox year (inc/Om/om reference), as an mjd. */ + Mag eo_mag; /* magnitude */ +} ObjE; + +/* basic info about an object in hyperbolic heliocentric orbit */ +typedef struct { + OBJ_SOLSYS_FLDS; + double ho_epoch; /* equinox year (inc/Om/om reference), as an mjd */ + double ho_ep; /* epoch of perihelion, as an mjd */ + float ho_startok; /* nominal first mjd this set is ok, else 0 */ + float ho_endok; /* nominal last mjd this set is ok, else 0 */ + float ho_inc; /* inclination, degs */ + float ho_Om; /* longitude of ascending node, degs */ + float ho_om; /* argument of perihelion, degs. */ + float ho_e; /* eccentricity */ + float ho_qp; /* perihelion distance, AU */ + float ho_g, ho_k; /* magnitude model coefficients */ + float ho_size; /* angular size, in arc seconds at 1 AU */ +} ObjH; + +/* basic info about an object in parabolic heliocentric orbit */ +typedef struct { + OBJ_SOLSYS_FLDS; + double po_epoch; /* reference epoch, as an mjd */ + double po_ep; /* epoch of perihelion, as an mjd */ + float po_startok; /* nominal first mjd this set is ok, else 0 */ + float po_endok; /* nominal last mjd this set is ok, else 0 */ + float po_inc; /* inclination, degs */ + float po_qp; /* perihelion distance, AU */ + float po_om; /* argument of perihelion, degs. */ + float po_Om; /* longitude of ascending node, degs */ + float po_g, po_k; /* magnitude model coefficients */ + float po_size; /* angular size, in arc seconds at 1 AU */ +} ObjP; + +/* basic earth satellite object info */ +typedef struct { + OBJ_COMMON_FLDS; + double eso_epoch; /* reference epoch, as an mjd */ + double eso_n; /* mean motion, rev/day + * N.B. we need double due to a sensitive differencing + * operation used to compute MeanAnomaly in + * esat_main()/satellite.c. + */ + float eso_startok; /* nominal first mjd this set is ok, else 0 */ + float eso_endok; /* nominal last mjd this set is ok, else 0 */ + float eso_inc; /* inclination, degs */ + float eso_raan; /* RA of ascending node, degs */ + float eso_e; /* eccentricity */ + float eso_ap; /* argument of perigee at epoch, degs */ + float eso_M; /* mean anomaly, ie, degrees from perigee at epoch */ + float eso_decay; /* orbit decay rate, rev/day^2 */ + float eso_drag; /* object drag coefficient, (earth radii)^-1 */ + int eso_orbit; /* integer orbit number of epoch */ + + /* computed "sky" results unique to earth satellites */ + float ess_elev; /* height of satellite above sea level, m */ + float ess_range; /* line-of-site distance from observer to satellite, m*/ + float ess_rangev; /* rate-of-change of range, m/s */ + float ess_sublat; /* latitude below satellite, >0 north, rads */ + float ess_sublng; /* longitude below satellite, >0 east, rads */ + int ess_eclipsed;/* 1 if satellite is in earth's shadow, else 0 */ +} ObjES; + +typedef union { + ObjAny any; /* these fields valid for all types */ + ObjSS anyss; /* these fields valid for all solar system types */ + ObjPl pl; /* planet */ + ObjF f; /* fixed object, plus proper motion */ + ObjB b; /* bona fide binary stars (doubles are stored in f) */ + ObjE e; /* object in heliocentric elliptical orbit */ + ObjH h; /* object in heliocentric hyperbolic trajectory */ + ObjP p; /* object in heliocentric parabolic trajectory */ + ObjES es; /* earth satellite */ +} Obj; + + +/* for o_flags -- everybody must agree */ +#define FUSER0 0x01 +#define FUSER1 0x02 +#define FUSER2 0x04 +#define FUSER3 0x08 +#define FUSER4 0x10 +#define FUSER5 0x20 +#define FUSER6 0x40 +#define FUSER7 0x80 + +/* mark an object as being a "field star" */ +#define FLDSTAR FUSER3 +/* mark an object as circum calculation failed */ +#define NOCIRCUM FUSER7 + +/* Obj shorthands: */ +#define o_type any.co_type +#define o_name any.co_name +#define o_flags any.co_flags +#define o_age any.co_age +#define s_ra any.co_ra +#define s_dec any.co_dec +#define s_gaera any.co_gaera +#define s_gaedec any.co_gaedec +#define s_az any.co_az +#define s_alt any.co_alt +#define s_elong any.co_elong +#define s_size any.co_size +#define s_mag any.co_mag + +#define s_sdist anyss.so_sdist +#define s_edist anyss.so_edist +#define s_hlong anyss.so_hlong +#define s_hlat anyss.so_hlat +#define s_phase anyss.so_phase + +#define s_elev es.ess_elev +#define s_range es.ess_range +#define s_rangev es.ess_rangev +#define s_sublat es.ess_sublat +#define s_sublng es.ess_sublng +#define s_eclipsed es.ess_eclipsed + +#define f_class f.fo_class +#define f_spect f.fo_spect +#define f_ratio f.fo_ratio +#define f_pa f.fo_pa +#define f_epoch f.fo_epoch +#define f_RA f.fo_ra +#define f_pmRA f.fo_pmra +#define f_dec f.fo_dec +#define f_pmdec f.fo_pmdec +#define f_mag f.fo_mag +#define f_size f.fo_size + +#define e_cepoch e.eo_cepoch +#define e_epoch e.eo_epoch +#define e_startok e.eo_startok +#define e_endok e.eo_endok +#define e_inc e.eo_inc +#define e_Om e.eo_Om +#define e_om e.eo_om +#define e_a e.eo_a +#define e_e e.eo_e +#define e_M e.eo_M +#define e_size e.eo_size +#define e_mag e.eo_mag + +#define h_epoch h.ho_epoch +#define h_startok h.ho_startok +#define h_endok h.ho_endok +#define h_ep h.ho_ep +#define h_inc h.ho_inc +#define h_Om h.ho_Om +#define h_om h.ho_om +#define h_e h.ho_e +#define h_qp h.ho_qp +#define h_g h.ho_g +#define h_k h.ho_k +#define h_size h.ho_size + +#define p_epoch p.po_epoch +#define p_startok p.po_startok +#define p_endok p.po_endok +#define p_ep p.po_ep +#define p_inc p.po_inc +#define p_qp p.po_qp +#define p_om p.po_om +#define p_Om p.po_Om +#define p_g p.po_g +#define p_k p.po_k +#define p_size p.po_size + +#define es_epoch es.eso_epoch +#define es_startok es.eso_startok +#define es_endok es.eso_endok +#define es_inc es.eso_inc +#define es_raan es.eso_raan +#define es_e es.eso_e +#define es_ap es.eso_ap +#define es_M es.eso_M +#define es_n es.eso_n +#define es_decay es.eso_decay +#define es_drag es.eso_drag +#define es_orbit es.eso_orbit + +#define pl_code pl.plo_code +#define pl_moon pl.plo_moon +#define pl_evis pl.plo_evis +#define pl_svis pl.plo_svis +#define pl_x pl.plo_x +#define pl_y pl.plo_y +#define pl_z pl.plo_z +#define pl_aux1 pl.plo_aux1 +#define pl_aux2 pl.plo_aux2 + +#define b_2compute b.b_2compute +#define b_2spect b.b_2spect +#define b_2mag b.b_2mag +#define b_bo b.u.b_bo +#define b_bp b.u.b_bp +#define b_nbp b.b_nbp + +/* insure we always refer to the fields and no monkey business */ +#undef OBJ_COMMON_FLDS +#undef OBJ_SOLSYS_FLDS + +/* o_type code. + * N.B. names are assigned in order in objmenu.c + * N.B. if add one add switch in obj_cir(). + * N.B. UNDEFOBJ must be zero so new objects are undefinied by being zeroed. + * N.B. maintain the bitmasks too. + */ +enum ObjType { + UNDEFOBJ=0, + FIXED, BINARYSTAR, ELLIPTICAL, HYPERBOLIC, PARABOLIC, EARTHSAT, PLANET, + NOBJTYPES +}; + +/* types as handy bitmasks too */ +#define OBJTYPE2MASK(t) (1<<(t)) +#define FIXEDM OBJTYPE2MASK(FIXED) +#define BINARYSTARM OBJTYPE2MASK(BINARYSTAR) +#define ELLIPTICALM OBJTYPE2MASK(ELLIPTICAL) +#define HYPERBOLICM OBJTYPE2MASK(HYPERBOLIC) +#define PARABOLICM OBJTYPE2MASK(PARABOLIC) +#define EARTHSATM OBJTYPE2MASK(EARTHSAT) +#define PLANETM OBJTYPE2MASK(PLANET) +#define ALLM (~0) + +/* rise, set and transit information. + */ +typedef struct { + int rs_flags; /* info about what has been computed and any + * special conditions; see flags, below. + */ + double rs_risetm; /* mjd time of rise today */ + double rs_riseaz; /* azimuth of rise, rads E of N */ + double rs_trantm; /* mjd time of transit today */ + double rs_tranalt; /* altitude of transit, rads up from horizon */ + double rs_tranaz; /* azimuth of transit, rads E of N */ + double rs_settm; /* mjd time of set today */ + double rs_setaz; /* azimuth of set, rads E of N */ +} RiseSet; + +/* RiseSet flags */ +#define RS_NORISE 0x0001 /* object does not rise as such today */ +#define RS_NOSET 0x0002 /* object does not set as such today */ +#define RS_NOTRANS 0x0004 /* object does not transit as such today */ +#define RS_CIRCUMPOLAR 0x0010 /* object stays up all day today */ +#define RS_NEVERUP 0x0020 /* object never up at all today */ +#define RS_ERROR 0x1000 /* can't figure out anything! */ +#define RS_RISERR (0x0100|RS_ERROR) /* error computing rise */ +#define RS_SETERR (0x0200|RS_ERROR) /* error computing set */ +#define RS_TRANSERR (0x0400|RS_ERROR) /* error computing transit */ + +#define is_type(op,m) (OBJTYPE2MASK((op)->o_type) & (m)) + +/* any planet or its moons */ +#define is_planet(op,p) (is_type(op,PLANETM) && op->pl_code == (p)) + +/* any solar system object */ +#define is_ssobj(op) is_type(op,PLANETM|HYPERBOLICM|PARABOLICM|ELLIPTICALM) + + +/* natural satellite support */ + +typedef struct { + char *full; /* full name */ + char *tag; /* Roman numeral tag */ + float x, y, z; /* sky loc in planet radii: +x:east +y:south +z:front */ + float ra, dec; /* sky location in ra/dec */ + float mag; /* magnitude */ + int evis; /* whether geometrically visible from earth */ + int svis; /* whether in sun light */ + int pshad; /* whether moon is casting shadow on planet */ + int trans; /* whether moon is transiting */ + float sx, sy; /* shadow sky loc in planet radii: +x:east +y:south */ +} MoonData; + +/* separate set for each planet -- use in pl_moon */ + + +enum _marsmoons { + M_MARS = 0, /* == X_PLANET */ + M_PHOBOS, M_DEIMOS, + M_NMOONS /* including planet at 0 */ +}; + +enum _jupmoons { + J_JUPITER = 0, /* == X_PLANET */ + J_IO, J_EUROPA, J_GANYMEDE, J_CALLISTO, + J_NMOONS /* including planet */ +}; + +enum _satmoons { + S_SATURN = 0, /* == X_PLANET */ + S_MIMAS, S_ENCELADUS, S_TETHYS, S_DIONE, + S_RHEA, S_TITAN, S_HYPERION, S_IAPETUS, + S_NMOONS /* including planet */ +}; + +enum _uramoons { + U_URANUS = 0, /* == X_PLANET */ + U_ARIEL, U_UMBRIEL, U_TITANIA, U_OBERON, U_MIRANDA, + U_NMOONS /* including planet */ +}; + +#define X_MAXNMOONS S_NMOONS /* N.B. chosen by hand */ + + +/* global function declarations */ + + +/* aa_hadec.c */ +extern void aa_hadec (double lt, double alt, double az, double *ha, + double *dec); +extern void hadec_aa (double lt, double ha, double dec, double *alt, + double *az); + +/* aberration.c */ +extern void ab_ecl (double m, double lsn, double *lam, double *bet); +extern void ab_eq (double m, double lsn, double *ra, double *dec); + +/* airmass.c */ +extern void airmass (double aa, double *Xp); + +/* anomaly.c */ +extern void anomaly (double ma, double s, double *nu, double *ea); + +/* ap_as.c */ +extern void ap_as ( Now *np, double Mjd, double *rap, double *decp); +extern void as_ap ( Now *np, double Mjd, double *rap, double *decp); + +/* atlas.c */ +extern char *um_atlas (double ra, double dec); +extern char *u2k_atlas (double ra, double dec); +extern char *msa_atlas (double ra, double dec); + +/* aux.c */ +extern double mm_mjed (Now *np); + +/* chap95.c */ +extern int chap95 (double m, int obj, double prec, double *ret); + +/* chap95_data.c */ + +/* circum.c */ +extern int obj_cir (Now *np, Obj *op); + +/* comet.c */ +extern void comet (double m, double ep, double inc, double ap, double qp, + double om, double *lpd, double *psi, double *rp, double *rho, double *lam, + double *bet); + +/* constel.c */ +#define NCNS 89 +extern int cns_pick (double r, double d, double e); +extern int cns_id (char *abbrev); +extern char *cns_name (int id); +extern int cns_edges (double e, double **ra0p, double **dec0p, double **ra1p, + double **dec1p); +extern int cns_list (double ra, double dec, double e, double rad, int ids[]); +extern int cns_figure (int id, double e, double ra[],double dec[],int dcodes[]); +extern int cns_loadfigs (FILE *fp, char msg[]); + +/* dbfmt.c */ +extern int db_crack_line (char s[], Obj *op, char nm[][MAXNM], int nnm, + char whynot[]); +extern void db_write_line (Obj *op, char *lp); +extern int dbline_candidate (char line[]); +extern int get_fields (char *s, int delim, char *fields[]); +extern int db_tle (char *name, char *l1, char *l2, Obj *op); +extern int dateRangeOK (Now *np, Obj *op); + +/* deltat.c */ +extern double deltat (double m); + +/* earthsat.c */ +extern int obj_earthsat (Now *np, Obj *op); + +/* eq_ecl.c */ +extern void eq_ecl (double m, double ra, double dec, double *lt,double *lg); +extern void ecl_eq (double m, double lt, double lg, double *ra,double *dec); + +/* eq_gal.c */ +extern void eq_gal (double m, double ra, double dec, double *lt,double *lg); +extern void gal_eq (double m, double lt, double lg, double *ra,double *dec); + +/* formats.c */ +extern int fs_sexa (char *out, double a, int w, int fracbase); +extern int fs_date (char out[], int format, double jd); +extern int f_scansexa (const char *str, double *dp); +extern void f_sscandate (char *bp, int pref, int *m, double *d, int *y); + +/* helio.c */ +extern void heliocorr (double jd, double ra, double dec, double *hcp); + +/* jupmoon.c */ +extern void jupiter_data (double Mjd, char dir[], Obj *sop, Obj *jop, + double *jupsize, double *cmlI, double *cmlII, double *polera, + double *poledec, MoonData md[J_NMOONS]); + +/* libration.c */ +extern void llibration (double JD, double *llatp, double *llonp); + +/* magdecl.c */ +extern int magdecl (double l, double L, double e, double y, char *dir, + double *dp, char *err); + +/* marsmoon.c */ +extern void marsm_data (double Mjd, char dir[], Obj *sop, Obj *mop, + double *marssize, double *polera, double *poledec, MoonData md[M_NMOONS]); + +/* misc.c */ +extern void zero_mem (void *loc, unsigned len); +extern int tickmarks (double min, double max, int numdiv, double ticks[]); +extern int lc (int cx, int cy, int cw, int x1, int y1, int x2, int y2, + int *sx1, int *sy1, int *sx2, int *sy2); +extern void hg_mag (double h, double g, double rp, double rho, double rsn, + double *mp); +extern int magdiam (int fmag, int magstp, double scale, double mag, + double size); +extern void gk_mag (double g, double k, double rp, double rho, double *mp); +extern double atod (char *buf); +extern void solve_sphere (double A, double b, double cc, double sc, + double *cap, double *Bp); +extern double delra (double dra); +extern void now_lst (Now *np, double *lstp); +extern void radec2ha (Now *np, double ra, double dec, double *hap); +extern void gha (Now *np, Obj *op, double *ghap); +extern char *obj_description (Obj *op); +extern int is_deepsky (Obj *op); + +/* mjd.c */ +extern void cal_mjd (int mn, double dy, int yr, double *m); +extern void mjd_cal (double m, int *mn, double *dy, int *yr); +extern int mjd_dow (double m, int *dow); +extern int isleapyear (int year); +extern void mjd_dpm (double m, int *ndays); +extern void mjd_year (double m, double *yr); +extern void year_mjd (double y, double *m); +extern void rnd_second (double *t); +extern void mjd_dayno (double jd, int *yr, double *dy); +extern double mjd_day (double jd); +extern double mjd_hr (double jd); +extern void range (double *v, double r); +extern void radecrange (double *ra, double *dec); + +/* moon.c */ +extern void moon (double m, double *lam, double *bet, double *rho, + double *msp, double *mdp); + +/* mooncolong.c */ +extern void moon_colong (double jd, double lt, double lg, double *cp, + double *kp, double *ap, double *sp); + +/* moonnf.c */ +extern void moonnf (double mj, double *mjn, double *mjf); + +/* nutation.c */ +extern void nutation (double m, double *deps, double *dpsi); +extern void nut_eq (double m, double *ra, double *dec); + +/* obliq.c */ +extern void obliquity (double m, double *eps); + +/* parallax.c */ +extern void ta_par (double tha, double tdec, double phi, double ht, + double *rho, double *aha, double *adec); + +/* parallactic.c */ +extern double parallacticLDA (double lt, double dec, double alt); +extern double parallacticLHD (double lt, double ha, double dec); + +/* plans.c */ +extern void plans (double m, PLCode p, double *lpd0, double *psi0, + double *rp0, double *rho0, double *lam, double *bet, double *dia, + double *mag); + +/* plshadow.c */ +extern int plshadow (Obj *op, Obj *sop, double polera, + double poledec, double x, double y, double z, float *sxp, float *syp); + +/* plmoon_cir.c */ +extern int plmoon_cir (Now *np, Obj *moonop); +extern int getBuiltInObjs (Obj **opp); +extern void setMoonDir (char *dir); + +/* precess.c */ +extern void precess (double mjd1, double mjd2, double *ra, double *dec); + +/* reduce.c */ +extern void reduce_elements (double mjd0, double m, double inc0, + double ap0, double om0, double *inc, double *ap, double *om); + +/* refract.c */ +extern void unrefract (double pr, double tr, double aa, double *ta); +extern void refract (double pr, double tr, double ta, double *aa); + +/* rings.c */ +extern void satrings (double sb, double sl, double sr, double el, double er, + double JD, double *etiltp, double *stiltp); + +/* riset.c */ +extern void riset (double ra, double dec, double lt, double dis, + double *lstr, double *lsts, double *azr, double *azs, int *status); + +/* riset_cir.c */ +extern void riset_cir (Now *np, Obj *op, double dis, RiseSet *rp); +extern void twilight_cir (Now *np, double dis, double *dawn, double *dusk, + int *status); + +/* satmoon.c */ +extern void saturn_data (double Mjd, char dir[], Obj *eop, Obj *sop, + double *satsize, double *etilt, double *stlit, double *polera, + double *poledec, MoonData md[S_NMOONS]); + +/* sphcart.c */ +extern void sphcart (double l, double b, double r, double *x, double *y, + double *z); +extern void cartsph (double x, double y, double z, double *l, double *b, + double *r); + +/* sun.c */ +extern void sunpos (double m, double *lsn, double *rsn, double *bsn); + +/* twobody.c */ +extern int vrc (double *v, double *r, double tp, double e, double q); + +/* umoon.c */ +extern void uranus_data (double Mjd, char dir[], Obj *sop, Obj *uop, + double *usize, double *polera, double *poledec, MoonData md[U_NMOONS]); + +/* utc_gst.c */ +extern void utc_gst (double m, double utc, double *gst); +extern void gst_utc (double m, double gst, double *utc); + +/* vsop87.c */ +extern int vsop87 (double m, int obj, double prec, double *ret); + +#ifdef __cplusplus +} +#endif + +#endif /* _ASTRO_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: astro.h,v $ $Date: 2013/01/06 01:12:57 $ $Revision: 1.33 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/atlas.c b/Common/Libraries/XEphemAstroLib/src/atlas.c new file mode 100644 index 000000000..236153741 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/atlas.c @@ -0,0 +1,196 @@ +/* look up which star atlas an ra/dec is in. + * Urano and Mill contributed by Atsuo Ohki <ohki@gssm.otsuka.tsukuba.ac.jp> + * U2K by Robert Lane <roblane@alum.mit.edu> + * + * N.B. skylist.c assumes a certain max length for any returned string. + */ + +#include <stdio.h> +#include <string.h> + +#include "astro.h" + +/* for Millennium Star Atlas */ +static int msa_charts[] = { + /* 90*/ 2, /* 84*/ 4, /* 78*/ 8, /* 72*/ 10, /* 66*/ 12, + /* 60*/ 14, /* 54*/ 16, /* 48*/ 20, /* 42*/ 20, /* 36*/ 22, + /* 30*/ 22, /* 24*/ 24, /* 18*/ 24, /* 12*/ 24, /* 6*/ 24, + /* 0*/ 24, + /* -6*/ 24, /*-12*/ 24, /*-18*/ 24, /*-24*/ 24, /*-30*/ 22, + /*-36*/ 22, /*-42*/ 20, /*-48*/ 20, /*-54*/ 16, /*-60*/ 14, + /*-66*/ 12, /*-72*/ 10, /*-78*/ 8, /*-84*/ 4, /*-90*/ 2 +}; + +/* + * find the chart number of Millennium Star Atlas and return pointer to static + * string describing location. + * 0 <= ra < 24; -90 <= dec <= 90 + */ +char * +msa_atlas(double ra, double dec) +{ + static char buf[512]; + int zone, band; + int i, p; + + ra = radhr(ra); + dec = raddeg(dec); + buf[0] = 0; + if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec) + return (buf); + zone = (int)(ra/8.0); + band = -((int)(dec+((dec>=0)?3:-3))/6 - 15); + for (p=0, i=0; i <= band; i++) + p += msa_charts[i]; + i = (int)((ra - 8.0*zone) / (8.0/msa_charts[band])); + sprintf(buf, "V%d - P%3d", zone+1, p-i+zone*516); + return (buf); +} + +/* for original Uranometria */ +static struct { + double l; + int n; +} um_zones[] = { + /* 84 - 90 */ { 84.5, 2}, + /* 72 - 85 */ { 72.5, 12}, + /* 60 - 73 */ { 61.0, 20}, + /* 49 - 62 */ { 50.0, 24}, + /* 38 - 51 */ { 39.0, 30}, + /* 27 - 40 */ { 28.0, 36}, + /* 16 - 29 */ { 17.0, 45}, + /* 5 - 18 */ { 5.5, 45}, + /* 0 - 6 */ { 0.0, 45}, + { 0.0, 0} +}; + +/* + * find the chart number of Uranometria first edition and return pointer to + * static string describing location. + * 0 <= ra < 24; -90 <= dec <= 90 + */ +char * +um_atlas(double ra, double dec) +{ + static char buf[512]; + int band, south; + int p; + double w; + + ra = radhr(ra); + dec = raddeg(dec); + buf[0] = 0; + if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec) + return (buf); + p = 0; + if (dec < 0.0) { + dec = -dec; + south = 1; + } else + south = 0; + p = 1; + for (band=0; um_zones[band].n; band++) { + if (um_zones[band].l <= dec) + break; + p += um_zones[band].n; + } + if (!um_zones[band].n) + return (buf); + w = 24.0 / um_zones[band].n; + if (band) { + ra += w/2.0; + if (ra >= 24.0) + ra -= 24.0; + } + if (south && um_zones[band+1].n) + p = 475 - p - um_zones[band].n; + if (south && band == 0) { + /* south pole part is mis-ordered! */ + ra = 24.0 - ra; + } + sprintf(buf, "V%d - P%3d", south+1, p+(int)(ra/w)); + return (buf); +} + +/* for Uranometria 2000.0 */ +static struct { + double lowDec; /* lower dec cutoff */ + int numZones; /* number of panels (aka zones) */ + +} u2k_zones[] = { /* array of book layout info */ + /* 84 - 90 */ { 84.5, 1}, /* lower dec cutoff, # of panels in band */ + /* 73 - 85 */ { 73.5, 6}, + /* 62 - 74 */ { 62.0, 10}, + /* 51 - 63 */ { 51.0, 12}, + /* 40 - 52 */ { 40.0, 15}, + /* 29 - 41 */ { 29.0, 18}, + /* 17 - 30 */ { 17.0, 18}, + /* 5 - 18 */ { 5.5, 20}, + /* 0 - 6 */ { 0.0, 20}, + { 0.0, 0} /*numZones value in this line is a stopper.*/ +}; + +/* find the chart number of Uranometria 2000.0 and return pointer to static + * string describing location. + * 0 <= ra < 24; -90 <= dec <= 90 + */ +char * +u2k_atlas(double ra, double dec) +{ + static char buf[512]; + static char err[] = "???"; + int band; /* index to array */ + int south; /* flag for volume 2*/ + int panel; /* panel number */ + + ra = radhr(ra); + dec = raddeg(dec); + buf[0] = 0; + if (ra < 0.0 || 24.0 <= ra || dec < -90.0 || 90.0 < dec) { + strcpy (buf, err); + return (buf); /* range checking */ + } + + if (dec < 0.0) { + dec = -dec; + south = 1; /* South is mirror of North */ + } else + south = 0; + + panel = 1; + band = 0; + + /* scan u2k_zones for the correct band: */ + while (u2k_zones[band].numZones != 0 && dec <= u2k_zones[band].lowDec ){ + panel += u2k_zones[band].numZones; /*accumulate total panels */ + band++ ; + } + + if (!u2k_zones[band].numZones) { /* hit end of array with no match. */ + strcpy (buf, err); + return (buf); + } + + ra -= 12.0 / u2k_zones[band].numZones; /*offset by half-width of panel*/ + if (ra >= 24.0) /* reality check. shouldn't happen. */ + ra -= 24.0; + + if (ra < 0.0) /* offset could give negative ra */ + ra += 24.0; + + if (south && u2k_zones[band+1].numZones) + panel = 222 - panel - u2k_zones[band].numZones; + + /* resultant panel number is accumulated panels in prior bands plus + * ra's fraction of panels in dec's band. panel # goes up as ra goes + * down. + */ + sprintf(buf, "V%d - P%3d", south+1, + panel+(int)(u2k_zones[band].numZones*(24.0 - ra)/24.0)); + + return (buf); +} + + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: atlas.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.8 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/auxil.c b/Common/Libraries/XEphemAstroLib/src/auxil.c new file mode 100644 index 000000000..0fa712f36 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/auxil.c @@ -0,0 +1,42 @@ +/* aux functions so programs besides XEphem can use this library. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "astro.h" +#include "preferences.h" + +/* default preferences */ +static int prefs[NPREFS] = { + PREF_TOPO, PREF_METRIC, PREF_MDY, PREF_UTCTZ, PREF_HIPREC, PREF_NOMSGBELL, + PREF_PREFILL, PREF_TIPSON, PREF_CONFIRMON, PREF_SUN +}; + +/* called anytime we want to know a preference. + */ +int +pref_get(Preferences pref) +{ + return (prefs[pref]); +} + +/* call to force a certain preference, return the old setting. + */ +int +pref_set (Preferences pref, int newp) +{ + int prior = pref_get(pref); + prefs[pref] = newp; + return (prior); +} + +/* given an mjd, return it modified for terrestial dynamical time */ +double +mm_mjed (Now *np) +{ + return (mjd + deltat(mjd)/86400.0); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: auxil.c,v $ $Date: 2003/05/04 04:41:57 $ $Revision: 1.8 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/bdl.c b/Common/Libraries/XEphemAstroLib/src/bdl.c new file mode 100644 index 000000000..048640518 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/bdl.c @@ -0,0 +1,238 @@ +/* crack natural satellite files from BDL */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <unistd.h> + +#include "astro.h" +#include "bdl.h" + +typedef enum {I, F, NL} ScanType; +#define SCANFLD(f,w,vp) if(readField(fp,f,w,(void *)vp,ynot)<0) return (-1) + +static int readField (FILE *fp, ScanType f, int w, void *ptr, char ynot[]); +static int readRec (FILE *fp, double *t0, double cmx[], double cfx[], + double cmy[], double cfy[], double cmz[], double cfz[], char ynot[]); + +/* given a sequencial text file in BDL natural satellite ephemeris format and a + * JD, find the x/y/z positions of each satellite. store in the given arrays, + * assumed to have one entry per moon. values are planetocentric, +x east, +y + * north, +z away from earth, all in au. corrected for light time. + * return the number of satellites or -1 and reason in ymot[]. + * files obtained from ftp://ftp.bdl.fr/pub/misc/satxyz. + */ +int +read_bdl (FILE *fp, double jd, double *xp, double *yp, double *zp, char ynot[]) +{ + int npla; + int nsat; + int idn[8]; + double freq[8]; + double delt[8]; + double djj; + double cmx[6], cfx[4], cmy[6], cfy[4], cmz[6], cfz[4]; + int ienrf; + int jan; + int reclen; + long os0; + double t0; + int i; + + /* read header line */ + SCANFLD (I, 2, &npla); + SCANFLD (I, 2, &nsat); + for (i = 0; i < nsat; i++) + SCANFLD (I, 5, &idn[i]); + for (i = 0; i < nsat; i++) + SCANFLD (F, 8, &freq[i]); + for (i = 0; i < nsat; i++) + SCANFLD (F, 5, &delt[i]); + SCANFLD (I, 5, &ienrf); + SCANFLD (F, 15, &djj); + SCANFLD (I, 5, &jan); + SCANFLD (NL, 0, NULL); + + /* record position of first record */ + os0 = ftell (fp); + + /* read first record to get length */ + reclen = readRec (fp, &t0, cmx, cfx, cmy, cfy, cmz, cfz, ynot); + if (reclen < 0) + return (-1); + + /* compute location of each satellite */ + for (i = 0; i < nsat; i++) { + int id = (int)floor((jd-djj)/delt[i]) + idn[i] - 2; + long os = os0 + id*reclen; + double t1, anu, tau, tau2, at; + double tbx, tby, tbz; + + if (fseek (fp, os, SEEK_SET) < 0) { + sprintf (ynot, "Seek error to %ld for rec %d", os, id); + return (-1); + } + + if (readRec (fp, &t0, cmx, cfx, cmy, cfy, cmz, cfz, ynot) < 0) + return (-1); + + t1 = floor(t0) + 0.5; + anu = freq[i]; + tau = jd - t1; + tau2 = tau * tau; + at = tau*anu; + + tbx = cmx[0]+cmx[1]*tau+cmx[2]*sin(at+cfx[0]) + +cmx[3]*tau*sin(at+cfx[1]) + +cmx[4]*tau2*sin(at+cfx[2]) + +cmx[5]*sin(2*at+cfx[3]); + tby = cmy[0]+cmy[1]*tau+cmy[2]*sin(at+cfy[0]) + +cmy[3]*tau*sin(at+cfy[1]) + +cmy[4]*tau2*sin(at+cfy[2]) + +cmy[5]*sin(2*at+cfy[3]); + tbz = cmz[0]+cmz[1]*tau+cmz[2]*sin(at+cfz[0]) + +cmz[3]*tau*sin(at+cfz[1]) + +cmz[4]*tau2*sin(at+cfz[2]) + +cmz[5]*sin(2*at+cfz[3]); + + xp[i] = tbx*1000./149597870.; + yp[i] = tby*1000./149597870.; + zp[i] = tbz*1000./149597870.; + } + + return (nsat); +} + +/* read one field. + * return 0 if ok else -1 + * N.B. this is enforce width, without skipping leading blanks. + */ +static int +readField (FILE *fp, ScanType f, int width, void *ptr, char ynot[]) +{ + char buf[128]; + char *bp; + + if (width > sizeof(buf)-1) { + sprintf (ynot, "BDL Field width %d > %d", width, (int)sizeof(buf)); + return (-1); + } + if (width != (int)fread (buf, 1, width, fp)) { + if (ferror(fp)) strcpy (ynot, "BDL IO error"); + else if (feof(fp)) strcpy (ynot, "BDL unexpected EOF"); + else strcpy (ynot, "BDL short file"); + return (-1); + } + + buf[width] = '\0'; + switch (f) { + case I: + *(int *)ptr = atoi (buf); + break; + case F: + bp = strchr (buf, 'D'); + if (bp) + *bp = 'e'; + *(double *)ptr = atof (buf); + break; + case NL: + fgets (buf, sizeof(buf), fp); + break; + default: + sprintf (ynot, "Bug! format = %d", f); + return (-1); + } + return (0); +} + +/* read one satellite record. + * return number of chars read else -1. + */ +static int +readRec (FILE *fp, double *t0, double cmx[], double cfx[], double cmy[], +double cfy[], double cmz[], double cfz[], char ynot[]) +{ + + long pos0, pos1; + int isat, idx; + int ldat1, ldat2; + int i; + + pos0 = ftell (fp); + + SCANFLD (I, 1, &isat); + SCANFLD (I, 5, &idx); + SCANFLD (I, 8, &ldat1); + SCANFLD (I, 8, &ldat2); + SCANFLD (F, 9, t0); + for (i = 0; i < 6; i++) + SCANFLD (F, 17, &cmx[i]); + for (i = 0; i < 4; i++) + SCANFLD (F, 17, &cfx[i]); + for (i = 0; i < 6; i++) + SCANFLD (F, 17, &cmy[i]); + for (i = 0; i < 4; i++) + SCANFLD (F, 17, &cfy[i]); + for (i = 0; i < 6; i++) + SCANFLD (F, 17, &cmz[i]); + for (i = 0; i < 4; i++) + SCANFLD (F, 17, &cfz[i]); + SCANFLD (NL, 0, NULL); + + pos1 = ftell (fp); + + return (pos1 - pos0); +} + + +#ifdef TEST_IT +/* stand-alone test program. + * for example, compare + * a.out jupiter.9910 2451910.50000 + * with + * satxyz2 + * jup.dir.9910 + * 2001 1 1 0 0 0 + * 1 0 0 0 + * 1 + */ +int +main (int ac, char *av[]) +{ + double x[10], y[10], z[10]; + char ynot[1024]; + double jd; + char *fn; + FILE *fp; + int nm; + int i; + + if (ac != 3) { + fprintf (stderr, "Usage: %s <filename> <jd>\n", av[0]); + abort(); + } + fn = av[1]; + jd = atof (av[2]); + + fp = fopen (fn, "r"); + if (!fp) { + perror (fn); + abort(); + } + + nm = read_bdl (fp, jd, x, y, z, ynot); + if (nm < 0) { + fprintf (stderr, "%s\n", ynot); + abort(); + } + + for (i = 0; i < nm; i++) + printf (" X= %19.11E Y= %19.11E Z= %19.11E\n", x[i], y[i], z[i]); + + return (0); +} +#endif + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: bdl.c,v $ $Date: 2008/04/20 08:11:35 $ $Revision: 1.6 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/bdl.h b/Common/Libraries/XEphemAstroLib/src/bdl.h new file mode 100644 index 000000000..3b4d0ea33 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/bdl.h @@ -0,0 +1,6 @@ +extern int read_bdl (FILE *fp, double jd, double *xp, double *yp, double *zp, + char ynot[]); + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: bdl.h,v $ $Date: 2003/03/20 08:56:31 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/chap95.c b/Common/Libraries/XEphemAstroLib/src/chap95.c new file mode 100644 index 000000000..bde4384f9 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/chap95.c @@ -0,0 +1,174 @@ +/* heliocentric rectangular equatorial coordinates of Jupiter to Pluto; + * from Chapront's expansion of DE200/extension of DE200; mean equator J2000.0 + * + * calculation time (milliseconds) on an HP 715/75, Jupiter to Pluto: + * (each coordinate component counted as 1 term, + * secular terms included for JD 2448908.5 = 1992 Oct 13.0) + * + * prec terms rates no rates + * 0.0 2256 5.1 4.6 + * + * 1e-7 792 2.6 2.4 --> nominal precision rel. to DE200 + * 1e-6 535 2.1 2.0 + * 1e-5 350 1.8 1.6 + * 1e-4 199 1.5 1.4 + * 1e-3 96 1.2 1.1 + * + * no drop 2256 4.5 3.9 (code without test criterion) + */ + +#include <math.h> + +#include "astro.h" +#include "chap95.h" + +#define CHAP_MAXTPOW 2 /* NB: valid for all 5 outer planets */ + +/* chap95() + * + * input: + * m modified JD; days from J1900.0 = 2415020.0 + * + * prec precision level, in radians. + * if (prec = 0.0), you get the full precision, namely + * a deviation of not more than 0.02 arc seconds (1e-7 rad) + * from the JPL DE200 integration, on which this expansion + * is based. + * + * obj object number as in astro.h (jupiter=3, saturn=4, ...) + * + * output: + * ret[6] cartesian components of position and velocity + * + * return: + * 0 Ok + * 1 time out of range [CHAP_BEGIN .. CHAP_END] + * 2 object out of range [JUPITER .. PLUTO] + * 3 precision out of range [0.0 .. 1e-3] + */ +int +chap95 (double m, int obj, double prec, double *ret) +{ + static double a0[] = { /* semimajor axes for precision ctrl */ + 0.39, 0.72, 1.5, 5.2, 9.6, 19.2, 30.1, 39.5, 1.0 + }; + double sum[CHAP_MAXTPOW+1][6]; /* [T^0, ..][X,Y,Z,X',Y',Z'] */ + double T, t; /* time in centuries and years */ + double ca, sa, Nu; /* aux vars for terms */ + double precT[CHAP_MAXTPOW+1]; /* T-augmented precision threshold */ + chap95_rec *rec; /* term coeffs */ + int cooidx; + + /* check parameters */ + if (m < CHAP_BEGIN || m > CHAP_END) + return (1); + + if (obj < JUPITER || obj > PLUTO) + return (2); + + if (prec < 0.0 || prec > 1e-3) + return (3); + + /* init the sums */ + zero_mem ((void *)sum, sizeof(sum)); + + T = (m - J2000)/36525.0; /* centuries since J2000.0 */ + + /* modify precision treshold for + * a) term storing scale + * b) convert radians to au + * c) account for skipped terms (more terms needed for better prec) + * threshold empirically established similar to VSOP; stern + * d) augment for secular terms + */ + precT[0] = prec * CHAP_SCALE /* a) */ + * a0[obj] /* b) */ + / (10. * (-log10(prec + 1e-35) - 2)); /* c) */ + t = 1./(fabs(T) + 1e-35); /* d) */ + precT[1] = precT[0]*t; + precT[2] = precT[1]*t; + + t = T * 100.0; /* YEARS since J2000.0 */ + + ca = sa = Nu = 0.; /* shut up compiler warning 'uninitialised' */ + + switch (obj) { /* set initial term record pointer */ + case JUPITER: rec = chap95_jupiter; break; + case SATURN: rec = chap95_saturn; break; + case URANUS: rec = chap95_uranus; break; + case NEPTUNE: rec = chap95_neptune; break; + case PLUTO: rec = chap95_pluto; break; + default: + return (2); /* wrong object: severe internal trouble */ + } + + /* do the term summation into sum[T^n] slots */ + for (; rec->n >= 0; ++rec) { + double *amp; + + /* NOTE: The formula + * X = SUM[i=1,Records] T**n_i*(CX_i*cos(Nu_k*t)+SX_i*sin(Nu_k*t)) + * could be rewritten as SUM( ... A sin (B + C*t) ) + * "saving" trigonometric calls. However, e.g. for Pluto, + * there are only 65 distinct angles NU_k (130 trig calls). + * With that manipulation, EVERY arg_i would be different for X, + * Y and Z, which is 3*96 terms. Hence, the formulation as + * given is good (optimal?). + */ + + for (cooidx = 0, amp = rec->amp; cooidx < 3; ++cooidx) { + double C, S, term, termdot; + short n; /* fast access */ + + C = *amp++; + S = *amp++; + n = rec->n; + + /* drop term if too small + * this is quite expensive: 17% of loop time + */ + if (fabs(C) + fabs(S) < precT[n]) + continue; + + if (n == 0 && cooidx == 0) { /* new Nu only here */ + double arg; + + Nu = rec->Nu; + arg = Nu * t; + arg -= floor(arg/(2.*PI))*(2.*PI); + ca = cos(arg); /* blast it - even for Nu = 0.0 */ + sa = sin(arg); + } + + term = C * ca + S * sa; + sum[n][cooidx] += term; +#if CHAP_GETRATE + termdot = (-C * sa + S * ca) * Nu; + sum[n][cooidx+3] += termdot; + if (n > 0) sum[n - 1][cooidx+3] += n/100.0 * term; +#endif + } /* cooidx */ + } /* records */ + + /* apply powers of time and sum up */ + for (cooidx = 0; cooidx < 6; ++cooidx) { + ret[cooidx] = (sum[0][cooidx] + + T * (sum[1][cooidx] + + T * (sum[2][cooidx] )) )/CHAP_SCALE; + } + + /* TEST: if the MAIN terms are dropped, get angular residue + ret[0] = sqrt(ret[0]*ret[0] + ret[1]*ret[1] + ret[2]*ret[2])/a0[obj]; + */ + +#if CHAP_GETRATE + for (cooidx = 3; cooidx < 6; ++cooidx) { + ret[cooidx] /= 365.25; /* yearly to daily rate */ + } +#endif + + return (0); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: chap95.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/chap95.h b/Common/Libraries/XEphemAstroLib/src/chap95.h new file mode 100644 index 000000000..fff8acdd7 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/chap95.h @@ -0,0 +1,68 @@ +/* Position of outer planets; straightforward from: +ftp://adc.gsfc.nasa.gov/pub/adc/archives/journal_tables/A+AS/109/181: + +J/A+AS/109/181 Planetary ephemerides (Chapront, 1995) +=============================================================================== +Representation of planetary ephemerides by frequency analysis. Application to +the five outer planets. + CHAPRONT J. + <Astron. Astrophys. Suppl. Ser. 109, 181 (1995)> + =1995A&AS..109..181C (SIMBAD/NED Reference) +=============================================================================== + +Keywords: ephemerides - planets and satellites: general - methods: numerical + +Contents: + Heliocentric equatorial rectangular coordinates of the five outer planets + (X, Y and Z). The source is based on DE200 (tables 4 to 7) or a reconstruction + of DE200 by numerical integration (tables 9 to 13). The reference frame is + the mean equator and equinox J2000 of DE200. + + The general formulation of the series X is: + X = SUM[i=1,Records] T**n_i*(CX_i*cos(Nu_k*t)+SX_i*sin(Nu_k*t)) + The formulation is identical for Y and Z. + T is the time (TDB) in Julian centuries from J2000: + T = (JulianDate - 2451545.0)/36525 + t is the time (TDB) in Julian years from J2000: + t = (JulianDate - 2451545.0)/365.25 + Nu is the frequency. Frequencies are identical for all terms of rank k: + Nu_k = Nu_i when n_i = 0 + For purely secular terms k = 0 and Nu_0 = 0 + +=============================================================================== +(End) Patricia Bauer [CDS] 03-Oct-1994 +*/ + +#define CHAP_SCALE 1e10 + +/* JDs of validity period */ +#define CHAP_BEGIN (2338032.5 - MJD0) /* 1689/3/19 */ +#define CHAP_END (2542032.5 - MJD0) /* 2247/10/1 */ + +/* coding flags */ +/* calculating rates increases time by about 10% + * + * On an HP715/75, for pluto the times per step are 0.00049 s and 0.00057 s + * This method is quite fast. + */ +#define CHAP_GETRATE 1 + +typedef struct { + short n; /* order of time; "-1" marks end of list */ + double amp[6]; /* amplitudes of cosine and sine terms for x,y,z */ + /* in original order [CX,SX,CY,SY,CZ,SZ] */ + double Nu; /* Frequency Nu_k; given only at n=0 */ +} chap95_rec; + +extern chap95_rec chap95_jupiter[]; +extern chap95_rec chap95_saturn[]; +extern chap95_rec chap95_uranus[]; +extern chap95_rec chap95_neptune[]; +extern chap95_rec chap95_pluto[]; + +extern int chap95 (double m, int obj, double prec, double *ret); + + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: chap95.h,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.2 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/chap95_data.c b/Common/Libraries/XEphemAstroLib/src/chap95_data.c new file mode 100644 index 000000000..2c177355b --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/chap95_data.c @@ -0,0 +1,783 @@ +/* data tables for Chapront95 expansion of DE200 for outer planets + * + * created by automatic conversion from original distribution files at + * ftp://adc.gsfc.nasa.gov/pub/adc/archives/journal_tables/A+AS/109/181 + */ + +#include "chap95.h" + +chap95_rec chap95_jupiter[] = { + { 0, { -3658015942., 0., -908357166., 0., -300271978., 0. }, 0. }, + { 1, { 3211736., 0., -12066362., 0., -5380492., 0. }, }, + { 0, { 4891337., 5430776., -9059458., 4045908., -3979137., 1598300. }, 0.0168745727060282 }, + { 1, { -1952368., 3224556., -3665363., -6161184., -1519962., -2703058. }, }, + { 0, { 589280., -62004., -1226982., 1326111., -536148., 568311. }, 0.0319163179770344 }, + { 0, { -132797., 113059., 332715., -538044., 144358., -232591. }, 0.0404897860926306 }, + { 0, { 19390., -8208., -31003., 153367., -13456., 65630. }, 0.0595473299932462 }, + { 0, { -2479., -51303., 154576., 368773., 65961., 157222. }, 0.0831987723231718 }, + { 1, { -170149., 190549., 249291., -236183., 108588., -106146. }, }, + { 0, { -14177274., -32784827., -28623327., 13932421., -12074567., 6670491. }, 0.1015656301267251 }, + { 1, { -3789129., 1413684., 2551178., 1957155., 1164465., 819456. }, }, + { 0, { 12762505., 226609., -4837955., 12330917., -2405339., 5249055. }, 0.1121334694975955 }, + { 1, { 547155., 1481967., -2013999., -2660987., -879208., -1179904. }, }, + { 0, { -62226., -41759., -601831., 240767., -255949., 106231. }, 0.1235484250413803 }, + { 0, { 38451., -38927., 103878., -40998., 43472., -16957. }, 0.1380033981088614 }, + { 0, { 6892., -67712., 62422., 39405., 26942., 18451. }, 0.1534434914458037 }, + { 0, { -75., 8062., -21151., -17198., -9222., -7580. }, 0.1694333239035300 }, + { 0, { 35355., 38181., 70566., -4376., 30386., -2939. }, 0.1895181584594278 }, + { 0, { -743715., -251198., -403257., 598432., -166123., 265466. }, 0.2002642151969322 }, + { 0, { 5834437., -10339387., 9606367., 9534188., 3806370., 4385708. }, 0.2140513638608579 }, + { 1, { 1033031., -590411., -1874404., 575478., -835406., 235620. }, }, + { 2, { 514744., -29792., -180518., -472533., -83894., -204253. }, }, + { 0, { 160903., -61277., -282564., -163689., -122933., -69902. }, 0.2282692683160305 }, + { 0, { -27903., 23114., 66255., 2167., 28792., 688. }, 0.2391180221674930 }, + { 0, { 4501., -5373., -15639., 12832., -6785., 5553. }, 0.2594200270243392 }, + { 0, { -7016., 15969., 7639., -40047., 3504., -17544. }, 0.2773387700991547 }, + { 0, { 12123., -71452., 49781., 137809., 20807., 61532. }, 0.2898870950096423 }, + { 0, { 9304., 220632., -262203., -258243., -112815., -119757. }, 0.2988785450891279 }, + { 0, { -326815., -368979., 836570., 374605., 369053., 187133. }, 0.3074463122377075 }, + { 0, { -285560., 1568528., -1374181., -462165., -548097., -222596. }, 0.3260929459480317 }, + { 1, { 61071., -241375., 291550., 243626., 110389., 123427. }, }, + { 2, { 227305., 162244., -116416., 352218., -65158., 140646. }, }, + { 0, { 132035., 23450., 116510., 219543., 39775., 92330. }, 0.3428930094327709 }, + { 0, { -45107., 4887., -87029., -68971., -33182., -29857. }, 0.3524288275557115 }, + { 0, { 11180., 1421., 46242., 3234., 18448., 1726. }, 0.3676619945918164 }, + { 0, { 55636., 74415., 46443., -53844., 16908., -25824. }, 0.3817149836030239 }, + { 0, { -38712., -7953., 29506., -14698., 13883., -4384. }, 0.4024967272931009 }, + { 0, { 737722., -3325874., -1725701., 1468892., -912453., 541637. }, 0.4182255664674069 }, + { 0, { 5843515., 17000877., -16425950., 5641739., -7208900., 1880856. }, 0.4281067291965077 }, + { 1, { -2114864., 879909., -1266263., -2982111., -450528., -1332322. }, }, + { 0, { -110808., 282843., -713054., 221824., -319044., 77631. }, 0.4373541005020147 }, + { 0, { 27829., -71864., 150036., -117804., 67370., -49093. }, 0.4560888031675395 }, + { 0, { 539822., 432225., -319385., 741980., -155058., 309230. }, 0.4797023746036813 }, + { 1, { 353284., -620503., 706907., 178082., 295983., 93413. }, }, + { 2, { -261070., -393195., 329623., -469610., 151911., -193312. }, }, + { 0, { -2161367., -547925., 176106., -2360409., 138737., -1001848. }, 0.5007107300722267 }, + { 0, { 27247697., -10878578., 11956310., 25892704., 4272604., 11389311. }, 0.5164419295757459 }, + { 0, { 42877248480., -29362030594., 27366424342., 39132999157., 10686125728., 17489248357. }, 0.5296606590588865 }, + { 1, { -15857296., -20344255., 19186229., -13052624., 8755482., -9908361. }, }, + { 2, { 6609281., 13149967., -10297853., 6131752., -4439009., 2280289. }, }, + { 0, { -18516226., 26000654., -21956172., -17721375., -8891106., -8274169. }, 0.5451799187785868 }, + { 0, { 924882., -10894893., 8857638., 2001907., 3741179., 1161552. }, 0.5595376466726170 }, + { 0, { 27311120., 29858821., -26928769., 14296744., -12217212., 5123580. }, 0.5795066100144535 }, + { 1, { 13030129., -18873913., 10742323., 12477743., 4123021., 5837654. }, }, + { 2, { -7424534., -11497916., 9860547., -3566473., 4394376., -1162013. }, }, + { 0, { -26277687., -24566747., 22551607., -14225886., 10328130., -5247184. }, 0.5911608643334181 }, + { 1, { 8339866., -11546546., 6481932., 8138775., 2473924., 3793057. }, }, + { 0, { -712821., 106326., 116149., -425425., 75173., -183273. }, 0.6154942605989902 }, + { 0, { 10367622., 10279698., -8594103., 9404066., -3937577., 3712537. }, 0.6326027345940838 }, + { 1, { 897045., 857895., -751707., 469816., -332572., 171768. }, }, + { 0, { 189069., -432469., 40216., 165708., -8464., 80857. }, 0.6444812066531010 }, + { 1, { 358961., 188063., -197366., 119155., -93776., 37030. }, }, + { 0, { 2801., -42321., 23044., 13212., 9231., 7153. }, 0.6631203366491857 }, + { 0, { 4336., 3618., -871., -1752., -434., -1180. }, 0.6824152589010221 }, + { 0, { -14481., -6624., 4573., -1496., 2554., -8. }, 0.7002707215510490 }, + { 0, { -223890., 106356., -2013., -41001., 13805., -21357. }, 0.7195602591163895 }, + { 1, { 28954., 129738., -23285., -9336., -9672., -11954. }, }, + { 0, { 500290., -303873., -27592., 125875., -40399., 71687. }, 0.7280600120460897 }, + { 0, { 729018., -876869., -461257., 537352., -184892., 325523. }, 0.7385877731868745 }, + { 1, { -549774., 403499., -445388., -787700., -178960., -329235. }, }, + { 0, { -154224., -136331., 129548., -90101., 64599., -32148. }, 0.7506622252123309 }, + { 0, { 36827., 21410., -22046., 16972., -12019., 7006. }, 0.7602186192346818 }, + { 0, { -9432., -929., 4761., -3712., 2630., -1835. }, 0.7714697369886172 }, + { 0, { 2272., -244., -1058., 1139., -553., 579. }, 0.7851226034217180 }, + { 0, { 236., 2440., 694., 90., 191., -135. }, 0.8150362349770407 }, + { 0, { 2171., -25731., -8199., 18101., -2071., 8952. }, 0.8291920856012017 }, + { 0, { -6488604., 1912961., -2051708., -5704251., -640826., -2468602. }, 0.8459901559232306 }, + { 1, { 133871., -10089., -90464., 3174., -43566., 7399. }, }, + { 2, { 3748., 19859., 25943., -57668., 8170., -24731. }, }, + { 0, { 41412., 22074., -6939., -4045., -5698., -1697. }, 0.8578592213260567 }, + { 0, { 574., 1501., -732., 4283., -255., 1685. }, 0.8738246080594192 }, + { 0, { 2322., -1798., 335., 937., 88., 501. }, 0.8963147077496537 }, + { 0, { -43604., -1899., 4040., -39896., 2661., -17151. }, 0.9105458422489332 }, + { 0, { 3596., -6271., 379., 5996., 286., 2760. }, 0.9259391061890530 }, + { 0, { -999582., 6287537., -5679601., -791405., -2413314., -507432. }, 0.9494173054851961 }, + { 1, { 111599., -339713., 235481., 52027., 98992., 33925. }, }, + { 2, { -33602., -140395., 93339., -35641., 41369., -10865. }, }, + { 0, { 149940., -187453., 95997., 203410., 38908., 91533. }, 0.9614421422806174 }, + { 0, { 46262., 123227., -97700., -14018., -43879., -8187. }, 0.9766842863215204 }, + { 0, { -150852., -63931., 82864., -16270., 39997., -7673. }, 0.9902969827486889 }, + { 0, { 580431., 130968., -306415., 215177., -145258., 96440. }, 1.0007147457558208 }, + { 0, { -315446., -113604., 191678., -91901., 90254., -41025. }, 1.0094608196461621 }, + { 1, { -3456., -446353., 229052., 185524., 103258., 88674. }, }, + { 0, { -189618., 113597., 8806., -140678., 6615., -64661. }, 1.0246980386783211 }, + { 0, { 4202483., 3000173., -2459447., 3363962., -1179328., 1385544. }, 1.0482030530764612 }, + { 1, { 1203874., -292900., 70065., 779465., 3811., 351179. }, }, + { 0, { 735702407., -1021641460., 944902088., 667150510., 387126729., 310854521. }, 1.0592824949737543 }, + { 1, { -225227., -2656169., 2070353., -678917., 860531., -321583. }, }, + { 0, { -906103., 1248865., -1249024., -614151., -510434., -296157. }, 1.0735437556293621 }, + { 0, { 133104., -244102., 224418., -12870., 91960., 2555. }, 1.0875704154537504 }, + { 0, { -98191., 334119., -93120., 114027., -39453., 36051. }, 1.1091289342301658 }, + { 1, { 131527., 1551., 58039., -54878., 19569., -21191. }, }, + { 2, { 65753., -188377., 68757., -76650., 28565., -25385. }, }, + { 0, { 61867., -343846., 16261., -113012., 8972., -35330. }, 1.1225031990563263 }, + { 0, { -7347., 137455., 17960., 22121., 5845., 4618. }, 1.1328877109810458 }, + { 0, { 11044., -88733., -25019., 37631., -8977., 18971. }, 1.1464066922869334 }, + { 0, { 11350781., -248125., 270190., 10489566., -145232., 4511204. }, 1.1622993228682923 }, + { 0, { -52127., 35850., -14691., -77957., -5084., -33671. }, 1.1728440239417584 }, + { 1, { -12008., 23292., -2942., -7282., -1291., -3563. }, }, + { 0, { 4294., 460., -3058., 3439., -1373., 1474. }, 1.1878668274609869 }, + { 0, { -1289., -734., 1786., -2248., 786., -941. }, 1.1998692758026896 }, + { 0, { 361., -793., 308., -1262., 122., -515. }, 1.2317935880659059 }, + { 0, { -195., 2534., -191., 3923., -67., 1609. }, 1.2448441509199817 }, + { 0, { -5385., -19904., 6349., -3489., 3158., -1221. }, 1.2560282933480911 }, + { 0, { 413790., -613072., 546872., 412919., 228594., 191066. }, 1.2653944427657104 }, + { 1, { -20115., 4841., -30066., -2156., -12194., -733. }, }, + { 0, { -56810., -2443., 14410., -37878., 7539., -15830. }, 1.2776927606634534 }, + { 1, { -883., -20034., 8211., 10587., 3489., 5153. }, }, + { 0, { -2444., 1465., 414., 793., 279., 259. }, 1.2924980461987274 }, + { 0, { 864., -632., -623., -218., -312., -55. }, 1.3014788911147197 }, + { 0, { 26233., -115536., 1588., -54448., 260., -17749. }, 1.3673745438817879 }, + { 0, { -366768., 241272., -241508., -348534., -93295., -154126. }, 1.3764442873088090 }, + { 1, { -4898., -22923., 39935., -25211., 16711., -10168. }, }, + { 0, { 7481., -4670., -7877., -4002., -3598., -1348. }, 1.3867469996002664 }, + { 0, { -2408., 1756., 2965., 1290., 1336., 416. }, 1.3958662188525488 }, + { 0, { 972., -751., -912., -28., -417., 39. }, 1.4068178503492994 }, + { 0, { -20343., 4804., -6579., -18594., -2298., -8037. }, 1.4396065958679622 }, + { 0, { 894., 1313., 1992., 632., 793., 162. }, 1.4496940872610145 }, + { 0, { -1983., -4631., -7582., 723., -2974., 660. }, 1.4625845924962999 }, + { 0, { 648492., 510288., -503142., 612739., -227097., 254982. }, 1.4790870471301645 }, + { 1, { -7847., 5399., -12816., -32834., -5768., -13533. }, }, + { 2, { -5935., 4107., 3696., -8454., 1585., -3763. }, }, + { 0, { 471., -326., 1178., -492., 455., -210. }, 1.5004111597792062 }, + { 0, { -1102., 5980., -5712., -389., -2409., -319. }, 1.5140608680143952 }, + { 0, { 235., -531., 427., -154., 168., -42. }, 1.5277453924778683 }, + { 0, { 1530., 1846., -2090., 2162., -918., 867. }, 1.5510420454912401 }, + { 0, { -8695., -5270., 3702., -11973., 1786., -4877. }, 1.5653775377343770 }, + { 0, { 108442., 13977., -7635., 130460., -5580., 54970. }, 1.5750243622459430 }, + { 0, { 12988439., -44123991., 40567288., 11522384., 17076170., 6015693. }, 1.5888946239094504 }, + { 1, { -297436., -96470., 75756., -224551., 37973., -97866. }, }, + { 2, { -140095., 49206., -15492., -114871., -4072., -51280. }, }, + { 0, { -213784., 360331., -204961., -174648., -85958., -85816. }, 1.5999174688094493 }, + { 0, { 34848., -82622., 33382., 30061., 14595., 15488. }, 1.6100691344943834 }, + { 1, { 43010., 10308., -12996., 14235., -6844., 6576. }, }, + { 0, { -1221., -3776., 845., 910., 489., 461. }, 1.6263710325060152 }, + { 0, { 554., 745., -310., -340., -171., -141. }, 1.6392210890659527 }, + { 0, { 20026., -16502., -3852., -9369., -2306., -3026. }, 1.6820002884969334 }, + { 0, { 813659., -336143., 300160., 724773., 109085., 319540. }, 1.6916922798012188 }, + { 1, { 1602., -17457., 27667., -10914., 11558., -4357. }, }, + { 0, { -5880., 742., -5245., -7508., -2092., -3141. }, 1.7051957386154943 }, + { 0, { 1260., 203., 1855., 1795., 753., 722. }, 1.7137017697983383 }, + { 0, { -181., 118., 893., -230., 356., -133. }, 1.7715707154892435 }, + { 0, { 715., -2305., -3568., 635., -1416., 471. }, 1.7804397794409668 }, + { 0, { 100206., -23631., 4854., 93727., 818., 43069. }, 1.7946296659726320 }, + { 1, { 4224., -2685., 2729., -6839., 1031., -2737. }, }, + { 2, { 84., 2460., 356., -441., 163., -287. }, }, + { 0, { -3928., 2396., -1944., -4367., -655., -1968. }, 1.8082885005321963 }, + { 1, { -1281., -1070., 1425., -1360., 663., -508. }, }, + { 0, { -434., -572., -639., 581., -222., 273. }, 1.8824124715680111 }, + { 0, { 5875., -12921., -96., 9965., 681., 4780. }, 1.8981641851181350 }, + { 1, { 3309., -927., -4565., 1029., -1995., 584. }, }, + { 0, { -14234., 16692., -15551., -9091., -6255., -4365. }, 1.9094415371356366 }, + { 1, { -5299., -4657., 1995., -4393., 1032., -1732. }, }, + { 0, { -215., 526., -123., -7., -42., -32. }, 1.9243893317056575 }, + { 0, { -1607., 1027., -1015., -1384., -397., -623. }, 1.9690057130935361 }, + { 0, { 907., -182., 55., -552., -12., -217. }, 1.9888685259410335 }, + { 0, { 80093., 1775., -15336., 49616., -8505., 21779. }, 2.0075896690458515 }, + { 1, { 3675., 886., 9437., 1003., 3841., 302. }, }, + { 2, { -2718., 2441., 1312., 2111., 647., 750. }, }, + { 0, { -749., 2213., 3067., 2387., 1321., 864. }, 2.0177406604319246 }, + { 0, { 82., 445., -97., 12., -47., -15. }, 2.0452450030168667 }, + { 0, { 939., 145., -364., 1452., -175., 622. }, 2.0918668035808388 }, + { 0, { 29763., -11270., 1340., 26747., 35., 12241. }, 2.1052596067061962 }, + { 1, { -752., -10176., 11464., -2886., 4981., -1015. }, }, + { 0, { -122433., -1948247., 1789021., -131787., 769924., -8458. }, 2.1185267640432053 }, + { 1, { -14746., -2745., 3642., -14273., 1472., -6101. }, }, + { 2, { -1381., -4337., 4157., -766., 1816., -296. }, }, + { 0, { 207., 2382., -2373., 455., -1016., 119. }, 2.1318821280894955 }, + { 0, { 317., -2045., -1566., 2287., -544., 1086. }, 2.2071860619320218 }, + { 0, { 45591., -42445., 35109., 42326., 14234., 19311. }, 2.2209783021218397 }, + { 1, { 100., -868., 334., -2387., 63., -853. }, }, + { 2, { -274., 556., 48., -449., -11., -223. }, }, + { 0, { 347., -11., -113., -232., -65., -97. }, 2.3082627901909945 }, + { 0, { 16054., -5418., 3307., 5345., 1043., 2606. }, 2.3219886353180517 }, + { 1, { -19., -205., 4127., -783., 1741., -387. }, }, + { 2, { -647., 309., -95., 84., -24., 13. }, }, + { 0, { 2409., -2117., -2607., -228., -1170., 136. }, 2.4200734218253461 }, + { 1, { 19., -536., 414., 216., 214., 119. }, }, + { 0, { 2201., 3681., -3051., 2808., -1347., 1419. }, 2.4294275957278497 }, + { 0, { -423., 745., -737., -631., -315., -318. }, 2.4385609820738123 }, + { 0, { 300., -1484., -1399., 755., -530., 425. }, 2.5260130486716892 }, + { 0, { 5490., -1919., 480., 4689., 156., 2132. }, 2.5361042359568997 }, + { 1, { 215., -174., 275., -263., 81., -64. }, }, + { 0, { 308., -156., 185., 292., 82., 121. }, 2.5459330159552604 }, + { 0, { 5463., 46., 202., 1602., -48., 766. }, 2.6374295145352566 }, + { 1, { 581., 381., 1106., 451., 460., 165. }, }, + { 0, { -36662., -85712., 78236., -34663., 34443., -12759. }, 2.6481663000165407 }, + { 0, { 1477., -1072., -1320., -336., -622., -3. }, 2.7397040327703399 }, + { 0, { 1659., -2071., 2391., 2294., 963., 1120. }, 2.7490048220101793 }, + { 1, { -1336., -455., -28., -609., -7., -260. }, }, + { 0, { 1366., -1582., -496., 1101., -173., 602. }, 2.8494750099923127 }, + { 1, { 141., -92., 188., -517., 50., -205. }, }, + { 2, { -23., 180., 65., -168., 19., -81. }, }, + { 0, { 1495., 362., 78., -117., -5., -23. }, 2.9530548702113095 }, + { 1, { 107., 70., 510., 245., 223., 92. }, }, + { 0, { 497., -250., -298., -554., -148., -215. }, 3.0510128159210788 }, + { 0, { 602., -271., -371., 232., -153., 154. }, 3.1654820818460752 }, + { 0, { -3037., -3424., 3284., -2814., 1483., -1134. }, 3.1775127563235914 }, + { 0, { 483., 216., 36., -224., 1., -77. }, 3.2694305438716178 }, + { 0, { 4935., 381., -381., 4408., -298., 2013. }, 3.3406022698986924 }, + { 0, { 235., -159., -104., -386., -58., -142. }, 3.3695779911862527 }, + { 0, { 339., -47., -126., -82., -67., -13. }, 3.4790904552288531 }, + { 0, { -5663., -29987., 27509., -5003., 11933., -2162. }, 6.2830762443769794 }, + { 0, { -59., -82., -23., 24., -12., 18. }, 8.4686530580615642 }, + { 0, { -17635., 511., -921., -16011., 697., -7231. }, 10.2131290491330340 }, + { 0, { -227., 115., -23., -264., 11., -116. }, 10.2220725794374050 }, + { /* end jupiter */ -1, }, +}; + +chap95_rec chap95_saturn[] = { + { 0, { 359537177., 0., -7206382337., 0., -2991243838., 0. }, 0. }, + { 1, { -20377631., 0., 15883341., 0., 8071624., 0. }, }, + { 0, { -64236683., -52860196., 142442224., -49744952., 58042432., -24365782. }, 0.0168745727060282 }, + { 0, { 30177751., 18129933., -67656128., 22849231., -27163043., 12315751. }, 0.0265670063186787 }, + { 1, { -8215259., 21212644., -23554648., -50768821., -12209063., -18901172. }, }, + { 0, { 1964057., 724735., -4686899., 1417179., -1646759., 941321. }, 0.0493811968866401 }, + { 1, { -134000., 3348965., -10011640., -8728398., -4234207., -2535628. }, }, + { 0, { 5686743., 3475773., -334368., 3091703., 72747., 926256. }, 0.0662237107929899 }, + { 0, { 554020., 1079938., -2966895., -1601162., -1509110., -278930. }, 0.0843726142307477 }, + { 0, { 4610964., 21987586., 31945199., -5263812., 13882828., -4598499. }, 0.1010129457774524 }, + { 0, { -66034588., -94070401., 111667599., -68387008., 47456033., -25071683. }, 0.1128014605528121 }, + { 1, { -4294328., -12886739., 37728596., -1754644., 11349347., 1748900. }, }, + { 0, { 6081642., 23561987., -38577166., -9734586., -12217167., -502775. }, 0.1245386660916166 }, + { 0, { -11635904., -19574871., 36907731., -11918213., 11119486., -6364841. }, 0.1376921108585382 }, + { 0, { 104499813., 75674727., -132241710., 152846005., -35848667., 59734045. }, 0.1532223867622918 }, + { 0, { -119336309., -65929841., 110429555., -174948245., 28176754., -66225503. }, 0.1635156403544941 }, + { 1, { 52564319., -48818442., 77555859., 94135021., 31177405., 26437148. }, }, + { 2, { 56660530., 23619473., -35687037., 84928050., -8020678., 31023884. }, }, + { 0, { 59047999., -9112158., 18208825., 74844916., 8173908., 26476289. }, 0.1849404508049137 }, + { 0, { -195085048., 130948239., -157301623., -207103141., -57416134., -80784650. }, 0.1994326216901347 }, + { 0, { 61319082350., -72972816459., 68513342186., 55646924765., 25657191842., 26113032275. }, 0.2133734516582497 }, + { 1, { 58897194., 107088220., -104901917., 68459614., -34345682., 47420026. }, }, + { 2, { -100212137., 21822222., -43604349., -89401596., -12674282., -32150723. }, }, + { 0, { 18845535., -49223999., 35615797., 26623302., 16402647., 15391365. }, 0.2335002178020494 }, + { 0, { -4180907., 4465884., 38621., -479609., 814285., -1219056. }, 0.2510310507212479 }, + { 1, { -18966213., 1413107., 11641634., -15116208., 6182492., -9256829. }, }, + { 0, { 3257184., 9509868., -11066286., -7321147., -6968557., -3079573. }, 0.2622227446243415 }, + { 0, { -1404116., -417364., 2858988., 1478988., 1856930., 162727. }, 0.2775489797512927 }, + { 0, { 1467706., 1107543., -4409004., 226468., -2199319., 678454. }, 0.2926511843672006 }, + { 0, { -63623237., -37507272., 39122548., -67696931., 18154709., -27796755. }, 0.3162439145857524 }, + { 1, { -3829645., 1269380., -9251051., -8961610., -4871745., -2487901. }, }, + { 2, { 1909651., 1468024., -7914338., 6203925., -2960534., 3971621. }, }, + { 0, { 6281876., -3642612., -4761114., 23447042., 286480., 12241212. }, 0.3340526064764550 }, + { 0, { -5802348., 5752123., -4991225., -30347977., -5911367., -14358380. }, 0.3467225133858732 }, + { 0, { 7539581., -27234846., 89254406., 72087653., 50683522., 25464083. }, 0.3654342931118227 }, + { 1, { -16970597., 906805., 25342361., -65544284., 5459306., -34110644. }, }, + { 2, { -5198192., 11224087., -33200716., -38195205., -20121188., -14873633. }, }, + { 0, { -2145161., 31156404., -111624554., -59422928., -60033284., -17237400. }, 0.3766625707476834 }, + { 0, { -2433702., -8759560., 35127703., 5461246., 17518688., -795950. }, 0.3868793178145906 }, + { 0, { 3948221., 3250926., -14710717., 6016597., -6668684., 4126312. }, 0.4021189702952532 }, + { 0, { -64852219., -1152783., 37078116., -78426047., 17075754., -36402504. }, 0.4173317886569649 }, + { 0, { 2598837096., -322512661., 333925850., 2403155625., 25718615., 1008149551. }, 0.4268085445169599 }, + { 1, { -8046615., 50513333., -65775281., -14855286., -30373245., -5862741. }, }, + { 0, { 14632122., -1627420., 391595., 27967394., 1503248., 13109492. }, 0.4393540871607130 }, + { 0, { -3977607., 2348335., -4492336., -11638695., -3044963., -5280793. }, 0.4516261147924168 }, + { 0, { 3891847., -6235742., 13257786., 12849113., 7381680., 5287411. }, 0.4647357720725654 }, + { 0, { -2681944., 5714068., -11275550., -8345687., -6000449., -3297402. }, 0.4765294470438712 }, + { 1, { -3310032., -1656488., 6283436., -7934719., 2454880., -4374462. }, }, + { 2, { 581001., -2310426., 4449727., 1912796., 2258154., 644572. }, }, + { 0, { -543181., 190668., 100357., -477814., 102237., -296580. }, 0.4992649823773071 }, + { 0, { 734019., 40318., 205332., 241668., 50065., 172083. }, 0.5130863461740709 }, + { 0, { 34991657., -27811324., 27384011., 28671165., 10659597., 13066000. }, 0.5295353231453532 }, + { 1, { -995667., 165111., 1788489., 16637., 818086., -43110. }, }, + { 2, { -317358., -198759., -6708., 263693., 27631., 133736. }, }, + { 0, { -31862., -65198., 73955., 29129., 36339., 15797. }, 0.5497097571860546 }, + { 0, { -4929., 225052., -215444., -8168., -89868., -12808. }, 0.5633695884286543 }, + { 0, { 24691., 22218., -9270., 18179., -4474., 5589. }, 0.5991350601911121 }, + { 0, { 289471., 202198., -100019., 60710., -58404., 1113. }, 0.6158926177569189 }, + { 1, { 99636., -158087., 49023., 12201., 5200., 13036. }, }, + { 0, { -1368816., -1646305., 699872., -1449808., 365729., -462486. }, 0.6277831102482128 }, + { 0, { 86066856., 61934875., -56200895., 80007767., -26961118., 30372088. }, 0.6401904307430363 }, + { 1, { -1903624., 1069032., -956603., -1766047., -334714., -771306. }, }, + { 2, { 388212., 231504., -217129., 594559., -86428., 243060. }, }, + { 0, { 806222., 541401., -454902., 1046875., -196326., 413041. }, 0.6510631728715514 }, + { 0, { -45865., -22253., 10036., -80738., 2915., -31853. }, 0.6610474418282967 }, + { 0, { 7873., 2358., 3189., 5877., 1281., 2008. }, 0.6837277548947647 }, + { 0, { -98664., 39992., -40413., -90837., -12525., -38879. }, 0.7043645359718698 }, + { 0, { -1946., 3664., 10236., -357., 4293., -1167. }, 0.7177278015736290 }, + { 0, { -284513., 3015890., 2554237., 521699., 1046024., 49179. }, 0.7348232721925007 }, + { 1, { 192624., 52403., 33461., -150025., -105., -61152. }, }, + { 0, { -574265., -320413., 457058., -572461., 214214., -240685. }, 0.7435248864377025 }, + { 1, { 1145., -36334., 41717., 108651., 15647., 49114. }, }, + { 0, { 4558., -12170., 12006., 2809., 4790., 1802. }, 0.7636282240814432 }, + { 0, { -13700., 9256., -10447., -12051., -3998., -5133. }, 0.7781708314331308 }, + { 0, { 2247., -693., 1592., 1083., 680., 202. }, 0.7950594399751412 }, + { 0, { -1275., 5493., -6655., 924., -2492., 1116. }, 0.8129117802019118 }, + { 0, { -1223., -19571., 23014., -16306., 6735., -10155. }, 0.8251778324059539 }, + { 0, { 303076., 327040., 524629., -601728., 145475., -284414. }, 0.8382097667143232 }, + { 1, { -68015., 68576., -104282., -95123., -56039., -18028. }, }, + { 0, { 804121., 5204866., -4807644., 856208., -2083791., 112505. }, 0.8530682323228537 }, + { 1, { 29622., -215766., 182882., 33800., 76379., -13007. }, }, + { 0, { -13943., 51584., -40954., -8800., -23024., -3606. }, 0.8654403493251860 }, + { 0, { 3328., -7556., 4381., 1661., 2910., -36. }, 0.8766682028622256 }, + { 0, { -1505., 1631., -856., 784., -507., 674. }, 0.8895787094971168 }, + { 0, { -7919., -1616., 1989., -5290., 1264., -2147. }, 0.9133756947048002 }, + { 0, { -719., -2923., 1034., -5631., 504., -2040. }, 0.9236279354499169 }, + { 0, { 235224., 39046., -67004., -248093., -51203., -88317. }, 0.9453092341234691 }, + { 1, { 23462., -3456., -13540., 1977., -2121., 4776. }, }, + { 2, { -14574., -833., 1399., 12342., 2166., 4371. }, }, + { 0, { -26186., -43172., 35585., -24094., 17801., -8640. }, 0.9587102428763801 }, + { 0, { 5306., 3426., -2598., 4654., -1521., 1836. }, 0.9687040706037242 }, + { 0, { -1404., -1568., 973., -1250., 478., -476. }, 0.9844044794489883 }, + { 0, { 710., 549., -640., -936., -297., -397. }, 1.0125530865194814 }, + { 0, { -4798., 528., 2241., 2772., 1073., 1027. }, 1.0243303434648821 }, + { 0, { 19204., -11735., -10052., -9127., -4600., -2887. }, 1.0350677988213037 }, + { 0, { -70967., 104737., 71732., 36807., 31189., 9485. }, 1.0444890430562743 }, + { 0, { -225798., 798684., 944928., 428637., 404105., 131989. }, 1.0535670598935039 }, + { 0, { 421437., -821624., 460671., 296203., 193979., 145015. }, 1.0624723083698995 }, + { 1, { 404141., 190563., -153412., 239290., -77801., 95534. }, }, + { 0, { -6822., -2424., -12141., -503., -4568., -254. }, 1.0799687683920178 }, + { 0, { 5231., 2124., 4765., -2411., 1681., -1002. }, 1.0944898935961935 }, + { 0, { -4360., -571., -2843., 2544., -920., 1015. }, 1.1034700208578079 }, + { 0, { 2352., -783., 1220., -2044., 355., -732. }, 1.1190075299813413 }, + { 0, { -5735., 3169., 186., 5121., 420., 1436. }, 1.1356439922218147 }, + { 0, { 26551., -30281., 5089., -56530., 4098., -12591. }, 1.1476494842799982 }, + { 0, { 182096., 230606., 190305., 20362., 32484., -34547. }, 1.1561539197957733 }, + { 1, { -46354., -35766., 25278., 21603., 6113., 24924. }, }, + { 2, { -6693., -10691., -762., -24972., 5267., -3607. }, }, + { 0, { 7509., -14080., 2266., 4828., -2812., 2396. }, 1.1724975800169239 }, + { 0, { -1097., 4594., -221., -711., 861., -846. }, 1.1827508062529084 }, + { 0, { 268., -1663., 197., 151., -139., 350. }, 1.1922546935063294 }, + { 0, { 3821., -6929., -9691., -9738., -1997., -3976. }, 1.2526642649376578 }, + { 1, { -3679., 2852., -872., 4458., -151., 647. }, }, + { 0, { 103288., 30887., 44394., -80994., 5313., -31354. }, 1.2615381418438327 }, + { 0, { 11722., -929., 20555., -32545., 6476., -10964. }, 1.2737411543354145 }, + { 0, { -17778., 2234., -8752., -2076., -2194., -1934. }, 1.2848042137871682 }, + { 1, { -807., -10464., -4345., -4583., -776., -1210. }, }, + { 0, { -2021., 243., -476., 1775., -175., 485. }, 1.2966706439177036 }, + { 0, { -414., 1251., 1334., 193., 402., 122. }, 1.3428511130177547 }, + { 0, { -6545., 29273., 20095., -2836., 7521., 1278. }, 1.3563973340863262 }, + { 1, { 13556., 3272., -1197., -10568., 545., -3663. }, }, + { 0, { -180708., 208447., 210704., 176234., 95276., 55650. }, 1.3681253803708262 }, + { 1, { 18503., 8458., -1041., -19835., 212., -7272. }, }, + { 2, { -2022., 9714., 3806., 25., 1699., 1106. }, }, + { 0, { 967., -692., -12., -1766., -76., -677. }, 1.3856345885533017 }, + { 0, { 704., -587., -2388., 1139., -927., 144. }, 1.4516885121122214 }, + { 0, { -2400., 3304., 8864., -6463., 3877., -1185. }, 1.4602508651959594 }, + { 0, { 69982., 97834., 73391., 17685., 16742., -10304. }, 1.4727239692395073 }, + { 1, { -11044., -13056., 19308., 14020., 3724., 10827. }, }, + { 2, { -6082., -426., 3637., -7457., 3010., -854. }, }, + { 0, { 2590., -1868., 1096., 1043., -731., -69. }, 1.4872423683478513 }, + { 0, { -938., 62., 121., -521., 280., -164. }, 1.4985129994148070 }, + { 0, { 1803., 2377., 1110., -3335., 260., -1477. }, 1.5652937634682971 }, + { 0, { 64498., -5114., 68142., -30202., 22032., -11748. }, 1.5815555196973523 }, + { 1, { -22825., 4620., 14325., -12393., 6615., -5873. }, }, + { 2, { -7166., 4559., -5012., 2048., -1874., 652. }, }, + { 0, { -2200., -10219., 11039., 3346., 4934., 1509. }, 1.5955514308541998 }, + { 0, { 1099., 1374., -2363., -260., -1043., -86. }, 1.6049203503395801 }, + { 0, { -1208., -104., 561., 969., 230., 560. }, 1.6737223157218182 }, + { 0, { -86480., 70728., 67924., 86008., 31534., 31153. }, 1.6843589552967209 }, + { 1, { 933., 1492., 4350., -2566., 1516., -847. }, }, + { 2, { -1244., -445., -70., 369., 72., 345. }, }, + { 0, { 1465., -2624., 397., -65., -76., -7. }, 1.6977622139834585 }, + { 0, { 14992., 53026., 36206., 5674., 12375., -4229. }, 1.7889276713056903 }, + { 1, { -1089., -6208., 2064., 7721., -744., 4049. }, }, + { 2, { -1281., -2343., -210., 276., 49., 532. }, }, + { 0, { 3295., -4264., -3112., 6622., -2534., 1159. }, 1.8013654629975304 }, + { 1, { 1876., 442., -2702., -870., -615., -793. }, }, + { 0, { 21586., 22255., 25169., -13704., 7397., -6814. }, 1.8952695349759525 }, + { 1, { 1293., 636., 1855., -2161., 651., -493. }, }, + { 2, { -1508., -959., -1185., 1162., -341., 540. }, }, + { 0, { -837., -468., -77., 639., 49., 332. }, 1.9082748451618770 }, + { 0, { -39181., 17943., 18554., 39996., 9033., 15315. }, 2.0006786235742782 }, + { 1, { 70., 479., 1963., -746., 664., -147. }, }, + { 2, { -729., 4., -323., -76., -29., 30. }, }, + { 0, { -726., 389., 1661., 467., 647., 367. }, 2.0949703642270960 }, + { 0, { -2813., 21512., 16741., 5023., 6930., 302. }, 2.1045989992211052 }, + { 0, { 6314., -196., -4305., 3407., -2614., -923. }, 2.1133294411524268 }, + { 0, { -1183., -1102., 1934., -946., 1020., -24. }, 2.1218152921149840 }, + { 0, { 7013., 13819., 14243., -3085., 4615., -2198. }, 2.2116085451863530 }, + { 1, { 548., 591., 1334., -724., 439., -127. }, }, + { 2, { -499., -647., -721., 383., -233., 184. }, }, + { 0, { -96., -348., -69., 163., -3., 83. }, 2.2246966026380783 }, + { 0, { -16878., 3417., 3609., 17709., 2011., 6948. }, 2.3169860146393306 }, + { 1, { -184., 273., 1066., -86., 376., 65. }, }, + { 2, { -421., -143., -106., -9., 9., 50. }, }, + { 0, { -1773., 10467., 5877., 4502., 2612., 236. }, 2.4212184393363345 }, + { 1, { 100., -1698., -212., 1585., -581., 698. }, }, + { 2, { -416., -532., 192., 38., 49., 218. }, }, + { 0, { 922., 6585., 6161., 638., 2178., -274. }, 2.5279051498015881 }, + { 1, { 305., 668., 969., -324., 338., -92. }, }, + { 0, { -7788., -691., -557., 7570., 62., 3142. }, 2.6333307376329276 }, + { 1, { -16., 174., 511., 158., 148., 85. }, }, + { 0, { -2797., 3622., 2705., 2693., 1341., 812. }, 2.7374368855151237 }, + { 0, { 1332., 523., -1008., -331., -394., -592. }, 2.7462646949156313 }, + { 0, { -528., 3192., 2851., 1151., 1069., 178. }, 2.8441606111313287 }, + { 1, { 54., 266., 527., 58., 138., 54. }, }, + { 0, { -3128., -1136., -1090., 3069., -358., 1285. }, 2.9496547906250985 }, + { 0, { -1332., 1366., 789., 1313., 449., 356. }, 3.0553439327040071 }, + { 1, { 46., -504., -405., 221., -232., 58. }, }, + { 0, { -722., 1469., 1417., 916., 574., 235. }, 3.1603882818225530 }, + { 1, { -8., 210., 314., 24., 105., 6. }, }, + { 0, { -1228., -704., -610., 1193., -210., 520. }, 3.2660150757959667 }, + { 0, { 4966., 349., -230., 4527., -271., 2058. }, 3.3406700896158381 }, + { 0, { -1003., 494., 345., 782., 229., 294. }, 3.3700954272546491 }, + { 0, { -642., 504., 417., 592., 188., 175. }, 3.4766263286125869 }, + { 0, { -5495., -30050., 27370., -5109., 11883., -2182. }, 6.2830758491321381 }, + { 1, { 12., 3., -21., -32., -16., -11. }, }, + { 0, { -127., 83., -47., -145., -13., -74. }, 8.4563910900857575 }, + { 0, { -17655., 888., -832., -16055., 726., -7281. }, 10.2133651230379790 }, + { 1, { -15., -178., 73., 27., 40., 18. }, }, + { 0, { 10., 56., 204., -33., 91., -14. }, 10.2233419556680150 }, + { /* end saturn */ -1, }, +}; + +chap95_rec chap95_uranus[] = { + { 0, { 13442911073., 0., -1930919457., 0., -1035250405., 0. }, 0. }, + { 1, { 54660667., 0., 47196247., 0., 21339801., 0. }, }, + { 0, { -6259970., -59715827., 56026092., -14879299., 23598892., -7731463. }, 0.0168745727060282 }, + { 0, { 5314993., 24095734., -17644181., 11961180., -6018215., 6587969. }, 0.0271621114651946 }, + { 0, { 816977., 27548111., -6448076., -468658., -4057252., -1448251. }, 0.0379771556339559 }, + { 0, { -1624242., 11338144., -20621799., 1496992., -5688694., 248222. }, 0.0558181533535525 }, + { 0, { 131350139561., 139711771423., -127221614269., 120945393838., -57589414088., 51010747052. }, 0.0747869939016385 }, + { 1, { 83579181., -50475439., 18032923., 50477352., 27217847., 30911037. }, }, + { 2, { 56177356., -62348507., 45006161., 56816875., 23394627., 20236290. }, }, + { 0, { -3192217., -67613872., 26532975., 31518890., 20804461., -5888651. }, 0.0851607526391989 }, + { 0, { 41246376., 168261887., -122401100., -97532527., -40313762., 5947933. }, 0.1076082382556661 }, + { 0, { -36235133., -140754409., 98201785., 64357246., 36255198., -9379330. }, 0.1131136321134916 }, + { 1, { 90255544., -46394994., -47508423., 75649120., 8064423., 19668708. }, }, + { 0, { -32042356., -21687295., 28029568., 15213468., 1662570., -3156568. }, 0.1256919464048962 }, + { 0, { 44969984., -2310664., -13084603., 20841905., 1428192., 12115421. }, 0.1384460864609660 }, + { 0, { -524718966., -4511367463., 4156633821., -484927968., 1817662129., -148236372. }, 0.1495664992280332 }, + { 0, { 61267776., 1565740., -24266489., 45519765., -3901964., 18298390. }, 0.1552897599647365 }, + { 0, { -7222268., 4911333., 3283374., -6377102., -254066., -1537379. }, 0.1694039594031046 }, + { 0, { 5873930., -4900474., -1827803., 7852582., -31798., 1819946. }, 0.1845250832150644 }, + { 0, { 1077339., 18380396., -901066., -10767827., -265560., 162663. }, 0.2002468734837309 }, + { 0, { -154311950., -219502970., 131091842., 178959446., 20655458., 5719299. }, 0.2141097583453364 }, + { 0, { -5528333., 212500368., -111109179., -139612191., -43337512., -21342579. }, 0.2193685795401007 }, + { 1, { -104517351., 177302072., 101064024., -75975513., -8816707., 3791842. }, }, + { 0, { 173653756., 151082404., -200861767., -135511564., -29950212., -17024507. }, 0.2293024101260499 }, + { 0, { -125918181., -44661266., 113832135., 56003631., 10092584., 6332126. }, 0.2359817391381943 }, + { 0, { 47624832., 2554277., -41914694., -13040594., -2759654., -2423818. }, 0.2431604796510437 }, + { 0, { -8805576., 2810717., 8600588., 666061., 636138., 663527. }, 0.2535948403663328 }, + { 0, { 1249271., -2422256., -2280787., 1243851., -81187., -241977. }, 0.2733943804314553 }, + { 0, { 90677., 14160054., 8529623., -8138579., 1686982., 1494393. }, 0.2885148535115661 }, + { 0, { 1004449., -20392040., -8104371., 18545176., -2778508., 705194. }, 0.2992461358046305 }, + { 1, { 5543727., 3362260., -1567031., -3163455., 585366., 471498. }, }, + { 2, { 2655788., 6883407., 3736665., -5070470., 1464904., 724248. }, }, + { 0, { 6192631., 6484479., 3731891., -6957619., 2642135., 445342. }, 0.3105692746147310 }, + { 0, { -1442546., -845134., -640944., 1375084., -614517., 35173. }, 0.3190867931520337 }, + { 0, { 683659., 282897., 363207., -694577., 243073., -261582. }, 0.3384589317094125 }, + { 0, { 210243., 95767., -88268., -40253., -126237., -71385. }, 0.3483018025771290 }, + { 0, { -122260., -61161., 139582., -75155., 89557., -59104. }, 0.3543646679104152 }, + { 0, { -341621., -166635., -6649., -236115., -4011., -98828. }, 0.3749354720310226 }, + { 0, { -34509., -47428., -33958., 69865., -15389., 28074. }, 0.3881544744399507 }, + { 0, { 127606., 82441., 63875., -131276., 30216., -55026. }, 0.4044642096018178 }, + { 0, { -55719., 35282., 53204., 42166., 20409., 8040. }, 0.4146735688956036 }, + { 0, { 745574., -86708., 85642., 660718., 2349., 278769. }, 0.4267276978319757 }, + { 0, { 46965., -63806., -140582., -2689., -51451., -6263. }, 0.4523712047583937 }, + { 1, { -44676., -29125., -21496., 62165., -11514., 20667. }, }, + { 0, { -47313., 131228., 153909., 13721., 54937., 13501. }, 0.4584750578982092 }, + { 0, { 64299., -217224., -204896., -47815., -89991., -26071. }, 0.4786471499447322 }, + { 0, { -216., 53443., -19130., -71538., -27839., -11228. }, 0.4920510287505367 }, + { 0, { -151224., -75735., -3305., 268854., -6542., 67361. }, 0.5051499531573665 }, + { 0, { 928196., 102377., -314167., -1414544., -33869., -402228. }, 0.5147029966036326 }, + { 0, { -1724399., 110969., 999802., 2605327., 184425., 789530. }, 0.5199630930448305 }, + { 0, { 40911206., -27399316., 26874089., 37399873., 10439229., 16767175. }, 0.5296669053399393 }, + { 1, { 583136., 1214598., 1755827., -1272416., 584159., -311166. }, }, + { 0, { 1173041., -1074191., -1886355., -1719260., -508991., -616258. }, 0.5369668320738028 }, + { 0, { -202800., 314145., 489969., 260218., 136957., 100165. }, 0.5445620632918582 }, + { 0, { 30834., -64556., -105954., -37083., -35677., -17746. }, 0.5559973222735549 }, + { 0, { 388., 18963., 34845., -2990., 13141., -175. }, 0.5645354635177183 }, + { 0, { -3029., -2222., -3901., 4299., -1477., 1512. }, 0.5864917785646289 }, + { 0, { 364., -3970., 4198., -17799., 1736., -7653. }, 0.6024030347783642 }, + { 0, { -64408., -16238., -14709., 52293., -7099., 22267. }, 0.6155618610057497 }, + { 0, { -8702., 7365., -847., 28860., 2496., 17960. }, 0.6266278765065182 }, + { 0, { 37681., 20807., -24633., 19631., -10642., 8265. }, 0.6366292306281224 }, + { 0, { 3191., 5638., -2365., 9854., -1386., 3658. }, 0.6449290790303238 }, + { 0, { -5177., -823., -2003., 5908., -949., 2341. }, 0.6763170666119763 }, + { 0, { -3638., 10059., 7207., 4377., 3151., 2651. }, 0.6862778987939261 }, + { 0, { 11748., -14352., -13920., -7897., -5625., -2944. }, 0.6979445752019332 }, + { 0, { -8438., 12018., 9236., 3586., 3477., 1505. }, 0.7048114577856822 }, + { 0, { 1834., -5463., -4042., -1281., -1755., -771. }, 0.7111948880743650 }, + { 0, { -4692., -8326., -4750., 8084., -2967., 3594. }, 0.7473196860221153 }, + { 0, { 4040., 13701., 10942., -11503., 6915., -5226. }, 0.7526899558709467 }, + { 0, { 22865., -59285., -48182., -15767., -20987., -6907. }, 0.7617757396112786 }, + { 1, { 3873., 1796., -260., -5778., -1031., -4126. }, }, + { 0, { 272., -668., 1897., 1033., 987., 184. }, 0.7769058037180200 }, + { 0, { -2176., 7071., 5492., 2930., 2571., 1313. }, 0.8199388514022748 }, + { 0, { -184998., 97937., 88915., 171155., 41794., 73600. }, 0.8350541004724259 }, + { 1, { -197., -3126., -715., 1748., -208., 825. }, }, + { 0, { -5824., 1942., -2170., -8871., -927., -3596. }, 0.8453935583217296 }, + { 0, { 252., 2148., -787., 1499., -241., 459. }, 0.8551127263577434 }, + { 0, { 3107., 6817., 10906., 19., 4504., -914. }, 0.8879713761393457 }, + { 0, { 6532., -6647., -8432., -9470., -3566., -3649. }, 0.8938517525956896 }, + { 1, { 2415., -4253., -3554., -6203., -2191., -2419. }, }, + { 0, { -3926., 523., -5326., 11396., -2537., 5007. }, 0.9076103122110721 }, + { 0, { 1486., 6143., -4417., -1583., -1883., -794. }, 0.9528977392964432 }, + { 0, { 1226., -908., 2507., -1706., 1029., -874. }, 0.9646777216958613 }, + { 0, { -11300., -22605., 26258., -9349., 12130., -5605. }, 0.9849512095278805 }, + { 1, { 1457., -2630., 860., 1293., 487., 641. }, }, + { 2, { -685., -2643., -646., -848., -225., -318. }, }, + { 0, { -2190., -3253., -891., -1611., -317., -665. }, 0.9964090016851210 }, + { 0, { -1179., -3116., -2763., 1595., -1346., 737. }, 1.0352639155374268 }, + { 0, { 7916., 3274., -3481., 4472., -1826., 2498. }, 1.0515675436820877 }, + { 0, { 697761., -973027., 901279., 634785., 369311., 295489. }, 1.0592810372818169 }, + { 1, { -1426., -5270., 2981., -566., 1562., -288. }, }, + { 0, { -1789., 2512., -1045., -777., -493., -461. }, 1.0720350844573199 }, + { 0, { 3343., -1231., -1017., -2862., -464., -1223. }, 1.1429483332496098 }, + { 0, { 11373., -2498., -1580., 8748., -883., 3741. }, 1.1609636069979286 }, + { 1, { -1522., -2635., 28., 1104., -15., 464. }, }, + { 0, { -1975., 3205., 2553., 2452., 995., 1112. }, 1.1691873087779718 }, + { 0, { -9107., -5910., -5019., 8600., -1999., 3899. }, 1.2152142837985198 }, + { 1, { -4., -1508., -1102., -242., -397., -127. }, }, + { 0, { -1971., 699., -3., 1482., -78., 551. }, 1.2226982614159414 }, + { 0, { -31., -206., 25., 63., 54., 23. }, 1.2355263592688024 }, + { 0, { 2581., 7563., 7150., -2433., 3120., -1128. }, 1.2857063346850945 }, + { 1, { 1638., -740., -410., -2267., -163., -1002. }, }, + { 0, { 6494., 16800., 14424., -5912., 6217., -2861. }, 1.2908372220692612 }, + { 0, { -2870., 4014., 4972., 2882., 2300., 1194. }, 1.3652019003010083 }, + { 1, { 121., -268., -412., 87., -162., 47. }, }, + { 2, { 204., -295., -187., 24., -76., 9. }, }, + { 0, { -3114., 953., -618., -2692., -475., -1304. }, 1.4390426416344881 }, + { 0, { 643., 554., -351., 588., -171., 247. }, 1.4790740463977397 }, + { 0, { 470., -497., -239., -9., -101., -35. }, 1.5778081754901920 }, + { 0, { 12015., -42122., 38323., 10981., 16121., 5766. }, 1.5889777636732787 }, + { 1, { -377., -28., -105., 615., -60., 248. }, }, + { 2, { -102., -86., -77., -32., -33., -28. }, }, + { 0, { -1329., 1696., 1422., 1073., 644., 441. }, 1.6698689170399983 }, + { 0, { 653., -443., 76., 737., 22., 321. }, 1.6917823552881666 }, + { 0, { 4010., -973., -776., -3727., -389., -1621. }, 1.7447101363840591 }, + { 0, { 796., 753., 911., -908., 375., -434. }, 1.8195524075201825 }, + { 0, { -67., 529., -320., 151., -164., 92. }, 1.8944084825549634 }, + { 0, { 10., -1636., 1676., -13., 718., 43. }, 2.1173586606692205 }, + { 0, { -176., -699., -800., 57., -346., 33. }, 2.1995558975407743 }, + { 0, { 4804., 493., -302., 4547., -271., 2069. }, 3.3406137564373255 }, + { 1, { -37., 63., -60., 6., -25., 5. }, }, + { 0, { -6127., -30327., 27236., -5550., 11893., -2472. }, 6.2830758108542479 }, + { 1, { 13., 96., 24., 144., -4., 74. }, }, + { 2, { 94., 86., 39., 73., 3., 45. }, }, + { 0, { -103., 11., 317., -154., 157., -57. }, 8.4710588767699999 }, + { 0, { -1072., -875., 799., -1217., 416., -503. }, 10.1988027176192690 }, + { 0, { -7126., 105., -353., -6736., 285., -3012. }, 10.2074359814049150 }, + { 1, { -735., 3920., -3778., -636., -1657., -531. }, }, + { 0, { -9779., 1441., -1464., -8409., -23., -3858. }, 10.2156685960931930 }, + { /* end uranus */ -1, }, +}; + +chap95_rec chap95_neptune[] = { + { 0, { -2753381808., 0., -2555187184., 0., -977694282., 0. }, 0. }, + { 1, { -53706852., 0., 9024894., 0., 5113590., 0. }, }, + { 0, { 5353414., 16329756., -10315608., -18211298., -4313685., -7909387. }, 0.0179617912970447 }, + { 0, { -19054385., -287482557., 282900211., 40600685., 114409567., 24195009. }, 0.0323644369574163 }, + { 0, { 171759338654., 246707191188., -226959547603., 161070501549., -97171931583., 59786666580. }, 0.0381185507042915 }, + { 0, { 269128284., 157897034., -86709918., 293605458., -39838078., 115245563. }, 0.0449423189622218 }, + { 0, { -93736103., -37825790., -26561507., -91732038., -9592733., -35920288. }, 0.0600427026897851 }, + { 0, { 178516553., 51475281., 124180124., 108331691., 49005129., 40587728. }, 0.0705779080356058 }, + { 0, { -1684231243., 681665499., -958998993., -1353650791., -355010040., -565296249. }, 0.0772675784146183 }, + { 0, { 1122264068., -578428299., 1063564939., 463713621., 414676760., 190864744. }, 0.0843726142307477 }, + { 0, { -781685034., 475952164., -808860716., -228929931., -316705638., -94548544. }, 0.0871507153151969 }, + { 0, { 56385979., -39979207., 64276567., 7694958., 25352958., 3214483. }, 0.1012471242645664 }, + { 1, { 63310243., 43285497., 22448880., 66731902., 8926250., 26309541. }, }, + { 0, { 2712359., -37080616., 26122509., -21572378., 10482381., -8529034. }, 0.1128959119291703 }, + { 0, { 1376659., 7176921., -1442553., 7206580., -479409., 2921144. }, 0.1246811309098641 }, + { 0, { -2552808., -3146754., -931704., -4559708., -491329., -1812338. }, 0.1349961443322037 }, + { 0, { 1162812., 462968., 719939., 2310847., 376498., 885784. }, 0.1402125408882514 }, + { 0, { -252283., -142326., -110247., -49287., -46731., -28945. }, 0.1616161402063230 }, + { 0, { 243162., -91598., 106479., 16854., 55597., 8501. }, 0.1776262925892778 }, + { 0, { -672251., 231673., -319786., 386301., -155882., 135214. }, 0.1904084544956719 }, + { 0, { 1867133., -1866896., 239943., -1803069., 228227., -732880. }, 0.2026926199831023 }, + { 0, { 32066276., -61274160., 6958960., -9094869., 4399306., -3854675. }, 0.2132050927412489 }, + { 1, { -11587231., -5526999., -7458452., 2330330., -3274130., 322813. }, }, + { 0, { -16700375., 45567407., 14051147., 28126677., 3238872., 12733553. }, 0.2160078733553654 }, + { 0, { 601249., -3740179., -1686685., -1590049., -510731., -804485. }, 0.2225065497464809 }, + { 0, { 71272., 256103., 179344., -10427., 65192., 15214. }, 0.2362432045351159 }, + { 0, { -58547., -82547., -51318., 58153., -20501., 15047. }, 0.2470536247773912 }, + { 0, { -6723., 19924., 26278., 12439., 9453., 3700. }, 0.2721326326759872 }, + { 0, { -3710., 4976., -7051., 254., -1464., 195. }, 0.2834391769690069 }, + { 0, { -12572., -6375., 5687., 15436., 615., 5233. }, 0.2938091870567225 }, + { 0, { -14716., 204103., 159833., 45074., 65416., 11053. }, 0.3117802888037338 }, + { 0, { -17577., 42568., 85327., -50768., 36610., -17999. }, 0.3148973170728874 }, + { 0, { -12308., -4224., -5418., 20456., -3011., 7048. }, 0.3237199721077774 }, + { 0, { -453., 863., 3006., -1602., 798., -820. }, 0.3434014414974197 }, + { 0, { -4296., 775., 4295., 2013., 1131., 245. }, 0.3679427772208049 }, + { 0, { 2844., 8238., -10394., 16799., -2798., 8324. }, 0.3785701069003719 }, + { 0, { -12477., -18952., 16324., -32949., 3954., -15266. }, 0.3833769854125967 }, + { 0, { -22365., 128., 5047., -4988., 1724., -1653. }, 0.3921552738853996 }, + { 0, { 4383., -6090., 178., -7672., -722., -3343. }, 0.4052046013289639 }, + { 0, { 714788., -68799., 122150., 736324., 10410., 310430. }, 0.4266933782608374 }, + { 1, { 12121., 14734., 49080., -28648., 20910., -8012. }, }, + { 0, { 46510., -21693., -58299., -84149., -12783., -39407. }, 0.4328778616668182 }, + { 0, { -18771., 8624., 16635., 18600., 2724., 10462. }, 0.4397536016965201 }, + { 0, { 3796., -9377., -6884., 415., -1798., -1014. }, 0.4503999814583104 }, + { 0, { -7089., 1370., -2220., 4940., -839., 2525. }, 0.4636405151525668 }, + { 0, { 5125., -1762., 2170., -4527., 631., -2166. }, 0.4745702135817129 }, + { 0, { 36688., -1584., -8174., -32426., -3946., -13037. }, 0.4886034832877044 }, + { 0, { -5607., 1955., 1641., 547., 484., -201. }, 0.5046352473687760 }, + { 0, { 45109., -21568., 12616., 26255., 6182., 12720. }, 0.5178003462986053 }, + { 0, { 40893658., -28000813., 26124943., 37354584., 10197353., 16693506. }, 0.5296623039564303 }, + { 1, { -21062., -35782., 31769., -20330., 15353., -11834. }, }, + { 2, { 10720., 5927., -12424., -538., -3613., -359. }, }, + { 0, { -28607., 23386., -38172., -43627., -12236., -20256. }, 0.5403804874893231 }, + { 0, { 66., 635., 4597., 3533., 1279., 1843. }, 0.5486365851140401 }, + { 0, { -1646., 2776., -3727., -1793., -1436., -354. }, 0.5631942288095021 }, + { 0, { -353., 460., 306., -526., 107., -133. }, 0.5739537566607668 }, + { 0, { -48., -518., 599., -406., 229., -183. }, 0.6031743297859348 }, + { 0, { -230., -43., -65., 493., -36., 204. }, 0.6175060453479511 }, + { 0, { 19445., 2550., -25130., 13108., -10967., 5418. }, 0.6333639350967218 }, + { 0, { 13473., 21421., -1023., 17345., -1204., 6355. }, 0.6373233385189475 }, + { 1, { 864., -8826., 6444., 11189., 2532., 4949. }, }, + { 0, { 1578., 3023., 2194., 1035., 836., 338. }, 0.6488504417528818 }, + { 0, { -3340., -7100., -6757., 2738., -2684., 1301. }, 0.6617542675140329 }, + { 0, { 1017., 744., 847., -982., 332., -425. }, 0.6999703675245400 }, + { 1, { 42., 10., 19., -41., 10., -16. }, }, + { 0, { 1891., 647., -479., 1705., -149., 715. }, 0.7361514522905745 }, + { 0, { -747., -1284., 1091., -507., 523., -190. }, 0.7442630004913908 }, + { 0, { -25., 104., -104., -129., -52., -37. }, 0.7785774183375729 }, + { 0, { -512., 349., 592., 506., 250., 205. }, 0.8337771392669406 }, + { 0, { -6683., 244., -856., -5864., -184., -2467. }, 0.8456021851592702 }, + { 1, { -1203., -318., -1016., 257., -373., 120. }, }, + { 0, { -24., 3933., -1820., 1132., -757., 301. }, 0.8511022350336571 }, + { 0, { 201., -293., -309., -190., -131., -68. }, 0.8740442975723336 }, + { 0, { 308., -601., -394., -483., -169., -197. }, 0.9077766553319553 }, + { 0, { -16598., 27372., 14431., 13730., 6210., 4914. }, 0.9458755575816939 }, + { 1, { -126., -1380., -1472., 3523., -609., 1504. }, }, + { 2, { 143., -540., 222., -105., 87., -32. }, }, + { 0, { 329., 51., -160., 190., -86., 81. }, 0.9622835434242619 }, + { 0, { 128., 272., 129., -159., 60., -76. }, 0.9782201450147658 }, + { 0, { 420., 770., -363., -155., -115., -92. }, 1.0124707282567436 }, + { 0, { -2248., -3936., 3766., -2218., 1312., -630. }, 1.0195444397190756 }, + { 0, { -857., -445., 435., -868., 168., -286. }, 1.0327159571739788 }, + { 0, { 3376., 287., -315., 3751., -219., 1451. }, 1.0465646752474935 }, + { 0, { 703800., -971644., 898780., 636713., 368186., 296800. }, 1.0592831516596322 }, + { 1, { -2151., -2956., 2235., -1431., 946., -697. }, }, + { 2, { -483., -834., 925., 208., 376., 16. }, }, + { 0, { -2186., 1237., -468., -857., -221., -500. }, 1.0699466056843263 }, + { 0, { 186., -107., -155., -33., -60., 1. }, 1.0856512764294945 }, + { 0, { -29., 176., 74., -52., 22., -24. }, 1.1079517768853906 }, + { 1, { 68., -82., -7., 40., -2., 17. }, }, + { 2, { 47., -125., -59., 70., -19., 30. }, }, + { 0, { -79., -181., -17., 75., 0., 31. }, 1.1242912886086618 }, + { 0, { 11970., 27., -219., 9608., -385., 4137. }, 1.1622448658047415 }, + { 1, { 148., -416., -127., 187., -55., 93. }, }, + { 0, { -1209., -240., 543., 444., 267., 180. }, 1.1657893477276102 }, + { 0, { 469., -600., 571., 404., 237., 192. }, 1.2652830224888050 }, + { 0, { -354., 198., -247., -335., -95., -149. }, 1.3749277491569207 }, + { 0, { 1875., 1364., 1214., -1793., 447., -768. }, 1.4364654070205274 }, + { 1, { 8., 17., -6., -31., -6., -14. }, }, + { 0, { -139., 116., 212., 18., 88., 1. }, 1.4674691182537039 }, + { 0, { 498., 950., -86., 629., -57., 244. }, 1.4773951127670801 }, + { 0, { -211., 132., -176., -151., -46., -37. }, 1.5126367782986652 }, + { 0, { 388., -45., -90., 143., -56., 57. }, 1.5755868837627032 }, + { 0, { -262., 394., 82., 179., 60., 76. }, 1.5824073222387700 }, + { 0, { 12274., -42141., 38563., 10654., 16215., 5586. }, 1.5888971797699629 }, + { 1, { 79., 26., 108., -116., 43., -61. }, }, + { 0, { 785., -282., 272., 723., 98., 317. }, 1.6918870360592064 }, + { 0, { 107., -210., -181., -174., -73., -72. }, 1.9281473841900221 }, + { 0, { -121., -1883., 1696., -129., 731., -7. }, 2.1185461864868773 }, + { 0, { 4845., 396., -313., 4430., -275., 2018. }, 3.3406127811310191 }, + { 1, { 1., 25., -4., 6., -1., 2. }, }, + { 0, { -5503., -29918., 27443., -5129., 11901., -2218. }, 6.2830758192539502 }, + { 0, { 149., -16., 70., 137., 24., 69. }, 6.6811483956904603 }, + { 0, { 14., 35., -47., -48., -19., -18. }, 8.4710967963441863 }, + { 1, { 1., -1., -17., -7., -7., -4. }, }, + { 0, { -17638., 555., -991., -16049., 673., -7250. }, 10.2132840866995910 }, + { 0, { -44., -259., 211., -59., 89., -24. }, 12.5662764645159580 }, + { /* end neptune */ -1, }, +}; + +chap95_rec chap95_pluto[] = { + { 0, { 101045891905., 0., 110312086224., 0., 6172492792., 0. }, 0. }, + { 1, { 2736962357., 0., 7289921703., 0., 8356828229., 0. }, }, + { 0, { -197631754827., 306850452168., -363706825084., -174047739469., -83742488844., -166197114948. }, 0.0255535185296511 }, + { 1, { -10339882709., 3627560682., -1704596538., 16082008148., -2615797675., 26582875457. }, }, + { 2, { 4555881844., 5354987944., 14163087849., 13295578846., 16544976961., 15318697408. }, }, + { 0, { 12877551757., 9141005248., 38823958976., 14074786713., 47081142550., 15934841957. }, 0.0383093966256461 }, + { 0, { -20363081906., 43534352230., -68888048997., -6054817551., -37922256273., -13665923314. }, 0.0512632279013590 }, + { 0, { 11372859069., -7331041505., 34135169446., -14164330338., 35562426110., -15256543947. }, 0.0629625800045217 }, + { 0, { -25223811753., 30334977886., -76993608077., 67207355885., -78022096909., 72709750549. }, 0.0739104871604531 }, + { 0, { 19031032676., -21606847641., 49490563510., -67837042251., 54793488046., -76660221358. }, 0.0843726142307477 }, + { 1, { 9888109415., 13390931761., 31569755508., 36949340015., 35801709881., 41063108577. }, }, + { 2, { -5391246864., 9125341237., -13760381761., 26757260022., -14709006932., 29981422406. }, }, + { 0, { 77016900., 8576436595., -758303524., 19868503441., 945693837., 21114141886. }, 0.1009656667626818 }, + { 0, { -425710709., -2201772586., -2981443460., -6781825029., -3324565933., -7783206250. }, 0.1181216342983851 }, + { 1, { 2255988361., -245384099., 5983679140., -939391729., 6514267045., -1323842110. }, }, + { 2, { 531179571., 1086625691., 2182247914., 3044397909., 2484824490., 3408389022. }, }, + { 0, { 670122662., 438458646., 1753307958., 718209879., 2047795531., 636335929. }, 0.1384952768343311 }, + { 0, { -179746215., -90394676., -766063009., -205567765., -854408253., -261725146. }, 0.1499201895782055 }, + { 1, { 110140865., -359336510., 28912500., -843378659., -67920831., -973289319. }, }, + { 0, { -118071179., 1819649., -265130729., 91955370., -298913452., 133716152. }, 0.1607487697162686 }, + { 0, { 38739517., 9002149., 12071193., -2098061., 15714901., -32081340. }, 0.1760768320056049 }, + { 0, { -2332129., 6073325., -5475022., 19141973., -5216109., 20872520. }, 0.1900452184842649 }, + { 0, { 8137788., -2826068., -3014741., -6719062., -5256740., -14189611. }, 0.2024941844674784 }, + { 0, { 18559203., -16541614., 25112499., 27558953., 14213163., 19938478. }, 0.2134752084935937 }, + { 0, { 1940133., -1267576., -1439934., -1986889., -2525015., -3851133. }, 0.2269557049635166 }, + { 1, { 1917476., -1704590., 4921317., -5434051., 4782139., -6305807. }, }, + { 0, { -822410., -563503., -2747944., -903463., -3210523., -702889. }, 0.2402479397150676 }, + { 0, { 962595., -74013., 1141117., 518365., 966375., 17190. }, 0.2531177145689346 }, + { 0, { -135658., -8463., -393590., 160618., -448155., 267162. }, 0.2643717493874742 }, + { 0, { 231442., -143885., 176186., -1443., 93050., -109960. }, 0.2777029906063622 }, + { 0, { -3000., -245., -27453., 92186., -35712., 133397. }, 0.2900297658482435 }, + { 0, { 55997., -115242., -44421., -45883., -43549., -47825. }, 0.3037412654012783 }, + { 0, { -14892., 15253., 52487., 23252., 43486., 48497. }, 0.3142803959054077 }, + { 0, { -2949., -95938., -94512., -17869., -51976., 3765. }, 0.3264027536592037 }, + { 0, { 8894., 9213., 33696., 2580., 28347., 6790. }, 0.3373713684595000 }, + { 0, { -16468., -43883., -57588., 8839., -17108., 18484. }, 0.3506196546089751 }, + { 0, { -4324., 14942., 537., 2320., 8817., -1258. }, 0.3768935755307548 }, + { 0, { -2257., -145., -272., -4909., 4559., -6184. }, 0.3901294315026133 }, + { 0, { -10889., 10437., -5474., 6213., 16279., -4595. }, 0.4045287784128869 }, + { 0, { 719443., -70760., 86542., 684112., 3209., 279550. }, 0.4267968486470127 }, + { 1, { 3728., 5875., 3969., 4141., 3826., 956. }, }, + { 2, { 9968., 1181., 2923., 6780., 6338., 2119. }, }, + { 0, { 6842., 1584., 10374., 4788., 8573., -4658. }, 0.4456721426794963 }, + { 0, { -10089., 9939., 3641., 7449., 544., 598. }, 0.4579662921251779 }, + { 0, { 1823., 688., 6471., -612., 1565., -5241. }, 0.4724826607880908 }, + { 0, { -3424., 9654., 4992., 7807., 583., 1356. }, 0.4869141744280314 }, + { 0, { -449., -1794., 3826., -7250., -2319., -7298. }, 0.5001714317315645 }, + { 0, { 15872., 9071., 15995., 31749., 10331., 14516. }, 0.5137491938947873 }, + { 0, { 40907450., -28046763., 26106307., 37325417., 10171143., 16690754. }, 0.5296557456960209 }, + { 1, { -42177., -28947., 38775., -19498., 29548., -4665. }, }, + { 2, { 3107., 30472., -6348., 11400., 8980., 1831. }, }, + { 0, { -7558., 61741., -13579., -15470., 9629., -26943. }, 0.5428748902518665 }, + { 0, { -5153., -16254., 1129., 1453., -5621., 9705. }, 0.5545763246422408 }, + { 1, { 4786., -5955., 927., 2343., -4914., 1978. }, }, + { 0, { -472., -1295., 65., -1013., 81., 865. }, 0.5737334589484931 }, + { 0, { 1071., -818., -1860., -1756., -2076., -217. }, 0.6240874769868805 }, + { 0, { 35210., 26306., -24283., 31193., -11240., 11870. }, 0.6381677442023816 }, + { 1, { -1433., -467., -610., 819., -193., 1466. }, }, + { 2, { -2302., -1111., 916., -1272., 326., -143. }, }, + { 0, { 713., -751., -578., -1512., 156., -696. }, 0.6775366989691358 }, + { 1, { 60., 611., -229., 120., -170., -479. }, }, + { 0, { 566., 1322., -824., 882., 271., -163. }, 0.7307010456855323 }, + { 1, { 315., -273., 931., -867., 656., -752. }, }, + { 0, { 2637., -5581., -3871., -2275., -3921., 187. }, 0.8349274544218315 }, + { 0, { -6012., 8879., 923., -5393., 1314., -3852. }, 0.8466308769723183 }, + { 1, { -2430., -2929., -1564., 2843., 65., 3053. }, }, + { 2, { -373., -2949., -1724., 190., -949., 999. }, }, + { 0, { 3787., 756., 723., -3294., -966., -1395. }, 0.8803279870880313 }, + { 0, { 5446., -1146., -595., -4608., -1861., -1044. }, 0.9048452745134871 }, + { 0, { 5058., -2711., -831., -3667., -1554., -139. }, 0.9284980837327494 }, + { 0, { 1760., -6922., -4114., -3639., -1717., 694. }, 0.9630502889662660 }, + { 1, { 963., 1525., 703., -3798., -966., -2055. }, }, + { 0, { -854., -5315., -3964., -3549., -797., 142. }, 0.9850575449612223 }, + { 1, { 453., 513., -533., -1316., -1407., -442. }, }, + { 0, { -1452., 2161., -2167., -2392., 843., -1017. }, 1.0358203937225836 }, + { 0, { 717822., -1016247., 926007., 647088., 383619., 291083. }, 1.0592833248900753 }, + { 1, { -29524., -7934., 4354., -18649., -4618., -10392. }, }, + { 2, { -5165., 7903., -5462., -3951., -3606., -275. }, }, + { 0, { -13391., 43036., -26981., -8012., -15174., 6191. }, 1.0698620958167548 }, + { 1, { -19633., -2810., 1597., -10192., -4219., -4352. }, }, + { 0, { 273., 2230., -349., -375., 851., 287. }, 1.0830212781676249 }, + { 0, { 10855., -624., 671., 9748., 207., 3846. }, 1.1622398168028405 }, + { 1, { -33., 92., -124., -554., -92., -612. }, }, + { 0, { 448., -1008., 1081., 183., 623., -187. }, 1.2654499680761597 }, + { 0, { -207., 526., 176., -733., 246., -400. }, 1.3757220045803040 }, + { 0, { 638., 340., -422., 36., 44., 18. }, 1.4777197679290477 }, + { 0, { 12128., -41950., 38517., 10211., 16357., 5050. }, 1.5888963534561586 }, + { 1, { -267., 195., -296., 12., -482., 121. }, }, + { 2, { -41., 86., -13., 298., -132., 311. }, }, + { 0, { 667., -280., 347., 903., -21., 475. }, 1.6918774676128379 }, + { 0, { 30., -1843., 2162., 314., 1153., 512. }, 2.1185453910327063 }, + { 0, { 4845., 477., -393., 4358., -362., 2072. }, 3.3406128168607023 }, + { 0, { -5939., -29727., 27855., -4133., 12163., -1725. }, 6.2830758108873654 }, + { 1, { 5., -58., 6., 45., 39., 54. }, }, + { 0, { -223., 149., 91., 102., 231., 420. }, 8.4710959288534031 }, + { 0, { -17640., -47., -831., -15721., 782., -7065. }, 10.2132856585962150 }, + { 1, { 165., 60., -38., 154., 112., 136. }, }, + { 2, { 20., 46., 112., -30., 119., 10. }, }, + { /* end pluto */ -1, }, +}; + + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: chap95_data.c,v $ $Date: 1997/05/19 18:21:12 $ $Revision: 1.1 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/circum.c b/Common/Libraries/XEphemAstroLib/src/circum.c new file mode 100644 index 000000000..31dbc4bbb --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/circum.c @@ -0,0 +1,861 @@ +/* given a Now and an Obj with the object definition portion filled in, + * fill in the sky position (s_*) portions. + * calculation of positional coordinates reworked by + * Michael Sternberg <sternberg@physik.tu-chemnitz.de> + * 3/11/98: deflect was using op->s_hlong before being set in cir_pos(). + * 4/19/98: just edit a comment + */ + +#include <stdio.h> +#include <math.h> +#include <stdlib.h> + +#include "astro.h" +#include "preferences.h" + + +static int obj_planet (Now *np, Obj *op); +static int obj_binary (Now *np, Obj *op); +static int obj_2binary (Now *np, Obj *op); +static int obj_fixed (Now *np, Obj *op); +static int obj_elliptical (Now *np, Obj *op); +static int obj_hyperbolic (Now *np, Obj *op); +static int obj_parabolic (Now *np, Obj *op); +static int sun_cir (Now *np, Obj *op); +static int moon_cir (Now *np, Obj *op); +static double solveKepler (double M, double e); +static void binaryStarOrbit (double t, double T, double e, double o, double O, + double i, double a, double P, double *thetap, double *rhop); +static void cir_sky (Now *np, double lpd, double psi, double rp, double *rho, + double lam, double bet, double lsn, double rsn, Obj *op); +static void cir_pos (Now *np, double bet, double lam, double *rho, Obj *op); +static void elongation (double lam, double bet, double lsn, double *el); +static void deflect (double mjd1, double lpd, double psi, double rsn, + double lsn, double rho, double *ra, double *dec); +static double h_albsize (double H); + +/* given a Now and an Obj, fill in the approprirate s_* fields within Obj. + * return 0 if all ok, else -1. + */ +int +obj_cir (Now *np, Obj *op) +{ + op->o_flags &= ~NOCIRCUM; + switch (op->o_type) { + case BINARYSTAR: return (obj_binary (np, op)); + case FIXED: return (obj_fixed (np, op)); + case ELLIPTICAL: return (obj_elliptical (np, op)); + case HYPERBOLIC: return (obj_hyperbolic (np, op)); + case PARABOLIC: return (obj_parabolic (np, op)); + case EARTHSAT: return (obj_earthsat (np, op)); + case PLANET: return (obj_planet (np, op)); + default: + printf ("obj_cir() called with type %d %s\n", op->o_type, op->o_name); + abort(); + return (-1); /* just for lint */ + } +} + +static int +obj_planet (Now *np, Obj *op) +{ + double lsn, rsn; /* true geoc lng of sun; dist from sn to earth*/ + double lpd, psi; /* heliocentric ecliptic long and lat */ + double rp; /* dist from sun */ + double rho; /* dist from earth */ + double lam, bet; /* geocentric ecliptic long and lat */ + double dia, mag; /* angular diameter at 1 AU and magnitude */ + PLCode p; + + /* validate code and check for a few special cases */ + p = op->pl_code; + if (p == SUN) + return (sun_cir (np, op)); + if (p == MOON) + return (moon_cir (np, op)); + if (op->pl_moon != X_PLANET) + return (plmoon_cir (np, op)); + if (p < 0 || p > MOON) { + printf ("unknown planet code: %d\n", p); + abort(); + } + + /* planet itself */ + + /* find solar ecliptical longitude and distance to sun from earth */ + sunpos (mjed, &lsn, &rsn, 0); + + /* find helio long/lat; sun/planet and earth/planet dist; ecliptic + * long/lat; diameter and mag. + */ + plans(mjed, p, &lpd, &psi, &rp, &rho, &lam, &bet, &dia, &mag); + + /* fill in all of op->s_* stuff except s_size and s_mag */ + cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op); + + /* set magnitude and angular size */ + set_smag (op, mag); + op->s_size = (float)(dia/rho); + + return (0); +} + +static int +obj_binary (Now *np, Obj *op) +{ + /* always compute circumstances of primary */ + if (obj_fixed (np, op) < 0) + return (0); + + /* compute secondary only if requested, and always reset request flag */ + if (!op->b_2compute) + return (0); + op->b_2compute = 0; + return (obj_2binary (np, op)); +} + +/* compute position of secondary component of a BINARYSTAR */ +static int +obj_2binary (Now *np, Obj *op) +{ + if (op->b_nbp > 0) { + /* we just have discrete pa/sep, project each from primary */ + int i; + for (i = 0; i < op->b_nbp; i++) { + BinPos *bp = &op->b_bp[i]; + bp->bp_dec = op->s_dec + bp->bp_sep*cos(bp->bp_pa); + bp->bp_ra = op->s_ra + bp->bp_sep*sin(bp->bp_pa)/cos(op->s_dec); + } + } else { + BinOrbit *bp = &op->b_bo; + double t, theta, rho; + + mjd_year (mjd, &t); + binaryStarOrbit (t, bp->bo_T, bp->bo_e, bp->bo_o, bp->bo_O, + bp->bo_i, bp->bo_a, bp->bo_P, &theta, &rho); + bp->bo_pa = (float)theta; + bp->bo_sep = (float)rho; + rho = degrad(rho/3600.); /* arc secs to rads */ + bp->bo_dec = op->s_dec + rho*cos(theta); + bp->bo_ra = op->s_ra + rho*sin(theta)/cos(op->s_dec); + } + + return (0); +} + +/* from W. M. Smart */ +static void +binaryStarOrbit ( +double t, /* desired ephemeris epoch, year */ +double T, /* epoch of periastron, year */ +double e, /* eccentricity */ +double o, /* argument of periastron, degrees */ +double O, /* ascending node, degrees */ +double i, /* inclination, degrees */ +double a, /* semi major axis, arcsecs */ +double P, /* period, years */ +double *thetap, /* position angle, rads E of N */ +double *rhop) /* separation, arcsecs */ +{ + double M, E, cosE, nu, cosnu, r, rho, theta; + + /* find mean anomaly, insure 0..2*PI */ + M = 2*PI/P*(t-T); + range (&M, 2*PI); + + /* solve for eccentric anomaly */ + E = solveKepler (M, e); + cosE = cos(E); + + /* find true anomaly and separation */ + cosnu = (cosE - e)/(1.0 - e*cosE); + r = a*(1.0 - e*e)/(1.0 + e*cosnu); + nu = acos(cosnu); + if (E > PI) + nu = -nu; + + /* project onto sky */ + theta = atan(tan(nu+degrad(o))*cos(degrad(i))) + degrad(O); + rho = r*cos(nu+degrad(o))/cos(theta-degrad(O)); + if (rho < 0) { + theta += PI; + rho = -rho; + } + range (&theta, 2*PI); + + *thetap = theta; + *rhop = rho; +} + +/* solve kepler equation using Newton-Raphson search. + * Charles and Tatum have shown it always converges starting with PI. + */ +static double +solveKepler (double M, double e) +{ + double E, Eprime = PI; + + do { + double cosE = cos(Eprime); + E = Eprime; + Eprime = (M - e*(E*cosE - sin(E)))/(1.0 - e*cosE); + } while (fabs(E-Eprime) > 1e-7); + + return (Eprime); +} + +static int +obj_fixed (Now *np, Obj *op) +{ + double lsn, rsn; /* true geoc lng of sun, dist from sn to earth*/ + double lam, bet; /* geocentric ecliptic long and lat */ + double ha; /* local hour angle */ + double el; /* elongation */ + double alt, az; /* current alt, az */ + double ra, dec; /* ra and dec at equinox of date */ + double rpm, dpm; /* astrometric ra and dec with PM to now */ + double lst; + + /* on the assumption that the user will stick with their chosen display + * epoch for a while, we move the defining values to match and avoid + * precession for every call until it is changed again. + * N.B. only compare and store jd's to lowest precission (f_epoch). + * N.B. maintaining J2k ref (which is arbitrary) helps avoid accum err + */ + if (epoch != EOD && (float)epoch != (float)op->f_epoch) { + double pr = op->f_RA, pd = op->f_dec, fe = (float)epoch; + /* first bring back to 2k */ + precess (op->f_epoch, J2000, &pr, &pd); + pr += op->f_pmRA*(J2000-op->f_epoch); + pd += op->f_pmdec*(J2000-op->f_epoch); + /* then to epoch */ + pr += op->f_pmRA*(fe-J2000); + pd += op->f_pmdec*(fe-J2000); + precess (J2000, fe, &pr, &pd); + op->f_RA = (float)pr; + op->f_dec = (float)pd; + op->f_epoch = (float)fe; + } + + /* apply proper motion .. assume pm epoch reference equals equinox */ + rpm = op->f_RA + op->f_pmRA*(mjd-op->f_epoch); + dpm = op->f_dec + op->f_pmdec*(mjd-op->f_epoch); + + /* set ra/dec to astrometric @ equinox of date */ + ra = rpm; + dec = dpm; + precess (op->f_epoch, mjed, &ra, &dec); + + /* convert equatoreal ra/dec to mean geocentric ecliptic lat/long */ + eq_ecl (mjed, ra, dec, &bet, &lam); + + /* find solar ecliptical long.(mean equinox) and distance from earth */ + sunpos (mjed, &lsn, &rsn, NULL); + + /* allow for relativistic light bending near the sun */ + deflect (mjed, lam, bet, lsn, rsn, 1e10, &ra, &dec); + + /* TODO: correction for annual parallax would go here */ + + /* correct EOD equatoreal for nutation/aberation to form apparent + * geocentric + */ + nut_eq(mjed, &ra, &dec); + ab_eq(mjed, lsn, &ra, &dec); + op->s_gaera = (float)ra; + op->s_gaedec = (float)dec; + + /* set s_ra/dec -- apparent if EOD else astrometric */ + if (epoch == EOD) { + op->s_ra = (float)ra; + op->s_dec = (float)dec; + } else { + /* annual parallax at time mjd is to be added here, too, but + * technically in the frame of equinox (usually different from mjd) + */ + op->s_ra = rpm; + op->s_dec = dpm; + } + + /* compute elongation from ecliptic long/lat and sun geocentric long */ + elongation (lam, bet, lsn, &el); + el = raddeg(el); + op->s_elong = (float)el; + + /* these are really the same fields ... + op->s_mag = op->f_mag; + op->s_size = op->f_size; + */ + + /* alt, az: correct for refraction; use eod ra/dec. */ + now_lst (np, &lst); + ha = hrrad(lst) - ra; + hadec_aa (lat, ha, dec, &alt, &az); + refract (pressure, temp, alt, &alt); + op->s_alt = alt; + op->s_az = az; + + return (0); +} + +/* compute sky circumstances of an object in heliocentric elliptic orbit at *np. + */ +static int +obj_elliptical (Now *np, Obj *op) +{ + double lsn, rsn; /* true geoc lng of sun; dist from sn to earth*/ + double dt; /* light travel time to object */ + double lg; /* helio long of earth */ + double nu; /* true anomaly */ + double rp=0; /* distance from the sun */ + double lo, slo, clo; /* angle from ascending node */ + double inc; /* inclination */ + double psi=0; /* heliocentric latitude */ + double spsi=0, cpsi=0; /* trig of heliocentric latitude */ + double lpd; /* heliocentric longitude */ + double rho=0; /* distance from the Earth */ + double om; /* arg of perihelion */ + double Om; /* long of ascending node. */ + double lam; /* geocentric ecliptic longitude */ + double bet; /* geocentric ecliptic latitude */ + double ll=0, sll, cll; /* helio angle between object and earth */ + double mag; /* magnitude */ + double e_n; /* mean daily motion */ + double tp; /* time from perihelion (days) */ + double rpd=0; + double y; + int pass; + + /* find location of earth from sun now */ + sunpos (mjed, &lsn, &rsn, 0); + lg = lsn + PI; + + /* mean daily motion is derived fro mean distance */ + e_n = 0.9856076686/pow((double)op->e_a, 1.5); + + /* correct for light time by computing position at time mjd, then + * again at mjd-dt, where + * dt = time it takes light to travel earth-object distance. + */ + dt = 0; + for (pass = 0; pass < 2; pass++) { + + reduce_elements (op->e_epoch, mjd-dt, degrad(op->e_inc), + degrad (op->e_om), degrad (op->e_Om), + &inc, &om, &Om); + + tp = mjed - dt - (op->e_cepoch - op->e_M/e_n); + if (vrc (&nu, &rp, tp, op->e_e, op->e_a*(1-op->e_e)) < 0) + op->o_flags |= NOCIRCUM; + nu = degrad(nu); + lo = nu + om; + slo = sin(lo); + clo = cos(lo); + spsi = slo*sin(inc); + y = slo*cos(inc); + psi = asin(spsi); + lpd = atan(y/clo)+Om; + if (clo<0) lpd += PI; + range (&lpd, 2*PI); + cpsi = cos(psi); + rpd = rp*cpsi; + ll = lpd-lg; + rho = sqrt(rsn*rsn+rp*rp-2*rsn*rp*cpsi*cos(ll)); + + dt = rho*LTAU/3600.0/24.0; /* light travel time, in days / AU */ + } + + /* compute sin and cos of ll */ + sll = sin(ll); + cll = cos(ll); + + /* find geocentric ecliptic longitude and latitude */ + if (rpd < rsn) + lam = atan(-1*rpd*sll/(rsn-rpd*cll))+lg+PI; + else + lam = atan(rsn*sll/(rpd-rsn*cll))+lpd; + range (&lam, 2*PI); + bet = atan(rpd*spsi*sin(lam-lpd)/(cpsi*rsn*sll)); + + /* fill in all of op->s_* stuff except s_size and s_mag */ + cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op); + + /* compute magnitude and size */ + if (op->e_mag.whichm == MAG_HG) { + /* the H and G parameters from the Astro. Almanac. + */ + hg_mag (op->e_mag.m1, op->e_mag.m2, rp, rho, rsn, &mag); + if (op->e_size) + op->s_size = (float)(op->e_size / rho); + else + op->s_size = (float)(h_albsize (op->e_mag.m1)/rho); + } else { + /* the g/k model of comets */ + gk_mag (op->e_mag.m1, op->e_mag.m2, rp, rho, &mag); + op->s_size = (float)(op->e_size / rho); + } + set_smag (op, mag); + + return (0); +} + +/* compute sky circumstances of an object in heliocentric hyperbolic orbit. + */ +static int +obj_hyperbolic (Now *np, Obj *op) +{ + double lsn, rsn; /* true geoc lng of sun; dist from sn to earth*/ + double dt; /* light travel time to object */ + double lg; /* helio long of earth */ + double nu; /* true anomaly and eccentric anomaly */ + double rp=0; /* distance from the sun */ + double lo, slo, clo; /* angle from ascending node */ + double inc; /* inclination */ + double psi=0; /* heliocentric latitude */ + double spsi=0, cpsi=0; /* trig of heliocentric latitude */ + double lpd; /* heliocentric longitude */ + double rho=0; /* distance from the Earth */ + double om; /* arg of perihelion */ + double Om; /* long of ascending node. */ + double lam; /* geocentric ecliptic longitude */ + double bet; /* geocentric ecliptic latitude */ + double e; /* fast eccentricity */ + double ll=0, sll, cll; /* helio angle between object and earth */ + double mag; /* magnitude */ + double a; /* mean distance */ + double tp; /* time from perihelion (days) */ + double rpd=0; + double y; + int pass; + + /* find solar ecliptical longitude and distance to sun from earth */ + sunpos (mjed, &lsn, &rsn, 0); + + lg = lsn + PI; + e = op->h_e; + a = op->h_qp/(e - 1.0); + + /* correct for light time by computing position at time mjd, then + * again at mjd-dt, where + * dt = time it takes light to travel earth-object distance. + */ + dt = 0; + for (pass = 0; pass < 2; pass++) { + + reduce_elements (op->h_epoch, mjd-dt, degrad(op->h_inc), + degrad (op->h_om), degrad (op->h_Om), + &inc, &om, &Om); + + tp = mjed - dt - op->h_ep; + if (vrc (&nu, &rp, tp, op->h_e, op->h_qp) < 0) + op->o_flags |= NOCIRCUM; + nu = degrad(nu); + lo = nu + om; + slo = sin(lo); + clo = cos(lo); + spsi = slo*sin(inc); + y = slo*cos(inc); + psi = asin(spsi); + lpd = atan(y/clo)+Om; + if (clo<0) lpd += PI; + range (&lpd, 2*PI); + cpsi = cos(psi); + rpd = rp*cpsi; + ll = lpd-lg; + rho = sqrt(rsn*rsn+rp*rp-2*rsn*rp*cpsi*cos(ll)); + + dt = rho*5.775518e-3; /* light travel time, in days */ + } + + /* compute sin and cos of ll */ + sll = sin(ll); + cll = cos(ll); + + /* find geocentric ecliptic longitude and latitude */ + if (rpd < rsn) + lam = atan(-1*rpd*sll/(rsn-rpd*cll))+lg+PI; + else + lam = atan(rsn*sll/(rpd-rsn*cll))+lpd; + range (&lam, 2*PI); + bet = atan(rpd*spsi*sin(lam-lpd)/(cpsi*rsn*sll)); + + /* fill in all of op->s_* stuff except s_size and s_mag */ + cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op); + + /* compute magnitude and size */ + gk_mag (op->h_g, op->h_k, rp, rho, &mag); + set_smag (op, mag); + op->s_size = (float)(op->h_size / rho); + + return (0); +} + +/* compute sky circumstances of an object in heliocentric hyperbolic orbit. + */ +static int +obj_parabolic (Now *np, Obj *op) +{ + double lsn, rsn; /* true geoc lng of sun; dist from sn to earth*/ + double lam; /* geocentric ecliptic longitude */ + double bet; /* geocentric ecliptic latitude */ + double mag; /* magnitude */ + double inc, om, Om; + double lpd, psi, rp, rho; + double dt; + int pass; + + /* find solar ecliptical longitude and distance to sun from earth */ + sunpos (mjed, &lsn, &rsn, 0); + + /* two passes to correct lam and bet for light travel time. */ + dt = 0.0; + for (pass = 0; pass < 2; pass++) { + reduce_elements (op->p_epoch, mjd-dt, degrad(op->p_inc), + degrad(op->p_om), degrad(op->p_Om), &inc, &om, &Om); + comet (mjed-dt, op->p_ep, inc, om, op->p_qp, Om, + &lpd, &psi, &rp, &rho, &lam, &bet); + dt = rho*LTAU/3600.0/24.0; /* light travel time, in days / AU */ + } + + /* fill in all of op->s_* stuff except s_size and s_mag */ + cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op); + + /* compute magnitude and size */ + gk_mag (op->p_g, op->p_k, rp, rho, &mag); + set_smag (op, mag); + op->s_size = (float)(op->p_size / rho); + + return (0); +} + +/* find sun's circumstances now. + */ +static int +sun_cir (Now *np, Obj *op) +{ + double lsn, rsn; /* true geoc lng of sun; dist from sn to earth*/ + double bsn; /* true latitude beta of sun */ + double dhlong; + + sunpos (mjed, &lsn, &rsn, &bsn);/* sun's true coordinates; mean ecl. */ + + op->s_sdist = 0.0; + op->s_elong = 0.0; + op->s_phase = 100.0; + set_smag (op, -26.8); /* TODO */ + dhlong = lsn-PI; /* geo- to helio- centric */ + range (&dhlong, 2*PI); + op->s_hlong = (float)dhlong; + op->s_hlat = (float)(-bsn); + + /* fill sun's ra/dec, alt/az in op */ + cir_pos (np, bsn, lsn, &rsn, op); + op->s_edist = (float)rsn; + op->s_size = (float)(raddeg(4.65242e-3/rsn)*3600*2); + + return (0); +} + +/* find moon's circumstances now. + */ +static int +moon_cir (Now *np, Obj *op) +{ + double lsn, rsn; /* true geoc lng of sun; dist from sn to earth*/ + double lam; /* geocentric ecliptic longitude */ + double bet; /* geocentric ecliptic latitude */ + double edistau; /* earth-moon dist, in au */ + double el; /* elongation, rads east */ + double ms; /* sun's mean anomaly */ + double md; /* moon's mean anomaly */ + double i; + + moon (mjed, &lam, &bet, &edistau, &ms, &md); /* mean ecliptic & EOD*/ + sunpos (mjed, &lsn, &rsn, NULL); /* mean ecliptic & EOD*/ + + op->s_hlong = (float)lam; /* save geo in helio fields */ + op->s_hlat = (float)bet; + + /* find angular separation from sun */ + elongation (lam, bet, lsn, &el); + op->s_elong = (float)raddeg(el); /* want degrees */ + + /* solve triangle of earth, sun, and elongation for moon-sun dist */ + op->s_sdist = (float) sqrt (edistau*edistau + rsn*rsn + - 2.0*edistau*rsn*cos(el)); + + /* TODO: improve mag; this is based on a flat moon model. */ + i = -12.7 + 2.5*(log10(PI) - log10(PI/2*(1+1.e-6-cos(el)))) + + 5*log10(edistau/.0025) /* dist */; + set_smag (op, i); + + /* find phase -- allow for projection effects */ + i = 0.1468*sin(el)*(1 - 0.0549*sin(md))/(1 - 0.0167*sin(ms)); + op->s_phase = (float)((1+cos(PI-el-degrad(i)))/2*100); + + /* fill moon's ra/dec, alt/az in op and update for topo dist */ + cir_pos (np, bet, lam, &edistau, op); + + op->s_edist = (float)edistau; + op->s_size = (float)(3600*2.0*raddeg(asin(MRAD/MAU/edistau))); + /* moon angular dia, seconds */ + + return (0); +} + +/* fill in all of op->s_* stuff except s_size and s_mag. + * this is used for sol system objects (except sun and moon); never FIXED. + */ +static void +cir_sky ( +Now *np, +double lpd, /* heliocentric ecliptic longitude */ +double psi, /* heliocentric ecliptic lat */ +double rp, /* dist from sun */ +double *rho, /* dist from earth: in as geo, back as geo or topo */ +double lam, /* true geocentric ecliptic long */ +double bet, /* true geocentric ecliptic lat */ +double lsn, /* true geoc lng of sun */ +double rsn, /* dist from sn to earth*/ +Obj *op) +{ + double el; /* elongation */ + double f; /* fractional phase from earth */ + + /* compute elongation and phase */ + elongation (lam, bet, lsn, &el); + el = raddeg(el); + op->s_elong = (float)el; + f = 0.25 * ((rp+ *rho)*(rp+ *rho) - rsn*rsn)/(rp* *rho); + op->s_phase = (float)(f*100.0); /* percent */ + + /* set heliocentric long/lat; mean ecliptic and EOD */ + op->s_hlong = (float)lpd; + op->s_hlat = (float)psi; + + /* fill solar sys body's ra/dec, alt/az in op */ + cir_pos (np, bet, lam, rho, op); /* updates rho */ + + /* set earth/planet and sun/planet distance */ + op->s_edist = (float)(*rho); + op->s_sdist = (float)rp; +} + +/* fill equatoreal and horizontal op-> fields; stern + * + * input: lam/bet/rho geocentric mean ecliptic and equinox of day + * + * algorithm at EOD: + * ecl_eq --> ra/dec geocentric mean equatoreal EOD (via mean obliq) + * deflect --> ra/dec relativistic deflection + * nut_eq --> ra/dec geocentric true equatoreal EOD + * ab_eq --> ra/dec geocentric apparent equatoreal EOD + * if (PREF_GEO) --> output + * ta_par --> ra/dec topocentric apparent equatoreal EOD + * if (!PREF_GEO) --> output + * hadec_aa --> alt/az topocentric horizontal + * refract --> alt/az observed --> output + * + * algorithm at fixed equinox: + * ecl_eq --> ra/dec geocentric mean equatoreal EOD (via mean obliq) + * deflect --> ra/dec relativistic deflection [for alt/az only] + * nut_eq --> ra/dec geocentric true equatoreal EOD [for aa only] + * ab_eq --> ra/dec geocentric apparent equatoreal EOD [for aa only] + * ta_par --> ra/dec topocentric apparent equatoreal EOD + * precess --> ra/dec topocentric equatoreal fixed equinox [eq only] + * --> output + * hadec_aa --> alt/az topocentric horizontal + * refract --> alt/az observed --> output + */ +static void +cir_pos ( +Now *np, +double bet, /* geo lat (mean ecliptic of date) */ +double lam, /* geo long (mean ecliptic of date) */ +double *rho, /* in: geocentric dist in AU; out: geo- or topocentic dist */ +Obj *op) /* object to set s_ra/dec as per equinox */ +{ + double ra, dec; /* apparent ra/dec, corrected for nut/ab */ + double tra, tdec; /* astrometric ra/dec, no nut/ab */ + double lsn, rsn; /* solar geocentric (mean ecliptic of date) */ + double ha_in, ha_out; /* local hour angle before/after parallax */ + double dec_out; /* declination after parallax */ + double dra, ddec; /* parallax correction */ + double alt, az; /* current alt, az */ + double lst; /* local sidereal time */ + double rho_topo; /* topocentric distance in earth radii */ + + /* convert to equatoreal [mean equator, with mean obliquity] */ + ecl_eq (mjed, bet, lam, &ra, &dec); + tra = ra; /* keep mean coordinates */ + tdec = dec; + + /* get sun position */ + sunpos(mjed, &lsn, &rsn, NULL); + + /* allow for relativistic light bending near the sun. + * (avoid calling deflect() for the sun itself). + */ + if (!is_planet(op,SUN) && !is_planet(op,MOON)) + deflect (mjed, op->s_hlong, op->s_hlat, lsn, rsn, *rho, &ra, &dec); + + /* correct ra/dec to form geocentric apparent */ + nut_eq (mjed, &ra, &dec); + if (!is_planet(op,MOON)) + ab_eq (mjed, lsn, &ra, &dec); + op->s_gaera = (float)ra; + op->s_gaedec = (float)dec; + + /* find parallax correction for equatoreal coords */ + now_lst (np, &lst); + ha_in = hrrad(lst) - ra; + rho_topo = *rho * MAU/ERAD; /* convert to earth radii */ + ta_par (ha_in, dec, lat, elev, &rho_topo, &ha_out, &dec_out); + + /* transform into alt/az and apply refraction */ + hadec_aa (lat, ha_out, dec_out, &alt, &az); + refract (pressure, temp, alt, &alt); + op->s_alt = alt; + op->s_az = az; + + /* Get parallax differences and apply to apparent or astrometric place + * as needed. For the astrometric place, rotating the CORRECTIONS + * back from the nutated equator to the mean equator will be + * neglected. This is an effect of about 0.1" at moon distance. + * We currently don't have an inverse nutation rotation. + */ + if (pref_get(PREF_EQUATORIAL) == PREF_GEO) { + /* no topo corrections to eq. coords */ + dra = ddec = 0.0; + } else { + dra = ha_in - ha_out; /* ra sign is opposite of ha */ + ddec = dec_out - dec; + *rho = rho_topo * ERAD/MAU; /* return topocentric distance in AU */ + } + + /* fill in ra/dec fields */ + if (epoch == EOD) { /* apparent geo/topocentric */ + ra = ra + dra; + dec = dec + ddec; + } else { /* astrometric geo/topocent */ + ra = tra + dra; + dec = tdec + ddec; + precess (mjed, epoch, &ra, &dec); + } + range(&ra, 2*PI); + op->s_ra = (float)ra; + op->s_dec = (float)dec; +} + +/* given geocentric ecliptic longitude and latitude, lam and bet, of some object + * and the longitude of the sun, lsn, find the elongation, el. this is the + * actual angular separation of the object from the sun, not just the difference + * in the longitude. the sign, however, IS set simply as a test on longitude + * such that el will be >0 for an evening object <0 for a morning object. + * to understand the test for el sign, draw a graph with lam going from 0-2*PI + * down the vertical axis, lsn going from 0-2*PI across the hor axis. then + * define the diagonal regions bounded by the lines lam=lsn+PI, lam=lsn and + * lam=lsn-PI. the "morning" regions are any values to the lower left of the + * first line and bounded within the second pair of lines. + * all angles in radians. + */ +static void +elongation (double lam, double bet, double lsn, double *el) +{ + *el = acos(cos(bet)*cos(lam-lsn)); + if (lam>lsn+PI || (lam>lsn-PI && lam<lsn)) *el = - *el; +} + +/* apply relativistic light bending correction to ra/dec; stern + * + * The algorithm is from: + * Mean and apparent place computations in the new IAU + * system. III - Apparent, topocentric, and astrometric + * places of planets and stars + * KAPLAN, G. H.; HUGHES, J. A.; SEIDELMANN, P. K.; + * SMITH, C. A.; YALLOP, B. D. + * Astronomical Journal (ISSN 0004-6256), vol. 97, April 1989, p. 1197-1210. + * + * This article is a very good collection of formulea for geocentric and + * topocentric place calculation in general. The apparent and + * astrometric place calculation in this file currently does not follow + * the strict algorithm from this paper and hence is not fully correct. + * The entire calculation is currently based on the rotating EOD frame and + * not the "inertial" J2000 frame. + */ +static void +deflect ( +double mjd1, /* equinox */ +double lpd, double psi, /* heliocentric ecliptical long / lat */ +double rsn, double lsn, /* distance and longitude of sun */ +double rho, /* geocentric distance */ +double *ra, double *dec)/* geocentric equatoreal */ +{ + double hra, hdec; /* object heliocentric equatoreal */ + double el; /* HELIOCENTRIC elongation object--earth */ + double g1, g2; /* relativistic weights */ + double u[3]; /* object geocentric cartesian */ + double q[3]; /* object heliocentric cartesian unit vect */ + double e[3]; /* earth heliocentric cartesian unit vect */ + double qe, uq, eu; /* scalar products */ + int i; /* counter */ + +#define G 1.32712438e20 /* heliocentric grav const; in m^3*s^-2 */ +#define c 299792458.0 /* speed of light in m/s */ + + elongation(lpd, psi, lsn-PI, &el); + el = fabs(el); + /* only continue if object is within about 10 deg around the sun, + * not obscured by the sun's disc (radius 0.25 deg) and farther away + * than the sun. + * + * precise geocentric deflection is: g1 * tan(el/2) + * radially outwards from sun; the vector munching below + * just applys this component-wise + * Note: el = HELIOCENTRIC elongation. + * g1 is always about 0.004 arc seconds + * g2 varies from 0 (highest contribution) to 2 + */ + if (el<degrad(170) || el>degrad(179.75) || rho<rsn) return; + + /* get cartesian vectors */ + sphcart(*ra, *dec, rho, u, u+1, u+2); + + ecl_eq(mjd1, psi, lpd, &hra, &hdec); + sphcart(hra, hdec, 1.0, q, q+1, q+2); + + ecl_eq(mjd1, 0.0, lsn-PI, &hra, &hdec); + sphcart(hra, hdec, 1.0, e, e+1, e+2); + + /* evaluate scalar products */ + qe = uq = eu = 0.0; + for(i=0; i<=2; ++i) { + qe += q[i]*e[i]; + uq += u[i]*q[i]; + eu += e[i]*u[i]; + } + + g1 = 2*G/(c*c*MAU)/rsn; + g2 = 1 + qe; + + /* now deflect geocentric vector */ + g1 /= g2; + for(i=0; i<=2; ++i) + u[i] += g1*(uq*e[i] - eu*q[i]); + + /* back to spherical */ + cartsph(u[0], u[1], u[2], ra, dec, &rho); /* rho thrown away */ +} + +/* estimate size in arc seconds @ 1AU from absolute magnitude, H, and assuming + * an albedo of 0.1. With this assumption an object with diameter of 1500m + * has an absolute mag of 18. + */ +static double +h_albsize (double H) +{ + return (3600*raddeg(.707*1500*pow(2.51,(18-H)/2)/MAU)); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: circum.c,v $ $Date: 2015/04/09 00:12:30 $ $Revision: 1.19 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/comet.c b/Common/Libraries/XEphemAstroLib/src/comet.c new file mode 100644 index 000000000..e03dc834e --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/comet.c @@ -0,0 +1,83 @@ +#include <math.h> + +#include "astro.h" + +/* given a modified Julian date, mj, and a set of heliocentric parabolic + * orbital elements referred to the epoch of date (mj): + * ep: epoch of perihelion, + * inc: inclination, + * ap: argument of perihelion (equals the longitude of perihelion minus the + * longitude of ascending node) + * qp: perihelion distance, + * om: longitude of ascending node; + * find: + * lpd: heliocentric longitude, + * psi: heliocentric latitude, + * rp: distance from the sun to the planet, + * rho: distance from the Earth to the planet, + * lam: geocentric ecliptic longitude, + * bet: geocentric ecliptic latitude, + * none are corrected for light time, ie, they are the true values for + * the given instant. + * + * all angles are in radians, all distances in AU. + * mutual perturbation corrections with other solar system objects are not + * applied. corrections for nutation and abberation must be made by the caller. + * The RA and DEC calculated from the fully-corrected ecliptic coordinates are + * then the apparent geocentric coordinates. Further corrections can be made, + * if required, for atmospheric refraction and geocentric parallax. + */ +void +comet (double mj, double ep, double inc, double ap, double qp, double om, +double *lpd, double *psi, double *rp, double *rho, double *lam, double *bet) +{ + double w, s, s2; + double l, sl, cl, y; + double spsi, cpsi; + double rd, lsn, rsn; + double lg, re, ll; + double cll, sll; + double nu; + +#define ERRLMT 0.0001 + w = ((mj-ep)*3.649116e-02)/(qp*sqrt(qp)); + s = w/3; + for (;;) { + double d; + s2 = s*s; + d = (s2+3)*s-w; + if (fabs(d) <= ERRLMT) + break; + s = ((2*s*s2)+w)/(3*(s2+1)); + } + + nu = 2*atan(s); + *rp = qp*(1+s2); + l = nu+ap; + sl = sin(l); + cl = cos(l); + spsi = sl*sin(inc); + *psi = asin(spsi); + y = sl*cos(inc); + *lpd = atan(y/cl)+om; + cpsi = cos(*psi); + if (cl<0) *lpd += PI; + range (lpd, 2*PI); + rd = *rp * cpsi; + sunpos (mj, &lsn, &rsn, 0); + lg = lsn+PI; + re = rsn; + ll = *lpd - lg; + cll = cos(ll); + sll = sin(ll); + *rho = sqrt((re * re)+(*rp * *rp)-(2*re*rd*cll)); + if (rd<re) + *lam = atan((-1*rd*sll)/(re-(rd*cll)))+lg+PI; + else + *lam = atan((re*sll)/(rd-(re*cll)))+*lpd; + range (lam, 2*PI); + *bet = atan((rd*spsi*sin(*lam-*lpd))/(cpsi*re*sll)); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: comet.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/constel.c b/Common/Libraries/XEphemAstroLib/src/constel.c new file mode 100644 index 000000000..efb5a2eb2 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/constel.c @@ -0,0 +1,1803 @@ +/* code to handle constellation boundaries and figures */ + +/* +Constellation boundaries: + + Primary reference: + + METHOD TO DETERMINE THE CONSTELLATION IN WHICH A POSITION IS LOCATED + + Recently, Mr. Barry N. Rappaport of New Mexico State University + transcribed the constellation boundaries as fixed by the IAU into + machine-readable form. These have been transcribed by Dr. Nancy G. + Roman to make it possible to determine by computer the constellation + in which a position is located. + + NSSDC catalog description: + 6042 AN Catalog of Constellation Boundary Data (Delporte, E. 1930, + Cambridge Univ. Press) + Comment(s): includes constellation identification software + (ADC 1987; see Roman, N.G. 1987, Publ. Astron. Soc. Pacific + 99, 695); 23 description, 118 software, 358 data records. + 3 files: 23x80, 118x80, 358x29 + + Further adapted for xephem by: + + Craig Counterman: conversion from original F77 to C + Elwood Downey: incorporation into xephem + Ernie Wright: additional speed and time improvments + +Constellation figures: + + Chris Marriott: original figures + Elwood Downey: incorporated into xephem +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <math.h> + +#include "astro.h" + +/* +====================================================================== +Ernie Wright 2 Mar 94 + +Find the constellation for a given position. + +First C version by Craig Counterman and Elwood Downey. Based on a +FORTRAN program by Nancy G. Roman (Roman, N.G. 1987, Publ. Astron. +Soc. Pacific 99, 695). IAU constellation boundaries transcribed into +machine-readable form by Barry N. Rappaport, New Mexico State Univ. +====================================================================== +*/ + +#define NBOUNDS 357 + +/* constellation ids */ +#define And 0 +#define Ant 1 +#define Aps 2 +#define Aql 3 +#define Aqr 4 +#define Ara 5 +#define Ari 6 +#define Aur 7 +#define Boo 8 +#define CMa 9 +#define CMi 10 +#define CVn 11 +#define Cae 12 +#define Cam 13 +#define Cap 14 +#define Car 15 +#define Cas 16 +#define Cen 17 +#define Cep 18 +#define Cet 19 +#define Cha 20 +#define Cir 21 +#define Cnc 22 +#define Col 23 +#define Com 24 +#define CrA 25 +#define CrB 26 +#define Crt 27 +#define Cru 28 +#define Crv 29 +#define Cyg 30 +#define Del 31 +#define Dor 32 +#define Dra 33 +#define Equ 34 +#define Eri 35 +#define For 36 +#define Gem 37 +#define Gru 38 +#define Her 39 +#define Hor 40 +#define Hya 41 +#define Hyi 42 +#define Ind 43 +#define LMi 44 +#define Lac 45 +#define Leo 46 +#define Lep 47 +#define Lib 48 +#define Lup 49 +#define Lyn 50 +#define Lyr 51 +#define Men 52 +#define Mic 53 +#define Mon 54 +#define Mus 55 +#define Nor 56 +#define Oct 57 +#define Oph 58 +#define Ori 59 +#define Pav 60 +#define Peg 61 +#define Per 62 +#define Phe 63 +#define Pic 64 +#define PsA 65 +#define Psc 66 +#define Pup 67 +#define Pyx 68 +#define Ret 69 +#define Scl 70 +#define Sco 71 +#define Sct 72 +#define Se1 73 +#define Sex 74 +#define Sge 75 +#define Sgr 76 +#define Tau 77 +#define Tel 78 +#define TrA 79 +#define Tri 80 +#define Tuc 81 +#define UMa 82 +#define UMi 83 +#define Vel 84 +#define Vir 85 +#define Vol 86 +#define Vul 87 +#define Se2 88 + +static char *cns_namemap[ NCNS ] = { + /* 0 */ "And: Andromeda", + /* 1 */ "Ant: Antlia", + /* 2 */ "Aps: Apus", + /* 3 */ "Aql: Aquila", + /* 4 */ "Aqr: Aquarius", + /* 5 */ "Ara: Ara", + /* 6 */ "Ari: Aries", + /* 7 */ "Aur: Auriga", + /* 8 */ "Boo: Bootes", + /* 9 */ "CMa: Canis Major", + /* 10 */ "CMi: Canis Minor", + /* 11 */ "CVn: Canes Venatici", + /* 12 */ "Cae: Caelum", + /* 13 */ "Cam: Camelopardalis", + /* 14 */ "Cap: Capricornus", + /* 15 */ "Car: Carina", + /* 16 */ "Cas: Cassiopeia", + /* 17 */ "Cen: Centaurus", + /* 18 */ "Cep: Cepheus", + /* 19 */ "Cet: Cetus", + /* 20 */ "Cha: Chamaeleon", + /* 21 */ "Cir: Circinus", + /* 22 */ "Cnc: Cancer", + /* 23 */ "Col: Columba", + /* 24 */ "Com: Coma Berenices", + /* 25 */ "CrA: Corona Australis", + /* 26 */ "CrB: Corona Borealis", + /* 27 */ "Crt: Crater", + /* 28 */ "Cru: Crux", + /* 29 */ "Crv: Corvus", + /* 30 */ "Cyg: Cygnus", + /* 31 */ "Del: Delphinus", + /* 32 */ "Dor: Dorado", + /* 33 */ "Dra: Draco", + /* 34 */ "Equ: Equuleus", + /* 35 */ "Eri: Eridanus", + /* 36 */ "For: Fornax", + /* 37 */ "Gem: Gemini", + /* 38 */ "Gru: Grus", + /* 39 */ "Her: Hercules", + /* 40 */ "Hor: Horologium", + /* 41 */ "Hya: Hydra", + /* 42 */ "Hyi: Hydrus", + /* 43 */ "Ind: Indus", + /* 44 */ "LMi: Leo Minor", + /* 45 */ "Lac: Lacerta", + /* 46 */ "Leo: Leo", + /* 47 */ "Lep: Lepus", + /* 48 */ "Lib: Libra", + /* 49 */ "Lup: Lupus", + /* 50 */ "Lyn: Lynx", + /* 51 */ "Lyr: Lyra", + /* 52 */ "Men: Mensa", + /* 53 */ "Mic: Microscopium", + /* 54 */ "Mon: Monoceros", + /* 55 */ "Mus: Musca", + /* 56 */ "Nor: Norma", + /* 57 */ "Oct: Octans", + /* 58 */ "Oph: Ophiuchus", + /* 59 */ "Ori: Orion", + /* 60 */ "Pav: Pavo", + /* 61 */ "Peg: Pegasus", + /* 62 */ "Per: Perseus", + /* 63 */ "Phe: Phoenix", + /* 64 */ "Pic: Pictor", + /* 65 */ "PsA: Piscis Austrinus", + /* 66 */ "Psc: Pisces", + /* 67 */ "Pup: Puppis", + /* 68 */ "Pyx: Pyxis", + /* 69 */ "Ret: Reticulum", + /* 70 */ "Scl: Sculptor", + /* 71 */ "Sco: Scorpius", + /* 72 */ "Sct: Scutum", + /* 73 */ "Se1: Serpens Caput", + /* 74 */ "Sex: Sextans", + /* 75 */ "Sge: Sagitta", + /* 76 */ "Sgr: Sagittarius", + /* 77 */ "Tau: Taurus", + /* 78 */ "Tel: Telescopium", + /* 79 */ "TrA: Triangulum Australe", + /* 80 */ "Tri: Triangulum", + /* 81 */ "Tuc: Tucana", + /* 82 */ "UMa: Ursa Major", + /* 83 */ "UMi: Ursa Minor", + /* 84 */ "Vel: Vela", + /* 85 */ "Vir: Virgo", + /* 86 */ "Vol: Volans", + /* 87 */ "Vul: Vulpecula", + /* 88 */ "Se2: Serpens Cauda", +}; + +static struct { + unsigned short lower_ra; /* hours * 1800 */ + unsigned short upper_ra; /* hours * 1800 */ + short lower_dec; /* degrees * 60 */ + short index; +} cbound[ NBOUNDS ] = { + { 0, 43200, 5280, UMi }, + { 14400, 26100, 5190, UMi }, + { 37800, 41400, 5170, UMi }, + { 32400, 37800, 5160, UMi }, + { 0, 14400, 5100, Cep }, + { 16500, 19200, 4920, Cam }, + { 0, 9000, 4800, Cep }, + { 19200, 26100, 4800, Cam }, + { 31500, 32400, 4800, UMi }, + { 36300, 37800, 4800, Dra }, + { 0, 6315, 4620, Cep }, + { 20700, 24450, 4620, Cam }, + { 29760, 31500, 4500, UMi }, + { 36300, 37200, 4500, Cep }, + { 14340, 16500, 4410, Cam }, + { 16500, 20400, 4410, Dra }, + { 23400, 29760, 4200, UMi }, + { 5580, 6150, 4080, Cas }, + { 36750, 37200, 4020, Dra }, + { 20400, 21600, 3990, Dra }, + { 0, 600, 3960, Cep }, + { 25200, 28200, 3960, UMi }, + { 42450, 43200, 3960, Cep }, + { 21600, 24300, 3840, Dra }, + { 24300, 25950, 3780, Dra }, + { 41700, 42450, 3780, Cep }, + { 10980, 12600, 3720, Cam }, + { 36000, 36750, 3690, Dra }, + { 36966, 37080, 3655, Cep }, + { 12600, 14340, 3600, Cam }, + { 14340, 15150, 3600, UMa }, + { 35580, 36000, 3570, Dra }, + { 36000, 36966, 3570, Cep }, + { 41160, 41700, 3545, Cep }, + { 0, 4380, 3510, Cas }, + { 34950, 35580, 3480, Dra }, + { 3060, 3435, 3450, Cas }, + { 4380, 5580, 3420, Cas }, + { 5580, 5700, 3420, Cam }, + { 40170, 41160, 3375, Cep }, + { 9000, 10980, 3360, Cam }, + { 25260, 25950, 3330, UMa }, + { 25950, 34950, 3330, Dra }, + { 5700, 6000, 3300, Cam }, + { 39840, 40170, 3300, Cep }, + { 37080, 39540, 3290, Cep }, + { 0, 3060, 3240, Cas }, + { 10980, 11700, 3240, Lyn }, + { 21750, 24300, 3180, UMa }, + { 27450, 28350, 3180, Dra }, + { 39540, 39840, 3165, Cep }, + { 6000, 9000, 3150, Cam }, + { 41160, 42000, 3150, Cas }, + { 28350, 30600, 3090, Dra }, + { 3675, 4530, 3030, Per }, + { 30600, 32820, 3030, Dra }, + { 0, 2460, 3000, Cas }, + { 2460, 3000, 3000, Per }, + { 11700, 12240, 3000, Lyn }, + { 42000, 43200, 3000, Cas }, + { 24300, 25260, 2910, UMa }, + { 0, 2010, 2880, Cas }, + { 42450, 43200, 2880, Cas }, + { 32715, 32820, 2850, Her }, + { 32820, 34350, 2850, Dra }, + { 34350, 34500, 2850, Cyg }, + { 3000, 3675, 2820, Per }, + { 15150, 16500, 2820, UMa }, + { 300, 1560, 2760, Cas }, + { 21600, 21750, 2700, UMa }, + { 12240, 13260, 2670, Lyn }, + { 39435, 39540, 2640, Cyg }, + { 39375, 39435, 2625, Cyg }, + { 34500, 34920, 2610, Cyg }, + { 16500, 18300, 2520, UMa }, + { 18300, 19410, 2400, UMa }, + { 27780, 28350, 2400, Boo }, + { 28350, 29400, 2400, Her }, + { 16650, 17250, 2385, Lyn }, + { 0, 4530, 2205, And }, + { 4530, 4620, 2205, Per }, + { 34845, 34920, 2190, Lyr }, + { 8100, 8445, 2160, Per }, + { 39120, 39375, 2160, Cyg }, + { 39375, 39600, 2160, Lac }, + { 11760, 13260, 2130, Aur }, + { 13260, 13950, 2130, Lyn }, + { 0, 3600, 2100, And }, + { 39600, 41070, 2100, Lac }, + { 41070, 41160, 2070, Lac }, + { 41160, 42300, 2070, And }, + { 4620, 4890, 2040, Per }, + { 19410, 19800, 2040, UMa }, + { 21600, 22200, 2040, CVn }, + { 13950, 16650, 2010, Lyn }, + { 16650, 17790, 2010, LMi }, + { 1290, 2535, 1980, And }, + { 27330, 27780, 1980, Boo }, + { 42300, 42750, 1925, And }, + { 22200, 23850, 1920, CVn }, + { 42750, 43200, 1880, And }, + { 25125, 25260, 1845, CVn }, + { 4350, 4890, 1840, Tri }, + { 4890, 8100, 1840, Per }, + { 8100, 8550, 1800, Aur }, + { 32715, 34845, 1800, Lyr }, + { 19800, 21600, 1740, UMa }, + { 35400, 37650, 1740, Cyg }, + { 8550, 10590, 1710, Aur }, + { 17790, 18900, 1710, LMi }, + { 23850, 25125, 1710, CVn }, + { 0, 120, 1680, And }, + { 2535, 3000, 1680, Tri }, + { 10590, 11760, 1680, Aur }, + { 14190, 14400, 1680, Gem }, + { 37650, 39120, 1680, Cyg }, + { 34665, 35400, 1650, Cyg }, + { 3450, 4350, 1635, Tri }, + { 29100, 29400, 1620, CrB }, + { 27150, 27330, 1560, Boo }, + { 27330, 29100, 1560, CrB }, + { 33060, 33960, 1560, Lyr }, + { 19350, 19800, 1530, LMi }, + { 33960, 34665, 1530, Lyr }, + { 3000, 3450, 1500, Tri }, + { 1290, 1530, 1425, Psc }, + { 18900, 19350, 1410, LMi }, + { 38250, 38550, 1410, Vul }, + { 10260, 10590, 1370, Tau }, + { 120, 255, 1320, And }, + { 28650, 28860, 1320, Se1 }, + { 10590, 11190, 1290, Gem }, + { 35700, 36450, 1275, Vul }, + { 33960, 34650, 1265, Vul }, + { 255, 1530, 1260, And }, + { 36450, 37020, 1230, Vul }, + { 14055, 14190, 1200, Gem }, + { 37020, 38250, 1170, Vul }, + { 34650, 35700, 1150, Vul }, + { 5910, 6060, 1140, Ari }, + { 33960, 34200, 1110, Sge }, + { 10260, 10380, 1080, Ori }, + { 11190, 11355, 1050, Gem }, + { 34200, 35700, 970, Sge }, + { 8940, 9600, 960, Tau }, + { 28650, 28950, 960, Her }, + { 35700, 36450, 945, Sge }, + { 8310, 8940, 930, Tau }, + { 9600, 10080, 930, Tau }, + { 23100, 24300, 900, Com }, + { 31050, 32850, 860, Her }, + { 21360, 23100, 840, Com }, + { 13500, 14055, 810, Gem }, + { 30150, 31050, 770, Her }, + { 0, 255, 750, Peg }, + { 10080, 10380, 750, Tau }, + { 12600, 13500, 750, Gem }, + { 38010, 38400, 750, Peg }, + { 11355, 12480, 720, Gem }, + { 32850, 33960, 720, Her }, + { 37575, 37890, 710, Del }, + { 37890, 38010, 710, Peg }, + { 20730, 21360, 660, Leo }, + { 11235, 11355, 600, Ori }, + { 12480, 12600, 600, Gem }, + { 14055, 14265, 600, Cnc }, + { 42900, 43200, 600, Peg }, + { 3000, 5910, 595, Ari }, + { 36255, 36540, 510, Del }, + { 24300, 27150, 480, Boo }, + { 40950, 42900, 450, Peg }, + { 14265, 16650, 420, Cnc }, + { 16650, 19350, 420, Leo }, + { 32850, 33592, 375, Oph }, + { 33592, 33960, 375, Aql }, + { 37500, 37575, 360, Del }, + { 12600, 12630, 330, CMi }, + { 32850, 33165, 270, Se2 }, + { 28950, 30150, 240, Her }, + { 32850, 33165, 180, Oph }, + { 38640, 39000, 165, Peg }, + { 0, 3600, 120, Psc }, + { 33450, 33960, 120, Se2 }, + { 36540, 37500, 120, Del }, + { 37500, 38400, 120, Equ }, + { 38400, 38640, 120, Peg }, + { 39600, 40950, 120, Peg }, + { 39000, 39600, 105, Peg }, + { 12630, 12960, 90, CMi }, + { 6450, 8310, 0, Tau }, + { 8310, 8400, 0, Ori }, + { 12960, 14550, 0, CMi }, + { 26400, 27150, 0, Vir }, + { 32100, 32850, 0, Oph }, + { 4770, 5910, -105, Cet }, + { 5910, 6450, -105, Tau }, + { 27150, 29280, -195, Se1 }, + { 8400, 9150, -240, Ori }, + { 10500, 11235, -240, Ori }, + { 32100, 32340, -240, Se2 }, + { 32850, 33450, -240, Se2 }, + { 33450, 33960, -240, Aql }, + { 40950, 42900, -240, Psc }, + { 19350, 20730, -360, Leo }, + { 20730, 21300, -360, Vir }, + { 0, 600, -420, Psc }, + { 42900, 43200, -420, Psc }, + { 25650, 26400, -480, Vir }, + { 28650, 29280, -480, Oph }, + { 36000, 36960, -540, Aql }, + { 38400, 39360, -540, Aqr }, + { 30900, 32340, -600, Oph }, + { 10500, 14550, -660, Mon }, + { 8850, 9150, -660, Eri }, + { 9150, 10500, -660, Ori }, + { 14550, 15060, -660, Hya }, + { 17250, 19350, -660, Sex }, + { 21300, 23100, -660, Vir }, + { 31650, 31800, -700, Oph }, + { 33960, 36000, -722, Aql }, + { 8700, 8850, -870, Eri }, + { 36960, 38400, -900, Aqr }, + { 30900, 32850, -960, Se2 }, + { 32850, 33960, -960, Sct }, + { 15060, 15450, -1020, Hya }, + { 29280, 29475, -1095, Oph }, + { 15450, 16350, -1140, Hya }, + { 19350, 19500, -1140, Crt }, + { 29280, 29475, -1155, Sco }, + { 28200, 28650, -1200, Lib }, + { 22650, 23100, -1320, Crv }, + { 23100, 25650, -1320, Vir }, + { 16350, 17550, -1440, Hya }, + { 3000, 4770, -1463, Cet }, + { 4770, 6750, -1463, Eri }, + { 19500, 21300, -1470, Crt }, + { 21300, 22650, -1470, Crv }, + { 25650, 26850, -1470, Lib }, + { 29280, 30150, -1475, Oph }, + { 0, 3000, -1530, Cet }, + { 38400, 39360, -1530, Cap }, + { 39360, 42900, -1530, Aqr }, + { 42900, 43200, -1530, Cet }, + { 17550, 18450, -1590, Hya }, + { 8460, 8700, -1635, Eri }, + { 8700, 11010, -1635, Lep }, + { 36000, 38400, -1680, Cap }, + { 18450, 19050, -1750, Hya }, + { 22650, 26850, -1770, Hya }, + { 26850, 28200, -1770, Lib }, + { 28200, 28800, -1770, Sco }, + { 8250, 8460, -1800, Eri }, + { 30150, 31680, -1800, Oph }, + { 31680, 32100, -1800, Sgr }, + { 19050, 19500, -1870, Hya }, + { 11010, 13260, -1980, CMa }, + { 22050, 22650, -1980, Hya }, + { 19500, 22050, -2100, Hya }, + { 6300, 6750, -2160, For }, + { 15060, 16860, -2205, Pyx }, + { 7680, 8250, -2220, Eri }, + { 32100, 34500, -2220, Sgr }, + { 38400, 41400, -2220, PsA }, + { 41400, 42000, -2220, Scl }, + { 5400, 6300, -2375, For }, + { 16860, 19800, -2385, Ant }, + { 0, 3000, -2400, Scl }, + { 3000, 5400, -2400, For }, + { 6960, 7680, -2400, Eri }, + { 42000, 43200, -2400, Scl }, + { 25500, 26850, -2520, Cen }, + { 28200, 28800, -2520, Lup }, + { 28800, 29557, -2520, Sco }, + { 8700, 9000, -2580, Cae }, + { 9000, 11850, -2580, Col }, + { 14400, 15060, -2580, Pup }, + { 6150, 6960, -2640, Eri }, + { 29557, 32100, -2730, Sco }, + { 32100, 34500, -2730, CrA }, + { 34500, 36600, -2730, Sgr }, + { 36600, 38400, -2730, Mic }, + { 5400, 6150, -2760, Eri }, + { 8100, 8700, -2790, Cae }, + { 27600, 28200, -2880, Lup }, + { 0, 4200, -2890, Phe }, + { 4800, 5400, -2940, Eri }, + { 7350, 7680, -2940, Hor }, + { 7680, 8100, -2940, Cae }, + { 38400, 39600, -3000, Gru }, + { 10800, 14400, -3045, Pup }, + { 14400, 14700, -3045, Vel }, + { 4350, 4800, -3060, Eri }, + { 6900, 7350, -3060, Hor }, + { 0, 3300, -3090, Phe }, + { 10800, 11100, -3150, Car }, + { 14700, 15210, -3180, Vel }, + { 6300, 6900, -3190, Hor }, + { 6900, 7200, -3190, Dor }, + { 0, 2850, -3210, Phe }, + { 3900, 4350, -3240, Eri }, + { 8100, 9000, -3240, Pic }, + { 27090, 27600, -3240, Lup }, + { 15210, 15900, -3270, Vel }, + { 11100, 11700, -3300, Car }, + { 21300, 23100, -3300, Cen }, + { 25500, 27090, -3300, Lup }, + { 27090, 27600, -3300, Nor }, + { 7200, 7800, -3390, Dor }, + { 15900, 19800, -3390, Vel }, + { 19800, 20250, -3390, Cen }, + { 31500, 32400, -3420, Ara }, + { 32400, 36600, -3420, Tel }, + { 39600, 42000, -3420, Gru }, + { 5760, 6300, -3450, Hor }, + { 9000, 9900, -3450, Pic }, + { 11700, 12300, -3480, Car }, + { 0, 2400, -3510, Phe }, + { 2400, 3900, -3510, Eri }, + { 42000, 43200, -3510, Phe }, + { 7800, 8250, -3540, Dor }, + { 27600, 29557, -3600, Nor }, + { 36600, 38400, -3600, Ind }, + { 9900, 10800, -3660, Pic }, + { 27300, 27600, -3660, Cir }, + { 29557, 29850, -3660, Ara }, + { 26850, 27300, -3815, Cir }, + { 29850, 30150, -3815, Ara }, + { 10800, 12300, -3840, Pic }, + { 12300, 16260, -3840, Car }, + { 20250, 21300, -3840, Cen }, + { 21300, 23100, -3840, Cru }, + { 23100, 26160, -3840, Cen }, + { 24300, 24600, -3900, Cir }, + { 30150, 30300, -3900, Ara }, + { 3900, 5760, -4050, Hor }, + { 5760, 8250, -4050, Ret }, + { 26550, 26850, -4050, Cir }, + { 30300, 31500, -4050, Ara }, + { 31500, 32400, -4050, Pav }, + { 39600, 42000, -4050, Tuc }, + { 8250, 11850, -4200, Dor }, + { 24600, 26550, -4200, Cir }, + { 26550, 30600, -4200, TrA }, + { 0, 2400, -4500, Tuc }, + { 6300, 8250, -4500, Hyi }, + { 11850, 16260, -4500, Vol }, + { 16260, 20250, -4500, Car }, + { 20250, 24600, -4500, Mus }, + { 32400, 38400, -4500, Pav }, + { 38400, 42000, -4500, Ind }, + { 42000, 43200, -4500, Tuc }, + { 1350, 2400, -4560, Tuc }, + { 0, 6300, -4950, Hyi }, + { 13800, 24600, -4950, Cha }, + { 24600, 32400, -4950, Aps }, + { 6300, 13800, -5100, Men }, + { 0, 43200, -5400, Oct } +}; + +static short start[] = { + 355, 352, 343, 340, 332, 320, + 303, 288, 277, 266, 257, 251, + 239, 229, 221, 211, 203, 189, + 177, 163, 149, 136, 124, 104, + 87, 75, 69, 54, 43, 29, + 23, 16, 12, 6, 4, 0, 0 +}; + + +/* +====================================================================== +constellation_pick() + +Do a constellation pick from RA and Dec. + +INPUTS + r right ascension, radians + d declination, radians + e epoch to which r and d precessed, as an mjd + +RESULTS + Returns an index for the constellation region that the coordinates + belong to, or -1 if no constellation pick can be found. + +The constellation is identified by linear search. We look for a +member of cbound[] whose lower_dec is less than the declination of the +pick point and whose lower_ra and upper_ra bracket the pick point's +right ascension. The data for that cbound[] member describes a sub- +region belonging to the picked constellation. + +In geometric terms, the search amounts to starting at the north pole +and traveling south on a line of constant right ascension through the +pick point. At every declination where a cbound[] member lives, we +wake up, and if (1) the pick point is now behind us, and (2) the +cbound[] segment is crossing our path, we know we've hit the edge of +a constellation subregion that the pick point belongs to. + +The cbound[] right ascension and declination values are scaled into +integers; this conserves storage and makes comparisons faster. The +start[] array, which gives starting points in cbound[] for different +declinations in 5-degree increments, further speeds the search by +skipping early parts of the list for which we know the search can't +succeed--geometrically, we start no more than 5 degrees north of the +pick point, rather than at the north pole. + +The data in cbound[] are for epoch 1875. +====================================================================== +*/ + +int +cns_pick(double r, double d, double e) +{ + double Mjd; + unsigned short ra; + short de, i; + + cal_mjd( 1, 1.0, 1875, &Mjd ); + precess( e, Mjd, &r, &d ); + ra = ( unsigned short )( radhr( r ) * 1800 ); + de = ( short )( raddeg( d ) * 60 ); + if (d < 0.0) --de; + + i = ( de + 5400 ) / 300; + if ( i < 0 || i > 36 ) return -1; + i = start[ i ]; + + for ( ; i < NBOUNDS; i++ ) + if ( cbound[ i ].lower_dec <= de && + cbound[ i ].upper_ra > ra && + cbound[ i ].lower_ra <= ra ) break; + + return ( i == NBOUNDS ) ? -1 : ( int ) cbound[ i ].index; +} + +/* given a constellation id (as from cns_pick()), return pointer to static + * storage containg its name in the form "AAA: Name". + * return "???: ???" if id is invalid. + */ +char * +cns_name (int id) +{ + if (id < 0 || id >= NCNS) + return ("???: ???"); + return (cns_namemap[id]); +} + +/* return cns_namemap index matching first three chars in abbrev[], else -1. + */ +int +cns_id (char *abbrev) +{ + int i; + + for (i = 0; i < NCNS; i++) + if (strncmp (abbrev, cns_namemap[i], 3) == 0) + return (i); + return (-1); +} + +/* edges of constant ra */ +static struct { + unsigned short ra; /* hours * 1800 */ + short dec0, dec1; /* degrees * 60 */ +} ra_edges[] = { + { 0, -4950, -4500 }, + { 0, 600, 750 }, + { 0, 1680, 1879 }, + { 120, 1320, 1680 }, + { 255, 750, 1260 }, + { 255, 1260, 1320 }, + { 300, 2760, 2880 }, + { 599, -420, 0 }, + { 599, 0, 120 }, + { 599, 3960, 4620 }, + { 1290, 1425, 1980 }, + { 1350, -4500, -4560 }, + { 1530, 1260, 1425 }, + { 1560, 2760, 2880 }, + { 2010, 2880, 3000 }, + { 2399, -4560, -3510 }, + { 2399, -3510, -3210 }, + { 2460, 3000, 3240 }, + { 2534, 1680, 1980 }, + { 2534, 1980, 2100 }, + { 2849, -3210, -3090 }, + { 3000, -2400, -1530 }, + { 3000, -1530, -1462 }, + { 3000, 595, 1500 }, + { 3000, 1500, 1680 }, + { 3000, 2820, 3000 }, + { 3060, 3240, 3450 }, + { 3299, -3090, -2890 }, + { 3434, 3450, 3510 }, + { 3450, 1500, 1635 }, + { 3600, 120, 595 }, + { 3600, 2100, 2205 }, + { 3675, 2820, 3030 }, + { 3900, -4050, -3510 }, + { 3900, -3510, -3240 }, + { 4199, -2890, -2400 }, + { 4350, -3240, -3060 }, + { 4350, 1635, 1840 }, + { 4379, 3420, 3510 }, + { 4530, 2205, 3030 }, + { 4620, 2040, 2205 }, + { 4770, -1462, -105 }, + { 4800, -3060, -2940 }, + { 4890, 1840, 2040 }, + { 5400, -2940, -2760 }, + { 5400, -2400, -2374 }, + { 5580, 3420, 4080 }, + { 5700, 3300, 3420 }, + { 5760, -3450, -4050 }, + { 5909, -105, 0 }, + { 5909, 0, 595 }, + { 5909, 595, 1140 }, + { 5999, 3150, 3300 }, + { 6060, 1140, 1840 }, + { 6150, -2760, -2640 }, + { 6150, 4080, 4620 }, + { 6300, -5100, -4950 }, + { 6300, -4950, -4500 }, + { 6300, -3190, -3450 }, + { 6300, -2374, -2160 }, + { 6314, 4620, 4800 }, + { 6449, -105, 0 }, + { 6750, -2160, -1462 }, + { 6899, -3060, -3190 }, + { 6960, -2640, -2400 }, + { 7200, -3390, -3190 }, + { 7349, -2940, -3060 }, + { 7680, -2400, -2940 }, + { 7680, -2220, -2400 }, + { 7799, -3540, -3390 }, + { 8100, -3240, -2940 }, + { 8100, -2940, -2790 }, + { 8100, 1800, 1840 }, + { 8100, 1840, 2160 }, + { 8249, -4500, -4200 }, + { 8249, -4050, -4200 }, + { 8249, -4050, -3540 }, + { 8249, -1800, -2220 }, + { 8310, 0, 930 }, + { 8400, -240, 0 }, + { 8445, 2160, 3150 }, + { 8460, -1635, -1800 }, + { 8550, 1710, 1800 }, + { 8699, -2790, -2580 }, + { 8699, -870, -1635 }, + { 8850, -660, -870 }, + { 8940, 930, 960 }, + { 9000, -3450, -3240 }, + { 9000, -2580, -1635 }, + { 9000, 3150, 3360 }, + { 9000, 4800, 5100 }, + { 9149, -660, -240 }, + { 9599, 930, 960 }, + { 9900, -3660, -3450 }, + { 10080, 750, 930 }, + { 10260, 1080, 1369 }, + { 10380, 750, 1080 }, + { 10499, -660, -240 }, + { 10589, 1290, 1369 }, + { 10589, 1369, 1680 }, + { 10589, 1680, 1710 }, + { 10800, -3840, -3660 }, + { 10800, -3150, -3045 }, + { 10800, -3045, -2580 }, + { 10980, 3240, 3360 }, + { 10980, 3360, 3720 }, + { 11010, -1980, -1635 }, + { 11010, -1635, -660 }, + { 11100, -3300, -3150 }, + { 11190, 1050, 1290 }, + { 11235, -240, 0 }, + { 11235, 0, 600 }, + { 11354, 600, 720 }, + { 11354, 720, 1050 }, + { 11700, -3480, -3300 }, + { 11700, 3000, 3240 }, + { 11759, 1680, 2130 }, + { 11849, -4200, -4500 }, + { 11849, -4200, -3840 }, + { 11849, -1980, -2580 }, + { 12240, 2670, 3000 }, + { 12299, -3840, -3480 }, + { 12479, 600, 720 }, + { 12600, 330, 600 }, + { 12600, 600, 750 }, + { 12600, 3600, 3720 }, + { 12630, 90, 330 }, + { 12960, 0, 90 }, + { 13260, -660, -1980 }, + { 13260, 2130, 2670 }, + { 13500, 750, 810 }, + { 13800, -5100, -4950 }, + { 13800, -4500, -4950 }, + { 13950, 2010, 2130 }, + { 14054, 600, 810 }, + { 14054, 810, 1200 }, + { 14189, 1200, 1680 }, + { 14265, 420, 600 }, + { 14340, 3600, 4410 }, + { 14400, -3045, -2580 }, + { 14400, 1680, 2010 }, + { 14400, 5100, 5190 }, + { 14400, 5280, 5190 }, + { 14549, -660, 0 }, + { 14549, 0, 420 }, + { 14700, -3180, -3045 }, + { 15060, -2580, -2205 }, + { 15060, -2205, -1020 }, + { 15060, -1020, -660 }, + { 15150, 2820, 3600 }, + { 15209, -3270, -3180 }, + { 15449, -1140, -1020 }, + { 15899, -3390, -3270 }, + { 16259, -4500, -3840 }, + { 16349, -1440, -1140 }, + { 16500, 2520, 2820 }, + { 16500, 4410, 4920 }, + { 16650, 420, 2010 }, + { 16650, 2010, 2385 }, + { 16860, -2385, -2205 }, + { 16860, -1440, -2205 }, + { 17249, -660, 0 }, + { 17249, 0, 420 }, + { 17249, 2385, 2520 }, + { 17550, -1590, -1440 }, + { 17789, 1710, 2010 }, + { 18300, 2400, 2520 }, + { 18450, -1750, -1590 }, + { 18900, 1410, 1710 }, + { 19049, -1870, -1750 }, + { 19200, 4800, 4920 }, + { 19350, -660, -1140 }, + { 19350, -360, -660 }, + { 19350, -360, 0 }, + { 19350, 0, 420 }, + { 19350, 1410, 1530 }, + { 19409, 2040, 2400 }, + { 19499, -2100, -1870 }, + { 19499, -1140, -1470 }, + { 19800, -3390, -2385 }, + { 19800, -2385, -2100 }, + { 19800, 1530, 1740 }, + { 19800, 1740, 2040 }, + { 20250, -4500, -3840 }, + { 20250, -3840, -3390 }, + { 20399, 3990, 4410 }, + { 20700, 4620, 4800 }, + { 20730, -360, 0 }, + { 20730, 0, 660 }, + { 21299, -3840, -3300 }, + { 21299, -1470, -660 }, + { 21299, -660, -360 }, + { 21360, 660, 840 }, + { 21360, 840, 1740 }, + { 21600, 1740, 2040 }, + { 21600, 2040, 2700 }, + { 21600, 3840, 3990 }, + { 21749, 2700, 3180 }, + { 22050, -1980, -2100 }, + { 22199, 1920, 2040 }, + { 22649, -1770, -1980 }, + { 22649, -1470, -1320 }, + { 23099, -3840, -3300 }, + { 23099, -1320, -660 }, + { 23099, 840, 900 }, + { 23400, 4620, 4200 }, + { 23850, 1710, 1920 }, + { 24300, -3900, -3840 }, + { 24300, 480, 900 }, + { 24300, 900, 1710 }, + { 24300, 2910, 3180 }, + { 24300, 3780, 3840 }, + { 24449, 4800, 4620 }, + { 24600, -4950, -4500 }, + { 24600, -4500, -4200 }, + { 24600, -4200, -3900 }, + { 25124, 1710, 1845 }, + { 25200, 4200, 3960 }, + { 25259, 1845, 2910 }, + { 25259, 2910, 3330 }, + { 25500, -3300, -2520 }, + { 25650, -1320, -1470 }, + { 25650, -480, -1320 }, + { 25950, 3330, 3780 }, + { 26100, 5190, 4800 }, + { 26159, -3840, -3300 }, + { 26400, 0, -480 }, + { 26550, -4200, -4050 }, + { 26850, -4050, -3814 }, + { 26850, -2520, -1770 }, + { 26850, -1470, -1770 }, + { 27090, -3300, -3240 }, + { 27149, -195, 0 }, + { 27149, 0, 480 }, + { 27149, 480, 1560 }, + { 27300, -3814, -3660 }, + { 27329, 1560, 1980 }, + { 27450, 3180, 3330 }, + { 27599, -3660, -3600 }, + { 27599, -3600, -3300 }, + { 27599, -3240, -2880 }, + { 27779, 1980, 2400 }, + { 28200, -2880, -2520 }, + { 28200, -1770, -1200 }, + { 28200, 3960, 4200 }, + { 28350, 2400, 3090 }, + { 28350, 3090, 3180 }, + { 28650, -1200, -480 }, + { 28650, -480, -195 }, + { 28650, 960, 1320 }, + { 28800, -2520, -1770 }, + { 28859, 1320, 1560 }, + { 28949, 240, 960 }, + { 29100, 1560, 1620 }, + { 29280, -1474, -1155 }, + { 29280, -1095, -480 }, + { 29280, -195, 0 }, + { 29280, 0, 240 }, + { 29399, 1620, 2400 }, + { 29475, -1155, -1095 }, + { 29557, -3660, -3600 }, + { 29557, -3600, -2730 }, + { 29557, -2730, -2520 }, + { 29759, 4200, 4500 }, + { 29849, -3814, -3660 }, + { 30150, -3900, -3814 }, + { 30150, -1800, -1474 }, + { 30150, 240, 769 }, + { 30299, -4050, -3900 }, + { 30600, -4050, -4200 }, + { 30600, 3030, 3090 }, + { 30900, -960, -600 }, + { 31050, 769, 859 }, + { 31500, -3420, -4050 }, + { 31500, 4500, 4800 }, + { 31649, -700, -600 }, + { 31680, -960, -1800 }, + { 31800, -700, -600 }, + { 32099, -2730, -2220 }, + { 32099, -1800, -2220 }, + { 32099, -240, 0 }, + { 32340, -600, -240 }, + { 32400, -4950, -4500 }, + { 32400, -4500, -4050 }, + { 32400, -2730, -3420 }, + { 32400, 4800, 5160 }, + { 32715, 1800, 2850 }, + { 32819, 2850, 3030 }, + { 32850, -240, -960 }, + { 32850, 0, 180 }, + { 32850, 270, 375 }, + { 32850, 720, 859 }, + { 33060, 1560, 1800 }, + { 33165, 180, 270 }, + { 33449, -240, 0 }, + { 33449, 0, 120 }, + { 33591, 375, 720 }, + { 33960, -960, -721 }, + { 33960, -721, -240 }, + { 33960, 120, 375 }, + { 33960, 720, 1110 }, + { 33960, 1110, 1264 }, + { 33960, 1264, 1530 }, + { 33960, 1530, 1560 }, + { 34200, 970, 1110 }, + { 34349, 2850, 3330 }, + { 34500, -2220, -2730 }, + { 34500, 2610, 2850 }, + { 34650, 1150, 1264 }, + { 34664, 1530, 1650 }, + { 34664, 1650, 1800 }, + { 34844, 1800, 2190 }, + { 34920, 2190, 2610 }, + { 34950, 3330, 3480 }, + { 35400, 1650, 1740 }, + { 35580, 3480, 3570 }, + { 35699, 945, 970 }, + { 35699, 1150, 1275 }, + { 36000, -1680, -721 }, + { 36000, -540, -721 }, + { 36000, 3570, 3690 }, + { 36255, 510, 945 }, + { 36300, 4500, 4800 }, + { 36450, 945, 1230 }, + { 36450, 1230, 1275 }, + { 36540, 120, 510 }, + { 36599, -3600, -3420 }, + { 36599, -3420, -2730 }, + { 36599, -2730, -1680 }, + { 36750, 3690, 4020 }, + { 36959, -900, -540 }, + { 36959, -540, 0 }, + { 36959, 0, 120 }, + { 36966, 3570, 3655 }, + { 37020, 1170, 1230 }, + { 37080, 3289, 3655 }, + { 37200, 4020, 4500 }, + { 37499, 120, 360 }, + { 37575, 360, 709 }, + { 37650, 1680, 1740 }, + { 37800, 4800, 5160 }, + { 37800, 5160, 5169 }, + { 37890, 709, 1170 }, + { 38010, 709, 750 }, + { 38250, 1170, 1410 }, + { 38399, -4500, -3600 }, + { 38399, -3000, -2730 }, + { 38399, -2220, -2730 }, + { 38399, -1680, -2220 }, + { 38399, -1680, -1530 }, + { 38399, -540, -900 }, + { 38399, 120, 750 }, + { 38550, 1410, 1680 }, + { 38640, 120, 165 }, + { 39000, 105, 165 }, + { 39119, 1680, 2160 }, + { 39360, -1530, -540 }, + { 39375, 2160, 2625 }, + { 39434, 2625, 2640 }, + { 39540, 2640, 3165 }, + { 39540, 3165, 3289 }, + { 39600, -4050, -3420 }, + { 39600, -3420, -3000 }, + { 39600, 105, 120 }, + { 39600, 2100, 2160 }, + { 39839, 3165, 3300 }, + { 40170, 3300, 3375 }, + { 40950, -240, 0 }, + { 40950, 0, 120 }, + { 40950, 120, 450 }, + { 41070, 2070, 2100 }, + { 41160, 2070, 3150 }, + { 41160, 3150, 3375 }, + { 41160, 3375, 3544 }, + { 41400, -2220, -1530 }, + { 41400, 5169, 5280 }, + { 41700, 3544, 3780 }, + { 41999, -4500, -4050 }, + { 41999, -3510, -3420 }, + { 41999, -3420, -2400 }, + { 41999, -2400, -2220 }, + { 41999, 3000, 3150 }, + { 42300, 1924, 2070 }, + { 42449, 2880, 3000 }, + { 42449, 3780, 3960 }, + { 42750, 1879, 1924 }, + { 42899, -1530, -420 }, + { 42899, -420, -240 }, + { 42899, 450, 600 }, +}; + +#define NRA ((int)(sizeof(ra_edges)/sizeof(ra_edges[0]))) + +/* edges of constant dec */ +static struct { + short dec; /* degrees * 60 */ + unsigned short ra0, ra1; /* hours * 1800 */ +} dec_edges[] = { + { -5100, 6300, 13800 }, + { -4950, 0, 6300 }, + { -4950, 13800, 24600 }, + { -4950, 24600, 32400 }, + { -4560, 1350, 2399 }, + { -4500, 0, 1350 }, + { -4500, 6300, 8249 }, + { -4500, 11849, 13800 }, + { -4500, 13800, 16259 }, + { -4500, 16259, 20250 }, + { -4500, 20250, 24600 }, + { -4500, 32400, 38399 }, + { -4500, 38399, 41999 }, + { -4500, 41999, 0 }, + { -4200, 8249, 11849 }, + { -4200, 24600, 26550 }, + { -4200, 30600, 26550 }, + { -4050, 3900, 5760 }, + { -4050, 5760, 8249 }, + { -4050, 26550, 26850 }, + { -4050, 30299, 30600 }, + { -4050, 31500, 30600 }, + { -4050, 31500, 32400 }, + { -4050, 39600, 41999 }, + { -3900, 24300, 24600 }, + { -3900, 30150, 30299 }, + { -3840, 10800, 11849 }, + { -3840, 11849, 12299 }, + { -3840, 12299, 16259 }, + { -3840, 20250, 21299 }, + { -3840, 21299, 23099 }, + { -3840, 23099, 24300 }, + { -3840, 24300, 26159 }, + { -3814, 26850, 27300 }, + { -3814, 29849, 30150 }, + { -3660, 9900, 10800 }, + { -3660, 27300, 27599 }, + { -3660, 29557, 29849 }, + { -3600, 27599, 29557 }, + { -3600, 36599, 38399 }, + { -3540, 7799, 8249 }, + { -3510, 2399, 3900 }, + { -3510, 2399, 41999 }, + { -3510, 3900, 2399 }, + { -3510, 41999, 2399 }, + { -3480, 11700, 12299 }, + { -3450, 6300, 5760 }, + { -3450, 9000, 9900 }, + { -3420, 32400, 31500 }, + { -3420, 32400, 36599 }, + { -3420, 39600, 41999 }, + { -3390, 7200, 7799 }, + { -3390, 15899, 19800 }, + { -3390, 19800, 20250 }, + { -3300, 11100, 11700 }, + { -3300, 21299, 23099 }, + { -3300, 25500, 26159 }, + { -3300, 26159, 27090 }, + { -3300, 27090, 27599 }, + { -3270, 15209, 15899 }, + { -3240, 3900, 4350 }, + { -3240, 8100, 9000 }, + { -3240, 27090, 27599 }, + { -3210, 2399, 2849 }, + { -3190, 6899, 6300 }, + { -3190, 6899, 7200 }, + { -3180, 14700, 15209 }, + { -3150, 10800, 11100 }, + { -3090, 2849, 3299 }, + { -3060, 4350, 4800 }, + { -3060, 7349, 6899 }, + { -3045, 10800, 14400 }, + { -3045, 14400, 14700 }, + { -3000, 38399, 39600 }, + { -2940, 4800, 5400 }, + { -2940, 7680, 7349 }, + { -2940, 7680, 8100 }, + { -2890, 3299, 4199 }, + { -2880, 27599, 28200 }, + { -2790, 8100, 8699 }, + { -2760, 5400, 6150 }, + { -2730, 29557, 32099 }, + { -2730, 32099, 32400 }, + { -2730, 34500, 32400 }, + { -2730, 34500, 36599 }, + { -2730, 38399, 36599 }, + { -2640, 6150, 6960 }, + { -2580, 8699, 9000 }, + { -2580, 10800, 9000 }, + { -2580, 11849, 10800 }, + { -2580, 14400, 15060 }, + { -2520, 25500, 26850 }, + { -2520, 28200, 28800 }, + { -2520, 29557, 28800 }, + { -2400, 3000, 41999 }, + { -2400, 4199, 3000 }, + { -2400, 4199, 5400 }, + { -2400, 6960, 7680 }, + { -2385, 16860, 19800 }, + { -2374, 5400, 6300 }, + { -2220, 8249, 7680 }, + { -2220, 32099, 34500 }, + { -2220, 38399, 41400 }, + { -2220, 41999, 41400 }, + { -2205, 16860, 15060 }, + { -2160, 6300, 6750 }, + { -2100, 19800, 19499 }, + { -2100, 22050, 19800 }, + { -1980, 11010, 11849 }, + { -1980, 13260, 11849 }, + { -1980, 22649, 22050 }, + { -1870, 19499, 19049 }, + { -1800, 8460, 8249 }, + { -1800, 30150, 31680 }, + { -1800, 31680, 32099 }, + { -1770, 26850, 22649 }, + { -1770, 26850, 28200 }, + { -1770, 28800, 28200 }, + { -1750, 19049, 18450 }, + { -1680, 36000, 36599 }, + { -1680, 36599, 38399 }, + { -1635, 8699, 8460 }, + { -1635, 8699, 9000 }, + { -1635, 9000, 11010 }, + { -1590, 18450, 17550 }, + { -1530, 3000, 42899 }, + { -1530, 38399, 39360 }, + { -1530, 41400, 39360 }, + { -1530, 41400, 42899 }, + { -1530, 42899, 3000 }, + { -1530, 42899, 41400 }, + { -1474, 29280, 30150 }, + { -1470, 19499, 21299 }, + { -1470, 21299, 22649 }, + { -1470, 25650, 26850 }, + { -1462, 3000, 4770 }, + { -1462, 4770, 6750 }, + { -1440, 16349, 16860 }, + { -1440, 17550, 16860 }, + { -1320, 22649, 23099 }, + { -1320, 23099, 25650 }, + { -1200, 28200, 28650 }, + { -1155, 29280, 29475 }, + { -1140, 15449, 16349 }, + { -1140, 19350, 19499 }, + { -1095, 29280, 29475 }, + { -1020, 15060, 15449 }, + { -960, 30900, 31680 }, + { -960, 32850, 31680 }, + { -960, 32850, 33960 }, + { -900, 38399, 36959 }, + { -870, 8850, 8699 }, + { -721, 36000, 33960 }, + { -700, 31649, 31800 }, + { -660, 9149, 8850 }, + { -660, 10499, 9149 }, + { -660, 11010, 10499 }, + { -660, 11010, 13260 }, + { -660, 14549, 13260 }, + { -660, 15060, 14549 }, + { -660, 17249, 19350 }, + { -660, 23099, 21299 }, + { -600, 30900, 31649 }, + { -600, 31800, 32340 }, + { -540, 36959, 36000 }, + { -540, 39360, 38399 }, + { -480, 26400, 25650 }, + { -480, 28650, 29280 }, + { -420, 599, 42899 }, + { -360, 20730, 19350 }, + { -360, 21299, 20730 }, + { -240, 8400, 9149 }, + { -240, 10499, 11235 }, + { -240, 32099, 32340 }, + { -240, 33449, 32850 }, + { -240, 33960, 33449 }, + { -240, 40950, 42899 }, + { -195, 28650, 27149 }, + { -195, 28650, 29280 }, + { -105, 4770, 5909 }, + { -105, 5909, 6449 }, + { 0, 6449, 8310 }, + { 0, 8310, 8400 }, + { 0, 12960, 14549 }, + { 0, 27149, 26400 }, + { 0, 32099, 32850 }, + { 90, 12630, 12960 }, + { 105, 39000, 39600 }, + { 120, 599, 3600 }, + { 120, 33449, 33960 }, + { 120, 36540, 36959 }, + { 120, 36959, 37499 }, + { 120, 37499, 38399 }, + { 120, 38399, 38640 }, + { 120, 39600, 40950 }, + { 165, 38640, 39000 }, + { 180, 32850, 33165 }, + { 240, 28949, 29280 }, + { 240, 29280, 30150 }, + { 270, 33165, 32850 }, + { 330, 12600, 12630 }, + { 360, 37499, 37575 }, + { 375, 32850, 33591 }, + { 375, 33591, 33960 }, + { 420, 14265, 14549 }, + { 420, 14549, 16650 }, + { 420, 16650, 17249 }, + { 420, 17249, 19350 }, + { 450, 40950, 42899 }, + { 480, 24300, 27149 }, + { 510, 36255, 36540 }, + { 595, 3000, 3600 }, + { 595, 3600, 5909 }, + { 600, 0, 42899 }, + { 600, 11235, 11354 }, + { 600, 12479, 12600 }, + { 600, 14054, 14265 }, + { 600, 42899, 0 }, + { 660, 20730, 21360 }, + { 709, 37575, 37890 }, + { 709, 37890, 38010 }, + { 720, 11354, 12479 }, + { 720, 32850, 33591 }, + { 720, 33591, 33960 }, + { 750, 0, 255 }, + { 750, 10080, 10380 }, + { 750, 12600, 13500 }, + { 750, 38010, 38399 }, + { 769, 30150, 31050 }, + { 810, 13500, 14054 }, + { 840, 21360, 23099 }, + { 859, 31050, 32850 }, + { 900, 23099, 24300 }, + { 930, 8310, 8940 }, + { 930, 9599, 10080 }, + { 945, 35699, 36255 }, + { 945, 36255, 36450 }, + { 960, 8940, 9599 }, + { 960, 28650, 28949 }, + { 970, 34200, 35699 }, + { 1050, 11190, 11354 }, + { 1080, 10260, 10380 }, + { 1110, 33960, 34200 }, + { 1140, 5909, 6060 }, + { 1150, 34650, 35699 }, + { 1170, 37020, 37890 }, + { 1170, 37890, 38250 }, + { 1200, 14054, 14189 }, + { 1230, 36450, 37020 }, + { 1260, 255, 1530 }, + { 1264, 33960, 34650 }, + { 1275, 35699, 36450 }, + { 1290, 10589, 11190 }, + { 1320, 120, 255 }, + { 1320, 28650, 28859 }, + { 1369, 10260, 10589 }, + { 1410, 18900, 19350 }, + { 1410, 38250, 38550 }, + { 1425, 1290, 1530 }, + { 1500, 3000, 3450 }, + { 1530, 19350, 19800 }, + { 1530, 33960, 34664 }, + { 1560, 27149, 27329 }, + { 1560, 27329, 28859 }, + { 1560, 28859, 29100 }, + { 1560, 33060, 33960 }, + { 1620, 29100, 29399 }, + { 1635, 3450, 4350 }, + { 1650, 34664, 35400 }, + { 1680, 0, 120 }, + { 1680, 2534, 3000 }, + { 1680, 10589, 11759 }, + { 1680, 14189, 14400 }, + { 1680, 37650, 38550 }, + { 1680, 38550, 39119 }, + { 1710, 8550, 10589 }, + { 1710, 17789, 18900 }, + { 1710, 23850, 24300 }, + { 1710, 24300, 25124 }, + { 1740, 19800, 21360 }, + { 1740, 21360, 21600 }, + { 1740, 35400, 37650 }, + { 1800, 8100, 8550 }, + { 1800, 32715, 33060 }, + { 1800, 34664, 34844 }, + { 1840, 4350, 4890 }, + { 1840, 4890, 6060 }, + { 1840, 6060, 8100 }, + { 1845, 25124, 25259 }, + { 1879, 0, 42750 }, + { 1920, 22199, 23850 }, + { 1924, 42300, 42750 }, + { 1980, 1290, 2534 }, + { 1980, 27329, 27779 }, + { 2010, 13950, 14400 }, + { 2010, 14400, 16650 }, + { 2010, 16650, 17789 }, + { 2040, 4620, 4890 }, + { 2040, 19409, 19800 }, + { 2040, 21600, 22199 }, + { 2070, 41070, 41160 }, + { 2070, 41160, 42300 }, + { 2100, 2534, 3600 }, + { 2100, 39600, 41070 }, + { 2130, 11759, 13260 }, + { 2130, 13260, 13950 }, + { 2160, 8100, 8445 }, + { 2160, 39119, 39375 }, + { 2160, 39375, 39600 }, + { 2190, 34844, 34920 }, + { 2205, 3600, 4530 }, + { 2205, 4530, 4620 }, + { 2385, 16650, 17249 }, + { 2400, 18300, 19409 }, + { 2400, 27779, 28350 }, + { 2400, 28350, 29399 }, + { 2520, 16500, 17249 }, + { 2520, 17249, 18300 }, + { 2610, 34500, 34920 }, + { 2625, 39375, 39434 }, + { 2640, 39434, 39540 }, + { 2670, 12240, 13260 }, + { 2700, 21600, 21749 }, + { 2760, 300, 1560 }, + { 2820, 3000, 3675 }, + { 2820, 15150, 16500 }, + { 2850, 32715, 32819 }, + { 2850, 32819, 34349 }, + { 2850, 34349, 34500 }, + { 2880, 300, 42449 }, + { 2880, 1560, 2010 }, + { 2880, 42449, 300 }, + { 2910, 24300, 25259 }, + { 3000, 2010, 2460 }, + { 3000, 2460, 3000 }, + { 3000, 11700, 12240 }, + { 3000, 41999, 42449 }, + { 3030, 3675, 4530 }, + { 3030, 30600, 32819 }, + { 3090, 28350, 30600 }, + { 3150, 5999, 8445 }, + { 3150, 8445, 9000 }, + { 3150, 41160, 41999 }, + { 3165, 39540, 39839 }, + { 3180, 21749, 24300 }, + { 3180, 27450, 28350 }, + { 3240, 2460, 3060 }, + { 3240, 10980, 11700 }, + { 3289, 37080, 39540 }, + { 3300, 5700, 5999 }, + { 3300, 39839, 40170 }, + { 3330, 25259, 25950 }, + { 3330, 25950, 27450 }, + { 3330, 34349, 34950 }, + { 3360, 9000, 10980 }, + { 3375, 40170, 41160 }, + { 3420, 4379, 5580 }, + { 3420, 5580, 5700 }, + { 3450, 3060, 3434 }, + { 3480, 34950, 35580 }, + { 3510, 3434, 4379 }, + { 3544, 41160, 41700 }, + { 3570, 35580, 36000 }, + { 3570, 36000, 36966 }, + { 3600, 12600, 14340 }, + { 3600, 14340, 15150 }, + { 3655, 36966, 37080 }, + { 3690, 36000, 36750 }, + { 3720, 10980, 12600 }, + { 3780, 24300, 25950 }, + { 3780, 41700, 42449 }, + { 3840, 21600, 24300 }, + { 3960, 599, 42449 }, + { 3960, 25200, 28200 }, + { 3960, 42449, 599 }, + { 3990, 20399, 21600 }, + { 4020, 36750, 37200 }, + { 4080, 5580, 6150 }, + { 4200, 23400, 25200 }, + { 4200, 28200, 29759 }, + { 4410, 14340, 16500 }, + { 4410, 16500, 20399 }, + { 4500, 29759, 31500 }, + { 4500, 36300, 37200 }, + { 4620, 599, 6150 }, + { 4620, 6150, 6314 }, + { 4620, 20700, 23400 }, + { 4620, 24449, 23400 }, + { 4800, 6314, 9000 }, + { 4800, 19200, 20700 }, + { 4800, 26100, 24449 }, + { 4800, 31500, 32400 }, + { 4800, 36300, 37800 }, + { 4920, 16500, 19200 }, + { 5100, 9000, 14400 }, + { 5160, 32400, 37800 }, + { 5169, 37800, 41400 }, + { 5190, 14400, 26100 }, + { 5280, 6300, 14400 }, + { 5280, 41400, 6300 }, +}; + +#define NDEC ((int)(sizeof(dec_edges)/sizeof(dec_edges[0]))) + +/* given an epoch, give caller a list of all constellation edges. + * return count if ok, else -1. + * N.B. caller should *not* free what we return because we cache it here. + */ +int +cns_edges (double e, double **ra0p, double **dec0p, double **ra1p, +double **dec1p) +{ +#define NEDGES (NRA+NDEC) + static double *ra0, *dec0, *ra1, *dec1; + static double laste = -12345.6; /* any bogus value */ + double mjd0; + int i, n; + + /* if same epoch just return the same list */ + if (e == laste) { + *ra0p = ra0; + *dec0p = dec0; + *ra1p = ra1; + *dec1p = dec1; + return (NEDGES); + } + + /* get space for arrays, first time only */ + if (!ra0) { + ra0 = (double *)malloc (NEDGES * sizeof(double)); + if (!ra0) + return (-1); + dec0 = (double *)malloc (NEDGES * sizeof(double)); + if (!dec0) { + free ((void *)ra0); + return (-1); + } + ra1 = (double *)malloc (NEDGES * sizeof(double)); + if (!ra1) { + free ((void *)ra0); + free ((void *)dec0); + return (-1); + } + dec1 = (double *)malloc (NEDGES * sizeof(double)); + if (!dec1) { + free ((void *)ra0); + free ((void *)dec0); + free ((void *)ra1); + return (-1); + } + } + + /* prepare for precession from 1875 */ + cal_mjd (1, 1.0, 1875, &mjd0); + + /* build the constant-ra edge lists */ + n = 0; + for (i = 0; i < NRA; i++) { + ra0[n] = ra1[n] = hrrad((double)ra_edges[i].ra/1800.0); + dec0[n] = degrad((double)ra_edges[i].dec0/60.0); + dec1[n] = degrad((double)ra_edges[i].dec1/60.0); + precess (mjd0, e, &ra0[n], &dec0[n]); + precess (mjd0, e, &ra1[n], &dec1[n]); + n++; + } + + /* add the constant-dec edge lists */ + for (i = 0; i < NDEC; i++) { + ra0[n] = hrrad((double)dec_edges[i].ra0/1800.0); + ra1[n] = hrrad((double)dec_edges[i].ra1/1800.0); + dec0[n] = dec1[n] = degrad((double)dec_edges[i].dec/60.0); + precess (mjd0, e, &ra0[n], &dec0[n]); + precess (mjd0, e, &ra1[n], &dec1[n]); + n++; + } + + /* sanity check the count */ + if (n != NEDGES) { + printf ("cns_edges(): n=%d NEDGES=%ld\n", n, (long)NEDGES); + abort(); + } + + /* ok */ + *ra0p = ra0; + *dec0p = dec0; + *ra1p = ra1; + *dec1p = dec1; + laste = e; + return (NEDGES); +} + +/* given an ra, dec and epoch return the list of constellation ids which + * *may* fall within the given radius of said location. + * return the number of ids. + * ids[] need be no larger than 89. + */ +/* ARGSUSED */ +int +cns_list (double ra, double dec, double e, double rad, int ids[]) +{ + int i; + + /* TODO: this! */ + for (i = 0; i < NCNS; i++) + ids[i] = i; + return (NCNS); +} + +/* epoch 2000 RA/Dec of constellation figure end-points. + * drawcodes: 0=move to; 1=draw to; 2=draw to dashed; -1=end + */ +typedef struct { + int drawcode; /* draw code */ + float ra; /* rads */ + float dec; /* rads */ +} ConFig; + +/* array of malloced lists of ConFigs, same order as cns_namemap[] + */ +static ConFig *figmap[NCNS]; + +/* add one entry to the drawing code lists */ +static void +addFigList (ConFig **new, int *nused, int c, int drawcode, double ra, double dec) +{ + ConFig *cp; + + new[c]= (ConFig*) realloc (new[c], (nused[c]+1)*sizeof(ConFig)); + cp = &new[c][nused[c]++]; + cp->drawcode = drawcode; + cp->ra = (float)hrrad(ra); + cp->dec = (float)degrad(dec); +} + +/* load the given constellation definition file. + * return 0 if ok else reason why not in msg[] and -1. + */ +int +cns_loadfigs (FILE *fp, char *msg) +{ + char line[1024]; /* one line from the file */ + char cname[1024]; /* constellation name */ + ConFig **new; /* array of ConFig[] for each cnstn */ + int *nused; /* number of ConFig[] for each cnstn */ + int c = -1; /* index, same as cns_namemap[] */ + int s = 0; /* status */ + + /* init the temp lists */ + new = (ConFig **) calloc (NCNS, sizeof(ConFig*)); + nused = (int *) calloc (NCNS, sizeof(int)); + + /* read the file */ + while (fgets (line, sizeof(line), fp)) { + char rastr[64], decstr[64]; + char *lp; + int code; + + /* skip leading/trailing whitespace, blank lines and # lines */ + for (lp = line+strlen(line)-1; lp>=line && isspace(*lp); --lp) + *lp = '\0'; + for (lp = line; isspace(*lp); lp++) + continue; + if (*lp == '#' || *lp == '\0') + continue; + + /* ok, line looks interesting, look more carefully */ + if (sscanf (lp, "%d %s %s", &code, rastr, decstr) == 3) { + /* looks like a drawing line */ + double ra, dec; + + /* must be working on a current constellation */ + if (c < 0) { + sprintf (msg,"Found coord line before first constellation"); + s = -1; + break; + } + + /* check draw code */ + if (code < 0 || code > 2) { + sprintf (msg, "Bad draw code in %s: %d", cname, code); + s = -1; + break; + } + + /* crack ra dec */ + if (f_scansexa (rastr, &ra) < 0 || ra < 0 || ra >= 24) { + sprintf (msg, "Bad RA format in %s: %s", cname, rastr); + s = -1; + break; + } + if (f_scansexa (decstr, &dec) < 0 || dec < -90 || dec > 90) { + sprintf (msg, "Bad Dec format in %s: %s", cname, decstr); + s = -1; + break; + } + + /* add to list */ + addFigList (new, nused, c, code, ra, dec); + + } else { + /* finish previous list, if any */ + if (c >= 0) + addFigList (new, nused, c, -1, 0.0, 0.0); + + /* see if it's a recognized constellation name */ + for (c = 0; c < NCNS; c++) + if (strcmp (lp, cns_namemap[c]+5) == 0) + break; + if (c == NCNS) { + sprintf (msg, "Unknown constellation: %s", lp); + s = -1; + break; + } + if (new[c]) { + sprintf (msg, "Duplicate definition for %s", lp); + s = -1; + break; + } + + /* init its list */ + strcpy (cname, lp); + new[c] = (ConFig *) malloc (1); /* realloc seed */ + } + } + + /* even if ok check we found all definitions */ + if (s == 0) { + int l = 0; + + /* finish last list */ + addFigList (new, nused, c, -1, 0.0, 0.0); + + for (c = 0; c < NCNS; c++) + if (!new[c]) + l += sprintf (msg+l, "%s ", cns_namemap[c]+5); + if (l > 0) { + strcat (msg, ": no definition found"); + s = -1; + } + } + + /* handle ok or error */ + if (s < 0) { + /* trouble: free temp lists */ + for (c = 0; c < NCNS; c++) + if (new[c]) + free (new[c]); + } else { + /* make temp lists persistent */ + for (c = 0; c < NCNS; c++) { + if (figmap[c]) + free (figmap[c]); + figmap[c] = new[c]; + } + } + + /* done with lists themselves regardless */ + free (new); + free (nused); + + /* done */ + return (s); +} + +/* given a constellation id and epoch, return arrays of ra[] and dec[] + * end-points precessed to the desired epoch that, if connected, will form the + * given constellation figure. + * dcodes is 0 if the coord is a "move-to", 1 if a "draw-to" or 2 if a "draw-to + * as dotted-line". + * return the total number of tripples or -1 if id is bogus. + * the arrays need be no larger than 35 entries. + */ +int +cns_figure (int id, double e, double ra[], double dec[], int dcodes[]) +{ + ConFig *cfp; + + if (id < 0 || id >= NCNS) + return (-1); + + for (cfp = figmap[id]; cfp->drawcode >= 0; cfp++) { + *ra = (double)cfp->ra; + *dec = (double)cfp->dec; + precess (J2000, e, ra, dec); + ra++; + dec++; + *dcodes++ = cfp->drawcode; + } + + return (cfp - figmap[id]); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: constel.c,v $ $Date: 2005/03/05 06:55:22 $ $Revision: 1.13 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/dbfmt.c b/Common/Libraries/XEphemAstroLib/src/dbfmt.c new file mode 100644 index 000000000..a562493fb --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/dbfmt.c @@ -0,0 +1,1029 @@ +/* code to convert between .edb format and an Obj */ + +#include <stdio.h> +#include <ctype.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#include "astro.h" +#include "preferences.h" + + +int get_fields (char *s, int delim, char *fields[]); + +#define MAXDBLINE 512 /* longest allowed db line */ + +#define FLDSEP ',' /* major field separator */ +#define SUBFLD '|' /* subfield separator */ +#define MAXFLDS 20 /* must be more than on any expected line */ +#define MAXESGOOD 100 /* max earth satellite good, days */ + +static char *enm (char *flds[MAXFLDS]); +static int crack_f (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]); +static int crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]); +static int crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]); +static int crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]); +static int crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]); +static int crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]); +static int crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]); +static int crack_name (Obj *op, char *flds[MAXFLDS], int nf, + char nm[][MAXNM], int nnm); +static void crack_year (char *bp, double *p); +static void crack_okdates (char *fld, float *startok, float *endok); +static int get_okdates (char *lp, float *sp, float *ep); +static int tle_sum (char *l); +static double tle_fld (char *l, int from, int thru); +static double tle_expfld (char *l, int start); +static void write_f (Obj *op, char lp[]); +static void write_e (Obj *op, char lp[]); +static void write_h (Obj *op, char lp[]); +static void write_p (Obj *op, char lp[]); +static void write_E (Obj *op, char lp[]); +static void write_P (Obj *op, char lp[]); +static void write_B (Obj *op, char lp[]); + +/* crack the given .edb database line into op. + * if ok + * return number of names in nm[], or 1 if nm == NULL + * else + * if whynot + * if not even a candidate + * set whynot[0] = '\0' + * else + * fill whynot with reason message. + * return -1 + * only the first name is stored in op, all names (up to nnm) are in nm[], or + * ignored if nm == NULL. + */ +int +db_crack_line (char s[], Obj *op, char nm[][MAXNM], int nnm, char whynot[]) +{ + char copy[MAXDBLINE]; /* work copy; leave s untouched */ + char *flds[MAXFLDS]; /* point to each field for easy reference */ + int nf; + int i; + + /* init no response */ + if (whynot) + whynot[0] = '\0'; + + /* basic initial check */ + if (dbline_candidate (s) < 0) + return (-1); + + /* do all the parsing on a copy */ + (void) strncpy (copy, s, MAXDBLINE-1); + copy[MAXDBLINE-1] = '\0'; + i = strlen(copy); + if (copy[i-1] == '\n') + copy[i-1] = '\0'; + + /* parse into main fields */ + nf = get_fields (copy, FLDSEP, flds); + + /* need at least 2: name and type */ + if (nf < 2) { + if (whynot) + sprintf (whynot, "Bogus: %s", s); + return (-1); + } + + /* switch out on type of object - the second field */ + switch (flds[1][0]) { + + case 'f': + if (crack_f (op, flds, nf, whynot) < 0) + return (-1); + break; + + case 'e': + if (crack_e (op, flds, nf, whynot) < 0) + return (-1); + break; + + case 'h': + if (crack_h (op, flds, nf, whynot) < 0) + return (-1); + break; + + case 'p': + if (crack_p (op, flds, nf, whynot) < 0) + return (-1); + break; + + case 'B': + if (crack_B (op, flds, nf, whynot) < 0) + return (-1); + break; + + case 'E': + if (crack_E (op, flds, nf, whynot) < 0) + return (-1); + break; + + case 'P': + if (crack_P (op, flds, nf, whynot) < 0) + return (-1); + break; + + default: + if (whynot) + sprintf (whynot, "%s: Unknown type %c for %s", enm(flds), + flds[1][0], flds[0]); + return (-1); + } + + return (crack_name (op, flds, nf, nm, nnm)); +} + +/* write the given Obj in .edb format to lp[]. + * we do _not_ include a trailing '\n'. + */ +void +db_write_line (Obj *op, char lp[]) +{ + switch (op->o_type) { + case FIXED: + write_f (op, lp); + break; + + case BINARYSTAR: + write_B (op, lp); + break; + + case ELLIPTICAL: + write_e (op, lp); + break; + + case HYPERBOLIC: + write_h (op, lp); + break; + + case PARABOLIC: + write_p (op, lp); + break; + + case EARTHSAT: + write_E (op, lp); + break; + + case PLANET: + write_P (op, lp); + break; + + default: + printf ("Unknown type for %s: %d\n", op->o_name, op->o_type); + abort(); + } +} + +/* given 3 lines, first of which is name and next 2 are TLE, fill op. + * we skip leading whitespace on all lines. + * we do /not/ assume the 2 TLE lines are 0 terminated, but we do reach out into + * each as far as 69 chars. + * we detect nonconformance as efficiently as possible. + * name ends at first '\0', '\r' or '\n'. + * set startok/endok. + * if ok return 0 else return -1 + */ +int +db_tle (char *name, char *l1, char *l2, Obj *op) +{ + double ep; + int i; + + /* check for correct line numbers, macthing satellite numbers and + * correct checksums. + */ + while (isspace(*l1)) + l1++; + if (*l1 != '1') + return (-1); + while (isspace(*l2)) + l2++; + if (*l2 != '2') + return (-1); + if (strncmp (l1+2, l2+2, 5)) + return (-1); + if (tle_sum (l1) < 0) + return (-1); + if (tle_sum (l2) < 0) + return (-1); + + /* assume it's ok from here out */ + + /* fresh */ + zero_mem ((void *)op, sizeof(ObjES)); + op->o_type = EARTHSAT; + + /* name, sans leading and trailing whitespace */ + while (isspace(*name)) + name++; + i = strcspn (name, "\r\n"); + while (i > 0 && name[i-1] == ' ') + --i; + if (i == 0) + return (-1); + if (i > MAXNM-1) + i = MAXNM-1; + sprintf (op->o_name, "%.*s", i, name); + + /* goodies from "line 1" */ + op->es_drag = (float) tle_expfld (l1, 54); + op->es_decay = (float) tle_fld (l1, 34, 43); + i = (int) tle_fld (l1, 19, 20); + if (i < 57) + i += 100; + cal_mjd (1, tle_fld(l1, 21, 32), i+1900, &ep); + op->es_epoch = ep; + + /* goodies from "line 2" */ + op->es_n = tle_fld (l2, 53, 63); + op->es_inc = (float)tle_fld (l2, 9, 16); + op->es_raan = (float)tle_fld (l2, 18, 25); + op->es_e = (float)(tle_fld (l2, 27, 33) * 1e-7); + op->es_ap = (float)tle_fld (l2, 35, 42); + op->es_M = (float)tle_fld (l2, 44, 51); + op->es_orbit = (int)tle_fld (l2, 64, 68); + + /* limit date range to decay period that changes period by 1% but + * never more than MAXESGOOD. + * es_n is rev/day, es_decay is (rev/day)/day + */ + if (fabs(op->es_decay) > 0) { + double dt = 0.01*op->es_n/fabs(op->es_decay); + if (dt > MAXESGOOD) + dt = MAXESGOOD; + op->es_startok = op->es_epoch - dt; + op->es_endok = op->es_epoch + dt; + } + + /* yes! */ + return (0); +} + +/* return 0 if op has no date range information or what it does have brackets + * now, else -1 + */ +int +dateRangeOK (Now *np, Obj *op) +{ + float *sp, *ep; + + switch (op->o_type) { + case ELLIPTICAL: + sp = &op->e_startok; + ep = &op->e_endok; + break; + case HYPERBOLIC: + sp = &op->h_startok; + ep = &op->h_endok; + break; + case PARABOLIC: + sp = &op->p_startok; + ep = &op->p_endok; + break; + case EARTHSAT: + sp = &op->es_startok; + ep = &op->es_endok; + break; + default: + return (0); + } + + if (*sp <= mjd && (!*ep || mjd <= *ep)) + return (0); + return (-1); +} + +/* given a null-terminated string, fill in fields[] with the starting addresses + * of each field delimited by delim or '\0'. + * N.B. each character matching delim is REPLACED BY '\0' IN PLACE. + * N.B. 0-length fields count, so even if *s=='\0' we return 1. + * return the number of fields. + */ +int +get_fields (char *s, int delim, char *fields[]) +{ + int n; + char c; + + *fields = s; + n = 0; + do { + c = *s++; + if (c == delim || c == '\0') { + s[-1] = '\0'; + *++fields = s; + n++; + } + } while (c); + + return (n); +} + +/* return 0 if buf qualifies as a database line worthy of a cracking + * attempt, else -1. + */ +int +dbline_candidate (char *buf) +{ + char c = buf[0]; + + return (c == '#' || c == '!' || isspace(c) ? -1 : 0); +} + +/* return 0 if TLE checksum is ok, else -1 */ +static int +tle_sum (char *l) +{ + char *lastl = l + 68; + int sum; + + for (sum = 0; l < lastl; ) { + char c = *l++; + if (c == '\0') + return (-1); + if (isdigit(c)) + sum += c - '0'; + else if (c == '-') + sum++; + } + + return (*l - '0' == (sum%10) ? 0 : -1); +} + +/* extract the given columns and return value. + * N.B. from and to are 1-based within l + */ +static double +tle_fld (char *l, int from, int thru) +{ + char buf[32]; + + sprintf (buf, "%.*s", thru-from+1, l+from-1); + return (atod (buf)); +} + +/* extract the exponential value starting at the given column. + * N.B. start is 1-based within l + */ +static double +tle_expfld (char *l, int start) +{ + char buf[32]; + double v; + + sprintf (buf, ".%.*s", 5, l+start); + v = atod (buf) * pow (10.0, tle_fld(l, start+6, start+7)); + if (l[start-1] == '-') + v = -v; + return (v); +} + +static int +crack_f (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]) +{ + char *sflds[MAXFLDS]; + double tmp; + int nsf; + + if (nf < 5 || nf > 7) { + if (whynot) + sprintf (whynot, "%s: type f needs 5-7 fields, not %d", + enm(flds),nf); + return (-1); + } + + zero_mem ((void *)op, sizeof(ObjF)); + op->o_type = FIXED; + + nsf = get_fields(flds[1], SUBFLD, sflds); + if (nsf > 1) { + switch (sflds[1][0]) { + case 'A': case 'B': case 'C': case 'D': case 'F': case 'G': + case 'H': case 'K': case 'J': case 'L': case 'M': case 'N': + case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'Y': + op->f_class = sflds[1][0]; + if (op->f_class == 'B') + op->f_class = 'D'; /* merge B and D since BINARYSTAR */ + break; + default: + if (whynot) + sprintf (whynot, "%s: Bad f class: %c", enm(flds), + sflds[1][0]); + return (-1); + } + } else + op->f_class = 'T'; /* default to star-like */ + if (nsf > 2) { + /* fill f_spect all the way */ + char buf[sizeof(op->f_spect)+1]; + memset (buf, 0, sizeof(buf)); + sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]); + memcpy (op->f_spect, buf, (int)sizeof(op->f_spect)); + } + + nsf = get_fields(flds[2], SUBFLD, sflds); + f_scansexa (sflds[0], &tmp); + op->f_RA = (float) hrrad(tmp); + if (nsf > 1) + op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/ + + nsf = get_fields(flds[3], SUBFLD, sflds); + f_scansexa (sflds[0], &tmp); + op->f_dec = (float) degrad(tmp); + if (nsf > 1) + op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/ + if (fabs(op->f_dec) < PI/2) + op->f_pmRA /= cos (op->f_dec); + + set_fmag (op, atod(flds[4])); + + if (nf > 5 && flds[5][0]) { + tmp = op->f_epoch; + crack_year (flds[5], &tmp); + op->f_epoch = (float) tmp; + } else + op->f_epoch = J2000; /* default */ + + if (nf > 6) { + op->f_size = (float) atod(flds[6]); + + /* optional minor axis and position angle subfields */ + nsf = get_fields(flds[6], SUBFLD, sflds); + if (nsf == 3) { + set_ratio(op, op->s_size, atod(sflds[1])); + set_pa(op,degrad(atod(sflds[2]))); + } else { + set_ratio(op,1,1); /* round */ + set_pa(op,0.0); + } + } + + return (0); +} + +static int +crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]) +{ + if (nf != 13 && nf != 14) { + if (whynot) + sprintf (whynot, "%s: type e needs 13 or 14 fields, not %d", + enm(flds), nf); + return (-1); + } + + zero_mem ((void *)op, sizeof(ObjE)); + op->o_type = ELLIPTICAL; + + op->e_inc = (float) atod (flds[2]); + op->e_Om = (float) atod (flds[3]); + op->e_om = (float) atod (flds[4]); + op->e_a = (float) atod (flds[5]); + /* retired op->e_n = (float) atod (flds[6]); */ + op->e_e = atod (flds[7]); + op->e_M = (float) atod (flds[8]); + crack_year (flds[9], &op->e_cepoch); + crack_okdates (flds[9], &op->e_startok, &op->e_endok); + crack_year (flds[10], &op->e_epoch); + + /* magnitude model gk or HG(default). allow prefixes in either field */ + op->e_mag.whichm = flds[11][0] == 'g' ? MAG_gk : MAG_HG; + if (isdigit(flds[11][0])) + op->e_mag.m1 = (float) atod(&flds[11][0]); + else + op->e_mag.m1 = (float) atod(&flds[11][1]); + if (isdigit(flds[12][0])) + op->e_mag.m2 = (float) atod(&flds[12][0]); + else + op->e_mag.m2 = (float) atod(&flds[12][1]); + + if (nf == 14) + op->e_size = (float) atod (flds[13]); + + return (0); +} + +static int +crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]) +{ + if (nf != 11 && nf != 12) { + if (whynot) + sprintf (whynot, "%s: type h needs 11 or 12 fields, not %d", + enm(flds), nf); + return (-1); + } + + zero_mem ((void *)op, sizeof(ObjH)); + op->o_type = HYPERBOLIC; + + crack_year (flds[2], &op->h_ep); + crack_okdates (flds[2], &op->h_startok, &op->h_endok); + op->h_inc = (float) atod (flds[3]); + op->h_Om = (float) atod (flds[4]); + op->h_om = (float) atod (flds[5]); + op->h_e = (float) atod (flds[6]); + op->h_qp = (float) atod (flds[7]); + crack_year (flds[8], &op->h_epoch); + op->h_g = (float) atod (flds[9]); + op->h_k = (float) atod (flds[10]); + + if (nf == 12) + op->h_size = (float) atod (flds[11]); + + return (0); +} + +static int +crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]) +{ + if (nf != 10 && nf != 11) { + if (whynot) + sprintf (whynot, "%s: type p needs 10 or 11 fields, not %d", + enm(flds), nf); + return (-1); + } + + zero_mem ((void *)op, sizeof(ObjP)); + op->o_type = PARABOLIC; + + crack_year (flds[2], &op->p_ep); + crack_okdates (flds[2], &op->p_startok, &op->p_endok); + op->p_inc = (float) atod (flds[3]); + op->p_om = (float) atod (flds[4]); + op->p_qp = (float) atod (flds[5]); + op->p_Om = (float) atod (flds[6]); + crack_year (flds[7], &op->p_epoch); + op->p_g = (float) atod (flds[8]); + op->p_k = (float) atod (flds[9]); + + if (nf == 11) + op->p_size = (float) atod (flds[10]); + + return (0); +} + +static int +crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]) +{ + if (nf != 11 && nf != 12) { + if (whynot) + sprintf (whynot, "%s: type E needs 11 or 12 fields, not %d", + enm(flds), nf); + return (-1); + } + + zero_mem ((void *)op, sizeof(ObjES)); + op->o_type = EARTHSAT; + crack_year (flds[2], &op->es_epoch); + crack_okdates (flds[2], &op->es_startok, &op->es_endok); + op->es_inc = (float) atod (flds[3]); + op->es_raan = (float) atod (flds[4]); + op->es_e = (float) atod (flds[5]); + op->es_ap = (float) atod (flds[6]); + op->es_M = (float) atod (flds[7]); + op->es_n = atod (flds[8]); + op->es_decay = (float) atod (flds[9]); + op->es_orbit = atoi (flds[10]); + if (nf == 12) + op->es_drag = (float) atod (flds[11]); + + /* if not already specified, limit date range to decay period that + * changes period by 1% but never longer than MAXESGOOD. + * es_n is rev/day, es_decay is (rev/day)/day + */ + if (op->es_startok == 0 && op->es_endok == 0 && fabs(op->es_decay) > 0){ + double dt = 0.01*op->es_n/fabs(op->es_decay); + if (dt > MAXESGOOD) + dt = MAXESGOOD; + op->es_startok = op->es_epoch - dt; + op->es_endok = op->es_epoch + dt; + } + + return (0); +} + +static int +crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]) +{ + Obj *bi; + int nbi; + int i; + + nbi = getBuiltInObjs (&bi); + + for (i = 0; i < nbi; i++) { + Obj *bop = bi + i; + if (is_type(bop,PLANETM) && !strcmp (flds[0], bop->o_name)) { + memcpy ((void *)op, bop, sizeof(ObjPl)); + return (0); + } + } + + if (whynot) + sprintf (whynot, "%s: Unknown planet or moon", enm(flds)); + return (-1); +} + +static int +crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]) +{ + char *sflds[MAXFLDS]; + double tmp; + int nsf; + + if (nf != 7) { + if (whynot) + sprintf (whynot, "%s: B need 7 fields, not %d", enm(flds), nf); + return (-1); + } + + zero_mem ((void *)op, sizeof(ObjB)); + op->o_type = BINARYSTAR; + + nsf = get_fields(flds[1], SUBFLD, sflds); + if (nsf > 1) { + switch (sflds[1][0]) { + case 'a': case 'c': case 'e': case 'x': case 'y': case 'o': + case 's': case 't': case 'u': case 'v': case 'b': case 'd': + case 'q': case 'r': case 'p': case 'U': case 'V': case 'Y': + op->f_class = sflds[1][0]; + break; + default: + if (whynot) + sprintf (whynot, "%s: Bad B class: %c", enm(flds), + sflds[1][0]); + return (-1); + } + } + if (nsf > 2) { + /* fill f_spect all the way */ + char buf[sizeof(op->f_spect)+1]; + memset (buf, 0, sizeof(buf)); + sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]); + memcpy (op->f_spect, buf, (int)sizeof(op->f_spect)); + } + if (nsf > 3) { + /* fill b_2spect all the way */ + char buf[sizeof(op->b_2spect)+1]; + memset (buf, 0, sizeof(buf)); + sprintf (buf, "%.*s", (int)sizeof(op->b_2spect), sflds[3]); + memcpy (op->b_2spect, buf, (int)sizeof(op->b_2spect)); + } + + nsf = get_fields(flds[2], SUBFLD, sflds); + f_scansexa (sflds[0], &tmp); + op->f_RA = (float) hrrad(tmp); + if (nsf > 1) + op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/ + + nsf = get_fields(flds[3], SUBFLD, sflds); + f_scansexa (sflds[0], &tmp); + op->f_dec = (float) degrad(tmp); + if (nsf > 1) + op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/ + if (fabs(op->f_dec) < PI/2) + op->f_pmRA /= cos (op->f_dec); + + nsf = get_fields(flds[4], SUBFLD, sflds); + if (nsf > 0) + set_fmag (op, atod(sflds[0])); + if (nsf > 1) + op->b_2mag = (short)floor((atod(sflds[1]))*MAGSCALE + 0.5); + + if (flds[5][0]) { + tmp = op->f_epoch; + crack_year (flds[5], &tmp); + op->f_epoch = (float) tmp; + } else + op->f_epoch = J2000; /* default */ + + nsf = get_fields(flds[6], SUBFLD, sflds); + if (nsf == 7) { + int l; + char c; + + op->b_bo.bo_a = atod(sflds[0]); + op->b_bo.bo_i = atod(sflds[1]); + op->b_bo.bo_O = atod(sflds[2]); + op->b_bo.bo_e = atod(sflds[3]); + op->b_bo.bo_T = atod(sflds[4]); + op->b_bo.bo_o = atod(sflds[5]); + op->b_bo.bo_P = atod(sflds[6]); + + /* reject some weird entries actually seen in real lists */ + if (op->b_bo.bo_a <= 0) { + if (whynot) + sprintf (whynot, "%s: Bogus B semi major axis: %g", + enm(flds), op->b_bo.bo_a); + return (-1); + } + if (op->b_bo.bo_P <= 0) { + if (whynot) + sprintf (whynot, "%s: Bogus B period: %g", enm(flds), + op->b_bo.bo_P); + return (-1); + } + + /* scale period */ + l = strlen (sflds[6]); + c = sflds[6][l-1]; + switch (c) { + case 'y': case 'Y': + break; + case 'h': case 'H': + op->b_bo.bo_P /= (24.0*365.25); + break; + case 'd': case 'D': + op->b_bo.bo_P /= 365.25; + break; + default: + if (c != ' ' && !isdigit(c)) { + if (whynot) + sprintf (whynot,"%s: B period suffix not Y, D or H: %c", + enm(flds), c); + return (-1); + } + } + + } else if (nsf==3 || nsf==6 || nsf==9) { + double yr; + int i; + + op->b_nbp = nsf/3; + for (i = 0; i < nsf; i += 3) { + tmp = 0; + crack_year (sflds[i+0], &tmp); + mjd_year (tmp, &yr); + op->b_bp[i/3].bp_ep = (float)yr; + op->b_bp[i/3].bp_sep = atod(sflds[i+1]); + op->b_bp[i/3].bp_pa = degrad(atod(sflds[i+2])); + } + } else { + if (whynot) + sprintf (whynot, + "%s: type B needs 3,6 or 7 subfields in field 7, not %d", + enm(flds), nsf); + return (-1); + } + + return (0); +} + +/* put all names in nm but load only the first into o_name */ +static int +crack_name (Obj *op, char *flds[MAXFLDS], int nf, char nm[][MAXNM], int nnm) +{ + char *sflds[MAXFLDS]; + int nsf; + int i; + + nsf = get_fields (flds[0], SUBFLD, sflds); + for (i = 0; nm && i < nsf && i < nnm; i++) { + strncpy (nm[i], sflds[i], MAXNM); + nm[i][MAXNM-1] = '\0'; + } + strncpy (op->o_name, sflds[0], MAXNM-1); + return (nsf); +} + +/* simple name cracker just for error messages */ +static char * +enm (char *flds[MAXFLDS]) +{ + char *sflds[MAXFLDS]; + int nsf = get_fields (flds[0], SUBFLD, sflds); + return (nsf > 0 ? sflds[0] : "Unknown"); +} + +/* given either a decimal year (xxxx[.xxx]) or a calendar (x/x/x) date + * convert it to an mjd and store it at *p. + */ +static void +crack_year (char *bp, double *p) +{ + int m, y; + double d; + + mjd_cal (*p, &m, &d, &y); /* init with current */ + f_sscandate (bp, PREF_MDY, &m, &d, &y); + cal_mjd (m, d, y, p); +} + +/* crack the startok and endok date fields found in several Obj types. + * set to 0 if blank or any problems. + */ +static void +crack_okdates (char *fld, float *startok, float *endok) +{ + char *sflds[MAXFLDS]; + double tmp; + int m, y; + double d; + int nsf; + + *startok = *endok = 0; + nsf = get_fields(fld, SUBFLD, sflds); + if (nsf > 1) { + d = m = y = 0; + f_sscandate (sflds[1], PREF_MDY, &m, &d, &y); + cal_mjd (m, d, y, &tmp); + *startok = (float)tmp; + if (nsf > 2) { + d = m = y = 0; + f_sscandate (sflds[2], PREF_MDY, &m, &d, &y); + cal_mjd (m, d, y, &tmp); + *endok = (float)tmp; + } + } +} + +/* add startok and endok to string at lp if non-zero. + * return number of characters added. + */ +static int +get_okdates (char *lp, float *sp, float *ep) +{ + char *lp0 = lp; + + if (*sp || *ep) { + *lp++ = '|'; + if (*sp) + lp += fs_date (lp, PREF_MDY, *sp); + if (*ep) { + *lp++ = '|'; + lp += fs_date (lp, PREF_MDY, *ep); + } + } + + return (lp - lp0); +} + +static void +write_f (Obj *op, char lp[]) +{ + double tmp; + + lp += sprintf (lp, "%s,f", op->o_name); + if (op->f_class) + lp += sprintf (lp, "|%c", op->f_class); + if (op->f_spect[0]) + lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect); + *lp++ = ','; + lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000); + if (op->f_pmRA) + lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11); + *lp++ = ','; + lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600); + if (op->f_pmdec) + lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11); + lp += sprintf (lp, ",%.2f", get_mag(op)); + mjd_year (op->f_epoch, &tmp); + lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */ + lp += sprintf (lp, ",%.7g", op->f_size); + if (op->f_size && (op->f_ratio || op->f_pa)) + lp += sprintf (lp,"|%g|%g", op->f_size*get_ratio(op), + raddeg(get_pa(op))); +} + +static void +write_e (Obj *op, char lp[]) +{ + lp += sprintf (lp, "%s,e", op->o_name); + lp += sprintf (lp, ",%.7g", op->e_inc); + lp += sprintf (lp, ",%.7g", op->e_Om); + lp += sprintf (lp, ",%.7g", op->e_om); + lp += sprintf (lp, ",%.7g", op->e_a); + lp += sprintf (lp, ",%.7g", 0.0); /* retired op->e_n */ + lp += sprintf (lp, ",%.7g", op->e_e); + lp += sprintf (lp, ",%.7g", op->e_M); + *lp++ = ','; + lp += fs_date (lp, PREF_MDY, op->e_cepoch); + lp += get_okdates (lp, &op->e_startok, &op->e_endok); + *lp++ = ','; + lp += fs_date (lp, PREF_MDY, op->e_epoch); + if (op->e_mag.whichm == MAG_gk) + lp += sprintf (lp, ",g%.7g", op->e_mag.m1); + else if (op->e_mag.whichm == MAG_HG) + lp += sprintf (lp, ",H%.7g", op->e_mag.m1); + else + lp += sprintf (lp, ",%.7g", op->e_mag.m1); + lp += sprintf (lp, ",%.7g", op->e_mag.m2); + lp += sprintf (lp, ",%.7g", op->e_size); +} + +static void +write_h (Obj *op, char lp[]) +{ + lp += sprintf (lp, "%s,h", op->o_name); + *lp++ = ','; + lp += fs_date (lp, PREF_MDY, op->h_ep); + lp += get_okdates (lp, &op->h_startok, &op->h_endok); + lp += sprintf (lp, ",%.7g", op->h_inc); + lp += sprintf (lp, ",%.7g", op->h_Om); + lp += sprintf (lp, ",%.7g", op->h_om); + lp += sprintf (lp, ",%.7g", op->h_e); + lp += sprintf (lp, ",%.7g", op->h_qp); + *lp++ = ','; + lp += fs_date (lp, PREF_MDY, op->h_epoch); + lp += sprintf (lp, ",%.7g", op->h_g); + lp += sprintf (lp, ",%.7g", op->h_k); + lp += sprintf (lp, ",%.7g", op->h_size); +} + +static void +write_p (Obj *op, char lp[]) +{ + lp += sprintf (lp, "%s,p", op->o_name); + *lp++ = ','; + lp += fs_date (lp, PREF_MDY, op->p_ep); + lp += get_okdates (lp, &op->p_startok, &op->p_endok); + lp += sprintf (lp, ",%.7g", op->p_inc); + lp += sprintf (lp, ",%.7g", op->p_om); + lp += sprintf (lp, ",%.7g", op->p_qp); + lp += sprintf (lp, ",%.7g", op->p_Om); + *lp++ = ','; + lp += fs_date (lp, PREF_MDY, op->p_epoch); + lp += sprintf (lp, ",%.7g", op->p_g); + lp += sprintf (lp, ",%.7g", op->p_k); + lp += sprintf (lp, ",%.7g", op->p_size); +} + +static void +write_E (Obj *op, char lp[]) +{ + double d; + int m, y; + + lp += sprintf (lp, "%s,E", op->o_name); + *lp++ = ','; + mjd_cal (op->es_epoch, &m, &d, &y); /* need more day prec than fs_date*/ + lp += sprintf (lp, "%d/%.12g/%d", m, d, y); + lp += get_okdates (lp, &op->es_startok, &op->es_endok); + lp += sprintf (lp, ",%.8g", op->es_inc); + lp += sprintf (lp, ",%.8g", op->es_raan); + lp += sprintf (lp, ",%.8g", op->es_e); + lp += sprintf (lp, ",%.8g", op->es_ap); + lp += sprintf (lp, ",%.8g", op->es_M); + lp += sprintf (lp, ",%.12g", op->es_n); /* double */ + lp += sprintf (lp, ",%.8g", op->es_decay); + lp += sprintf (lp, ",%d", op->es_orbit); + lp += sprintf (lp, ",%.8g", op->es_drag); +} + +static void +write_B (Obj *op, char lp[]) +{ + double tmp; + + lp += sprintf (lp, "%s,B", op->o_name); + if (op->f_class) + lp += sprintf (lp, "|%c", op->f_class); + if (op->f_spect[0]) + lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect); + if (op->b_2spect[0]) + lp += sprintf (lp, "|%.*s", (int)sizeof(op->b_2spect),op->b_2spect); + *lp++ = ','; + lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000); + if (op->f_pmRA) + lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11); + *lp++ = ','; + lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600); + if (op->f_pmdec) + lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11); + lp += sprintf (lp, ",%.2f", get_mag(op)); + lp += sprintf (lp, "|%.2f", op->b_2mag/MAGSCALE); + mjd_year (op->f_epoch, &tmp); + lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */ + if (op->b_nbp == 0) { + lp += sprintf (lp, ",%.6g", op->b_bo.bo_a); + lp += sprintf (lp, "|%.6g", op->b_bo.bo_i); + lp += sprintf (lp, "|%.6g", op->b_bo.bo_O); + lp += sprintf (lp, "|%.6g", op->b_bo.bo_e); + lp += sprintf (lp, "|%.6g", op->b_bo.bo_T); + lp += sprintf (lp, "|%.6g", op->b_bo.bo_o); + lp += sprintf (lp, "|%.6gy", op->b_bo.bo_P); + } else { + int i; + + for (i = 0; i < op->b_nbp; i++) { + BinPos *bp = &op->b_bp[i]; + lp += sprintf (lp, "%c%.6g", i==0?',':'|', bp->bp_ep); + lp += sprintf (lp, "|%.6g", bp->bp_sep); + lp += sprintf (lp, "|%.6g", raddeg(bp->bp_pa)); + } + } +} + +static void +write_P (Obj *op, char lp[]) +{ + + lp += sprintf (lp, "%s,P", op->o_name); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: dbfmt.c,v $ $Date: 2009/10/09 21:28:11 $ $Revision: 1.45 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/deep.c b/Common/Libraries/XEphemAstroLib/src/deep.c new file mode 100644 index 000000000..fcb13f5a4 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/deep.c @@ -0,0 +1,790 @@ +#include <stdlib.h> +#include <math.h> + +#include "deepconst.h" +#include "satspec.h" + +/* * DEEP SPACE 31 OCT 80 */ +/* SUBROUTINE DEEP */ +/* COMMON/E1/XMO,XNODEO,OMEGAO,EO,XINCL,XNO,XNDT2O, */ +/* 1 XNDD6O,BSTAR,X,Y,Z,XDOT,YDOT,ZDOT,EPOCH,DS50 */ +/* COMMON/C1/CK2,CK4,E6A,QOMS2T,S,TOTHRD, */ +/* 1 XJ3,XKE,XKMPER,XMNPDA,AE */ +/* COMMON/C2/DE2RA,PI,PIO2,TWOPI,X3PIO2 */ +/* DOUBLE PRECISION EPOCH, DS50 */ +/* DOUBLE PRECISION */ +/* * DAY,PREEP,XNODCE,ATIME,DELT,SAVTSN,STEP2,STEPN,STEPP */ +/* DATA ZNS, C1SS, ZES/ */ +/* A 1.19459E-5, 2.9864797E-6, .01675/ */ +/* DATA ZNL, C1L, ZEL/ */ +/* A 1.5835218E-4, 4.7968065E-7, .05490/ */ +/* DATA ZCOSIS, ZSINIS, ZSINGS/ */ +/* A .91744867, .39785416, -.98088458/ */ +/* DATA ZCOSGS, ZCOSHS, ZSINHS/ */ +/* A .1945905, 1.0, 0.0/ */ +/* DATA Q22,Q31,Q33/1.7891679E-6,2.1460748E-6,2.2123015E-7/ */ +/* DATA G22,G32/5.7686396,0.95240898/ */ +/* DATA G44,G52/1.8014998,1.0508330/ */ +/* DATA G54/4.4108898/ */ +/* DATA ROOT22,ROOT32/1.7891679E-6,3.7393792E-7/ */ +/* DATA ROOT44,ROOT52/7.3636953E-9,1.1428639E-7/ */ +/* DATA ROOT54/2.1765803E-9/ */ +/* DATA THDT/4.3752691E-3/ */ + +#define XMO (sat->elem->se_XMO) +#define XNODEO (sat->elem->se_XNODEO) +#define OMEGAO (sat->elem->se_OMEGAO) +#define EO (sat->elem->se_EO) +#define XINCL (sat->elem->se_XINCL) +#define XNO (sat->elem->se_XNO) +#define XNDT20 (sat->elem->se_XNDT20) +#define XNDD60 (sat->elem->se_XNDD60) +#define BSTAR (sat->elem->se_BSTAR) +#define EPOCH (sat->elem->se_EPOCH) + +#define ZNS (1.19459E-5) +#define C1SS (2.9864797E-6) +#define ZES (.01675) +#define ZNL (1.5835218E-4) +#define C1L (4.7968065E-7) +#define ZEL (.05490) +#define ZCOSIS (.91744867) +#define ZSINIS (.39785416) +#define ZSINGS (-.98088458) +#define ZCOSGS (.1945905) +#define ZCOSHS (1.0) +#define ZSINHS (0.0) + +#define Q22 (1.7891679E-6) +#define Q31 (2.1460748E-6) +#define Q33 (2.2123015E-7) +#define G22 (5.7686396) +#define G32 (0.95240898) +#define G44 (1.8014998) +#define G52 (1.0508330) +#define G54 (4.4108898) +#define ROOT22 (1.7891679E-6) +#define ROOT32 (3.7393792E-7) +#define ROOT44 (7.3636953E-9) +#define ROOT52 (1.1428639E-7) +#define ROOT54 (2.1765803E-9) +#define THDT (4.3752691E-3) + +#define IRESFL (sat->deep->deep_flags.IRESFL) +#define ISYNFL (sat->deep->deep_flags.ISYNFL) + +#define s_SINIQ (sat->deep->deep_s_SINIQ) +#define s_COSIQ (sat->deep->deep_s_COSIQ) +#define s_OMGDT (sat->deep->deep_s_OMGDT) +#define ATIME (sat->deep->deep_ATIME) +#define D2201 (sat->deep->deep_D2201) +#define D2211 (sat->deep->deep_D2211) +#define D3210 (sat->deep->deep_D3210) +#define D3222 (sat->deep->deep_D3222) +#define D4410 (sat->deep->deep_D4410) +#define D4422 (sat->deep->deep_D4422) +#define D5220 (sat->deep->deep_D5220) +#define D5232 (sat->deep->deep_D5232) +#define D5421 (sat->deep->deep_D5421) +#define D5433 (sat->deep->deep_D5433) +#define DEL1 (sat->deep->deep_DEL1) +#define DEL2 (sat->deep->deep_DEL2) +#define DEL3 (sat->deep->deep_DEL3) +#define E3 (sat->deep->deep_E3) +#define EE2 (sat->deep->deep_EE2) +#define FASX2 (sat->deep->deep_FASX2) +#define FASX4 (sat->deep->deep_FASX4) +#define FASX6 (sat->deep->deep_FASX6) +#define OMEGAQ (sat->deep->deep_OMEGAQ) +#define PE (sat->deep->deep_PE) +#define PINC (sat->deep->deep_PINC) +#define PL (sat->deep->deep_PL) +#define SAVTSN (sat->deep->deep_SAVTSN) +#define SE2 (sat->deep->deep_SE2) +#define SE3 (sat->deep->deep_SE3) +#define SGH2 (sat->deep->deep_SGH2) +#define SGH3 (sat->deep->deep_SGH3) +#define SGH4 (sat->deep->deep_SGH4) +#define SGHL (sat->deep->deep_SGHL) +#define SGHS (sat->deep->deep_SGHS) +#define SH2 (sat->deep->deep_SH2) +#define SH3 (sat->deep->deep_SH3) +#define SHS (sat->deep->deep_SHS) +#define SHL (sat->deep->deep_SHL) +#define SI2 (sat->deep->deep_SI2) +#define SI3 (sat->deep->deep_SI3) +#define SL2 (sat->deep->deep_SL2) +#define SL3 (sat->deep->deep_SL3) +#define SL4 (sat->deep->deep_SL4) +#define SSE (sat->deep->deep_SSE) +#define SSG (sat->deep->deep_SSG) +#define SSH (sat->deep->deep_SSH) +#define SSI (sat->deep->deep_SSI) +#define SSL (sat->deep->deep_SSL) +#define STEP2 (sat->deep->deep_STEP2) +#define STEPN (sat->deep->deep_STEPN) +#define STEPP (sat->deep->deep_STEPP) +#define THGR (sat->deep->deep_THGR) +#define XFACT (sat->deep->deep_XFACT) +#define XGH2 (sat->deep->deep_XGH2) +#define XGH3 (sat->deep->deep_XGH3) +#define XGH4 (sat->deep->deep_XGH4) +#define XH2 (sat->deep->deep_XH2) +#define XH3 (sat->deep->deep_XH3) +#define XI2 (sat->deep->deep_XI2) +#define XI3 (sat->deep->deep_XI3) +#define XL2 (sat->deep->deep_XL2) +#define XL3 (sat->deep->deep_XL3) +#define XL4 (sat->deep->deep_XL4) +#define XLAMO (sat->deep->deep_XLAMO) +#define XLI (sat->deep->deep_XLI) +#define XNI (sat->deep->deep_XNI) +#define XNQ (sat->deep->deep_XNQ) +#define XQNCL (sat->deep->deep_XQNCL) +#define ZMOL (sat->deep->deep_ZMOL) +#define ZMOS (sat->deep->deep_ZMOS) + +/* * ENTRANCE FOR DEEP SPACE INITIALIZATION */ + +/* ENTRY DPINIT(EQSQ,SINIQ,COSIQ,RTEQSQ,AO,COSQ2,SINOMO,COSOMO, */ +/* 1 BSQ,XLLDOT,OMGDT,XNODOT,XNODP) */ + +void +dpinit(SatData *sat, double EQSQ, double SINIQ, double COSIQ, + double RTEQSQ, double AO, double COSQ2, double SINOMO, + double COSOMO, double BSQ, double XLLDOT, double OMGDT, + double XNODOT, double XNODP) +{ + double A1, A10, A2, A3, A4, A5, A6, A7, A8, A9, AINV2, AQNV, BFACT, + C, CC, COSQ, CTEM, DAY, DS50, EOC, EQ, F220, F221, F311, F321, F322, + F330, F441, F442, F522, F523, F542, F543, G200, G201, G211, G300, + G310, G322, G410, G422, G520, G521, G532, G533, GAM, PREEP, S1, S2, + S3, S4, S5, S6, S7, SE, SGH, SH, SI, SINI2, SINQ, SL, STEM, TEMP, + TEMP1, X1, X2, X3, X4, X5, X6, X7, X8, XMAO, XNO2, XNODCE, XNOI, + XPIDOT, Z1, Z11, Z12, Z13, Z2, Z21, Z22, Z23, Z3, Z31, Z32, Z33, + ZCOSG, ZCOSGL, ZCOSH, ZCOSHL, ZCOSI, ZCOSIL, ZE, ZMO, ZN, ZSING, + ZSINGL, ZSINH, ZSINHL, ZSINI, ZSINIL, ZX, ZY; + + int c; +#if 0 + A1=A10=A2=A3=A4=A5=A6=A7=A8=A9=AINV2=AQNV=BFACT = signaling_nan(); + C=CC=COSQ=CTEM=DAY=DS50=EOC=EQ=F220=F221=F311=F321=F322 = signaling_nan(); + F330=F441=F442=F522=F523=F542=F543=G200=G201=G211=G300 = signaling_nan(); + G310=G322=G410=G422=G520=G521=G532=G533=GAM=PREEP=S1=S2 = signaling_nan(); + S3=S4=S5=S6=S7=SE=SGH=SH=SI=SINI2=SINQ=SL=STEM=TEMP = signaling_nan(); + TEMP1=X1=X2=X3=X4=X5=X6=X7=X8=XMAO=XNO2=XNODCE=XNOI = signaling_nan(); + XPIDOT=Z1=Z11=Z12=Z13=Z2=Z21=Z22=Z23=Z3=Z31=Z32=Z33 = signaling_nan(); + ZCOSG=ZCOSGL=ZCOSH=ZCOSHL=ZCOSI=ZCOSIL=ZE=ZMO=ZN=ZSING = signaling_nan(); + ZSINGL=ZSINH=ZSINHL=ZSINI=ZSINIL=ZX=ZY = signaling_nan(); +#endif + if(!sat->deep) + sat->deep = (struct deep_data *) malloc(sizeof(struct deep_data)); + else + return; + + /* init_deep(sat->deep); */ + PREEP = 0.0; + + ZCOSGL = ZCOSHL = ZCOSIL = ZSINGL = ZSINHL = ZSINIL = 0.0; + + /* Save some of the arguments, for use by dpsec() and dpper() */ + s_SINIQ = SINIQ; + s_COSIQ = COSIQ; + s_OMGDT = OMGDT; + + THGR = thetag(EPOCH, &DS50); + + EQ = EO; + XNQ = XNODP; + AQNV = 1.0/AO; + XQNCL = XINCL; + XMAO = XMO; + XPIDOT = OMGDT + XNODOT; + SINQ = sin(XNODEO); + COSQ = cos(XNODEO); + OMEGAQ = OMEGAO; + + /* INITIALIZE LUNAR SOLAR TERMS */ + + DAY = DS50 + 18261.5; + + if(DAY != PREEP) { + PREEP = DAY; + XNODCE = 4.5236020 - 9.2422029E-4 * DAY; + STEM = sin(XNODCE); + CTEM = cos(XNODCE); + ZCOSIL = .91375164 - .03568096 * CTEM; + ZSINIL = sqrt(1.0 - ZCOSIL * ZCOSIL); + ZSINHL = .089683511 * STEM / ZSINIL; + ZCOSHL = sqrt(1.0 - ZSINHL * ZSINHL); + C = 4.7199672 + .22997150 * DAY; + GAM = 5.8351514 + .0019443680 * DAY; + ZMOL = fmod(C-GAM, TWOPI); + ZX = .39785416 * STEM / ZSINIL; + ZY = ZCOSHL * CTEM + 0.91744867 * ZSINHL * STEM; + ZX = actan(ZX, ZY); + ZX = GAM + ZX - XNODCE; + ZCOSGL = cos(ZX); + ZSINGL = sin(ZX); + ZMOS = 6.2565837 + .017201977 * DAY; + ZMOS = fmod(ZMOS, TWOPI); + } + + /* DO SOLAR TERMS */ + + SAVTSN = 1.0E20; + ZCOSG = ZCOSGS; + ZSING = ZSINGS; + ZCOSI = ZCOSIS; + ZSINI = ZSINIS; + ZCOSH = COSQ; + ZSINH = SINQ; + CC = C1SS; + ZN = ZNS; + ZE = ZES; + ZMO = ZMOS; + XNOI = 1.0 / XNQ; + + for(c = 0; c < 2; c++) { + A1 = ZCOSG * ZCOSH + ZSING * ZCOSI * ZSINH; + A3 = -ZSING * ZCOSH + ZCOSG * ZCOSI * ZSINH; + A7 = -ZCOSG * ZSINH + ZSING * ZCOSI * ZCOSH; + A8 = ZSING * ZSINI; + A9 = ZSING * ZSINH + ZCOSG * ZCOSI * ZCOSH; + A10 = ZCOSG * ZSINI; + A2 = COSIQ * A7 + SINIQ * A8; + A4 = COSIQ * A9 + SINIQ * A10; + A5 = - SINIQ * A7 + COSIQ * A8; + A6 = - SINIQ * A9 + COSIQ * A10; + + X1 = A1 * COSOMO + A2 * SINOMO; + X2 = A3 * COSOMO + A4 * SINOMO; + X3 = - A1 * SINOMO + A2 * COSOMO; + X4 = - A3 * SINOMO + A4 * COSOMO; + X5 = A5 * SINOMO; + X6 = A6 * SINOMO; + X7 = A5 * COSOMO; + X8 = A6 * COSOMO; + + Z31 = 12.0 * X1 * X1 -3.0 * X3 * X3; + Z32 = 24.0 * X1 * X2 -6.0 * X3 * X4; + Z33 = 12.0 * X2 * X2 -3.0 * X4 * X4; + Z1 = 3.0 * (A1 * A1 + A2 * A2) + Z31 * EQSQ; + Z2 = 6.0 * (A1 * A3 + A2 * A4) + Z32 * EQSQ; + Z3 = 3.0 * (A3 * A3 + A4 * A4) + Z33 * EQSQ; + Z11 = -6.0 * A1 * A5 + EQSQ * (-24.0 * X1 * X7 - 6.0 * X3 * X5); + + Z12 = -6.0 * (A1 * A6 + A3 * A5) + + EQSQ * (-24.0 * (X2 * X7 + X1 * X8) - 6.0 * (X3 * X6 + X4 * X5)); + + Z13 = -6.0 * A3 * A6 + EQSQ * (-24.0 * X2 * X8 - 6.0 * X4 * X6); + Z21 = 6.0 * A2 * A5 + EQSQ * (24.0 * X1 * X5 - 6.0 * X3 * X7); + + Z22 = 6.0 * (A4 * A5 + A2 * A6) + + EQSQ * (24.0 * (X2 * X5 + X1 * X6) - 6.0 * (X4 * X7 + X3 * X8)); + + Z23 = 6.0 * A4 * A6 + EQSQ * (24.0 * X2 * X6 - 6.0 * X4 * X8); + Z1 = Z1 + Z1 + BSQ * Z31; + Z2 = Z2 + Z2 + BSQ * Z32; + Z3 = Z3 + Z3 + BSQ * Z33; + S3 = CC * XNOI; + S2 = -.5 * S3 / RTEQSQ; + S4 = S3 * RTEQSQ; + S1 = -15.0 * EQ * S4; + S5 = X1 * X3 + X2 * X4; + S6 = X2 * X3 + X1 * X4; + S7 = X2 * X4 - X1 * X3; + SE = S1 * ZN * S5; + SI = S2 * ZN * (Z11 + Z13); + SL = -ZN * S3 * (Z1 + Z3 - 14.0 - 6.0 * EQSQ); + SGH = S4 * ZN * (Z31 + Z33 - 6.0); + SH = -ZN * S2 * (Z21 + Z23); + + if(XQNCL < 5.2359877E-2) + SH = 0.0; + + EE2 = 2.0 * S1 * S6; + E3 = 2.0 * S1 * S7; + XI2 = 2.0 * S2 * Z12; + XI3 = 2.0 * S2 * (Z13 - Z11); + XL2 = -2.0 * S3 * Z2; + XL3 = -2.0 * S3 * (Z3 - Z1); + XL4 = -2.0 * S3 * (-21.0 - 9.0 * EQSQ) * ZE; + XGH2 = 2.0 * S4 * Z32; + XGH3 = 2.0 * S4 * (Z33 - Z31); + XGH4 = -18.0 * S4 * ZE; + XH2 = -2.0 * S2 * Z22; + XH3 = -2.0 * S2 * (Z23 - Z21); + + if(c == 0) { + /* DO LUNAR TERMS */ + SSE = SE; + SSI = SI; + SSL = SL; + SSH = SH / SINIQ; + SSG = SGH - COSIQ * SSH; + SE2 = EE2; + SI2 = XI2; + SL2 = XL2; + SGH2 = XGH2; + SH2 = XH2; + SE3 = E3; + SI3 = XI3; + SL3 = XL3; + SGH3 = XGH3; + SH3 = XH3; + SL4 = XL4; + SGH4 = XGH4; + + ZCOSG = ZCOSGL; + ZSING = ZSINGL; + ZCOSI = ZCOSIL; + ZSINI = ZSINIL; + ZCOSH = ZCOSHL * COSQ + ZSINHL * SINQ; + ZSINH = SINQ * ZCOSHL - COSQ * ZSINHL; + ZN = ZNL; + CC = C1L; + ZE = ZEL; + ZMO = ZMOL; + } + } + + SSE = SSE + SE; + SSI = SSI + SI; + SSL = SSL + SL; + SSG = SSG + SGH - COSIQ / SINIQ * SH; + SSH = SSH + SH / SINIQ; + + /* GEOPOTENTIAL RESONANCE INITIALIZATION FOR 12 HOUR ORBITS */ + + IRESFL = 0; + ISYNFL = 0; + + if(XNQ <= .0034906585 || XNQ >= .0052359877) { + + if(XNQ < (8.26E-3) || XNQ > (9.24E-3)) + return; + + if(EQ < 0.5) + return; + + IRESFL = 1; + EOC = EQ * EQSQ; + G201 = -.306 - (EQ - .64) * .440; + + if(EQ <= (.65)) { + G211 = 3.616 - 13.247 * EQ + 16.290 * EQSQ; + G310 = -19.302 + 117.390 * EQ - 228.419 * EQSQ + 156.591 * EOC; + G322 = -18.9068 + 109.7927 * EQ - 214.6334 * EQSQ + 146.5816 * EOC; + G410 = -41.122 + 242.694 * EQ - 471.094 * EQSQ + 313.953 * EOC; + G422 = -146.407 + 841.880 * EQ - 1629.014 * EQSQ + 1083.435 * EOC; + G520 = -532.114 + 3017.977 * EQ - 5740 * EQSQ + 3708.276 * EOC; + } else { + G211 = -72.099 + 331.819 * EQ - 508.738 * EQSQ + 266.724 * EOC; + G310 = -346.844 + 1582.851 * EQ - 2415.925 * EQSQ + 1246.113 * EOC; + G322 = -342.585 + 1554.908 * EQ - 2366.899 * EQSQ + 1215.972 * EOC; + G410 = -1052.797 + 4758.686 * EQ - 7193.992 * EQSQ + + 3651.957 * EOC; + G422 = -3581.69 + 16178.11 * EQ - 24462.77 * EQSQ + 12422.52 * EOC; + + if(EQ > (.715)) + G520 = -5149.66 + 29936.92 * EQ - 54087.36 * EQSQ + + 31324.56 * EOC; + + G520 = 1464.74 - 4664.75 * EQ + 3763.64 * EQSQ; + } + + if(EQ < (.7)) { + G533 = -919.2277 + 4988.61 * EQ - 9064.77 * EQSQ + 5542.21 * EOC; + + G521 = -822.71072 + 4568.6173 * EQ - 8491.4146 * EQSQ + + 5337.524 * EOC; + + G532 = -853.666 + 4690.25 * EQ - 8624.77 * EQSQ + 5341.4 * EOC; + } else { + G533 = -37995.78 + 161616.52 * EQ - 229838.2 * EQSQ + + 109377.94 * EOC; + + G521 = -51752.104 + 218913.95 * EQ - 309468.16 * EQSQ + + 146349.42 * EOC; + + G532 = -40023.88 + 170470.89 * EQ - 242699.48 * EQSQ + + 115605.82 * EOC; + } + + SINI2 = SINIQ * SINIQ; + F220 = .75 * (1.0 + 2.0 * COSIQ + COSQ2); + F221 = 1.5 * SINI2; + F321 = 1.875 * SINIQ * (1.0 - 2.0 * COSIQ - 3.0 * COSQ2); + F322 = -1.875 * SINIQ * (1.0 + 2.0 * COSIQ - 3.0 * COSQ2); + F441 = 35.0 * SINI2 * F220; + F442 = 39.3750 * SINI2 * SINI2; + + F522 = 9.84375 * SINIQ * (SINI2 * (1.0 - 2.0 * COSIQ - 5.0 * COSQ2) + + .33333333 * (-2.0 + 4.0 * COSIQ + + 6.0 * COSQ2)); + + F523 = SINIQ * (4.92187512 * SINI2 * (-2.0 - 4.0 * COSIQ + + 10.0 * COSQ2) + + 6.56250012 * (1.0 + + 2.0 * COSIQ - + 3.0 * COSQ2)); + + F542 = 29.53125 * SINIQ * (2.0 - 8.0 * COSIQ + + COSQ2 * (-12.0 + 8.0 * COSIQ + + 10.0 * COSQ2)); + + F543 = 29.53125 * SINIQ * (-2.0 - 8.0 * COSIQ + + COSQ2 * (12.0 + 8.0 * COSIQ - + 10.0 * COSQ2)); + + XNO2 = XNQ * XNQ; + AINV2 = AQNV * AQNV; + TEMP1 = 3.0 * XNO2 * AINV2; + TEMP = TEMP1 * ROOT22; + D2201 = TEMP * F220 * G201; + D2211 = TEMP * F221 * G211; + TEMP1 = TEMP1 * AQNV; + TEMP = TEMP1 * ROOT32; + D3210 = TEMP * F321 * G310; + D3222 = TEMP * F322 * G322; + TEMP1 = TEMP1 * AQNV; + TEMP = 2.0 * TEMP1 * ROOT44; + D4410 = TEMP * F441 * G410; + D4422 = TEMP * F442 * G422; + TEMP1 = TEMP1 * AQNV; + TEMP = TEMP1 * ROOT52; + D5220 = TEMP * F522 * G520; + D5232 = TEMP * F523 * G532; + TEMP = 2.0 * TEMP1 * ROOT54; + D5421 = TEMP * F542* G521; + D5433 = TEMP * F543* G533; + XLAMO = XMAO + XNODEO + XNODEO - THGR - THGR; + BFACT = XLLDOT + XNODOT + XNODOT - THDT - THDT; + BFACT = BFACT + SSL + SSH + SSH; + } else { + /* SYNCHRONOUS RESONANCE TERMS INITIALIZATION */ + + IRESFL = 1; + ISYNFL = 1; + G200 = 1.0 + EQSQ * (-2.5 + .8125 * EQSQ); + G310 = 1.0 + 2.0 * EQSQ; + G300 = 1.0 + EQSQ * (-6.0 + 6.60937 * EQSQ); + F220 = .75 * (1.0 + COSIQ) * (1.0 + COSIQ); + F311 = .9375 * SINIQ * SINIQ * (1.0 + 3.0 * COSIQ) - + .75 * (1.0 + COSIQ); + F330 = 1.0 + COSIQ; + F330 = 1.875 * F330 * F330 * F330; + DEL1 = 3.0 * XNQ * XNQ * AQNV * AQNV; + DEL2 = 2.0 * DEL1 * F220 * G200 * Q22; + DEL3 = 3.0 * DEL1 * F330 * G300 * Q33 * AQNV; + DEL1 = DEL1 * F311 * G310 * Q31 * AQNV; + FASX2 = .13130908; + FASX4 = 2.8843198; + FASX6 = .37448087; + XLAMO = XMAO + XNODEO + OMEGAO - THGR; + BFACT = XLLDOT + XPIDOT - THDT; + BFACT = BFACT + SSL + SSG + SSH; + + } + + XFACT = BFACT - XNQ; + + XLI = XLAMO; + XNI = XNQ; + ATIME = 0.0; + STEPP = 720.0; + STEPN = -720.0; + STEP2 = 259200.0; +} + +/* ENTRANCE FOR DEEP SPACE SECULAR EFFECTS */ + +void +dpsec(SatData *sat, double *XLL, double *OMGASM, double *XNODES, + double *EM, double *XINC, double *XN, double T) +{ + double DELT, XL, TEMP, XOMI, X2OMI, X2LI, XLDOT; + double XNDOT, XNDDT, FT; + int state, iret, iretn, done; + + DELT = XLDOT = XNDOT = XNDDT = FT = 0.0; + iret = iretn = 0; + +#if 0 + DELT = XL = TEMP = XOMI = X2OMI = X2LI = XLDOT = signaling_nan(); + XNDOT = XNDDT = FT = signaling_nan(); +#endif + + *XLL = *XLL + SSL * T; + *OMGASM = *OMGASM + SSG * T; + *XNODES = *XNODES + SSH * T; + *EM = EO + SSE * T; + *XINC = XINCL + SSI * T; + + if(*XINC < 0.0) { + *XINC = -*XINC; + *XNODES = *XNODES + PI; + *OMGASM = *OMGASM - PI; + } + + if(IRESFL == 0) + return; + + state = 1; + done = 0; + while(!done) { + /* printf("state = %d\n", state); */ + switch(state) { + case 1: + /* + * Chunk #1 + */ + if(ATIME == 0.0 || (T >= 0.0 && ATIME < 0.0) || + (T < 0.0 && ATIME >= 0.0)) { + /* + * Chunk #10 + */ + if(T >= 0.0) + DELT = STEPP; + else + DELT = STEPN; + + ATIME = 0.0; + XNI = XNQ; + XLI = XLAMO; + state = 4; + break; + } + + /* Fall through */ + case 2: + /* + * Chunk #2 + */ + if(fabs(T) < fabs(ATIME)) { + /* + * Chunk #2 + */ + if(T >= 0.0) + DELT = STEPN; + else + DELT = STEPP; + + iret = 1; + state = 8; + break; + } + + /* + * Chunk #3 + */ + if(T > 0.0) + DELT = STEPP; + else + DELT = STEPN; + + /* fall through */ + case 4: + /* + * Chunk #4 + */ + if(fabs(T - ATIME) >= STEPP) { + iret = 4; + state = 8; + } else { + /* + * Chunk #5 + */ + FT = T - ATIME; + iretn = 6; + state = 7; + } + + break; + + case 6: + /* + * Chunk #6 + */ + *XN = XNI + XNDOT * FT + XNDDT * FT * FT * 0.5; + XL = XLI + XLDOT * FT + XNDOT * FT * FT * 0.5; + TEMP = -*XNODES + THGR + T * THDT; + + if(ISYNFL == 0) + *XLL = XL + 2.0 * TEMP; + else + *XLL = XL - *OMGASM + TEMP; + + done = 1; + break; + + case 7: + /* DOT TERMS CALCULATED */ + + /* + * Chunk #7 + */ + if(ISYNFL != 0) { + XNDOT = + DEL1 * sin(XLI - FASX2) + + DEL2 * sin(2.0 * (XLI - FASX4)) + + DEL3 * sin(3.0 * (XLI - FASX6)); + + XNDDT = + DEL1 * cos(XLI - FASX2) + + 2.0 * DEL2 * cos(2.0 * (XLI - FASX4)) + + 3.0 * DEL3 * cos(3.0 * (XLI - FASX6)); + } else { + XOMI = OMEGAQ + s_OMGDT * ATIME; + X2OMI = XOMI + XOMI; + X2LI = XLI + XLI; + XNDOT = D2201 * sin(X2OMI + XLI - G22) + + D2211 * sin(XLI - G22) + + D3210 * sin(XOMI + XLI - G32) + + D3222 * sin(- XOMI + XLI - G32) + + D4410 * sin(X2OMI + X2LI - G44) + + D4422 * sin(X2LI - G44) + + D5220 * sin(XOMI + XLI - G52) + + D5232 * sin(- XOMI + XLI - G52) + + D5421 * sin(XOMI + X2LI - G54) + + D5433 * sin(- XOMI + X2LI - G54); + + XNDDT = D2201 * cos(X2OMI + XLI - G22) + + D2211 * cos(XLI - G22) + + D3210 * cos(XOMI + XLI - G32) + + D3222 * cos(- XOMI + XLI - G32) + + D5220 * cos(XOMI + XLI - G52) + + D5232 * cos(- XOMI + XLI - G52) + + 2.*(D4410 * cos(X2OMI + X2LI - G44) + + D4422 * cos(X2LI - G44) + + D5421 * cos(XOMI + X2LI - G54) + + D5433 * cos(- XOMI + X2LI - G54)); + } + + XLDOT = XNI + XFACT; + XNDDT = XNDDT * XLDOT; + + state = iretn; + break; + + case 8: + /* + * Chunk #8 + */ + + /* INTEGRATOR */ + iretn = 9; + state = 7; + break; + + case 9: + XLI = XLI + XLDOT * DELT + XNDOT * STEP2; + XNI = XNI + XNDOT * DELT + XNDDT * STEP2; + ATIME = ATIME + DELT; + + state = iret; + break; + } + } +} + +/* local */ + +/* C */ +/* C ENTRANCES FOR LUNAR-SOLAR PERIODICS */ +/* C */ +/* C */ +/* ENTRY DPPER(EM,XINC,OMGASM,XNODES,XLL) */ +void +dpper(SatData *sat, double *EM, double *XINC, double *OMGASM, + double *XNODES, double *XLL, double T) +{ + double SINIS, COSIS, ZM, ZF, SINZF, F2, F3, SES, SIS, SLS, SEL, SIL, SLL, PGH, PH, SINOK, COSOK, ALFDP, BETDP, DALF, DBET, XLS, DLS; + +#if 0 + SINIS = COSIS = ZM = ZF = SINZF = F2 = F3 = SES = SIS = signaling_nan(); + SLS = SEL = SIL = SLL = PGH = signaling_nan(); + PH = SINOK = COSOK = ALFDP = BETDP = DALF = DBET = XLS = signaling_nan(); + DLS = signaling_nan();; +#endif + SINIS = sin(*XINC); + COSIS = cos(*XINC); + + +/* IF (DABS(SAVTSN-T).LT.(30.D0)) GO TO 210 */ + if(fabs(SAVTSN - T) >= (30.0)) { + SAVTSN = T; + ZM = ZMOS + ZNS * T; +/* 205 ZF = ZM + 2.0 * ZES * sin(ZM) */ + ZF = ZM + 2.0 * ZES * sin(ZM); + SINZF = sin(ZF); + F2 = .5 * SINZF * SINZF - .25; + F3 = -.5 * SINZF * cos(ZF); + SES = SE2 * F2 + SE3 * F3; + SIS = SI2 * F2 + SI3 * F3; + SLS = SL2 * F2 + SL3 * F3 + SL4 * SINZF; + SGHS = SGH2 * F2 + SGH3 * F3 + SGH4 * SINZF; + SHS = SH2 * F2 + SH3 * F3; + ZM = ZMOL + ZNL * T; + ZF = ZM + 2.0 * ZEL * sin(ZM); + SINZF = sin(ZF); + F2 = .5 * SINZF * SINZF -.25; + F3 = -.5 * SINZF * cos(ZF); + SEL = EE2 * F2 + E3 * F3; + SIL = XI2 * F2 + XI3 * F3; + SLL = XL2 * F2 + XL3 * F3 + XL4 * SINZF; + SGHL = XGH2 * F2 + XGH3 * F3 + XGH4 * SINZF; + SHL = XH2 * F2 + XH3 * F3; + PE = SES + SEL; + PINC = SIS + SIL; + PL = SLS + SLL; + } + +/* 210 PGH=SGHS+SGHL */ + PGH = SGHS + SGHL; + PH = SHS + SHL; + *XINC = *XINC + PINC; + *EM = *EM + PE; + +/* IF(XQNCL.LT.(.2)) GO TO 220 */ + if(XQNCL >= (.2)) { +/* GO TO 218 */ +/* C */ +/* C APPLY PERIODICS DIRECTLY */ +/* C */ +/* 218 PH=PH/SINIQ */ + PH = PH / s_SINIQ; + PGH = PGH - s_COSIQ * PH; + *OMGASM = *OMGASM + PGH; + *XNODES = *XNODES + PH; + *XLL = *XLL + PL; +/* GO TO 230 */ + } else { +/* C */ +/* C APPLY PERIODICS WITH LYDDANE MODIFICATION */ +/* C */ +/* 220 SINOK=sin(XNODES) */ + SINOK = sin(*XNODES); + COSOK = cos(*XNODES); + ALFDP = SINIS * SINOK; + BETDP = SINIS * COSOK; + DALF = PH * COSOK + PINC * COSIS * SINOK; + DBET = -PH * SINOK + PINC * COSIS * COSOK; + ALFDP = ALFDP + DALF; + BETDP = BETDP + DBET; + XLS = *XLL + *OMGASM + COSIS * *XNODES; + DLS = PL + PGH - PINC * *XNODES * SINIS; + XLS = XLS + DLS; + *XNODES = actan(ALFDP, BETDP); + *XLL = *XLL + PL; + *OMGASM = XLS - *XLL - cos(*XINC) * *XNODES; + } +/* 230 CONTINUE */ +/* RETURN */ + +} +/* END */ + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: deep.c,v $ $Date: 2000/09/25 19:43:03 $ $Revision: 1.2 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/deepconst.h b/Common/Libraries/XEphemAstroLib/src/deepconst.h new file mode 100644 index 000000000..8c715676a --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/deepconst.h @@ -0,0 +1,34 @@ +#ifndef _CONST_H +#define _CONST_H + +/* $Id: deepconst.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + + +#define GE (3.986005E14) + +#define PI (3.1415926535897932385) + +#define XKE (7.43669161E-2) +#define CK2 (5.413080E-4) +#define CK4 (6.2098875E-7) +#define E6A (10E6) +#define QOMS2T (1.88027916E-9) +#define S (1.01222928) +#define TOTHRD (2.0/3.0) /* 6.6666666666666666667E-1 */ +#define XJ3 (-2.53881E-6) +/* #define XKE KE */ +#define XKMPER (6378.135) +#define XMNPDA (1440.0) +#define AE (1.0) +#define DE2RA (1.7453292519943295769E-2) +#define PIO2 (1.57079632679489661925) /* PI/2 */ +#define TWOPI (6.2831853071795864770) +#define X3PIO2 (4.7123889803846898578) /* 3*PI/2 */ + +#define RHO (0.15696590235) + +#endif /* _CONST_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: deepconst.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/deltat.c b/Common/Libraries/XEphemAstroLib/src/deltat.c new file mode 100644 index 000000000..fb92df726 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/deltat.c @@ -0,0 +1,334 @@ +/* DeltaT = Ephemeris Time - Universal Time + * + * Adapted 2011/4/14 from Stephen Moshier <moshier@world.std.com>, + * cosmetic changes only. + * + * Compile as follows to create stand-alone test program: + * cc -DTEST_MAIN deltat.c libastro.a + * + * Tabulated values of deltaT, in hundredths of a second, are + * from The Astronomical Almanac and current IERS reports. + * A table of values for the pre-telescopic period was taken from + * Morrison and Stephenson (2004). The overall tabulated range is + * -1000.0 through 2011.0. Values at intermediate times are interpolated + * from the tables. + * + * For dates earlier and later than the tabulated range, the program + * calculates a polynomial extrapolation formula. + * + * Updated deltaT predictions can be obtained from this network archive, + * http://maia.usno.navy.mil + * then appended to the dt[] table and update TABEND. + * + * Input is XEphem's MJD, output is ET-UT in seconds. + * + * + * References: + * + * Morrison, L. V., and F. R. Stephenson, Historical values of the Earth's + * clock error deltat T and the calculation of eclipses. Journal for the + * History of Astronomy 35, 327-336 (2004) + * + * Stephenson, F. R., and L. V. Morrison, "Long-term changes + * in the rotation of the Earth: 700 B.C. to A.D. 1980," + * Philosophical Transactions of the Royal Society of London + * Series A 313, 47-70 (1984) + * + * Chapront-Touze, Michelle, and Jean Chapront, _Lunar Tables + * and Programs from 4000 B.C. to A.D. 8000_, Willmann-Bell 1991 + * + * Stephenson, F. R., and M. A. Houlden, _Atlas of Historical + * Eclipse Maps_, Cambridge U. Press (1986) + * + */ + +#include <math.h> + +#include "astro.h" + +#define TABSTART 1620 +#define TABEND 2011 +#define TABSIZ (TABEND - TABSTART + 1) + +/* Morrison and Stephenson (2004) + * This table covers -1000 through 1700 in 100-year steps. + * Values are in whole seconds. + * Estimated standard error at -1000 is 640 seconds; at 1600, 20 seconds. + * The first value in the table has been adjusted 28 sec for + * continuity with their long-term quadratic extrapolation formula. + * The last value in this table agrees with the AA table at 1700, + * so there is no discontinuity at either endpoint. + */ +#define MS_SIZ 28 +short m_s[MS_SIZ] = { + /* -1000 to -100 */ + 25428, 23700, 22000, 21000, 19040, 17190, 15530, 14080, 12790, 11640, + + /* 0 to 900 */ + 10580, 9600, 8640, 7680, 6700, 5710, 4740, 3810, 2960, 2200, + + /* 1000 to 1700 */ + 1570, 1090, 740, 490, 320, 200, 120, 9, +}; + + +/* Entries prior to 1955 in the following table are from + * the 1984 Astronomical Almanac and assume ndot = -26.0. + * For dates prior to 1700, the above table is used instead of this one. + */ +short dt[TABSIZ] = { + /* 1620.0 thru 1659.0 */ + 12400, 11900, 11500, 11000, 10600, 10200, 9800, 9500, 9100, 8800, + 8500, 8200, 7900, 7700, 7400, 7200, 7000, 6700, 6500, 6300, + 6200, 6000, 5800, 5700, 5500, 5400, 5300, 5100, 5000, 4900, + 4800, 4700, 4600, 4500, 4400, 4300, 4200, 4100, 4000, 3800, + + /* 1660.0 thru 1699.0 */ + 3700, 3600, 3500, 3400, 3300, 3200, 3100, 3000, 2800, 2700, + 2600, 2500, 2400, 2300, 2200, 2100, 2000, 1900, 1800, 1700, + 1600, 1500, 1400, 1400, 1300, 1200, 1200, 1100, 1100, 1000, + 1000, 1000, 900, 900, 900, 900, 900, 900, 900, 900, + + /* 1700.0 thru 1739.0 */ + 900, 900, 900, 900, 900, 900, 900, 900, 1000, 1000, + 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1100, 1100, 1100, + 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, + 1100, 1100, 1100, 1100, 1200, 1200, 1200, 1200, 1200, 1200, + + /* 1740.0 thru 1779.0 */ + 1200, 1200, 1200, 1200, 1300, 1300, 1300, 1300, 1300, 1300, + 1300, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1500, 1500, + 1500, 1500, 1500, 1500, 1500, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1700, 1700, 1700, 1700, 1700, + + /* 1780.0 thru 1799.0 */ + 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, + 1700, 1700, 1600, 1600, 1600, 1600, 1500, 1500, 1400, 1400, + + /* 1800.0 thru 1819.0 */ + 1370, 1340, 1310, 1290, 1270, 1260, 1250, 1250, 1250, 1250, + 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1240, 1230, 1220, + + /* 1820.0 thru 1859.0 */ + 1200, 1170, 1140, 1110, 1060, 1020, 960, 910, 860, 800, + 750, 700, 660, 630, 600, 580, 570, 560, 560, 560, + 570, 580, 590, 610, 620, 630, 650, 660, 680, 690, + 710, 720, 730, 740, 750, 760, 770, 770, 780, 780, + + /* 1860.0 thru 1899.0 */ + 788, 782, 754, 697, 640, 602, 541, 410, 292, 182, + 161, 10, -102, -128, -269, -324, -364, -454, -471, -511, + -540, -542, -520, -546, -546, -579, -563, -564, -580, -566, + -587, -601, -619, -664, -644, -647, -609, -576, -466, -374, + + /* 1900.0 thru 1939.0 */ + -272, -154, -2, 124, 264, 386, 537, 614, 775, 913, + 1046, 1153, 1336, 1465, 1601, 1720, 1824, 1906, 2025, 2095, + 2116, 2225, 2241, 2303, 2349, 2362, 2386, 2449, 2434, 2408, + 2402, 2400, 2387, 2395, 2386, 2393, 2373, 2392, 2396, 2402, + + /* 1940.0 thru 1979.0 */ + 2433, 2483, 2530, 2570, 2624, 2677, 2728, 2778, 2825, 2871, + 2915, 2957, 2997, 3036, 3072, 3107, 3135, 3168, 3218, 3268, + 3315, 3359, 3400, 3447, 3503, 3573, 3654, 3743, 3829, 3920, + 4018, 4117, 4223, 4337, 4449, 4548, 4646, 4752, 4853, 4959, + + /* 1980.0 thru 2011.0 */ + 5054, 5138, 5217, 5296, 5379, 5434, 5487, 5532, 5582, 5630, + 5686, 5757, 5831, 5912, 5998, 6078, 6163, 6230, 6297, 6347, + 6383, 6409, 6430, 6447, 6457, 6469, 6485, 6515, 6546, 6578, + 6607, 6632, +}; + + +/* Given MJD return DeltaT = ET - UT1 in seconds. Describes the irregularities + * of the Earth rotation rate in the ET time scale. + */ +double +deltat(double mj) +{ + static double ans, lastmj; + double Y, p, B; + int d[6]; + int i, iy, k; + + if (mj == lastmj) + return (ans); + lastmj = mj; + + mjd_year (mj, &Y); + + if( Y > TABEND ) { + /* Extrapolate future values beyond the lookup table. */ + if (Y > (TABEND + 100.0)) { + /* Morrison & Stephenson (2004) long-term curve fit. */ + B = 0.01 * (Y - 1820.0); + ans = 32.0 * B * B - 20.0; + + } else { + + double a, b, c, d, m0, m1; + + /* Cubic interpolation between last tabulated value + * and long-term curve evaluated at 100 years later. + */ + + /* Last tabulated delta T value. */ + a = 0.01 * dt[TABSIZ-1]; + /* Approximate slope in past 10 years. */ + b = 0.001 * (dt[TABSIZ-1] - dt[TABSIZ - 11]); + + /* Long-term curve 100 years hence. */ + B = 0.01 * (TABEND + 100.0 - 1820.0); + m0 = 32.0 * B*B - 20.0; + /* Its slope. */ + m1 = 0.64 * B; + + /* Solve for remaining coefficients of an interpolation polynomial + * that agrees in value and slope at both ends of the 100-year + * interval. + */ + d = 2.0e-6 * (50.0 * (m1 + b) - m0 + a); + c = 1.0e-4 * (m0 - a - 100.0 * b - 1.0e6 * d); + + /* Note, the polynomial coefficients do not depend on Y. + * A given tabulation and long-term formula + * determine the polynomial. + * Thus, for the IERS table ending at 2011.0, the coefficients are + * a = 66.32 + * b = 0.223 + * c = 0.03231376 + * d = -0.0001607784 + */ + + /* Compute polynomial value at desired time. */ + p = Y - TABEND; + ans = a + p * (b + p * (c + p * d)); + } + + return (ans); + } + + + /* Use Morrison and Stephenson (2004) prior to the year 1700. */ + if( Y < 1700.0 ) { + if (Y <= -1000.0) { + /* Morrison and Stephenson long-term fit. */ + B = 0.01 * (Y - 1820.0); + ans = 32.0 * B * B - 20.0; + + } else { + + /* Morrison and Stephenson recommend linear interpolation + * between tabulations. + */ + iy = Y; + iy = (iy + 1000) / 100; /* Integer index into the table. */ + B = -1000 + 100 * iy; /* Starting year of tabulated interval. */ + p = m_s[iy]; + ans = p + 0.01 * (Y - B) * (m_s[iy + 1] - p); + } + + return (ans); + } + + /* Besselian interpolation between tabulated values + * in the telescopic era. + * See AA page K11. + */ + + /* Index into the table. */ + p = floor(Y); + iy = (int) (p - TABSTART); + /* Zeroth order estimate is value at start of year */ + ans = dt[iy]; + k = iy + 1; + if( k >= TABSIZ ) + goto done; /* No data, can't go on. */ + + /* The fraction of tabulation interval */ + p = Y - p; + + /* First order interpolated value */ + ans += p*(dt[k] - dt[iy]); + if( (iy-1 < 0) || (iy+2 >= TABSIZ) ) + goto done; /* can't do second differences */ + + /* Make table of first differences */ + k = iy - 2; + for (i=0; i<5; i++) { + if( (k < 0) || (k+1 >= TABSIZ) ) + d[i] = 0; + else + d[i] = dt[k+1] - dt[k]; + k += 1; + } + + /* Compute second differences */ + for( i=0; i<4; i++ ) + d[i] = d[i+1] - d[i]; + B = 0.25*p*(p-1.0); + ans += B*(d[1] + d[2]); + if (iy+2 >= TABSIZ) + goto done; + + /* Compute third differences */ + for( i=0; i<3; i++ ) + d[i] = d[i+1] - d[i]; + B = 2.0*B/3.0; + ans += (p-0.5)*B*d[1]; + if ((iy-2 < 0) || (iy+3 > TABSIZ) ) + goto done; + + /* Compute fourth differences */ + for( i=0; i<2; i++ ) + d[i] = d[i+1] - d[i]; + B = 0.125*B*(p+1.0)*(p-2.0); + ans += B*(d[0] + d[1]); + + done: + + ans *= 0.01; + +#if 0 /* ndot = -26.0 assumed; no correction. */ + + /* Astronomical Almanac table is corrected by adding the expression + * -0.000091 (ndot + 26)(year-1955)^2 seconds + * to entries prior to 1955 (AA page K8), where ndot is the secular + * tidal term in the mean motion of the Moon. + * + * Entries after 1955 are referred to atomic time standards and + * are not affected by errors in Lunar or planetary theory. + */ + if( Y < 1955.0 ) + { + B = (Y - 1955.0); + #if 1 + ans += -0.000091 * (-25.8 + 26.0) * B * B; + #else + ans += -0.000091 * (-23.8946 + 26.0) * B * B; + #endif + } + +#endif /* 0 */ + + return( ans ); +} + + +#ifdef TEST_MAIN + +/* Exercise program. + */ +#include <stdio.h> +#include <stdlib.h> + +int main(int ac, char *av[]) +{ + double ans, mj, y = atof(av[1]); + year_mjd (y, &mj); + ans = deltat(mj); + printf( "%.4lf\n", ans ); + return (0); +} +#endif diff --git a/Common/Libraries/XEphemAstroLib/src/descrip.mms b/Common/Libraries/XEphemAstroLib/src/descrip.mms new file mode 100644 index 000000000..89be3eb38 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/descrip.mms @@ -0,0 +1,92 @@ +# Makefile for the basic astronomy routines. +# The idea is to compile and archive them into libastro.a + +# compiler and flags + +# gcc +CC = cc +#CFLAGS= -O2 -ffast-math -Wall + +# solaris +# CC = cc +# CFLAGS= -O + +# AIX +# CC = xlc +# CFLAGS= -O2 -qlanglvl=ansi -qarch=com -qmaxmem=16384 + +# HP-UX +# CC = cc +# CFLAGS= -Aa -fast + +HS = astro.h bdl.h chap95.h deepconst.h preferences.h satlib.h satspec.h \ + sattypes.h vector.h vsop87.h + +OBJS = \ + aa_hadec.obj, \ + aberration.obj, \ + actan.obj, \ + airmass.obj, \ + anomaly.obj, \ + ap_as.obj, \ + atlas.obj, \ + auxil.obj, \ + bdl.obj, \ + chap95.obj, \ + chap95_data.obj, \ + circum.obj, \ + comet.obj, \ + constel.obj, \ + dbfmt.obj, \ + deep.obj, \ + deltat.obj, \ + earthsat.obj, \ + eq_ecl.obj, \ + eq_gal.obj, \ + formats.obj, \ + helio.obj, \ + jupmoon.obj, \ + libration.obj, \ + magdecl.obj, \ + marsmoon.obj, \ + misc.obj, \ + mjd.obj, \ + moon.obj, \ + mooncolong.obj, \ + moonnf.obj, \ + nutation.obj, \ + obliq.obj, \ + parallax.obj, \ + parallactic.obj, \ + plans.obj, \ + plmoon.obj, \ + plshadow.obj, \ + precess.obj, \ + reduce.obj, \ + refract.obj, \ + rings.obj, \ + riset.obj, \ + riset_cir.obj, \ + satmoon.obj, \ + sdp4.obj, \ + sgp4.obj, \ + sphcart.obj, \ + sun.obj, \ + thetag.obj, \ + utc_gst.obj, \ + umoon.obj, \ + twobody.obj, \ + vsop87.obj, \ + vsop87_data.obj + +libastro.olb : $(OBJS) + lib/crea $@ $(OBJS) + +#libastro.so: $(HS) $(OBJS) +# $(CC) -shared -o $@ $(OBJS) + +clean : + del *.o;* + +# For RCS Only -- Do Not Edit +# @(#) $RCSfile: descrip.mms,v $ $Date: 2005/07/27 21:28:40 $ $Revision: 1.1 $ $Name: $ diff --git a/Common/Libraries/XEphemAstroLib/src/earthsat.c b/Common/Libraries/XEphemAstroLib/src/earthsat.c new file mode 100644 index 000000000..c86bea39a --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/earthsat.c @@ -0,0 +1,792 @@ +/* this file contains routines to support Earth satellites. + * + * Orbit propagation is based on the NORAD SGP4/SDP4 code, as converted from + * the original FORTRAN to C by Magnus Backstrom. The paper "Spacetrack + * Report Number 3: Models for Propagation of NORAD Element Sets" describes + * the calculations. + * See http://www.celestrak.com/NORAD/documentation/spacetrk.pdf. + * + * A few topocentric routines are also used from the 'orbit' program which is + * Copyright (c) 1986,1987,1988,1989,1990 Robert W. Berger N3EMO + * + */ + +/* define this to use orbit's propagator +#define USE_ORBIT_PROPAGATOR + */ + +/* define this to print some stuff +#define ESAT_TRACE + */ + +#include <stdio.h> +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#include "astro.h" +#include "preferences.h" + +#include "vector.h" +#include "sattypes.h" +#include "satlib.h" + + +#define ESAT_MAG 2 /* fake satellite magnitude */ + +typedef double MAT3x3[3][3]; + +static int crazyOp (Now *np, Obj *op); +static void esat_prop (Now *np, Obj *op, double *SatX, double *SatY, double + *SatZ, double *SatVX, double *SatVY, double *SatVZ); +static void GetSatelliteParams (Obj *op); +static void GetSiteParams (Now *np); +static double Kepler (double MeanAnomaly, double Eccentricity); +static void GetSubSatPoint (double SatX, double SatY, double SatZ, + double T, double *Latitude, double *Longitude, double *Height); +static void GetSatPosition (double EpochTime, double EpochRAAN, + double EpochArgPerigee, double SemiMajorAxis, double Inclination, + double Eccentricity, double RAANPrecession, double PerigeePrecession, + double T, double TrueAnomaly, double *X, double *Y, double *Z, + double *Radius, double *VX, double *VY, double *VZ); +static void GetSitPosition (double SiteLat, double SiteLong, + double SiteElevation, double CrntTime, double *SiteX, double *SiteY, + double *SiteZ, double *SiteVX, double *SiteVY, MAT3x3 SiteMatrix); +static void GetRange (double SiteX, double SiteY, double SiteZ, + double SiteVX, double SiteVY, double SatX, double SatY, double SatZ, + double SatVX, double SatVY, double SatVZ, double *Range, + double *RangeRate); +static void GetTopocentric (double SatX, double SatY, double SatZ, + double SiteX, double SiteY, double SiteZ, MAT3x3 SiteMatrix, double *X, + double *Y, double *Z); +static void GetBearings (double SatX, double SatY, double SatZ, + double SiteX, double SiteY, double SiteZ, MAT3x3 SiteMatrix, + double *Azimuth, double *Elevation); +static int Eclipsed (double SatX, double SatY, double SatZ, + double SatRadius, double CrntTime); +static void InitOrbitRoutines (double EpochDay, int AtEod); + +#ifdef USE_ORBIT_PROPAGATOR +static void GetPrecession (double SemiMajorAxis, double Eccentricity, + double Inclination, double *RAANPrecession, double *PerigeePrecession); +#endif /* USE_ORBIT_PROPAGATOR */ + +/* stuff from orbit */ +/* char VersionStr[] = "N3EMO Orbit Simulator v3.9"; */ + +#ifdef PI2 +#undef PI2 +#endif + +#define PI2 (PI*2) + +#define MinutesPerDay (24*60.0) +#define SecondsPerDay (60*MinutesPerDay) +#define HalfSecond (0.5/SecondsPerDay) +#define EarthRadius 6378.16 /* Kilometers */ +#define C 2.997925e5 /* Kilometers/Second */ +#define RadiansPerDegree (PI/180) +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) +#define SQR(x) ((x)*(x)) + +#define EarthFlat (1/298.25) /* Earth Flattening Coeff. */ +#define SiderealSolar 1.0027379093 +#define SidRate (PI2*SiderealSolar/SecondsPerDay) /* radians/second */ +#define GM 398600 /* Kilometers^3/seconds^2 */ + +#define Epsilon (RadiansPerDegree/3600) /* 1 arc second */ +#define SunRadius 695000 +#define SunSemiMajorAxis 149598845.0 /* Kilometers */ + +/* Keplerian Elements and misc. data for the satellite */ +static double EpochDay; /* time of epoch */ +static double EpochMeanAnomaly; /* Mean Anomaly at epoch */ +static long EpochOrbitNum; /* Integer orbit # of epoch */ +static double EpochRAAN; /* RAAN at epoch */ +static double epochMeanMotion; /* Revolutions/day */ +static double OrbitalDecay; /* Revolutions/day^2 */ +static double EpochArgPerigee; /* argument of perigee at epoch */ +static double Eccentricity; +static double Inclination; + +/* Site Parameters */ +static double SiteLat,SiteLong,SiteAltitude; + + +static double SidDay,SidReference; /* Date and sidereal time */ + +/* Keplerian elements for the sun */ +static double SunEpochTime,SunInclination,SunRAAN,SunEccentricity, + SunArgPerigee,SunMeanAnomaly,SunMeanMotion; + +/* values for shadow geometry */ +static double SinPenumbra,CosPenumbra; + + +/* given a Now and an Obj with info about an earth satellite in the es_* fields + * fill in the s_* sky fields describing the satellite. + * as usual, we compute the geocentric ra/dec precessed to np->n_epoch and + * compute topocentric altitude accounting for refraction. + * return 0 if all ok, else -1. + */ +int +obj_earthsat (Now *np, Obj *op) +{ + double Radius; /* From geocenter */ + double SatX,SatY,SatZ; /* In Right Ascension based system */ + double SatVX,SatVY,SatVZ; /* Kilometers/second */ + double SiteX,SiteY,SiteZ; + double SiteVX,SiteVY; + double SiteMatrix[3][3]; + double Height; + double SSPLat,SSPLong; + double Azimuth,Elevation,Range; + double RangeRate; + double dtmp; + double CrntTime; + double ra, dec; + +#ifdef ESAT_TRACE + printf ("\n"); + printf ("Name = %s\n", op->o_name); + printf ("current jd = %13.5f\n", mjd+MJD0); + printf ("current mjd = %g\n", mjd); + printf ("satellite jd = %13.5f\n", op->es_epoch+MJD0); + printf ("satellite mjd = %g\n", op->es_epoch); +#endif /* ESAT_TRACE */ + + /* xephem uses noon 12/31/1899 as 0; orbit uses midnight 1/1/1900. + * thus, xephem runs 12 hours, or 1/2 day, behind of what orbit wants. + */ + CrntTime = mjd + 0.5; + + /* extract the XEphem data forms into those used by orbit. + * (we still use some functions and names from orbit, thank you). + */ + InitOrbitRoutines(CrntTime, 1); + GetSatelliteParams(op); + GetSiteParams(np); + + /* propagate to np->n_mjd */ + esat_prop (np, op, &SatX, &SatY, &SatZ, &SatVX, &SatVY, &SatVZ); + Radius = sqrt (SatX*SatX + SatY*SatY + SatZ*SatZ); + + /* find geocentric EOD equatorial directly from xyz vector */ + dtmp = atan2 (SatY, SatX); + range (&dtmp, 2*PI); + op->s_gaera = (float) dtmp; + op->s_gaedec = (float) atan2 (SatZ, sqrt(SatX*SatX + SatY*SatY)); + + /* find topocentric from site location */ + GetSitPosition(SiteLat,SiteLong,SiteAltitude,CrntTime, + &SiteX,&SiteY,&SiteZ,&SiteVX,&SiteVY,SiteMatrix); + GetBearings(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix, + &Azimuth,&Elevation); + + op->s_az = Azimuth; + refract (pressure, temp, Elevation, &dtmp); + op->s_alt = dtmp; + + /* Range: line-of-site distance to satellite, m + * RangeRate: m/s + */ + GetRange(SiteX,SiteY,SiteZ,SiteVX,SiteVY, + SatX,SatY,SatZ,SatVX,SatVY,SatVZ,&Range,&RangeRate); + + op->s_range = (float)(Range*1000); /* we want m */ + op->s_rangev = (float)(RangeRate*1000); /* we want m/s */ + + /* SSPLat: sub-satellite latitude, rads + * SSPLong: sub-satellite longitude, >0 west, rads + * Height: height of satellite above ground, m + */ + GetSubSatPoint(SatX,SatY,SatZ,CrntTime, + &SSPLat,&SSPLong,&Height); + + op->s_elev = (float)(Height*1000); /* we want m */ + op->s_sublat = (float)SSPLat; + op->s_sublng = (float)(-SSPLong); /* we want +E */ + + op->s_eclipsed = Eclipsed(SatX,SatY,SatZ,Radius,CrntTime); + +#ifdef ESAT_TRACE + printf ("CrntTime = %g\n", CrntTime); + printf ("SatX = %g\n", SatX); + printf ("SatY = %g\n", SatY); + printf ("SatZ = %g\n", SatZ); + printf ("Radius = %g\n", Radius); + printf ("SatVX = %g\n", SatVX); + printf ("SatVY = %g\n", SatVY); + printf ("SatVZ = %g\n", SatVZ); + printf ("SiteX = %g\n", SiteX); + printf ("SiteY = %g\n", SiteY); + printf ("SiteZ = %g\n", SiteZ); + printf ("SiteVX = %g\n", SiteVX); + printf ("SiteVY = %g\n", SiteVY); + printf ("Height = %g\n", Height); + printf ("SSPLat = %g\n", SSPLat); + printf ("SSPLong = %g\n", SSPLong); + printf ("Azimuth = %g\n", Azimuth); + printf ("Elevation = %g\n", Elevation); + printf ("Range = %g\n", Range); + printf ("RangeRate = %g\n", RangeRate); + fflush (stdout); +#endif /* ESAT_TRACE */ + + /* find s_ra/dec, depending on current options. */ + if (pref_get(PREF_EQUATORIAL) == PREF_TOPO) { + double ha, lst; + aa_hadec (lat, Elevation, (double)op->s_az, &ha, &dec); + now_lst (np, &lst); + ra = hrrad(lst) - ha; + range (&ra, 2*PI); + } else { + ra = op->s_gaera; + dec = op->s_gaedec; + } + if (epoch != EOD) + precess (mjd, epoch, &ra, &dec); + op->s_ra = (float)ra; + op->s_dec = (float)dec; + + /* just make up a size and brightness */ + set_smag (op, ESAT_MAG); + op->s_size = (float)0; + + return (0); +} + +/* find position and velocity vector for given Obj at the given time. + * set USE_ORBIT_PROPAGATOR depending on desired propagator to use. + */ +static void +esat_prop (Now *np, Obj *op, double *SatX, double *SatY, double *SatZ, +double *SatVX, double *SatVY, double *SatVZ) +{ +#ifdef USE_ORBIT_PROPAGATOR + double ReferenceOrbit; /* Floating point orbit # at epoch */ + double CurrentOrbit; + long OrbitNum; + double RAANPrecession,PerigeePrecession; + double MeanAnomaly,TrueAnomaly; + double SemiMajorAxis; + double AverageMotion, /* Corrected for drag */ + CurrentMotion; + double Radius; + double CrntTime; + + if (crazyOp (np, op)) { + *SatX = *SatY = *SatZ = *SatVX = *SatVY = *SatVZ = 0; + return; + } + + SemiMajorAxis = 331.25 * exp(2*log(MinutesPerDay/epochMeanMotion)/3); + GetPrecession(SemiMajorAxis,Eccentricity,Inclination,&RAANPrecession, + &PerigeePrecession); + + ReferenceOrbit = EpochMeanAnomaly/PI2 + EpochOrbitNum; + + CrntTime = mjd + 0.5; + AverageMotion = epochMeanMotion + (CrntTime-EpochDay)*OrbitalDecay/2; + CurrentMotion = epochMeanMotion + (CrntTime-EpochDay)*OrbitalDecay; + + SemiMajorAxis = 331.25 * exp(2*log(MinutesPerDay/CurrentMotion)/3); + + CurrentOrbit = ReferenceOrbit + (CrntTime-EpochDay)*AverageMotion; + + OrbitNum = CurrentOrbit; + + MeanAnomaly = (CurrentOrbit-OrbitNum)*PI2; + + TrueAnomaly = Kepler(MeanAnomaly,Eccentricity); + + GetSatPosition(EpochDay,EpochRAAN,EpochArgPerigee,SemiMajorAxis, + Inclination,Eccentricity,RAANPrecession,PerigeePrecession, + CrntTime,TrueAnomaly,SatX,SatY,SatZ,&Radius,SatVX,SatVY,SatVZ); + +#ifdef ESAT_TRACE + printf ("O Radius = %g\n", Radius); + printf ("ReferenceOrbit = %g\n", ReferenceOrbit); + printf ("CurrentOrbit = %g\n", CurrentOrbit); + printf ("RAANPrecession = %g\n", RAANPrecession); + printf ("PerigeePrecession = %g\n", PerigeePrecession); + printf ("MeanAnomaly = %g\n", MeanAnomaly); + printf ("TrueAnomaly = %g\n", TrueAnomaly); + printf ("SemiMajorAxis = %g\n", SemiMajorAxis); + printf ("AverageMotion = %g\n", AverageMotion); + printf ("CurrentMotion = %g\n", CurrentMotion); +#endif /* ESAT_TRACE */ + +#else /* ! USE_ORBIT_PROPAGATOR */ +#define MPD 1440.0 /* minutes per day */ + + SatElem se; + SatData sd; + Vec3 posvec, velvec; + double dy; + double dt; + int yr; + + if (crazyOp (np, op)) { + *SatX = *SatY = *SatZ = *SatVX = *SatVY = *SatVZ = 0; + return; + } + + /* init */ + memset ((void *)&se, 0, sizeof(se)); + memset ((void *)&sd, 0, sizeof(sd)); + sd.elem = &se; + + /* se_EPOCH is packed as yr*1000 + dy, where yr is years since 1900 + * and dy is day of year, Jan 1 being 1 + */ + mjd_dayno (op->es_epoch, &yr, &dy); + yr -= 1900; + dy += 1; + se.se_EPOCH = yr*1000 + dy; + + /* others carry over with some change in units */ + se.se_XNO = op->es_n * (2*PI/MPD); /* revs/day to rads/min */ + se.se_XINCL = (float)degrad(op->es_inc); + se.se_XNODEO = (float)degrad(op->es_raan); + se.se_EO = op->es_e; + se.se_OMEGAO = (float)degrad(op->es_ap); + se.se_XMO = (float)degrad(op->es_M); + se.se_BSTAR = op->es_drag; + se.se_XNDT20 = op->es_decay*(2*PI/MPD/MPD); /*rv/dy^^2 to rad/min^^2*/ + + se.se_id.orbit = op->es_orbit; + + dt = (mjd-op->es_epoch)*MPD; + +#ifdef ESAT_TRACE + printf ("se_EPOCH : %30.20f\n", se.se_EPOCH); + printf ("se_XNO : %30.20f\n", se.se_XNO); + printf ("se_XINCL : %30.20f\n", se.se_XINCL); + printf ("se_XNODEO : %30.20f\n", se.se_XNODEO); + printf ("se_EO : %30.20f\n", se.se_EO); + printf ("se_OMEGAO : %30.20f\n", se.se_OMEGAO); + printf ("se_XMO : %30.20f\n", se.se_XMO); + printf ("se_BSTAR : %30.20f\n", se.se_BSTAR); + printf ("se_XNDT20 : %30.20f\n", se.se_XNDT20); + printf ("se_orbit : %30d\n", se.se_id.orbit); + printf ("dt : %30.20f\n", dt); +#endif /* ESAT_TRACE */ + + /* compute the state vectors */ + if (se.se_XNO >= (1.0/225.0)) + sgp4(&sd, &posvec, &velvec, dt); /* NEO */ + else + sdp4(&sd, &posvec, &velvec, dt); /* GEO */ + if (sd.prop.sgp4) + free (sd.prop.sgp4); /* sd.prop.sdp4 is in same union */ + if (sd.deep) + free (sd.deep); + + /* earth radii to km */ + *SatX = (ERAD/1000)*posvec.x; + *SatY = (ERAD/1000)*posvec.y; + *SatZ = (ERAD/1000)*posvec.z; + /* Minutes per day/Seconds by day = Minutes/Second = 1/60 */ + *SatVX = (ERAD*velvec.x)/(1000*60); + *SatVY =(ERAD*velvec.y)/(1000*60); + *SatVZ = (ERAD*velvec.z)/(1000*60); + +#endif +} + +/* return 1 if op is crazy @ np */ +static int +crazyOp (Now *np, Obj *op) +{ + /* toss if more than a year old */ + return (fabs(op->es_epoch - mjd) > 365); +} + +/* grab the xephem stuff from op and copy into orbit's globals. + */ +static void +GetSatelliteParams(Obj *op) +{ + /* the following are for the orbit functions */ + /* xephem uses noon 12/31/1899 as 0; orbit uses midnight 1/1/1900 as 1. + * thus, xephem runs 12 hours, or 1/2 day, behind of what orbit wants. + */ + EpochDay = op->es_epoch + 0.5; + + /* xephem stores inc in degrees; orbit wants rads */ + Inclination = degrad(op->es_inc); + + /* xephem stores RAAN in degrees; orbit wants rads */ + EpochRAAN = degrad(op->es_raan); + + Eccentricity = op->es_e; + + /* xephem stores arg of perigee in degrees; orbit wants rads */ + EpochArgPerigee = degrad(op->es_ap); + + /* xephem stores mean anomaly in degrees; orbit wants rads */ + EpochMeanAnomaly = degrad (op->es_M); + + epochMeanMotion = op->es_n; + + OrbitalDecay = op->es_decay; + + EpochOrbitNum = op->es_orbit; +} + + + +static void +GetSiteParams(Now *np) +{ + SiteLat = lat; + + /* xephem stores longitude as >0 east; orbit wants >0 west */ + SiteLong = 2.0*PI - lng; + + /* what orbit calls altitude xephem calls elevation and stores it from + * sea level in earth radii; orbit wants km + */ + SiteAltitude = elev*ERAD/1000.0; + + /* we don't implement a minimum horizon altitude cutoff + SiteMinElev = 0; + */ + +#ifdef ESAT_TRACE + printf ("SiteLat = %g\n", SiteLat); + printf ("SiteLong = %g\n", SiteLong); + printf ("SiteAltitude = %g\n", SiteAltitude); + fflush (stdout); +#endif +} + + +/* Solve Kepler's equation */ +/* Inputs: */ +/* MeanAnomaly Time Since last perigee, in radians. */ +/* PI2 = one complete orbit. */ +/* Eccentricity Eccentricity of orbit's ellipse. */ +/* Output: */ +/* TrueAnomaly Angle between perigee, geocenter, and */ +/* current position. */ + +static +double Kepler(double MeanAnomaly, double Eccentricity) +{ +register double E; /* Eccentric Anomaly */ +register double Error; +register double TrueAnomaly; + + E = MeanAnomaly ;/*+ Eccentricity*sin(MeanAnomaly); -- Initial guess */ + do + { + Error = (E - Eccentricity*sin(E) - MeanAnomaly) + / (1 - Eccentricity*cos(E)); + E -= Error; + } + while (ABS(Error) >= Epsilon); + + if (ABS(E-PI) < Epsilon) + TrueAnomaly = PI; + else + TrueAnomaly = 2*atan(sqrt((1+Eccentricity)/(1-Eccentricity)) + *tan(E/2)); + if (TrueAnomaly < 0) + TrueAnomaly += PI2; + + return TrueAnomaly; +} + +static void +GetSubSatPoint(double SatX, double SatY, double SatZ, double T, +double *Latitude, double *Longitude, double *Height) +{ + double r; + /* ECD: long i; */ + + r = sqrt(SQR(SatX) + SQR(SatY) + SQR(SatZ)); + + *Longitude = PI2*((T-SidDay)*SiderealSolar + SidReference) + - atan2(SatY,SatX); + + /* ECD: + * want Longitude in range -PI to PI , +W + */ + range (Longitude, 2*PI); + if (*Longitude > PI) + *Longitude -= 2*PI; + + *Latitude = atan(SatZ/sqrt(SQR(SatX) + SQR(SatY))); + +#define SSPELLIPSE +#ifdef SSPELLIPSE + /* ECD */ + *Height = r - EarthRadius*(sqrt(1-(2*EarthFlat-SQR(EarthFlat))*SQR(sin(*Latitude)))); +#else + *Height = r - EarthRadius; +#endif +} + + +#ifdef USE_ORBIT_PROPAGATOR +static void +GetPrecession(double SemiMajorAxis, double Eccentricity, double Inclination, +double *RAANPrecession, double *PerigeePrecession) +{ + *RAANPrecession = 9.95*pow(EarthRadius/SemiMajorAxis,3.5) * cos(Inclination) + / SQR(1-SQR(Eccentricity)) * RadiansPerDegree; + + *PerigeePrecession = 4.97*pow(EarthRadius/SemiMajorAxis,3.5) + * (5*SQR(cos(Inclination))-1) + / SQR(1-SQR(Eccentricity)) * RadiansPerDegree; +} +#endif /* USE_ORBIT_PROPAGATOR */ + +/* Compute the satellite postion and velocity in the RA based coordinate + * system. + * ECD: take care not to let Radius get below EarthRadius. + */ + +static void +GetSatPosition(double EpochTime, double EpochRAAN, double EpochArgPerigee, +double SemiMajorAxis, double Inclination, double Eccentricity, +double RAANPrecession, double PerigeePrecession, double T, +double TrueAnomaly, double *X, double *Y, double *Z, double *Radius, +double *VX, double *VY, double *VZ) + +{ + double RAAN,ArgPerigee; + + + double Xw,Yw,VXw,VYw; /* In orbital plane */ + double Tmp; + double Px,Qx,Py,Qy,Pz,Qz; /* Escobal transformation 31 */ + double CosArgPerigee,SinArgPerigee; + double CosRAAN,SinRAAN,CoSinclination,SinInclination; + + *Radius = SemiMajorAxis*(1-SQR(Eccentricity)) + / (1+Eccentricity*cos(TrueAnomaly)); + + if (*Radius <= EarthRadius) + *Radius = EarthRadius; + + + Xw = *Radius * cos(TrueAnomaly); + Yw = *Radius * sin(TrueAnomaly); + + Tmp = sqrt(GM/(SemiMajorAxis*(1-SQR(Eccentricity)))); + + VXw = -Tmp*sin(TrueAnomaly); + VYw = Tmp*(cos(TrueAnomaly) + Eccentricity); + + ArgPerigee = EpochArgPerigee + (T-EpochTime)*PerigeePrecession; + RAAN = EpochRAAN - (T-EpochTime)*RAANPrecession; + + CosRAAN = cos(RAAN); SinRAAN = sin(RAAN); + CosArgPerigee = cos(ArgPerigee); SinArgPerigee = sin(ArgPerigee); + CoSinclination = cos(Inclination); SinInclination = sin(Inclination); + + Px = CosArgPerigee*CosRAAN - SinArgPerigee*SinRAAN*CoSinclination; + Py = CosArgPerigee*SinRAAN + SinArgPerigee*CosRAAN*CoSinclination; + Pz = SinArgPerigee*SinInclination; + Qx = -SinArgPerigee*CosRAAN - CosArgPerigee*SinRAAN*CoSinclination; + Qy = -SinArgPerigee*SinRAAN + CosArgPerigee*CosRAAN*CoSinclination; + Qz = CosArgPerigee*SinInclination; + + *X = Px*Xw + Qx*Yw; /* Escobal, transformation #31 */ + *Y = Py*Xw + Qy*Yw; + *Z = Pz*Xw + Qz*Yw; + + *VX = Px*VXw + Qx*VYw; + *VY = Py*VXw + Qy*VYw; + *VZ = Pz*VXw + Qz*VYw; +} + +/* Compute the site postion and velocity in the RA based coordinate + system. SiteMatrix is set to a matrix which is used by GetTopoCentric + to convert geocentric coordinates to topocentric (observer-centered) + coordinates. */ + +static void +GetSitPosition(double SiteLat, double SiteLong, double SiteElevation, +double CrntTime, double *SiteX, double *SiteY, double *SiteZ, double *SiteVX, +double *SiteVY, MAT3x3 SiteMatrix) +{ + static double G1,G2; /* Used to correct for flattening of the Earth */ + static double CosLat,SinLat; + static double OldSiteLat = -100000; /* Used to avoid unneccesary recomputation */ + static double OldSiteElevation = -100000; + double Lat; + double SiteRA; /* Right Ascension of site */ + double CosRA,SinRA; + + if ((SiteLat != OldSiteLat) || (SiteElevation != OldSiteElevation)) + { + OldSiteLat = SiteLat; + OldSiteElevation = SiteElevation; + Lat = atan(1/(1-SQR(EarthFlat))*tan(SiteLat)); + + CosLat = cos(Lat); + SinLat = sin(Lat); + + G1 = EarthRadius/(sqrt(1-(2*EarthFlat-SQR(EarthFlat))*SQR(SinLat))); + G2 = G1*SQR(1-EarthFlat); + G1 += SiteElevation; + G2 += SiteElevation; + } + + + SiteRA = PI2*((CrntTime-SidDay)*SiderealSolar + SidReference) + - SiteLong; + CosRA = cos(SiteRA); + SinRA = sin(SiteRA); + + + *SiteX = G1*CosLat*CosRA; + *SiteY = G1*CosLat*SinRA; + *SiteZ = G2*SinLat; + *SiteVX = -SidRate * *SiteY; + *SiteVY = SidRate * *SiteX; + + SiteMatrix[0][0] = SinLat*CosRA; + SiteMatrix[0][1] = SinLat*SinRA; + SiteMatrix[0][2] = -CosLat; + SiteMatrix[1][0] = -SinRA; + SiteMatrix[1][1] = CosRA; + SiteMatrix[1][2] = 0.0; + SiteMatrix[2][0] = CosRA*CosLat; + SiteMatrix[2][1] = SinRA*CosLat; + SiteMatrix[2][2] = SinLat; +} + +static void +GetRange(double SiteX, double SiteY, double SiteZ, double SiteVX, +double SiteVY, double SatX, double SatY, double SatZ, double SatVX, +double SatVY, double SatVZ, double *Range, double *RangeRate) +{ + double DX,DY,DZ; + + DX = SatX - SiteX; DY = SatY - SiteY; DZ = SatZ - SiteZ; + + *Range = sqrt(SQR(DX)+SQR(DY)+SQR(DZ)); + + *RangeRate = ((SatVX-SiteVX)*DX + (SatVY-SiteVY)*DY + SatVZ*DZ) + / *Range; +} + +/* Convert from geocentric RA based coordinates to topocentric + (observer centered) coordinates */ + +static void +GetTopocentric(double SatX, double SatY, double SatZ, double SiteX, +double SiteY, double SiteZ, MAT3x3 SiteMatrix, double *X, double *Y, +double *Z) +{ + SatX -= SiteX; + SatY -= SiteY; + SatZ -= SiteZ; + + *X = SiteMatrix[0][0]*SatX + SiteMatrix[0][1]*SatY + + SiteMatrix[0][2]*SatZ; + *Y = SiteMatrix[1][0]*SatX + SiteMatrix[1][1]*SatY + + SiteMatrix[1][2]*SatZ; + *Z = SiteMatrix[2][0]*SatX + SiteMatrix[2][1]*SatY + + SiteMatrix[2][2]*SatZ; +} + +static void +GetBearings(double SatX, double SatY, double SatZ, double SiteX, +double SiteY, double SiteZ, MAT3x3 SiteMatrix, double *Azimuth, +double *Elevation) +{ + double x,y,z; + + GetTopocentric(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,&x,&y,&z); + + *Elevation = atan(z/sqrt(SQR(x) + SQR(y))); + + *Azimuth = PI - atan2(y,x); + + if (*Azimuth < 0) + *Azimuth += PI; +} + +static int +Eclipsed(double SatX, double SatY, double SatZ, double SatRadius, +double CrntTime) +{ + double MeanAnomaly,TrueAnomaly; + double SunX,SunY,SunZ,SunRad; + double vx,vy,vz; + double CosTheta; + + MeanAnomaly = SunMeanAnomaly+ (CrntTime-SunEpochTime)*SunMeanMotion*PI2; + TrueAnomaly = Kepler(MeanAnomaly,SunEccentricity); + + GetSatPosition(SunEpochTime,SunRAAN,SunArgPerigee,SunSemiMajorAxis, + SunInclination,SunEccentricity,0.0,0.0,CrntTime, + TrueAnomaly,&SunX,&SunY,&SunZ,&SunRad,&vx,&vy,&vz); + + CosTheta = (SunX*SatX + SunY*SatY + SunZ*SatZ)/(SunRad*SatRadius) + *CosPenumbra + (SatRadius/EarthRadius)*SinPenumbra; + + if (CosTheta < 0) + if (CosTheta < -sqrt(SQR(SatRadius)-SQR(EarthRadius))/SatRadius + *CosPenumbra + (SatRadius/EarthRadius)*SinPenumbra) + + return 1; + return 0; +} + +/* Initialize the Sun's keplerian elements for a given epoch. + Formulas are from "Explanatory Supplement to the Astronomical Ephemeris". + Also init the sidereal reference */ + +static void +InitOrbitRoutines(double EpochDay, int AtEod) +{ + double T,T2,T3,Omega; + int n; + double SunTrueAnomaly,SunDistance; + + T = (floor(EpochDay)-0.5)/36525; + T2 = T*T; + T3 = T2*T; + + SidDay = floor(EpochDay); + + SidReference = (6.6460656 + 2400.051262*T + 0.00002581*T2)/24; + SidReference -= floor(SidReference); + + /* Omega is used to correct for the nutation and the abberation */ + Omega = AtEod ? (259.18 - 1934.142*T) * RadiansPerDegree : 0.0; + n = (int)(Omega / PI2); + Omega -= n*PI2; + + SunEpochTime = EpochDay; + SunRAAN = 0; + + SunInclination = (23.452294 - 0.0130125*T - 0.00000164*T2 + + 0.000000503*T3 +0.00256*cos(Omega)) * RadiansPerDegree; + SunEccentricity = (0.01675104 - 0.00004180*T - 0.000000126*T2); + SunArgPerigee = (281.220833 + 1.719175*T + 0.0004527*T2 + + 0.0000033*T3) * RadiansPerDegree; + SunMeanAnomaly = (358.475845 + 35999.04975*T - 0.00015*T2 + - 0.00000333333*T3) * RadiansPerDegree; + n = (int)(SunMeanAnomaly / PI2); + SunMeanAnomaly -= n*PI2; + + SunMeanMotion = 1/(365.24219879 - 0.00000614*T); + + SunTrueAnomaly = Kepler(SunMeanAnomaly,SunEccentricity); + SunDistance = SunSemiMajorAxis*(1-SQR(SunEccentricity)) + / (1+SunEccentricity*cos(SunTrueAnomaly)); + + SinPenumbra = (SunRadius-EarthRadius)/SunDistance; + CosPenumbra = sqrt(1-SQR(SinPenumbra)); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: earthsat.c,v $ $Date: 2015/04/08 23:36:35 $ $Revision: 1.14 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/eq_ecl.c b/Common/Libraries/XEphemAstroLib/src/eq_ecl.c new file mode 100644 index 000000000..14abc5e26 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/eq_ecl.c @@ -0,0 +1,72 @@ +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +static void ecleq_aux (int sw, double mj, double x, double y, + double *p, double *q); + +#define EQtoECL 1 +#define ECLtoEQ (-1) + + +/* given the modified Julian date, mj, and an equitorial ra and dec, each in + * radians, find the corresponding geocentric ecliptic latitude, *lt, and + * longititude, *lg, also each in radians. + * correction for the effect on the angle of the obliquity due to nutation is + * not included. + */ +void +eq_ecl (double mj, double ra, double dec, double *lt, double *lg) +{ + ecleq_aux (EQtoECL, mj, ra, dec, lg, lt); +} + +/* given the modified Julian date, mj, and a geocentric ecliptic latitude, + * *lt, and longititude, *lg, each in radians, find the corresponding + * equitorial ra and dec, also each in radians. + * correction for the effect on the angle of the obliquity due to nutation is + * not included. + */ +void +ecl_eq (double mj, double lt, double lg, double *ra, double *dec) +{ + ecleq_aux (ECLtoEQ, mj, lg, lt, ra, dec); +} + +static void +ecleq_aux ( +int sw, /* +1 for eq to ecliptic, -1 for vv. */ +double mj, +double x, double y, /* sw==1: x==ra, y==dec. sw==-1: x==lg, y==lt. */ +double *p, double *q) /* sw==1: p==lg, q==lt. sw==-1: p==ra, q==dec. */ +{ + static double lastmj = -10000; /* last mj calculated */ + static double seps, ceps; /* sin and cos of mean obliquity */ + double sx, cx, sy, cy, ty, sq; + + if (mj != lastmj) { + double eps; + obliquity (mj, &eps); /* mean obliquity for date */ + seps = sin(eps); + ceps = cos(eps); + lastmj = mj; + } + + sy = sin(y); + cy = cos(y); /* always non-negative */ + if (fabs(cy)<1e-20) cy = 1e-20; /* insure > 0 */ + ty = sy/cy; + cx = cos(x); + sx = sin(x); + sq = (sy*ceps)-(cy*seps*sx*sw); + if (sq < -1) sq = -1; + if (sq > 1) sq = 1; + *q = asin(sq); + *p = atan(((sx*ceps)+(ty*seps*sw))/cx); + if (cx<0) *p += PI; /* account for atan quad ambiguity */ + range (p, 2*PI); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: eq_ecl.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/eq_gal.c b/Common/Libraries/XEphemAstroLib/src/eq_gal.c new file mode 100644 index 000000000..d4a5fafcf --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/eq_gal.c @@ -0,0 +1,99 @@ +/* code to convert between equitorial and galactic coordinates */ + +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +static void galeq_aux (int sw, double x, double y, double *p, double *q); +static void galeq_init (void); + +#define EQtoGAL 1 +#define GALtoEQ (-1) +#define SMALL (1e-20) + +static double an = degrad(32.93192); /* G lng of asc node on equator */ +static double gpr = degrad(192.85948); /* RA of North Gal Pole, 2000 */ +static double gpd = degrad(27.12825); /* Dec of " */ +static double cgpd, sgpd; /* cos() and sin() of gpd */ +static double mj2000; /* mj of 2000 */ +static int before; /* whether these have been set yet */ + +/* given ra and dec, each in radians, for the given epoch, find the + * corresponding galactic latitude, *lt, and longititude, *lg, also each in + * radians. + */ +void +eq_gal (double mj, double ra, double dec, double *lt, double *lg) +{ + galeq_init(); + precess (mj, mj2000, &ra, &dec); + galeq_aux (EQtoGAL, ra, dec, lg, lt); +} + +/* given galactic latitude, lt, and longititude, lg, each in radians, find + * the corresponding equitorial ra and dec, also each in radians, at the + * given epoch. + */ +void +gal_eq (double mj, double lt, double lg, double *ra, double *dec) +{ + galeq_init(); + galeq_aux (GALtoEQ, lg, lt, ra, dec); + precess (mj2000, mj, ra, dec); +} + +static void +galeq_aux ( +int sw, /* +1 for eq to gal, -1 for vv. */ +double x, double y, /* sw==1: x==ra, y==dec. sw==-1: x==lg, y==lt. */ +double *p, double *q) /* sw==1: p==lg, q==lt. sw==-1: p==ra, q==dec. */ +{ + double sy, cy, a, ca, sa, b, sq, c, d; + + cy = cos(y); + sy = sin(y); + a = x - an; + if (sw == EQtoGAL) + a = x - gpr; + ca = cos(a); + sa = sin(a); + b = sa; + if (sw == EQtoGAL) + b = ca; + sq = (cy*cgpd*b) + (sy*sgpd); + *q = asin (sq); + + if (sw == GALtoEQ) { + c = cy*ca; + d = (sy*cgpd) - (cy*sgpd*sa); + if (fabs(d) < SMALL) + d = SMALL; + *p = atan (c/d) + gpr; + } else { + c = sy - (sq*sgpd); + d = cy*sa*cgpd; + if (fabs(d) < SMALL) + d = SMALL; + *p = atan (c/d) + an; + } + + if (d < 0) *p += PI; + if (*p < 0) *p += 2*PI; + if (*p > 2*PI) *p -= 2*PI; +} + +/* set up the definitions */ +static void +galeq_init() +{ + if (!before) { + cgpd = cos (gpd); + sgpd = sin (gpd); + mj2000 = J2000; + before = 1; + } +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: eq_gal.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/formats.c b/Common/Libraries/XEphemAstroLib/src/formats.c new file mode 100644 index 000000000..f6c10538e --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/formats.c @@ -0,0 +1,212 @@ +#include <stdio.h> +#include <math.h> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + +#include "astro.h" +#include "preferences.h" + +/* sprint the variable a in sexagesimal format into out[]. + * w is the number of spaces for the whole part. + * fracbase is the number of pieces a whole is to broken into; valid options: + * 360000: <w>:mm:ss.ss + * 36000: <w>:mm:ss.s + * 3600: <w>:mm:ss + * 600: <w>:mm.m + * 60: <w>:mm + * return number of characters written to out, not counting final '\0'. + */ +int +fs_sexa (char *out, double a, int w, int fracbase) +{ + char *out0 = out; + unsigned long n; + int d; + int f; + int m; + int s; + int isneg; + + /* save whether it's negative but do all the rest with a positive */ + isneg = (a < 0); + if (isneg) + a = -a; + + /* convert to an integral number of whole portions */ + n = (unsigned long)(a * fracbase + 0.5); + d = n/fracbase; + f = n%fracbase; + + /* form the whole part; "negative 0" is a special case */ + if (isneg && d == 0) + out += sprintf (out, "%*s-0", w-2, ""); + else + out += sprintf (out, "%*d", w, isneg ? -d : d); + + /* do the rest */ + switch (fracbase) { + case 60: /* dd:mm */ + m = f/(fracbase/60); + out += sprintf (out, ":%02d", m); + break; + case 600: /* dd:mm.m */ + out += sprintf (out, ":%02d.%1d", f/10, f%10); + break; + case 3600: /* dd:mm:ss */ + m = f/(fracbase/60); + s = f%(fracbase/60); + out += sprintf (out, ":%02d:%02d", m, s); + break; + case 36000: /* dd:mm:ss.s*/ + m = f/(fracbase/60); + s = f%(fracbase/60); + out += sprintf (out, ":%02d:%02d.%1d", m, s/10, s%10); + break; + case 360000: /* dd:mm:ss.ss */ + m = f/(fracbase/60); + s = f%(fracbase/60); + out += sprintf (out, ":%02d:%02d.%02d", m, s/100, s%100); + break; + default: + printf ("fs_sexa: unknown fracbase: %d\n", fracbase); + abort(); + } + + return (out - out0); +} + +/* put the given modified Julian date, jd, in out[] according to the given + * preference format. + * return number of characters written to out, not counting final '\0'. + */ +int +fs_date (char out[], int format, double jd) +{ + char *out0 = out; + int m, y; + double d; + + mjd_cal (jd, &m, &d, &y); + /* beware of %g rounding day up */ + if ((d < 1.0 && d - floor(d) >= .9999995) + || (d < 10.0 && d - floor(d) >= .999995) + || (d >= 10.0 && d - floor(d) >= .99995)) + mjd_cal (mjd_day(jd+0.5), &m, &d, &y); + + switch (format) { + case PREF_YMD: + out += sprintf (out, "%4d/%02d/%02.6g", y, m, d); + break; + case PREF_DMY: + out += sprintf (out, "%2.6g/%02d/%-4d", d, m, y); + break; + case PREF_MDY: + out += sprintf (out, "%2d/%02.6g/%-4d", m, d, y); + break; + default: + printf ("fs_date: bad date pref: %d\n", format); + abort(); + } + + return (out - out0); +} + + +/* convert sexagesimal string str AxBxC to double. + * x can be anything non-numeric. Any missing A, B or C will be assumed 0. + * optional - and + can be anywhere. + * return 0 if ok, -1 if can't find a thing. + */ +int +f_scansexa ( +const char *str0, /* input string */ +double *dp) /* cracked value, if return 0 */ +{ + double a, b, c; + char str[256]; + char *neg; + int isneg, r; + + /* copy str0 so we can play with it */ + strncpy (str, str0, sizeof(str)-1); + str[sizeof(str)-1] = '\0'; + + /* note first negative (but not fooled by neg exponent) */ + isneg = 0; + neg = strchr(str, '-'); + if (neg && (neg == str || (neg[-1] != 'E' && neg[-1] != 'e'))) { + *neg = ' '; + isneg = 1; + } + + /* crack up to three components */ + a = b = c = 0.0; + r = sscanf (str, "%lf%*[^0-9]%lf%*[^0-9]%lf", &a, &b, &c); + if (r < 1) + return (-1); + + /* back to one value, restoring neg */ + *dp = (c/60.0 + b)/60.0 + a; + if (isneg) + *dp *= -1; + return (0); +} + +/* crack a floating date string, bp, of the form X/Y/Z determined by the + * PREF_DATE_FORMAT preference into its components. allow the day to be a + * floating point number, + * the slashes may also be spaces or colons. + * a lone component with a decimal point is considered a year. + */ +void +f_sscandate ( +char *bp, +int pref, /* one of PREF_X for PREF_DATE_FORMAT */ +int *m, +double *d, +int *y) +{ + double X,Y,Z; /* the three components */ + int n; + + X = Y = Z = 0.0; + n = sscanf (bp, "%lf%*[/: ]%lf%*[/: ]%lf", &X, &Y, &Z); + if (n == 1 && (strchr(bp, '.') + || (pref == PREF_MDY && (X < 1 || X > 12)) + || (pref == PREF_DMY && (X < 1 || X > 31)))) { + double Mjd; + year_mjd (X, &Mjd); + mjd_cal (Mjd, m, d, y); + } else { + switch (pref) { + case PREF_MDY: + if (n > 0 && X != 0) + *m = (int)X; + if (n > 1 && Y != 0) + *d = Y; + if (n > 2 && Z != 0) + *y = (int)Z; + break; + case PREF_YMD: + if (n > 0 && X != 0) + *y = (int)X; + if (n > 1 && Y != 0) + *m = (int)Y; + if (n > 2 && Z != 0) + *d = Z; + break; + case PREF_DMY: + if (n > 0 && X != 0) + *d = X; + if (n > 1 && Y != 0) + *m = (int)Y; + if (n > 2 && Z != 0) + *y = (int)Z; + break; + } + } +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: formats.c,v $ $Date: 2006/04/10 09:00:06 $ $Revision: 1.17 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/helio.c b/Common/Libraries/XEphemAstroLib/src/helio.c new file mode 100644 index 000000000..d0dceae1d --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/helio.c @@ -0,0 +1,51 @@ +#include <stdlib.h> +#include <math.h> +#include <math.h> + +#include "astro.h" + +/* given geocentric time jd and coords of a distant object at ra/dec (J2000), + * find the difference in time between light arriving at earth vs the sun. + * *hcp must be subtracted from geocentric jd to get heliocentric jd. + * From RLM Oct 12, 1995. + */ +void +heliocorr (double jd, double ra, double dec, double *hcp) +{ + double e; /* obliquity of ecliptic */ + double n; /* day number */ + double g; /* solar mean anomaly */ + double L; /* solar ecliptic longitude */ + double l; /* mean solar ecliptic longitude */ + double R; /* sun distance, AU */ + double X, Y; /* equatorial rectangular solar coords */ + double cdec, sdec; + double cra, sra; + + /* following algorithm really wants EOD */ + precess (J2000, jd - MJD0, &ra, &dec); + + cdec = cos(dec); + sdec = sin(dec); + cra = cos(ra); + sra = sin(ra); + + n = jd - 2451545.0; /* use epoch 2000 */ + e = degrad(23.439 - 0.0000004*n); + g = degrad(357.528) + degrad(0.9856003)*n; + L = degrad(280.461) + degrad(0.9856474)*n; + l = L + degrad(1.915)*sin(g) + degrad(0.02)*sin(2.0*g); + R = 1.00014 - 0.01671*cos(g) - 0.00014*cos(2.0*g); + X = R*cos(l); + Y = R*cos(e)*sin(l); + +#if 0 + printf ("n=%g g=%g L=%g l=%g R=%g X=%g Y=%g\n", + n, raddeg(g), raddeg(L), raddeg(l), R, X, Y); +#endif + + *hcp = 0.0057755 * (cdec*cra*X + (cdec*sra + tan(e)*sdec)*Y); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: helio.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/jupmoon.c b/Common/Libraries/XEphemAstroLib/src/jupmoon.c new file mode 100644 index 000000000..40cb4ada9 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/jupmoon.c @@ -0,0 +1,391 @@ +/* jupiter moon info */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <math.h> + +#include "astro.h" +#include "bdl.h" + +static int use_bdl (double jd, char *dir, MoonData md[J_NMOONS]); +static void meeus_jupiter (double d, double *cmlI, double *cmlII, + MoonData md[J_NMOONS]); +static void moonradec (double jupsize, MoonData md[J_NMOONS]); +static void moonSVis (Obj *sop, Obj *jop, MoonData md[J_NMOONS]); +static void moonEVis (MoonData md[J_NMOONS]); +static void moonPShad (Obj *sop, Obj *jop, MoonData md[J_NMOONS]); +static void moonTrans (MoonData md[J_NMOONS]); + +/* moon table and a few other goodies and when it was last computed */ +static double mdmjd = -123456; +static MoonData jmd[J_NMOONS] = { + {"Jupiter", NULL}, + {"Io", "I"}, + {"Europa", "II"}, + {"Ganymede", "III"}, + {"Callisto", "IV"} +}; +static double sizemjd; /* size at last mjd */ +static double cmlImjd; /* central meridian long sys I, at last mjd */ +static double cmlIImjd; /* " II " */ + +/* These values are from the Explanatory Supplement. + * Precession degrades them gradually over time. + */ +#define POLE_RA degrad(268.05) /* RA of Jupiter's north pole */ +#define POLE_DEC degrad(64.50) /* Dec of Jupiter's north pole */ + + +/* get jupiter info in md[0], moon info in md[1..J_NMOONS-1]. + * if !dir always use meeus model. + * if !jop caller just wants md[] for names + * N.B. we assume sop and jop are updated. + */ +void +jupiter_data ( +double Mjd, /* mjd */ +char dir[], /* dir in which to look for helper files */ +Obj *sop, /* Sun */ +Obj *jop, /* jupiter */ +double *sizep, /* jup angular diam, rads */ +double *cmlI, double *cmlII, /* central meridian longitude, rads */ +double *polera, double *poledec, /* pole location */ +MoonData md[J_NMOONS]) /* return info */ +{ + double JD; + + /* always copy back at least for name */ + memcpy (md, jmd, sizeof(jmd)); + + /* pole */ + if (polera) *polera = POLE_RA; + if (poledec) *poledec = POLE_DEC; + + /* nothing else if repeat call or just want names */ + if (Mjd == mdmjd || !jop) { + if (jop) { + *sizep = sizemjd; + *cmlI = cmlImjd; + *cmlII = cmlIImjd; + } + return; + } + JD = Mjd + MJD0; + + /* planet in [0] */ + md[0].ra = jop->s_ra; + md[0].dec = jop->s_dec; + md[0].mag = get_mag(jop); + md[0].x = 0; + md[0].y = 0; + md[0].z = 0; + md[0].evis = 1; + md[0].svis = 1; + + /* size is straight from jop */ + *sizep = degrad(jop->s_size/3600.0); + + /* mags from JPL ephemeris */ + md[1].mag = 5.7; + md[2].mag = 5.8; + md[3].mag = 5.3; + md[4].mag = 6.7; + + /* get moon data from BDL if possible, else Meeus' model. + * always use Meeus for cml + */ + if (dir && use_bdl (JD, dir, md) == 0) + meeus_jupiter (Mjd, cmlI, cmlII, NULL); + else + meeus_jupiter (Mjd, cmlI, cmlII, md); + + /* set visibilities */ + moonSVis (sop, jop, md); + moonPShad (sop, jop, md); + moonEVis (md); + moonTrans (md); + + /* fill in moon ra and dec */ + moonradec (*sizep, md); + + /* save */ + mdmjd = Mjd; + sizemjd = *sizep; + cmlImjd = *cmlI; + cmlIImjd = *cmlII; + memcpy (jmd, md, sizeof(jmd)); +} + +/* hunt for BDL file in dir[] and use if possible + * return 0 if ok, else -1 + */ +static int +use_bdl ( +double JD, /* julian date */ +char dir[], /* directory */ +MoonData md[J_NMOONS]) /* fill md[1..NM-1].x/y/z for each moon */ +{ +#define JUPRAU .0004769108 /* jupiter radius, AU */ + double x[J_NMOONS], y[J_NMOONS], z[J_NMOONS]; + char buf[1024]; + FILE *fp; + char *fn; + int i; + + /* check ranges and appropriate data file */ + if (JD < 2451179.50000) /* Jan 1 1999 UTC */ + return (-1); + if (JD < 2455562.5) /* Jan 1 2011 UTC */ + fn = "jupiter.9910"; + else if (JD < 2459215.5) /* Jan 1 2021 UTC */ + fn = "jupiter.1020"; + else + return (-1); + + /* open */ + (void) sprintf (buf, "%s/%s", dir, fn); + fp = fopen (buf, "r"); + if (!fp) { + fprintf (stderr, "%s: %s\n", fn, strerror(errno)); + return (-1); + } + + /* use it */ + if ((i = read_bdl (fp, JD, x, y, z, buf)) < 0) { + fprintf (stderr, "%s: %s\n", fn, buf); + fclose (fp); + return (-1); + } + if (i != J_NMOONS-1) { + fprintf (stderr, "%s: BDL says %d moons, code expects %d", fn, + i, J_NMOONS-1); + fclose (fp); + return (-1); + } + + /* copy into md[1..NM-1] with our scale and sign conventions */ + for (i = 1; i < J_NMOONS; i++) { + md[i].x = x[i-1]/JUPRAU; /* we want jup radii +E */ + md[i].y = -y[i-1]/JUPRAU; /* we want jup radii +S */ + md[i].z = -z[i-1]/JUPRAU; /* we want jup radii +front */ + } + + /* ok */ + fclose (fp); + return (0); +} + +/* compute location of GRS and Galilean moons. + * if md == NULL, just to cml. + * from "Astronomical Formulae for Calculators", 2nd ed, by Jean Meeus, + * Willmann-Bell, Richmond, Va., U.S.A. (c) 1982, chapters 35 and 36. + */ +static void +meeus_jupiter( +double d, +double *cmlI, double *cmlII, /* central meridian longitude, rads */ +MoonData md[J_NMOONS]) /* fill in md[1..NM-1].x/y/z for each moon. + * N.B. md[0].ra/dec must already be set + */ +{ +#define dsin(x) sin(degrad(x)) +#define dcos(x) cos(degrad(x)) + double A, B, Del, J, K, M, N, R, V; + double cor_u1, cor_u2, cor_u3, cor_u4; + double solc, tmp, G, H, psi, r, r1, r2, r3, r4; + double u1, u2, u3, u4; + double lam, Ds; + double z1, z2, z3, z4; + double De, dsinDe; + double theta, phi; + double tvc, pvc; + double salpha, calpha; + int i; + + V = 134.63 + 0.00111587 * d; + + M = (358.47583 + 0.98560003*d); + N = (225.32833 + 0.0830853*d) + 0.33 * dsin (V); + + J = 221.647 + 0.9025179*d - 0.33 * dsin(V); + + A = 1.916*dsin(M) + 0.02*dsin(2*M); + B = 5.552*dsin(N) + 0.167*dsin(2*N); + K = (J+A-B); + R = 1.00014 - 0.01672 * dcos(M) - 0.00014 * dcos(2*M); + r = 5.20867 - 0.25192 * dcos(N) - 0.00610 * dcos(2*N); + Del = sqrt (R*R + r*r - 2*R*r*dcos(K)); + psi = raddeg (asin (R/Del*dsin(K))); + + *cmlI = degrad(268.28 + 877.8169088*(d - Del/173) + psi - B); + range (cmlI, 2*PI); + *cmlII = degrad(290.28 + 870.1869088*(d - Del/173) + psi - B); + range (cmlII, 2*PI); + + /* that's it if don't want moon info too */ + if (!md) + return; + + solc = (d - Del/173.); /* speed of light correction */ + tmp = psi - B; + + u1 = 84.5506 + 203.4058630 * solc + tmp; + u2 = 41.5015 + 101.2916323 * solc + tmp; + u3 = 109.9770 + 50.2345169 * solc + tmp; + u4 = 176.3586 + 21.4879802 * solc + tmp; + + G = 187.3 + 50.310674 * solc; + H = 311.1 + 21.569229 * solc; + + cor_u1 = 0.472 * dsin (2*(u1-u2)); + cor_u2 = 1.073 * dsin (2*(u2-u3)); + cor_u3 = 0.174 * dsin (G); + cor_u4 = 0.845 * dsin (H); + + r1 = 5.9061 - 0.0244 * dcos (2*(u1-u2)); + r2 = 9.3972 - 0.0889 * dcos (2*(u2-u3)); + r3 = 14.9894 - 0.0227 * dcos (G); + r4 = 26.3649 - 0.1944 * dcos (H); + + md[1].x = -r1 * dsin (u1+cor_u1); + md[2].x = -r2 * dsin (u2+cor_u2); + md[3].x = -r3 * dsin (u3+cor_u3); + md[4].x = -r4 * dsin (u4+cor_u4); + + lam = 238.05 + 0.083091*d + 0.33*dsin(V) + B; + Ds = 3.07*dsin(lam + 44.5); + De = Ds - 2.15*dsin(psi)*dcos(lam+24.) + - 1.31*(r-Del)/Del*dsin(lam-99.4); + dsinDe = dsin(De); + + z1 = r1 * dcos(u1+cor_u1); + z2 = r2 * dcos(u2+cor_u2); + z3 = r3 * dcos(u3+cor_u3); + z4 = r4 * dcos(u4+cor_u4); + + md[1].y = z1*dsinDe; + md[2].y = z2*dsinDe; + md[3].y = z3*dsinDe; + md[4].y = z4*dsinDe; + + /* compute sky transformation angle as triple vector product */ + tvc = PI/2.0 - md[0].dec; + pvc = md[0].ra; + theta = PI/2.0 - POLE_DEC; + phi = POLE_RA; + salpha = -sin(tvc)*sin(theta)*(cos(pvc)*sin(phi) - sin(pvc)*cos(phi)); + calpha = sqrt (1.0 - salpha*salpha); + + for (i = 0; i < J_NMOONS; i++) { + double tx = md[i].x*calpha + md[i].y*salpha; + double ty = -md[i].x*salpha + md[i].y*calpha; + md[i].x = tx; + md[i].y = ty; + } + + md[1].z = z1; + md[2].z = z2; + md[3].z = z3; + md[4].z = z4; +} + + +/* given jupiter loc in md[0].ra/dec and size, and location of each moon in + * md[1..NM-1].x/y in jup radii, find ra/dec of each moon in md[1..NM-1].ra/dec. + */ +static void +moonradec ( +double jupsize, /* jup diameter, rads */ +MoonData md[J_NMOONS]) /* fill in RA and Dec */ +{ + double juprad = jupsize/2; + double jupra = md[0].ra; + double jupdec = md[0].dec; + int i; + + for (i = 1; i < J_NMOONS; i++) { + double dra = juprad * md[i].x; + double ddec = juprad * md[i].y; + md[i].ra = jupra + dra; + md[i].dec = jupdec - ddec; + } +} + +/* set svis according to whether moon is in sun light */ +static void +moonSVis( +Obj *sop, /* SUN */ +Obj *jop, /* jupiter */ +MoonData md[J_NMOONS]) +{ + double esd = sop->s_edist; + double eod = jop->s_edist; + double sod = jop->s_sdist; + double soa = degrad(jop->s_elong); + double esa = asin(esd*sin(soa)/sod); + double h = sod*jop->s_hlat; + double nod = h*(1./eod - 1./sod); + double sca = cos(esa), ssa = sin(esa); + int i; + + for (i = 1; i < J_NMOONS; i++) { + MoonData *mdp = &md[i]; + double xp = sca*mdp->x + ssa*mdp->z; + double yp = mdp->y; + double zp = -ssa*mdp->x + sca*mdp->z; + double ca = cos(nod), sa = sin(nod); + double xpp = xp; + double ypp = ca*yp - sa*zp; + double zpp = sa*yp + ca*zp; + int outside = xpp*xpp + ypp*ypp > 1.0; + int infront = zpp > 0.0; + mdp->svis = outside || infront; + } +} + +/* set evis according to whether moon is geometrically visible from earth */ +static void +moonEVis (MoonData md[J_NMOONS]) +{ + int i; + + for (i = 1; i < J_NMOONS; i++) { + MoonData *mdp = &md[i]; + int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0; + int infront = mdp->z > 0.0; + mdp->evis = outside || infront; + } +} + +/* set pshad and sx,sy shadow info */ +static void +moonPShad( +Obj *sop, /* SUN */ +Obj *jop, /* jupiter */ +MoonData md[J_NMOONS]) +{ + int i; + + for (i = 1; i < J_NMOONS; i++) { + MoonData *mdp = &md[i]; + mdp->pshad = !plshadow (jop, sop, POLE_RA, POLE_DEC, mdp->x, + mdp->y, mdp->z, &mdp->sx, &mdp->sy); + } +} + +/* set whether moons are transiting */ +static void +moonTrans (MoonData md[J_NMOONS]) +{ + int i; + + for (i = 1; i < J_NMOONS; i++) { + MoonData *mdp = &md[i]; + mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1; + } +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: jupmoon.c,v $ $Date: 2006/08/29 03:16:47 $ $Revision: 1.7 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/libration.c b/Common/Libraries/XEphemAstroLib/src/libration.c new file mode 100644 index 000000000..59b5598fc --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/libration.c @@ -0,0 +1,2213 @@ +/* This file contains code to calculate the libration in Lunar lat and long. + * It is based entirely on code supplied to me 2 Oct 1996 by Stephen L. Moshier, + * <moshier@world.std.com>, which implements a trigonometric expansion to + * approximate the librations according to JPL DE403. The following doc file + * was also supplied therewith: + +This program calculates a trigonometric series adjusted for a best fit +to the lunar librations from the Jet Propulsion Laboratory's DE403 +ephemeris. + +lblon403.c and lblat403.c are series for the selenographic longitude +and latitude of the earth. The longitude series matches DE403 +with a maximum discrepancy of 2.6" (0.4" rms). The latitude has a +maximum discrepancy of 1.9" (0.2" rms). The two series are valid in +the Julian year interval 1600 to 2200. + +In both Eckhardt and DE403 the moon's principal moment of inertia axes +form the lunar body coordinate system. The estimated geographic +locations of these axes vary as measurements and theories gradually +become more refined. There is a significant difference between +Eckhardt and DE403 in the constant term of the longitude. Almanac and +cartography coordinates drop the constant term (which is -64" for +DE403). That practice gives librations relative to the mean +selenographic longitude of the earth, for which the discrepancy from +one theory to the next is small. + +Steve Moshier +October, 1996 + + * Any errors in adapting this code to xephem are strictly my own. + * Elwood Downey. +*/ + +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +#define CHAR short + + +/* plantbl.h */ + +struct plantbl { + /* char max_harmonic[9]; */ + char max_harmonic[14]; + char max_power_of_t; + CHAR *arg_tbl; + int *lon_tbl; + int *lat_tbl; + int *rad_tbl; + double distance; + double timescale; + double trunclvl; +}; + + +/* libra403.c */ + +static double JD2000 = 2451545.0; +/* Conversion factors between degrees and radians */ +static double STR = 4.8481368110953599359e-6; /* radians per arc second */ + +static double ss[14][24]; +static double cc[14][24]; + +/* Reduce arc seconds modulo 360 degrees, + answer in arc seconds. */ +static double +mods3600 (double x) +{ + double y; + y = x - 1.296e6 * floor (x / 1.296e6); + return y; +} + +/* Prepare lookup table of sin and cos ( i * L_k ) + for required multiple angles. + K is the array offset corresponding to the planet. + ARG is in radians. + n is the highest harmonic to compute. */ +static int +sscc (int k, double arg, int n) +{ + double cu, su, cv, sv, s; + int i; + + if (n <= 0) + return 0; + + su = sin (arg); + cu = cos (arg); + ss[k][0] = su; /* sin(L) */ + cc[k][0] = cu; /* cos(L) */ + sv = 2.0 * su * cu; + cv = cu * cu - su * su; + ss[k][1] = sv; /* sin(2L) */ + cc[k][1] = cv; + for (i = 2; i < n; i++) + { + s = su * cv + cu * sv; + cv = cu * cv - su * sv; + sv = s; + ss[k][i] = sv; /* sin( i+1 L ) */ + cc[k][i] = cv; + } + return (0); +} + + +/* Mean elements. + Copied from cmoon.c, DE404 version. */ + +static double Jlast = -1.0e38; +static double T; + +static int +dargs (double J, struct plantbl *plan) +{ + double T2, w; + + if (J == Jlast) + return 0; + + T = (J - JD2000) / 36525.0; + T2 = T * T; + + /* Mean anomaly of sun = l' (J. Laskar) */ + w = mods3600 (129596581.038354 * T + 1287104.76154); + w += (((((((( + 1.62e-20 * T + - 1.0390e-17) * T + - 3.83508e-15) * T + + 4.237343e-13) * T + + 8.8555011e-11) * T + - 4.77258489e-8) * T + - 1.1297037031e-5) * T + + 1.4732069041e-4) * T + - 0.552891801772) * T2; + sscc (10, STR * w, plan->max_harmonic[10]); + + /* Mean distance of moon from its ascending node = F */ + w = mods3600 ((1739527263.0983 - 2.079419901760e-01) * T + 335779.55755); + w = w + ((-9.646018347184e-06 * T2 /* F, t^4 */ + - 1.138215912580e-03) * T /* F, t^3 */ + - 1.312045233711e+01) * T; /* F, t^2 */ + sscc (11, STR * w, plan->max_harmonic[11]); + + /* Mean anomaly of moon = l */ + w = mods3600 ((1717915923.4728 - 2.035946368532e-01) * T + 485868.28096); + w = w + ((-3.421689790404e-04 * T2 /* l, t^4 */ + + 4.768357585780e-02) * T /* l, t^3 */ + + 3.146734198839e+01) * T; /* l, t^2 */ + sscc (9, STR * w, plan->max_harmonic[9]); + + /* Mean elongation of moon = D */ + w = mods3600 ((1602961601.4603 + 3.962893294503e-01) * T + 1072260.73512); + w = w + ((-2.905334122698e-04 * T2 /* D, t^4 */ + - 5.834100476561e-03) * T /* D, t^3 */ + - 6.847070905410e+00) * T; /* D, t^2 */ + sscc (12, STR * w, plan->max_harmonic[12]); + + /* Mean longitude of moon, re mean ecliptic and equinox of date */ + w = mods3600 ((1732564372.83264 - 6.784914260953e-01) * T + 785939.95571); + w = w + ((-8.466472828815e-05 * T2 /* L, t^4 */ + + 5.722859298199e-03) * T /* L, t^3 */ + - 5.663161722088e+00) * T; /* L, t^2 */ + sscc (13, STR * w, plan->max_harmonic[13]); + + /* Mean longitudes of planets (Laskar, Bretagnon) */ + + /* Venus. */ + w = mods3600 (210664136.4335482 * T + 655127.283046); + w += (((((((( + -9.36e-023 * T + - 1.95e-20) * T + + 6.097e-18) * T + + 4.43201e-15) * T + + 2.509418e-13) * T + - 3.0622898e-10) * T + - 2.26602516e-9) * T + - 1.4244812531e-5) * T + + 0.005871373088) * T2; + sscc (1, STR * w, plan->max_harmonic[1]); + + /* Earth. */ + w = mods3600 (129597742.26669231 * T + 361679.214649); + w += ((((((((-1.16e-22 * T + + 2.976e-19) * T + + 2.8460e-17) * T + - 1.08402e-14) * T + - 1.226182e-12) * T + + 1.7228268e-10) * T + + 1.515912254e-7) * T + + 8.863982531e-6) * T + - 2.0199859001e-2) * T2; + sscc (2, STR * w, plan->max_harmonic[2]); + + /* Mars. */ + w = mods3600 (68905077.59284 * T + 1279559.78866); + w += (-1.043e-5 * T + 9.38012e-3) * T2; + sscc (3, STR * w, plan->max_harmonic[3]); + + /* Jupiter. */ + w = mods3600 (10925660.428608 * T + 123665.342120); + w += (1.543273e-5 * T - 3.06037836351e-1) * T2; + sscc (4, STR * w, plan->max_harmonic[4]); + + /* Saturn. */ + w = mods3600 (4399609.65932 * T + 180278.89694); + w += ((4.475946e-8 * T - 6.874806E-5) * T + 7.56161437443E-1) * T2; + sscc (5, STR * w, plan->max_harmonic[5]); + return 0; +} + + + +/* Evaluate series PLAN at Julian date J. + Result in arcseconds, usually. */ + +static double +gplan (double J, struct plantbl *plan) +{ + double su, cu, sv, cv; + double t, sl; + int j, k, m, k1, ip, np, nt; + CHAR *p; + int *pl; + + dargs (J, plan); + /* Point to start of table of arguments. */ + p = plan->arg_tbl; + /* Point to tabulated cosine and sine amplitudes. */ + pl = plan->lon_tbl; + sl = 0.0; + + for (;;) + { + /* Find sine and cosine of argument for this term in the series. + The argument has the form J_1 L_1 + J_2 L_2 + ... + where J_i are integers and L_i are mean elements. */ + + /* Number of periodic arguments. */ + np = *p++; + if (np < 0) + break; + if (np == 0) + { + /* If no periodic arguments, it is a polynomial term. + Evaluate A_n T^n + A_n-1 T^n-1 + ... + A_0. */ + nt = *p++; + cu = *pl++; + for (ip = 0; ip < nt; ip++) + cu = cu * T + *pl++; + sl += cu; + continue; + } + k1 = 0; + cv = 0.0; + sv = 0.0; + for (ip = 0; ip < np; ip++) + { + /* What harmonic. */ + j = *p++; + /* Which planet. */ + m = *p++ - 1; + if (j) + { + k = j; + if (j < 0) + k = -k; + k -= 1; + /* sin(k*angle) for planet m. */ + su = ss[m][k]; + if (j < 0) + su = -su; + /* cos(k*angle) for planet m. */ + cu = cc[m][k]; + if (k1 == 0) + { + /* Set sine and cosine of first angle. */ + sv = su; + cv = cu; + k1 = 1; + } + else + { + /* Combine angles by trigonometry. */ + t = su * cv + cu * sv; + cv = cu * cv - su * sv; + sv = t; + } + } + } + /* Now cv = cos(arg), sv = sin(arg). + Evaluate + cu = (C_n T^n + C_n-1 T^n-1 + ... + C_0) cos(arg) + su = (S_n T^n + S_n-1 T^n-1 + ... + S_0) sin(arg). */ + + /* Highest power of T. */ + nt = *p++; + /* Coefficients C_i, S_i. */ + cu = *pl++; + su = *pl++; + for (ip = 0; ip < nt; ip++) + { + cu = cu * T + *pl++; + su = su * T + *pl++; + } + sl += cu * cv + su * sv; + } + return (plan->trunclvl * sl); +} + + +/* lblat403.c */ + +static int lattabr[] = {-1}; +static int lattabb[] = {-1}; +static int lattabl[] = { + 785710, + + -1958, 780, + + -178, 2850, 2243, 5927, 2714, -2911, + + -174, 5888, -16705, 10828, -15113, -25049, + + -172, 1976, + + 37, -13560, + + -40, -911, + + -300, 691, + + 3779, 722, + + 68, -1048, + + -3092, -4, 3011, -31, 250, -14293664, + + -149, -228, + + -5, -842, + + 62, 57967, + + -7, -11207, + + 15, -66055, + + -79, -71560, + + 8, 2998, + + -1062, -46, + + -2, 711, + + -5, -2, + + 367, -5, -353, 1, -117, 2324027, + + 0, -176, + + 19, -4, + + -3, -1229, + + 7, 4327, + + -2, 112, + + -1, -540, + + 73, 102982, + + 0, -137, + + 2, 239, + + 0, -216, + + 2, 3707, + + -1, -100, + + -2, 124, + + 0, 408, + + 1, 561, + + 0, 594, + + 0, 11866, + + -2, -229, + + 11, 6768, + + 2, 1, + + -2, -788, -24, 314732, + + -5, -3238, + + -2, -1263, + + -1, 94, + + -2, 206, + + -283, 6489836, + + 63, 2562, + + -6, 1220, + + 0, 135, + + 795, -338, + + -406, -101, + + 757, -383, + + -73, -31018, + + -5, -3010, + + 6, 5821, + + 167, 7, + + 2, 122623, + + 41, 138924, + + 2, 253, + + 0, -198, + + 135, 30, + + 2, 934, + + 62, -14, + + -531, -297537, + + -3, -205, + + 1, -393, + + -4, -156, + + -467, 90, + + 9, -346, + + -55, 1368, + + 4414, 2094, + + 480, 510, + + 35, 728, + + 6832, 6429, + + -2099, -3703, + + -9, 579, + + 239, 1738, + + 22, 968, 60260, -8929, + + 26, -64, + + 0, 0, + + -47, -351, 2248, -1175, 3976, 7150, + + 15191, 1, -15535, -143, -2308,-239959618, + + -45, 355, 2252, 1189, 4009, -7131, + + -158, 499, + + 776, -34, + + -389, 4363, + + 30, 28, + + 0, -593, + + 1, -1, + + 58, -66, + + 4, 1552, + + -1, 244, + + 288, 59, + + -276, 62, + + 8, 3309, + + 2, 1249, + + -156, -3, + + 0, -7903, + + -47, 154458, + + -710, 160, + + 0, 288, + + 328, 219514, + + -1, 113, + + -1, 1515, + + -20, 28493, + + 13, 9011, + + -1, 1110, + + -1, -103, + + 0, 312, + + 1, 360, + + 6, 6139, + + -1, 142, + + -1, -709, + + -1, -242, + + 67, 67200, + + 5, 4148, + + 1, 137, + + -15, -17969, + + -2, -3372, + + -2, -1739, + + 154, 116200, + + -1, -640, + + -269, -336274, + + 0, -1557, + + -1, -353, + + 993, 39, + + -1, -294, + + -646, -135, + + 750, -3, -661, 8, -163, 2591179, + + -1, -258, + + 0, 381, + + 6, 8272, + + -44, -92044, + + -29, 70397, + + -25, -17892, + + 1, 67, + + -44, -17118, + + 2743, 349, + + -4, 231, + + 1501, 3099, + + -33, 21, + + -1130, 97, 1263, 164, -226, -13139965, + + 839, -202, + + -1, 660, + + 12, -10482, + + 1, 17, + + -2, -1480, + + -45, -26084, + + 2, 259, + + 0, 258, + + -1, -1560, + + 32, 73046, + + -1, -370, + + -1, -77, + + 46, 20687, + + 1, 742, + + 1, 2399, + + 2, 741, + + 0, 52, + + 0, 112, + + 0, 297, + + 2, 825, + + 0, 161, + + 1, 4228, + + 0, 212, + + -1, -105, + + 6, 2782, + + 9, 37199, + + 3, 5045, + + 105, -1, + + -1, -179, + + 75, 31274, + + -3, -1321, + + -1, 363, + + 0, 1137, + + 58, 104090, + + -2, -2695, + + -1, -392, + + -35, -21763, + + -2, -205, + + 567, 38, + + -7, 117, + + -569, -9, 321, -1522061, + + -4, 276, + + -2, -590, + + 2, 632, + + -14, -10601, + + 4, 8703, + + -10, 16870, + + -4, -995, + + 597, -6, -386, -805403, + + 1025, -474, + + -2, 201, + + -95, 16, + + -127, 135570, + + 0, -173, + + 10, 8565, + + -3, 1812, + + -1, -108, + + -107, -649, + + 0, 151, + + 1, 950, + + 1, 312, + + 1, 403, + + 0, -576, + + 7, 4418, + + -3, -4769, + + -1, -769, + + 63, 38890, + + 0, -101, + + 0, 169, + + -3, -14837, + + 1, 372, + + 0, -674, + + -3, -1488, + + -36, -196300, + + 0, -176, + + -10, -4811, + + -2, -991, + + 1, 831, + + 1, 3138, + + -103, -51819, + + 0, -133, + + -4, 22171, + + 2, 820, + + 1, 149, + + 2227, 1277, + + -502, -3049, + + 1, 122, + + 0, 370, + + 0, 166, + + 2, 772, + + 2, 2057, + + -1, -486, + + 13, -15447, + + -2, -1619, + + 0, 335, + + 0, -206, + + 0, -104, + + -19, -19726, + + 0, 414, + + -8, -3425, + + -19, -1, + + 1, 546, + + 0, -392, + + 0, -2754, + + 0, -158, + + -3, -1790, + + -1, -230, + + 0, -190, + + 0, -366, + + 0, -154, + +}; + +static CHAR latargs[] = { + 0, 0, + 3, 1, 2, 9, 3,-20, 4, 0, + 4, 1, 13, -1, 10, 3, 2, -4, 3, 2, + 4, 1, 13, -1, 10, -5, 2, 9, 3, 2, + 3, 9, 10, -9, 14, 1, 3, 0, + 3, 1, 11, -1, 12, 1, 13, 0, + 4, 1, 10, -2, 11, 1, 12, -2, 13, 0, + 4, 2, 11, -1, 14, 18, 2,-18, 3, 0, + 3, 1, 13, -1, 10, 1, 3, 0, + 2, 1, 10, -1, 14, 0, + 2, 1, 10, -1, 12, 2, + 4, 1, 14,-18, 2, 16, 3, 1, 5, 0, + 3, 2, 10, -1, 12, -1, 13, 0, + 3, 1, 10, 1, 11, -1, 12, 0, + 4, 1, 10, -1, 11, 1, 12, -2, 13, 0, + 2, 1, 12, -1, 13, 0, + 3, 1, 10, -1, 11, -1, 12, 0, + 3, 3, 10, -1, 12, -2, 13, 0, + 2, 2, 10, -2, 13, 0, + 3, 1, 10, 2, 11, -1, 12, 0, + 3, 1, 10, -2, 13, 1, 3, 0, + 3, 1, 10, 1, 12, -2, 13, 2, + 3, 1, 11, 1, 12, -1, 13, 0, + 2, 2, 12, -2, 13, 0, + 3, 1, 10, -2, 11, -1, 12, 0, + 3, 1, 10, -3, 12, 2, 13, 0, + 4, 3, 10, 1, 11, -1, 12, -2, 13, 0, + 3, 2, 10, 1, 12, -3, 13, 0, + 4, 1, 10, 1, 11, 1, 12, -2, 13, 0, + 2, 3, 12, -3, 13, 0, + 4, 1, 10, -1, 11, -3, 12, 2, 13, 0, + 3, 3, 10, 1, 12, -4, 13, 0, + 4, 1, 10, 2, 11, 1, 12, -2, 13, 0, + 3, 1, 10, 3, 12, -4, 13, 0, + 4, 1, 10, 3, 11, 1, 12, -2, 13, 0, + 3, 3, 11, 1, 12, -2, 13, 0, + 4, 2, 10, 1, 11, 1, 12, -4, 13, 0, + 2, 3, 12, -4, 13, 0, + 3, 2, 11, 1, 12, -2, 13, 0, + 4, 1, 10, 1, 11, 1, 12, -3, 13, 0, + 3, 2, 10, 1, 12, -4, 13, 0, + 4, 1, 14, -3, 2,-16, 3, -4, 4, 0, + 3, 1, 11, 1, 12, -2, 13, 1, + 3, 1, 10, 1, 12, -3, 13, 0, + 4, 2, 10, 1, 11, -1, 12, -2, 13, 0, + 3, 2, 10, -3, 12, 2, 13, 0, + 4, 1, 10, -1, 11, -1, 12, 1, 13, 0, + 2, 1, 12, -2, 13, 0, + 2, 2, 13, -1, 14, 0, + 2, 2, 11, -1, 12, 0, + 4, 1, 10, -1, 11, 1, 12, -3, 13, 0, + 3, 2, 10, -3, 14, 4, 4, 0, + 2, 1, 10, -2, 13, 0, + 3, 1, 13, -3, 3, 4, 4, 0, + 3, 2, 10, -1, 12, -2, 13, 0, + 3, 2, 10, -1, 11, -1, 12, 0, + 3, 1, 10, -1, 12, 1, 13, 0, + 2, 1, 10, -1, 11, 0, + 3, 1, 11, -1, 12, 2, 13, 0, + 2, 1, 11, -1, 12, 0, + 3, 1, 10, -1, 12, -1, 13, 0, + 4, 2, 13, -1, 12, 2, 2, -2, 3, 0, + 3, 1, 13, 2, 2, -3, 3, 0, + 4, 2, 10, -1, 11, -1, 12, -2, 13, 0, + 3, 1, 13, -1, 2, 2, 3, 0, + 2, 2, 10, -1, 12, 0, + 4, 2, 13, -1, 12, 2, 3, -2, 5, 0, + 4, 2, 13, -1, 12, 3, 2, -3, 3, 0, + 4, 2, 10, -2, 11, 1, 12, -2, 13, 0, + 3, 1, 13, 1, 3, -2, 5, 0, + 4, 1, 10, 1, 11, -1, 12, 1, 13, 0, + 3, 1, 13, -5, 2, 9, 3, 0, + 3, 1, 14, 2, 3, -4, 4, 0, + 3, 3, 10, 4, 12, -6, 14, 0, + 3, 1, 13, 3, 2, -4, 3, 0, + 1, 1, 10, 0, + 3, 1, 13, -3, 12, 9, 2, 0, + 4, 1, 10, -1, 11, 1, 12, -1, 13, 0, + 3, 2, 11, -1, 12, 2, 13, 0, + 1, 1, 14, 1, + 4, 1, 12, 1, 10, -1, 14, 1, 5, 0, + 4, 9, 13, -9, 10, 7, 2, 10, 3, 0, + 3, 1, 12, -8, 2, 13, 3, 2, + 1, 1, 12, 2, + 3, 1, 12, 8, 2,-13, 3, 2, + 2, 1, 13, 2, 4, 0, + 4, 2, 13, -1, 12, 5, 2, -6, 3, 0, + 3, 1, 13, -2, 12, 1, 3, 0, + 3, 1, 13, -3, 2, 6, 3, 0, + 4, 1, 10, -1, 11, -1, 12, -1, 13, 0, + 2, 1, 14, 2, 5, 0, + 2, 1, 10, -2, 12, 0, + 2, 2, 10, -3, 12, 0, + 4, 2, 13, -1, 12, 4, 2, -4, 3, 0, + 3, 1, 14, 4, 2, -6, 3, 0, + 2, 1, 13, 1, 2, 0, + 3, 2, 10, 1, 11, -1, 12, 0, + 4, 2, 10, -1, 11, 1, 12, -2, 13, 0, + 2, 1, 10, 1, 11, 0, + 3, 1, 10, 1, 12, -1, 13, 0, + 2, 1, 11, 1, 12, 0, + 3, 3, 12, -2, 13, -1, 3, 0, + 3, 4, 10, -1, 12, -2, 13, 0, + 3, 2, 10, 1, 12, -2, 13, 0, + 4, 1, 10, 1, 11, 1, 12, -1, 13, 0, + 2, 2, 11, 1, 12, 0, + 2, 3, 12, -2, 13, 0, + 4, 2, 10, 1, 11, 1, 12, -2, 13, 0, + 3, 1, 11, 3, 12, -2, 13, 0, + 3, 4, 10, 1, 12, -4, 13, 0, + 4, 2, 10, 2, 11, 1, 12, -2, 13, 0, + 4, 1, 10, 2, 11, 1, 12, -4, 13, 0, + 4, 1, 10, 1, 11, 1, 12, -4, 13, 0, + 4, 1, 10, 3, 11, -1, 12, -2, 13, 0, + 4, 1, 10, -2, 11, -1, 12, 2, 13, 0, + 3, 1, 11, 1, 12, -3, 13, 0, + 3, 1, 10, 1, 12, -4, 13, 0, + 4, 1, 10, 2, 11, -1, 12, -2, 13, 0, + 3, 3, 10, -1, 12, -4, 13, 0, + 4, 1, 10, -1, 11, -1, 12, 2, 13, 0, + 2, 1, 12, -3, 13, 0, + 4, 1, 10, -1, 11, 1, 12, -4, 13, 0, + 4, 1, 10, 1, 11, -1, 12, -2, 13, 0, + 3, 2, 10, -1, 12, -3, 13, 0, + 3, 1, 10, -1, 12, 2, 13, 0, + 3, 1, 10, -2, 11, 1, 12, 0, + 3, 1, 11, -1, 12, 3, 13, 0, + 1, 2, 13, 0, + 3, 1, 11, -1, 12, -1, 13, 0, + 3, 1, 10, -3, 13, -1, 3, 0, + 3, 1, 10, -1, 12, -2, 13, 2, + 3, 3, 10, -1, 11, -1, 12, 0, + 3, 2, 10, -1, 12, 1, 13, 0, + 4, 1, 10, 1, 11, -1, 12, 2, 13, 0, + 3, 1, 10, -1, 11, 1, 12, 0, + 2, 1, 12, 1, 13, 0, + 4, 1, 10, -1, 11, -1, 12, -2, 13, 0, + 3, 1, 10, 1, 11, -3, 12, 0, + 2, 3, 10, -1, 12, 0, + 1, 2, 10, 0, + 4, 2, 10, -1, 11, 1, 12, -1, 13, 0, + 3, 1, 13, 1, 10, 1, 11, 0, + 3, 2, 13, 3, 3, -2, 11, 0, + 2, 1, 10, 1, 12, 2, + 3, 1, 10, -3, 14, 2, 5, 0, + 3, 3, 10, -1, 14, 4, 5, 0, + 3, 1, 11, 1, 12, 1, 13, 0, + 1, 2, 12, 0, + 4, 1, 10, -2, 11, -1, 12, -2, 13, 0, + 2, 1, 10, -3, 12, 0, + 3, 3, 10, 1, 11, -1, 12, 0, + 4, 3, 10, -1, 11, 1, 12, -2, 13, 0, + 3, 2, 10, 1, 12, -1, 13, 0, + 3, 1, 10, 1, 11, 1, 12, 0, + 2, 3, 12, -1, 13, 0, + 3, 1, 10, -1, 11, -3, 12, 0, + 3, 3, 10, 1, 12, -2, 13, 0, + 3, 1, 10, 2, 11, 1, 12, 0, + 3, 1, 10, 3, 12, -2, 13, 0, + 4, 3, 10, 1, 11, 1, 12, -2, 13, 0, + 4, 1, 10, 1, 11, 3, 12, -2, 13, 0, + 4, 2, 10, 1, 11, 1, 12, -6, 13, 0, + 3, 2, 11, 1, 12, -4, 13, 0, + 3, 2, 10, 1, 12, -6, 13, 0, + 4, 2, 10, 2, 11, -1, 12, -4, 13, 0, + 3, 1, 11, 1, 12, -4, 13, 0, + 3, 3, 11, -1, 12, -2, 13, 0, + 3, 1, 10, 1, 12, -5, 13, 0, + 4, 2, 10, 1, 11, -1, 12, -4, 13, 0, + 2, 1, 12, -4, 13, 0, + 3, 2, 11, -1, 12, -2, 13, 0, + 2, 1, 10, -4, 13, 0, + 4, 1, 10, 1, 11, -1, 12, -3, 13, 0, + 3, 2, 10, -1, 12, -4, 13, 0, + 4, 2, 10, -1, 11, -1, 12, 2, 13, 0, + 3, 1, 10, -1, 12, 3, 13, 0, + 3, 1, 11, -1, 12, 4, 13, 0, + 3, 1, 11, -1, 12, -2, 13, 0, + 3, 1, 10, -1, 12, -3, 13, 0, + 4, 2, 10, -1, 11, -1, 12, -4, 13, 0, + 3, 2, 10, -1, 12, 2, 13, 0, + 3, 2, 10, -2, 11, 1, 12, 0, + 2, 1, 10, 2, 13, 0, + 4, 1, 10, -1, 11, 1, 12, 1, 13, 0, + 2, 1, 12, 2, 13, 1, + 4, 1, 10, -1, 11, -1, 12, -3, 13, 0, + 3, 2, 10, -3, 12, -2, 13, 0, + 4, 2, 10, 1, 11, -1, 12, 2, 13, 0, + 3, 2, 10, -1, 11, 1, 12, 0, + 3, 1, 10, 1, 12, 1, 13, 0, + 3, 1, 11, 1, 12, 2, 13, 0, + 2, 4, 10, -1, 12, 0, + 2, 2, 10, 1, 12, 1, + 4, 1, 13, 1, 12, 10, 2, -2, 3, 0, + 3, 2, 11, 1, 12, 2, 13, 0, + 2, 2, 12, 1, 14, 0, + 1, 3, 12, 0, + 3, 3, 10, 1, 12, -1, 13, 0, + 3, 2, 10, 1, 11, 1, 12, 0, + 3, 4, 10, 1, 12, -2, 13, 0, + 3, 2, 10, 3, 12, -2, 13, 0, + 3, 4, 10, -9, 3, -1, 4, 0, + 4, 1, 10, 1, 11, 1, 12, -6, 13, 0, + 3, 1, 10, 1, 12, -6, 13, 0, + 4, 1, 10, 2, 11, -1, 12, -4, 13, 0, + 3, 3, 10, -1, 12, -6, 13, 0, + 4, 1, 10, -1, 11, -1, 12, 4, 13, 0, + 4, 1, 10, 1, 11, -1, 12, -4, 13, 0, + 3, 1, 10, -1, 12, 4, 13, 0, + 4, 1, 10, -2, 11, 1, 12, 2, 13, 0, + 3, 1, 10, -1, 12, -4, 13, 0, + 4, 3, 10, -1, 11, -1, 12, 2, 13, 0, + 4, 1, 10, 1, 11, -1, 12, 4, 13, 0, + 4, 1, 10, -1, 11, 1, 12, 2, 13, 0, + 2, 1, 12, 3, 13, 0, + 4, 1, 10, -1, 11, -1, 12, -4, 13, 0, + 3, 3, 10, -1, 12, 2, 13, 0, + 3, 1, 10, 1, 12, 2, 13, 0, + 3, 1, 11, 1, 12, 3, 13, 0, + 3, 1, 10, -3, 12, -2, 13, 0, + 3, 3, 10, -1, 11, 1, 12, 0, + 3, 2, 10, 1, 12, 1, 13, 0, + 4, 1, 10, 1, 11, 1, 12, 2, 13, 0, + 2, 3, 10, 1, 12, 0, + 4, 2, 10, 1, 11, 1, 12, 1, 13, 0, + 2, 1, 10, 3, 12, 0, + 3, 3, 10, 1, 11, 1, 12, 0, + 3, 5, 10, 1, 12, -2, 13, 0, + 3, 4, 14, -4, 2, 8, 3, 0, + 3, 5, 10, -9, 3, -1, 4, 0, + 4, 2, 10, 1, 11, -1, 12, -6, 13, 0, + 2, 1, 12, -6, 13, 0, + 3, 2, 11, -1, 12, -4, 13, 0, + 3, 2, 10, -1, 12, -6, 13, 0, + 3, 1, 11, -1, 12, -4, 13, 0, + 3, 2, 10, -1, 12, 4, 13, 0, + 2, 1, 12, 4, 13, 0, + 4, 2, 10, -1, 11, 1, 12, 2, 13, 0, + 3, 1, 11, 1, 12, 4, 13, 0, + 3, 1, 11, -3, 12, -2, 13, 0, + 3, 4, 10, -1, 12, 2, 13, 0, + 3, 2, 10, 1, 12, 2, 13, 0, + 4, 2, 10, 1, 11, 1, 12, 2, 13, 0, + 2, 4, 10, 1, 12, 0, + 3, 7, 12, -2, 10, -4, 5, 0, + 3, 1, 10, -1, 12, -6, 13, 0, + 4, 1, 10, -1, 11, 1, 12, 4, 13, 0, + 3, 1, 10, 1, 12, 4, 13, 0, + 4, 3, 10, -1, 11, 1, 12, 2, 13, 0, + 3, 3, 10, 1, 12, 2, 13, 0, + 2, 5, 10, 1, 12, 0, + 2, 1, 12, 6, 13, 0, + 3, 2, 10, 1, 12, 4, 13, 0, + 3, 4, 10, 1, 12, 2, 13, 0, + -1 +}; + +/* Total terms = 254, small = 254 */ +static struct plantbl liblat = { + /* { 0, 18, 18, 20, 4, 0, 0, 0, 0, 9, 3, 7, 9, 9,}, */ + /* Use max of liblon, liblat. */ + { 0, 18, 18, 20, 4, 2, 0, 0, 0, 9, 16, 7, 9, 9,}, + 2, + latargs, + lattabl, + lattabb, + lattabr, + 3.850000e+05, + 36525.0, + 1.0e-4, +}; + +/* lblon403.c */ +static int lontabr[] = {-1}; +static int lontabb[] = {-1}; +static int lontabl[] = { + -640001, + + -19, 3, + + -1, 0, + + -3, 17, + + 2, -9, + + 2, 3, + + 141, 1816, + + 2, -76, + + 78, -81, + + 3, 1, + + 50, -13, + + -12, 18, + + -6, 74, + + 19, 10, + + -19, 701, + + -26, 37, + + 36, -122, + + 131, -71, + + -40, 1, + + 61463, 12853, + + 5, -29, + + 354, 201, + + 94, -5, + + 31, 25, + + -73, -22, + + 673, 1435, + + 3844, 44, + + -44, -8, + + 195, -16, + + -827, -171768, + + 7051, -4116, + + 1036, 616, -2034, 6300, -13786, -3808, + + -118, -536, -1246, 771, 2555, 3214, + + 203, 26, + + 2975, -715, + + -743, 1286, + + -232, -50, + + 4, 234, + + -139, 475, + + 0, -98, + + -3, -11848, + + 0, 118, + + -202, 146, + + -33673, 7601, + + -150, 88, + + -1720, 1002, + + -293, 481, + + -2078, 1, + + 199, 220655, + + 137, 7459, + + -127, 28, + + -10, 2259, + + 4, 450, + + -26, 30, -76, 19043, 215, -7577830, + + -65, -45, + + -5, -14189, + + -6, -496, + + 9, 3265, + + 0, -131, + + 48, -90, + + -9, -155, + + -2, 21, + + 151, 19, + + -101, -516, + + -827, 3, 796, 2, 134, -2215850, + + -11, -1908, + + 0, 451, + + -2, 1399, + + 3, 7, + + -163, 5, + + -1582, 61, + + -22, -77215, + + 167, -471084, + + -85, -28, + + 1, -473, + + -1, 444, + + 4, 89, + + 6, -88, + + -157, -87813, + + 3, 274, + + -3, -1036, + + 7, -17005, + + -1, -332, + + 0, 50, + + -1, -228, + + -5, -2986, + + -1, -334, + + 1, -452, + + 0, 4, + + 0, -247, + + -3, -2493, + + -4, -1000, + + 0, -160, + + 0, -3163, + + -75, -74207, + + 13, 829, + + 32, 481, + + -33, -11859, + + -2, -3634, + + 7, -1611, + + 3, 520, + + -1, 2534, + + 5, -446, + + -471, 8, 399, 5160, 201, -2057189, + + 83, -2106, + + 11, 12240, + + 3, -270, + + 248, 1112, + + -63, -61809, + + -183, 594, + + 27, 25844, + + -3, 5594, + + 8, 571, + + -23, -1855, + + 477, -466, + + 0, -1257, + + 247, 1550, + + -10178, -175, 9570, -423, 2610, -45917681, + + -51, 937, + + -1001, 168, + + -168, 882, + + 1260, -2894, 4306, -1515, + + 7, 402, + + 0, 36, + + -280, -373, + + -19, 840, + + -1227, -138, + + 3486, 1478247, + + 1649, -644, + + 840, 377, + + 47, -1464, + + 167, -1251123, + + -194, -713, 133, 284429, + + 0, -191, + + -3, 1534, + + -700, 918, + + -7, -633, + + -221, -559, + + 1, 99, + + -17, -3513, + + -30, 14, + + -602, -5006, + + 908, 4178, + + 542, -379, + + 1568, 782, 528, 2761, + + -38994, -25804, + + 1696398, -324306, + + 47292, 71061, 457883, 52470, 159777, 224906030, + + -13068, -18508, + + -104, 3754, + + 541, 614, -290, 1412, + + -48, 162, + + 42, -50, + + -609, -4969, + + 44, -11435, + + -473, -412, + + 22, -6389, + + -87, 44, + + -39, 180182, + + -4186, -2227, + + -503, -208, + + 976, -512, -1016, -4403, + + 16, 25357, + + 565, -891, + + 28, 38836, + + -659, -855, + + -200, 619, + + 1, -1780, + + 24, 17531, + + 1053, 335, + + 502, 2745, -309, -1094576, + + -1, -263, + + 3, -394, + + 0, 4152, + + -1, -467, + + -339, -132142, + + -14, -11676, + + 29, 63360, + + 0, 129, + + -12, -4802, + + -1, -180, + + 2, 3424, + + 0, 45, + + -1, -155, + + -1, -74, + + 0, -134, + + -4, -1588, + + -1, -3424, + + 2, 119, + + -57, -27417, + + 0, 168, + + 0, 206, + + -21, -80823, + + 8, 2324, + + -4, 835, + + 396, -6, -244, -308040, + + 0, -294, + + -56, -1332, + + 2, -110, + + 306, 4060, -58, -1644587, + + -155, -210, + + 67, -1642, + + 27, 32070, + + 9, 3592, + + -8, -17, + + -1, 2, + + -9, -4580, + + 5, 1940, + + 5, -1217, + + 62, -862, + + -522, -1163, + + 0, 0, + + -1646, 1, 1169, 109, 1395, 23634968, + + 2, 0, + + -512, 1148, + + -9, 32, + + 0, -2749, + + 969, -4, + + 2, 351, + + 1, 105, + + 152, 97075, + + -55, -84524, + + -49, 607, 29, -242117, + + 4, 6518, + + 5, -77, + + 1, -39, + + 9, 1, + + 5, -231, + + 2296, -10, -2453, 3, 138, 7689964, + + 0, -689, + + 1, 12635, + + 5444, 372, + + 9, -1843, + + 3485, -560, + + 909, 3, -742, -1, -66, -6945414, + + 8, -7, + + -3, -181, + + 1, 1282, + + -115, -76497, + + 3, -90, + + 1, -142, + + -5, 10263, + + -33, -9479, + + 0, -657, + + 19, 15040, + + -2, 1084, + + -1, -295, + + -161, 403, + + 0, -175, + + -1, -392, + + -4, -3096, + + -9, -2928, + + 1, 332, + + -56, -43733, + + 1, 572, + + 2, -660, + + 4, 7540, + + 4, -659, + + -505, -382941, + + -3, 256, + + 2, 30, + + 76, 145296, + + -4, 4115, + + 9, 6329, + + 11, 6962, + + 0, -338, + + 1, 153, + + 2, -147, + + -270, 211, + + -519, 97, 385, 1912268, + + -1, 1495, + + -3, 223, + + 254, 152832, + + 15, 6709, + + -8, -5835, + + -12, -29016, + + 0, -5641, + + -2, 4217, + + -2, -1176, + + -496, 4, 331, 360972, + + 1, 918, + + -2, -136, + + -111, -762309, + + 2, -610, + + 1, 96, + + -11, -5468, + + 0, 4856, + + 0, -2, + + -16, -668, + + 20, 1963, + + -1, -95, + + 0, -83, + + 0, -96, + + -2, -902, + + 0, -1523, + + -14, -5691, + + -10, -18650, + + 0, 131, + + 0, 128, + + 0, 243, + + 1, 644, + + -76, 138046, + + -1, 316, + + 8, 2703, + + 15, 11758, + + -1, 16, + + 2, -2867, + + 5, 6504, + + 180, 143085, + + -1, 224, + + 86, -96384, + + 1, 471, + + 0, -407, + + -3, -2886, + + -1, -919, + + 0, 742, + + -2, 1145, + + 59, 19306, + + 0, 67, + + -61, -67569, + + -14, 11725, + + -1, -395, + + 1, 772, + + -1, -49, + + 563, 871, 1951, -22, + + -1, -711, + + 0, 240, + + -6, -3912, + + 1, 2812, + + 0, 106, + + 0, 378, + + 4, 19609, + + 6, 3331, + + 2, 930, + + 0, -37, + + 0, -502, + + 0, -1257, + + 21, 10531, + + 2, -16662, + + 0, -267, + + -1, 22, + + 6, 1104, + + -14, -5544, + + 1, -250, + + -1, 1248, + + 0, 325, + + 2, 2163, + + 2, -1421, + + 0, 73, + + -1, -67, + + 2, 771, + + -1, -2085, + + 0, 67, + + 1, 226, + + 1, 212, + + 0, 56, + +}; + +static CHAR lonargs[] = { + 0, 0, + 4, 1, 10, 3, 11,-18, 2, 13, 3, 0, + 4, -2, 12, 2, 13, 5, 2, -6, 3, 0, + 4, 2, 10, -2, 13, -2, 3, 3, 5, 0, + 3, 1, 10, -1, 14, 1, 5, 0, + 4, -2, 10, 2, 13, -5, 3, -6, 4, 0, + 2, 1, 12, -1, 14, 0, + 4, -2, 10, 2, 13, 2, 3, -2, 5, 0, + 2, 1, 3, -2, 4, 0, + 4, -1, 12, 1, 13, -3, 2, 6, 3, 0, + 1, 1, 5, 0, + 4, -1, 10, 2, 13,-15, 2, 13, 3, 0, + 4, 2, 10, -2, 13, -3, 2, 3, 3, 0, + 2, 2, 12, -2, 14, 0, + 3, 1, 10, -1, 11, -1, 13, 0, + 2, 11, 2,-18, 3, 0, + 2, 3, 2, -5, 3, 0, + 2, 2, 3, -4, 4, 0, + 2, 5, 2, -8, 3, 0, + 2, 1, 10, -1, 12, 0, + 4, -1, 12, 1, 14, 3, 2, -5, 3, 0, + 3, 6, 12, -6, 13, -4, 2, 0, + 2, 3, 3, -6, 4, 0, + 2, 5, 3, -9, 4, 0, + 4, -1, 10, 2, 13,-18, 2, 18, 3, 0, + 3, 2, 10, -2, 3, -2, 13, 0, + 2, 2, 2, -3, 3, 0, + 4, 2, 10, -2, 13, -4, 2, 5, 3, 0, + 2, 4, 3, -7, 4, 0, + 2, 2, 10, -2, 12, 0, + 2, 3, 3, -5, 4, 0, + 3, 3, 2, -4, 3, -1, 4, 2, + 3, 1, 2, -5, 3, 7, 4, 2, + 4, -2, 10, 2, 13, 5, 2, -6, 3, 0, + 2, 1, 2, -2, 3, 0, + 2, 2, 3, -3, 4, 0, + 4, -1, 12, 1, 14, 4, 2, -6, 3, 0, + 2, 1, 3, -1, 4, 0, + 2, 4, 2, -6, 3, 0, + 4, 2, 10, -2, 13, -2, 2, 2, 3, 0, + 2, 1, 2, -1, 3, 0, + 3, 2, 10, 1, 11, -2, 12, 0, + 2, 1, 3, -3, 5, 0, + 3, 2, 10, -1, 3, -2, 13, 0, + 2, 4, 3, -6, 4, 0, + 2, 1, 3, -2, 5, 0, + 2, 3, 3, -4, 4, 0, + 2, 3, 2, -4, 3, 0, + 2, 1, 10, -1, 13, 0, + 2, 1, 3, -1, 5, 0, + 2, 1, 3, -2, 6, 0, + 2, 2, 3, -2, 4, 0, + 2, 1, 3, -1, 6, 0, + 1, 1, 11, 2, + 2, 1, 3, 1, 5, 0, + 3, 1, 11, -2, 12, 2, 13, 0, + 3, 1, 10, -2, 12, 1, 13, 0, + 2, 2, 2, -2, 3, 0, + 3, 2, 10, -1, 11, -2, 12, 0, + 2, 4, 3, -5, 4, 0, + 2, 3, 3, -3, 4, 0, + 3, 4, 10, -2, 12, -2, 13, 0, + 1, 1, 2, 0, + 2, 2, 3, -3, 5, 0, + 2, 2, 10, -2, 13, 2, + 2, 2, 3, -2, 5, 0, + 2, 3, 3, -3, 2, 0, + 3, 1, 10, 1, 11, -1, 13, 0, + 3, 3, 3, -1, 2, 1, 4, 0, + 2, 2, 3, -1, 5, 0, + 3, 1, 10, 1, 12, -2, 13, 0, + 1, 2, 11, 0, + 2, 2, 12, -2, 13, 0, + 2, 2, 2, -1, 3, 0, + 2, 4, 2, -4, 3, 0, + 2, 3, 10, -3, 13, 0, + 4, 2, 10, -2, 13, 1, 3, -1, 5, 0, + 2, 3, 3, -3, 5, 0, + 3, 2, 10, 1, 11, -2, 13, 0, + 3, 1, 10, 2, 12, -3, 13, 0, + 1, 3, 11, 0, + 3, 1, 11, 2, 12, -2, 13, 0, + 2, 5, 2, -5, 3, 0, + 2, 4, 10, -4, 13, 0, + 2, 6, 2, -6, 3, 0, + 3, 2, 10, 2, 11, -2, 13, 0, + 3, 2, 10, 2, 12, -4, 13, 0, + 3, 2, 11, 2, 12, -2, 13, 0, + 3, 4, 10, 1, 11, -4, 13, 0, + 4, 1, 10, 1, 11, 2, 12, -4, 13, 0, + 3, 1, 10, 3, 11, -2, 13, 0, + 3, 3, 10, 1, 11, -4, 13, 0, + 4, 1, 10, -2, 11, -2, 12, 2, 13, 0, + 3, 1, 10, 2, 12, -4, 13, 0, + 3, 1, 10, 2, 11, -2, 13, 0, + 3, 2, 10, 1, 11, -3, 13, 0, + 3, 1, 13, -2, 2, 1, 4, 0, + 2, 3, 10, -4, 13, 0, + 4, 1, 10, -1, 11, -2, 12, 2, 13, 0, + 4, -1, 10, 2, 13, -2, 2, 2, 3, 0, + 2, 1, 10, -3, 11, 0, + 2, 2, 12, -3, 13, 0, + 2, 2, 11, -1, 13, 0, + 3, 1, 10, 1, 11, -2, 13, 2, + 4, -1, 10, 2, 13, -1, 3, 1, 5, 0, + 2, 2, 10, -3, 13, 0, + 3, 3, 10, -1, 11, -4, 13, 0, + 3, 4, 11, 2, 13,-11, 2, 0, + 3, 1, 10, -2, 12, 2, 13, 0, + 3, 1, 12, -2, 13, 1, 5, 0, + 2, 1, 10, -2, 11, 0, + 2, 1, 11, -1, 13, 0, + 3, 1, 10, -2, 13, 1, 5, 0, + 3, 1, 10, -2, 3, 2, 5, 0, + 3, 18, 2,-18, 3, 2, 5, 0, + 3, 1, 10, -3, 2, 3, 3, 0, + 3, 2, 13, 16, 11,-18, 2, 0, + 2, 1, 10, -2, 13, 2, + 3, 1, 13, -2, 10, 5, 4, 0, + 3, 2, 12, -2, 14, 7, 2, 0, + 3, 1, 10, -2, 3, 3, 5, 0, + 3, 1, 12, -1, 3, -2, 5, 1, + 3, 2, 10, -1, 11, -3, 13, 0, + 3, 3, 10, -2, 12, -2, 13, 0, + 2, 8, 2, -1, 3, 0, + 4, 1, 10, 1, 11, -2, 12, 2, 13, 0, + 3, 1, 12, -2, 14, 2, 4, 0, + 2, 1, 10, -1, 11, 0, + 3, 8, 2, -5, 3, 8, 4, 0, + 2, 18, 2,-17, 3, 0, + 3, 1, 10, -1, 3, 1, 5, 0, + 1, 1, 13, 0, + 3, 1, 10, -1, 11, -2, 13, 1, + 3, 1, 10, 1, 11, -2, 12, 0, + 3, 1, 10, -1, 2, 1, 3, 0, + 3, 2, 13, -8, 2, 1, 3, 0, + 2, 3, 10, -2, 12, 0, + 3, 2, 10, -1, 12, -1, 5, 0, + 3, 3, 10, -2, 11, -2, 13, 0, + 3, 2, 10, -1, 11, -1, 13, 0, + 3, 2, 10, 1, 3, -2, 4, 0, + 3, 1, 12, -1, 10, -1, 14, 0, + 4, -1, 10, 2, 13, 2, 3, -3, 5, 0, + 3, 2, 13, -4, 2, -5, 3, 0, + 3, 2, 12, 2, 10, -3, 14, 1, + 2, 1, 12, -2, 5, 0, + 2, 10, 2, -3, 11, 0, + 1, 1, 10, 2, + 3, 1, 12, -2, 10, -2, 5, 0, + 2, 18, 2,-16, 3, 0, + 2, 2, 12, -3, 14, 1, + 3, 1, 13,-17, 2, 2, 11, 0, + 3, 1, 10, 1, 2, -3, 4, 0, + 3, 1, 12, 1, 10, -1, 14, 0, + 4, -1, 10, 2, 13, 2, 3, -2, 5, 0, + 3, 1, 10, -1, 3, 2, 4, 0, + 4, -1, 10, 2, 13, 3, 2, -3, 3, 0, + 4, 1, 10, -2, 11, 2, 12, -2, 13, 0, + 2, 1, 11, 1, 13, 0, + 3, 8, 2, 2, 3, -3, 4, 0, + 1, 1, 12, 0, + 3, 6, 2, 9, 3,-10, 4, 1, + 3, 1, 10, -2, 11, -2, 13, 0, + 2, 8, 2, 1, 4, 0, + 2, 1, 10, -2, 12, 0, + 2, 11, 2, -4, 3, 0, + 3, 3, 11, -2, 14, 6, 2, 0, + 3, 3, 10, -1, 11, -2, 13, 0, + 2, 2, 10, -1, 13, 0, + 3, 1, 12, -2, 2, 4, 3, 0, + 2, 1, 10, 1, 11, 1, + 4, 1, 10, -1, 11, 2, 12, -2, 13, 0, + 2, 2, 11, 1, 13, 0, + 2, 2, 12, -1, 13, 0, + 3, 1, 10, -1, 11, -2, 12, 0, + 2, 3, 10, -2, 13, 0, + 2, 1, 10, 2, 11, 0, + 3, 1, 10, 2, 12, -2, 13, 0, + 3, 1, 11, 2, 12, -1, 13, 0, + 3, 3, 10, 1, 11, -2, 13, 0, + 2, 1, 10, 3, 11, 0, + 4, 1, 10, 1, 11, 2, 12, -2, 13, 0, + 2, 5, 10, -4, 13, 0, + 3, 3, 10, 2, 11, -2, 13, 0, + 3, 3, 10, 2, 12, -4, 13, 0, + 2, 4, 11, -2, 13, 0, + 3, 2, 10, 2, 11, -4, 13, 0, + 2, 3, 11, -2, 13, 0, + 3, 1, 10, 2, 11, -3, 13, 0, + 3, 2, 10, 1, 11, -4, 13, 0, + 2, 3, 10, -5, 13, 0, + 2, 2, 12, -4, 13, 0, + 2, 2, 11, -2, 13, 0, + 3, 1, 10, 1, 11, -3, 13, 0, + 3, 2, 13, -2, 3, 2, 5, 0, + 2, 2, 10, -4, 13, 1, + 4, 2, 10, -1, 11, -2, 12, 2, 13, 0, + 2, 2, 14, -2, 2, 0, + 3, 1, 10, -2, 12, 3, 13, 0, + 2, 1, 11, -2, 13, 1, + 3, 2, 14, -2, 2, 3, 5, 0, + 3, 2, 13, -1, 3, 1, 5, 0, + 2, 1, 10, -3, 13, 0, + 3, 2, 10, -1, 11, -4, 13, 0, + 4, 2, 10, 1, 11, -2, 12, -2, 13, 0, + 3, 2, 13, 1, 14, -8, 2, 0, + 3, 2, 10, -2, 12, 2, 13, 0, + 2, 2, 10, -2, 11, 0, + 3, 1, 10, -1, 11, 1, 13, 0, + 3, 1, 12, -2, 13, -1, 14, 0, + 3, 2, 13, -8, 2, 13, 3, 0, + 3, 3, 10, -5, 13, 5, 4, 0, + 1, 2, 13, 2, + 3, 3, 10, -1, 13, 5, 4, 0, + 3, 2, 13, 8, 2,-13, 3, 0, + 2, 2, 11, -2, 12, 0, + 3, 1, 10, -1, 11, -3, 13, 0, + 3, 1, 10, -1, 12, -2, 13, 0, + 3, 2, 10, -2, 11, -4, 13, 0, + 3, 2, 10, -2, 12, -2, 13, 0, + 2, 2, 10, -1, 11, 0, + 2, 1, 10, 1, 13, 0, + 2, 1, 11, 2, 13, 1, + 2, 1, 11, -2, 12, 0, + 3, 1, 10, -2, 12, -1, 13, 0, + 2, 4, 10, -2, 12, 0, + 2, 3, 10, -1, 12, 0, + 3, 3, 10, -1, 11, -1, 13, 0, + 1, 2, 10, 2, + 2, 2, 14, -2, 5, 0, + 3, 1, 10, 1, 11, 1, 13, 0, + 2, 1, 10, 1, 12, 0, + 2, 2, 11, 2, 13, 0, + 2, 1, 12, 1, 14, 0, + 1, 2, 12, 2, + 2, 1, 10, -3, 12, 0, + 3, 4, 10, -1, 11, -2, 13, 0, + 2, 3, 10, -1, 13, 0, + 2, 2, 10, 1, 11, 0, + 3, 1, 10, 2, 11, 1, 13, 0, + 3, 1, 10, 2, 12, -1, 13, 0, + 2, 1, 11, 2, 12, 0, + 2, 4, 10, -2, 13, 0, + 2, 2, 10, 2, 11, 0, + 3, 2, 10, 2, 12, -2, 13, 0, + 2, 4, 12, -2, 13, 0, + 3, 4, 10, 1, 11, -2, 13, 0, + 3, 2, 13, 11, 2,-13, 3, 0, + 3, 1, 10, 3, 11, -4, 13, 0, + 3, 3, 10, 1, 11, -6, 13, 0, + 3, 1, 10, 2, 11, -4, 13, 0, + 2, 3, 10, -6, 13, 0, + 3, 1, 10, -3, 11, 2, 13, 0, + 3, 1, 10, 1, 11, -4, 13, 0, + 2, 2, 10, -5, 13, 0, + 3, 1, 10, -2, 12, 4, 13, 0, + 3, 1, 10, -2, 11, 2, 13, 0, + 2, 1, 11, -3, 13, 0, + 2, 1, 10, -4, 13, 0, + 4, 1, 10, 2, 11, -2, 12, -2, 13, 0, + 3, 3, 10, -2, 12, -4, 13, 0, + 3, 1, 10, -1, 11, 2, 13, 0, + 1, 3, 13, 0, + 3, 1, 10, -1, 11, -4, 13, 0, + 4, 1, 10, 1, 11, -2, 12, -2, 13, 0, + 3, 3, 10, -2, 12, 2, 13, 0, + 2, 3, 10, -2, 11, 0, + 3, 2, 10, -1, 11, 1, 13, 0, + 3, 1, 12, 2, 13, -2, 5, 0, + 2, 1, 10, 2, 13, 1, + 2, 1, 11, 3, 13, 0, + 3, 1, 10, -2, 11, -4, 13, 0, + 3, 1, 10, -2, 12, -2, 13, 0, + 2, 3, 10, -1, 11, 0, + 2, 2, 10, 1, 13, 0, + 3, 1, 10, 1, 11, 2, 13, 0, + 3, 1, 10, -1, 11, 2, 12, 0, + 2, 2, 12, 1, 13, 0, + 4, 1, 10, -1, 11, -2, 12, -2, 13, 0, + 1, 3, 10, 1, + 3, 2, 10, 1, 11, 1, 13, 0, + 3, 1, 10, 2, 11, 2, 13, 0, + 2, 1, 10, 2, 12, 0, + 3, 1, 11, 2, 12, 1, 13, 0, + 2, 4, 10, -1, 13, 0, + 2, 3, 10, 1, 11, 0, + 3, 1, 10, 1, 11, 2, 12, 0, + 4, 1, 10, -1, 11, 4, 12, -2, 13, 0, + 2, 5, 10, -2, 13, 0, + 3, 3, 10, 2, 12, -2, 13, 0, + 3, 1, 10, 4, 12, -2, 13, 0, + 3, 2, 10, 2, 11, -6, 13, 0, + 2, 3, 11, -4, 13, 0, + 3, 2, 10, 1, 11, -6, 13, 0, + 2, 2, 11, -4, 13, 0, + 2, 2, 10, -6, 13, 0, + 2, 1, 11, -4, 13, 0, + 2, 1, 10, -5, 13, 0, + 3, 2, 10, -1, 11, -6, 13, 0, + 4, 2, 10, 1, 11, -2, 12, -4, 13, 0, + 3, 2, 10, -2, 11, 2, 13, 0, + 1, 4, 13, 0, + 3, 2, 11, -2, 12, -2, 13, 0, + 3, 2, 10, -2, 12, -4, 13, 0, + 3, 2, 10, -1, 11, 2, 13, 0, + 2, 1, 10, 3, 13, 0, + 2, 1, 11, 4, 13, 0, + 3, 1, 11, -2, 12, -2, 13, 0, + 2, 2, 10, 2, 13, 0, + 3, 1, 10, 1, 11, 3, 13, 0, + 2, 2, 12, 2, 13, 0, + 2, 4, 10, -1, 11, 0, + 2, 3, 10, 1, 13, 0, + 3, 2, 10, 1, 11, 2, 13, 0, + 3, 2, 10, -1, 11, 2, 12, 0, + 3, 1, 10, 2, 12, 1, 13, 0, + 3, 1, 11, 2, 12, 2, 13, 0, + 1, 4, 10, 0, + 3, 3, 10, 1, 11, 1, 13, 0, + 2, 2, 10, 2, 12, 0, + 1, 4, 12, 0, + 2, 4, 10, 1, 11, 0, + 3, 2, 10, 1, 11, 2, 12, 0, + 2, 6, 10, -2, 13, 0, + 3, 5, 12, -1, 14, 2, 4, 1, + 3, 1, 10, 1, 11, -6, 13, 0, + 3, 1, 10, -2, 11, 4, 13, 0, + 2, 1, 10, -6, 13, 0, + 3, 1, 10, -1, 11, 4, 13, 0, + 3, 1, 10, -1, 11, -6, 13, 0, + 4, 1, 10, 1, 11, -2, 12, -4, 13, 0, + 2, 1, 10, 4, 13, 0, + 3, 1, 10, -2, 12, -4, 13, 0, + 3, 3, 10, -1, 11, 2, 13, 0, + 2, 2, 10, 3, 13, 0, + 3, 1, 10, 1, 11, 4, 13, 0, + 4, 1, 10, -1, 11, 2, 12, 2, 13, 0, + 2, 3, 10, 2, 13, 0, + 3, 1, 10, 2, 12, 2, 13, 0, + 3, 3, 10, 1, 11, 2, 13, 0, + 3, 1, 10, -1, 11, 4, 12, 0, + 1, 5, 10, 0, + 2, 3, 10, 2, 12, 0, + 2, 1, 11, -6, 13, 0, + 1, 6, 13, 0, + 3, 2, 10, -1, 11, 4, 13, 0, + 2, 2, 10, 4, 13, 0, + 2, 2, 12, 4, 13, 0, + 3, 4, 10, -1, 11, 2, 13, 0, + 3, 2, 10, 1, 11, 4, 13, 0, + 2, 4, 10, 2, 13, 0, + 3, 2, 10, 2, 12, 2, 13, 0, + 1, 6, 10, 0, + 2, 1, 10, 6, 13, 0, + 2, 3, 10, 4, 13, 0, + 2, 5, 10, 2, 13, 0, + -1 +}; + +/* Total terms = 356, small = 356 */ +static struct plantbl liblon = { + /* { 0, 18, 18, 10, 3, 2, 0, 0, 0, 6, 16, 6, 6, 3,}, */ + /* Use max of liblon, liblat. */ + { 0, 18, 18, 20, 4, 2, 0, 0, 0, 9, 16, 7, 9, 9,}, + 2, + lonargs, + lontabl, + lontabb, + lontabr, + 3.850000e+05, + 36525.0, + 1.0e-4, +}; + + +/* given a Julian date, return the lunar libration in lat and long, in rads. + */ +void +llibration (double JD, double *llatp, double *llonp) +{ + double lg, lt; /* arc seconds */ + + lg = gplan (JD, &liblon); + lt = gplan (JD, &liblat); + + *llonp = degrad (lg/3600.0); + *llatp = degrad (lt/3600.0); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: libration.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/magdecl.c b/Common/Libraries/XEphemAstroLib/src/magdecl.c new file mode 100644 index 000000000..f3efa98fb --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/magdecl.c @@ -0,0 +1,381 @@ +/* DoD NIMA World Magnetic Model. + * from http://www.ngdc.noaa.gov + * +#define TEST_MAIN + */ + + +#include <math.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include "astro.h" + +static char mfn[] = "wmm.cof"; /* file with model coefficients */ + +static int geomag(FILE *wmmdat, int *maxdeg); +static int geomg1(FILE *wmmdat, float alt, float glat, float glon, + float t, float *dec, float *mdp, float *ti, float *gv); + +/* compute magnetic declination for given location, elevation and time. + * sign is such that mag bearing = true az + mag deviation. + * return 0 if ok, -1 if no model file, -2 if time outside model range. + * fill err[] with excuse if return < 0. + */ +int +magdecl ( +double l, double L, /* geodesic lat, +N, long, +E, rads */ +double e, /* elevation, m */ +double y, /* time, decimal year */ +char *dir, /* dir for model file */ +double *mdp, /* magnetic deviation, rads E of N */ +char *err) /* err message if return < 0 */ +{ + float dlat = raddeg(l); + float dlon = raddeg(L); + float alt = e/1000.; + int maxdeg = 12; + float dec, dp, ti, gv; + char mfile[1024]; + FILE *wmmdat; + int s; + + /* open model file */ + sprintf (mfile, "%s/%s", dir, mfn); + wmmdat = fopen (mfile, "r"); + if (!wmmdat) { + sprintf (err, "%s: %s", mfile, strerror(errno)); + return (-1); + } + + /* compute deviation */ + geomag(wmmdat, &maxdeg); + s = geomg1(wmmdat,alt,dlat,dlon,y,&dec,&dp,&ti,&gv); + fclose(wmmdat); + if (s < 0) { + sprintf (err, "%s: Magnetic model only available for %g .. %g. See http://www.ngdc.noaa.gov", mfile, ti, ti+5); + return (-2); + } + *mdp = degrad(dec); + return (0); +} + +#if defined(TEST_MAIN) + +int +main(int ac, char *av[]) +{ + char err[1024]; + float altm, dlat, dlon; + float t; + double dec; + + S1: + printf("\n\n\n ENTER LATITUDE IN DECIMAL DEGREES (+25.0)\n"); + scanf("%f", &dlat); + + printf(" ENTER LONGITUDE IN DECIMAL DEGREES (-100.0)\n"); + scanf("%f", &dlon); + + printf(" ENTER ALTITUDE IN METERS\n"); + scanf("%f", &altm); + + printf(" ENTER TIME IN DECIMAL YEAR\n"); + scanf("%f",&t); + + if (magdecl (degrad(dlat), degrad(dlon), altm, t, "auxil", &dec, + err) < 0) { + printf ("%s\n", err); + return(1); + } + + printf("\n LATITUDE: = %-7.2f DEG",dlat); + printf("\n LONGITUDE: = %-7.2f DEG\n",dlon); + printf("\n ALTITUDE = %.2f METERS",altm); + printf("\n DATE = %-5.1f\n",t); + + printf("\n\t\t\t OUTPUT\n\t\t\t ------"); + + printf("\n DEC = %-7.2f DEG", raddeg(dec)); + + printf("\n\n\n DO YOU NEED MORE POINT DATA? (y or n)\n"); + scanf("%s", err); + if ((err[0] =='y')||(err[0] == 'Y')) goto S1; + + return(0); +} +#endif /* defined(TEST_MAIN) */ + +/************************************************************************* + * return 0 if ok, -1 if time is out of range with base epoc in *ti + */ + +static int E0000(FILE *wmmdat, int IENTRY, int *maxdeg, float alt, +float glat, float glon, float t, float *dec, float *mdp, float *ti, +float *gv) +{ + static int maxord,i,icomp,n,m,j,D1,D2,D3,D4; + static float c[13][13],cd[13][13],tc[13][13],dp[13][13],snorm[169], + sp[13],cp[13],fn[13],fm[13],pp[13],k[13][13],pi,dtr,a,b,re, + a2,b2,c2,a4,b4,c4,epoc,gnm,hnm,dgnm,dhnm,flnmj,otime,oalt, + olat,olon,dt,rlon,rlat,srlon,srlat,crlon,crlat,srlat2, + crlat2,q,q1,q2,ct,st,r2,r,d,ca,sa,aor,ar,br,bt,bp,bpp, + par,temp1,temp2,parp,bx,by,bz,bh; + static char model[20], c_str[81], c_new[5]; + static float *p = snorm; + + switch(IENTRY){case 0: goto GEOMAG; case 1: goto GEOMG1;} + +GEOMAG: + +/* INITIALIZE CONSTANTS */ + maxord = *maxdeg; + sp[0] = 0.0; + cp[0] = *p = pp[0] = 1.0; + dp[0][0] = 0.0; + a = 6378.137; + b = 6356.7523142; + re = 6371.2; + a2 = a*a; + b2 = b*b; + c2 = a2-b2; + a4 = a2*a2; + b4 = b2*b2; + c4 = a4 - b4; + +/* READ WORLD MAGNETIC MODEL SPHERICAL HARMONIC COEFFICIENTS */ + c[0][0] = 0.0; + cd[0][0] = 0.0; + fgets(c_str, 80, wmmdat); + sscanf(c_str,"%f%s",&epoc,model); +S3: + fgets(c_str, 80, wmmdat); +/* CHECK FOR LAST LINE IN FILE */ + for (i=0; i<4 && (c_str[i] != '\0'); i++) + { + c_new[i] = c_str[i]; + c_new[i+1] = '\0'; + } + icomp = strcmp("9999", c_new); + if (icomp == 0) goto S4; +/* END OF FILE NOT ENCOUNTERED, GET VALUES */ + sscanf(c_str,"%d%d%f%f%f%f",&n,&m,&gnm,&hnm,&dgnm,&dhnm); + if (m <= n) + { + c[m][n] = gnm; + cd[m][n] = dgnm; + if (m != 0) + { + c[n][m-1] = hnm; + cd[n][m-1] = dhnm; + } + } + goto S3; + +/* CONVERT SCHMIDT NORMALIZED GAUSS COEFFICIENTS TO UNNORMALIZED */ +S4: + *snorm = 1.0; + for (n=1; n<=maxord; n++) + { + *(snorm+n) = *(snorm+n-1)*(float)(2*n-1)/(float)n; + j = 2; + for (m=0,D1=1,D2=(n-m+D1)/D1; D2>0; D2--,m+=D1) + { + k[m][n] = (float)(((n-1)*(n-1))-(m*m))/(float)((2*n-1)*(2*n-3)); + if (m > 0) + { + flnmj = (float)((n-m+1)*j)/(float)(n+m); + *(snorm+n+m*13) = *(snorm+n+(m-1)*13)*sqrt(flnmj); + j = 1; + c[n][m-1] = *(snorm+n+m*13)*c[n][m-1]; + cd[n][m-1] = *(snorm+n+m*13)*cd[n][m-1]; + } + c[m][n] = *(snorm+n+m*13)*c[m][n]; + cd[m][n] = *(snorm+n+m*13)*cd[m][n]; + } + fn[n] = (float)(n+1); + fm[n] = (float)n; + } + k[1][1] = 0.0; + + otime = oalt = olat = olon = -1000.0; + return (0); + +/*************************************************************************/ + +GEOMG1: + + dt = t - epoc; + if (otime < 0.0 && (dt < 0.0 || dt > 5.0)) { + *ti = epoc; /* pass back base time for diag msg */ + return (-1); + } + + pi = 3.14159265359; + dtr = pi/180.0; + rlon = glon*dtr; + rlat = glat*dtr; + srlon = sin(rlon); + srlat = sin(rlat); + crlon = cos(rlon); + crlat = cos(rlat); + srlat2 = srlat*srlat; + crlat2 = crlat*crlat; + sp[1] = srlon; + cp[1] = crlon; + +/* CONVERT FROM GEODETIC COORDS. TO SPHERICAL COORDS. */ + if (alt != oalt || glat != olat) + { + q = sqrt(a2-c2*srlat2); + q1 = alt*q; + q2 = ((q1+a2)/(q1+b2))*((q1+a2)/(q1+b2)); + ct = srlat/sqrt(q2*crlat2+srlat2); + st = sqrt(1.0-(ct*ct)); + r2 = (alt*alt)+2.0*q1+(a4-c4*srlat2)/(q*q); + r = sqrt(r2); + d = sqrt(a2*crlat2+b2*srlat2); + ca = (alt+d)/r; + sa = c2*crlat*srlat/(r*d); + } + if (glon != olon) + { + for (m=2; m<=maxord; m++) + { + sp[m] = sp[1]*cp[m-1]+cp[1]*sp[m-1]; + cp[m] = cp[1]*cp[m-1]-sp[1]*sp[m-1]; + } + } + aor = re/r; + ar = aor*aor; + br = bt = bp = bpp = 0.0; + for (n=1; n<=maxord; n++) + { + ar = ar*aor; + for (m=0,D3=1,D4=(n+m+D3)/D3; D4>0; D4--,m+=D3) + { +/* + COMPUTE UNNORMALIZED ASSOCIATED LEGENDRE POLYNOMIALS + AND DERIVATIVES VIA RECURSION RELATIONS +*/ + if (alt != oalt || glat != olat) + { + if (n == m) + { + *(p+n+m*13) = st**(p+n-1+(m-1)*13); + dp[m][n] = st*dp[m-1][n-1]+ct**(p+n-1+(m-1)*13); + goto S50; + } + if (n == 1 && m == 0) + { + *(p+n+m*13) = ct**(p+n-1+m*13); + dp[m][n] = ct*dp[m][n-1]-st**(p+n-1+m*13); + goto S50; + } + if (n > 1 && n != m) + { + if (m > n-2) *(p+n-2+m*13) = 0.0; + if (m > n-2) dp[m][n-2] = 0.0; + *(p+n+m*13) = ct**(p+n-1+m*13)-k[m][n]**(p+n-2+m*13); + dp[m][n] = ct*dp[m][n-1] - st**(p+n-1+m*13)-k[m][n]*dp[m][n-2]; + } + } +S50: +/* + TIME ADJUST THE GAUSS COEFFICIENTS +*/ + if (t != otime) + { + tc[m][n] = c[m][n]+dt*cd[m][n]; + if (m != 0) tc[n][m-1] = c[n][m-1]+dt*cd[n][m-1]; + } +/* + ACCUMULATE TERMS OF THE SPHERICAL HARMONIC EXPANSIONS +*/ + par = ar**(p+n+m*13); + if (m == 0) + { + temp1 = tc[m][n]*cp[m]; + temp2 = tc[m][n]*sp[m]; + } + else + { + temp1 = tc[m][n]*cp[m]+tc[n][m-1]*sp[m]; + temp2 = tc[m][n]*sp[m]-tc[n][m-1]*cp[m]; + } + bt = bt-ar*temp1*dp[m][n]; + bp += (fm[m]*temp2*par); + br += (fn[n]*temp1*par); +/* + SPECIAL CASE: NORTH/SOUTH GEOGRAPHIC POLES +*/ + if (st == 0.0 && m == 1) + { + if (n == 1) pp[n] = pp[n-1]; + else pp[n] = ct*pp[n-1]-k[m][n]*pp[n-2]; + parp = ar*pp[n]; + bpp += (fm[m]*temp2*parp); + } + } + } + if (st == 0.0) bp = bpp; + else bp /= st; +/* + ROTATE MAGNETIC VECTOR COMPONENTS FROM SPHERICAL TO + GEODETIC COORDINATES +*/ + bx = -bt*ca-br*sa; + by = bp; + bz = bt*sa-br*ca; +/* + COMPUTE DECLINATION (DEC), INCLINATION (DIP) AND + TOTAL INTENSITY (TI) +*/ + bh = sqrt((bx*bx)+(by*by)); + *ti = sqrt((bh*bh)+(bz*bz)); + *dec = atan2(by,bx)/dtr; + *mdp = atan2(bz,bh)/dtr; +/* + COMPUTE MAGNETIC GRID VARIATION IF THE CURRENT + GEODETIC POSITION IS IN THE ARCTIC OR ANTARCTIC + (I.E. GLAT > +55 DEGREES OR GLAT < -55 DEGREES) + + OTHERWISE, SET MAGNETIC GRID VARIATION TO -999.0 +*/ + *gv = -999.0; + if (fabs(glat) >= 55.) + { + if (glat > 0.0 && glon >= 0.0) *gv = *dec-glon; + if (glat > 0.0 && glon < 0.0) *gv = *dec+fabs(glon); + if (glat < 0.0 && glon >= 0.0) *gv = *dec+glon; + if (glat < 0.0 && glon < 0.0) *gv = *dec-fabs(glon); + if (*gv > +180.0) *gv -= 360.0; + if (*gv < -180.0) *gv += 360.0; + } + otime = t; + oalt = alt; + olat = glat; + olon = glon; + return (0); +} + +/*************************************************************************/ + +static int +geomag(FILE *wmmdat, int *maxdeg) +{ + return (E0000(wmmdat,0,maxdeg,0.0,0.0,0.0,0.0,NULL,NULL,NULL,NULL)); +} + +/*************************************************************************/ + +static int +geomg1(FILE *wmmdat, float alt, float glat, float glon, float t, +float *dec, float *mdp, float *ti, float *gv) +{ + return (E0000(wmmdat,1,NULL,alt,glat,glon,t,dec,mdp,ti,gv)); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: magdecl.c,v $ $Date: 2004/10/12 15:21:48 $ $Revision: 1.6 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/marsmoon.c b/Common/Libraries/XEphemAstroLib/src/marsmoon.c new file mode 100644 index 000000000..b09b13526 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/marsmoon.c @@ -0,0 +1,265 @@ +/* mars moon info */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <math.h> + +#include "astro.h" +#include "bdl.h" + +static int use_bdl (double JD, char *dir, MoonData md[M_NMOONS]); +static void moonradec (double msize, MoonData md[M_NMOONS]); +static void moonSVis (Obj *sop, Obj *mop, MoonData md[M_NMOONS]); +static void moonEVis (MoonData md[M_NMOONS]); +static void moonPShad (Obj *sop, Obj *mop, MoonData md[M_NMOONS]); +static void moonTrans (MoonData md[M_NMOONS]); + +/* moon table and a few other goodies and when it was last computed */ +static double mdmjd = -123456; +static MoonData mmd[M_NMOONS] = { + {"Mars", NULL}, + {"Phobos", "I"}, + {"Deimos", "II"}, +}; +static double sizemjd; + +/* These values are from the Explanatory Supplement. + * Precession degrades them gradually over time. + */ +#define POLE_RA degrad(317.61) +#define POLE_DEC degrad(52.85) + + +/* get mars info in md[0], moon info in md[1..M_NMOONS-1]. + * if !dir always use bruton model. + * if !mop caller just wants md[] for names + * N.B. we assume sop and mop are updated. + */ +void +marsm_data ( +double Mjd, /* mjd */ +char dir[], /* dir in which to look for helper files */ +Obj *sop, /* Sun */ +Obj *mop, /* mars */ +double *sizep, /* mars's angular diam, rads */ +double *polera, double *poledec,/* pole location */ +MoonData md[M_NMOONS]) /* return info */ +{ + double JD, dmag; + + /* always copy back at least for name */ + memcpy (md, mmd, sizeof(mmd)); + + /* pole */ + if (polera) *polera = POLE_RA; + if (poledec) *poledec = POLE_DEC; + + /* nothing else if repeat call or just want names */ + if (Mjd == mdmjd || !mop) { + if (mop) { + *sizep = sizemjd; + } + return; + } + JD = Mjd + MJD0; + + /* planet in [0] */ + md[0].ra = mop->s_ra; + md[0].dec = mop->s_dec; + md[0].mag = get_mag(mop); + md[0].x = 0; + md[0].y = 0; + md[0].z = 0; + md[0].evis = 1; + md[0].svis = 1; + + /* size is straight from mop */ + *sizep = degrad(mop->s_size/3600.0); + + /* from Pasachoff/Menzel: brightest @ .6 AU */ + dmag = 5.0*log10(mop->s_edist + 0.4); + md[1].mag = 11.8 + dmag; + md[2].mag = 12.9 + dmag; + + /* get moon x,y,z from BDL if possible */ + if (!dir || use_bdl (JD, dir, md) < 0) { + int i; + for (i = 1; i < M_NMOONS; i++) + md[i].x = md[i].y = md[i].z = 0.0; + fprintf (stderr, "No mars model available\n"); + } + + /* set visibilities */ + moonSVis (sop, mop, md); + moonPShad (sop, mop, md); + moonEVis (md); + moonTrans (md); + + /* fill in moon ra and dec */ + moonradec (*sizep, md); + + /* save */ + mdmjd = Mjd; + sizemjd = *sizep; + memcpy (mmd, md, sizeof(mmd)); +} + +/* hunt for BDL file in dir[] and use if possible. + * return 0 if ok, else -1 + */ +static int +use_bdl ( +double JD, /* julian date */ +char dir[], /* directory */ +MoonData md[M_NMOONS]) /* fill md[1..NM-1].x/y/z for each moon */ +{ +#define MRAU .00002269 /* Mars radius, AU */ + double x[M_NMOONS], y[M_NMOONS], z[M_NMOONS]; + char buf[1024]; + FILE *fp; + char *fn; + int i; + + /* check ranges and appropriate data file */ + if (JD < 2451179.50000) /* Jan 1 1999 UTC */ + return (-1); + if (JD < 2455562.5) /* Jan 1 2011 UTC */ + fn = "mars.9910"; + else if (JD < 2459215.5) /* Jan 1 2021 UTC */ + fn = "mars.1020"; + else + return (-1); + + /* open */ + (void) sprintf (buf, "%s/%s", dir, fn); + fp = fopen (buf, "r"); + if (!fp) { + fprintf (stderr, "%s: %s\n", fn, strerror(errno)); + return (-1); + } + + /* use it */ + if ((i = read_bdl (fp, JD, x, y, z, buf)) < 0) { + fprintf (stderr, "%s: %s\n", fn, buf); + fclose (fp); + return (-1); + } + if (i != M_NMOONS-1) { + fprintf (stderr, "%s: BDL says %d moons, code expects %d", fn, + i, M_NMOONS-1); + fclose (fp); + return (-1); + } + + /* copy into md[1..NM-1] with our scale and sign conventions */ + for (i = 1; i < M_NMOONS; i++) { + md[i].x = x[i-1]/MRAU; /* we want mars radii +E */ + md[i].y = -y[i-1]/MRAU; /* we want mars radii +S */ + md[i].z = -z[i-1]/MRAU; /* we want mars radii +front */ + } + + /* ok */ + fclose (fp); + return (0); +} + +/* given mars loc in md[0].ra/dec and size, and location of each moon in + * md[1..NM-1].x/y in mars radii,find ra/dec of each moon in md[1..NM-1].ra/dec. + */ +static void +moonradec ( +double msize, /* mars diameter, rads */ +MoonData md[M_NMOONS]) /* fill in RA and Dec */ +{ + double mrad = msize/2; + double mra = md[0].ra; + double mdec = md[0].dec; + int i; + + for (i = 1; i < M_NMOONS; i++) { + double dra = mrad * md[i].x; + double ddec = mrad * md[i].y; + md[i].ra = mra + dra; + md[i].dec = mdec - ddec; + } +} + +/* set svis according to whether moon is in sun light */ +static void +moonSVis( +Obj *sop, /* SUN */ +Obj *mop, /* mars */ +MoonData md[M_NMOONS]) +{ + double esd = sop->s_edist; + double eod = mop->s_edist; + double sod = mop->s_sdist; + double soa = degrad(mop->s_elong); + double esa = asin(esd*sin(soa)/sod); + double h = sod*mop->s_hlat; + double nod = h*(1./eod - 1./sod); + double sca = cos(esa), ssa = sin(esa); + int i; + + for (i = 1; i < M_NMOONS; i++) { + MoonData *mdp = &md[i]; + double xp = sca*mdp->x + ssa*mdp->z; + double yp = mdp->y; + double zp = -ssa*mdp->x + sca*mdp->z; + double ca = cos(nod), sa = sin(nod); + double xpp = xp; + double ypp = ca*yp - sa*zp; + double zpp = sa*yp + ca*zp; + int outside = xpp*xpp + ypp*ypp > 1.0; + int infront = zpp > 0.0; + mdp->svis = outside || infront; + } +} + +/* set evis according to whether moon is geometrically visible from earth */ +static void +moonEVis (MoonData md[M_NMOONS]) +{ + int i; + + for (i = 1; i < M_NMOONS; i++) { + MoonData *mdp = &md[i]; + int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0; + int infront = mdp->z > 0.0; + mdp->evis = outside || infront; + } +} + +/* set pshad and sx,sy shadow info */ +static void +moonPShad( +Obj *sop, /* SUN */ +Obj *mop, /* mars */ +MoonData md[M_NMOONS]) +{ + int i; + + for (i = 1; i < M_NMOONS; i++) { + MoonData *mdp = &md[i]; + mdp->pshad = !plshadow (mop, sop, POLE_RA, POLE_DEC, mdp->x, + mdp->y, mdp->z, &mdp->sx, &mdp->sy); + } +} + +/* set whether moons are transiting */ +static void +moonTrans (MoonData md[M_NMOONS]) +{ + int i; + + for (i = 1; i < M_NMOONS; i++) { + MoonData *mdp = &md[i]; + mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1; + } +} + + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: marsmoon.c,v $ $Date: 2006/08/29 03:16:47 $ $Revision: 1.8 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/misc.c b/Common/Libraries/XEphemAstroLib/src/misc.c new file mode 100644 index 000000000..504713733 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/misc.c @@ -0,0 +1,503 @@ +/* misc handy functions. + * every system has such, no? + * 4/20/98 now_lst() always just returns apparent time + */ + +#include <stdio.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#include "astro.h" + +/* zero from loc for len bytes */ +void +zero_mem (void *loc, unsigned len) +{ + (void) memset (loc, 0, len); +} + +/* given min and max and an approximate number of divisions desired, + * fill in ticks[] with nicely spaced values and return how many. + * N.B. return value, and hence number of entries to ticks[], might be as + * much as 2 more than numdiv. + */ +int +tickmarks (double min, double max, int numdiv, double ticks[]) +{ + static int factor[] = { 1, 2, 5 }; + double minscale; + double delta; + double lo; + double v; + int n; + + minscale = fabs(max - min); + delta = minscale/numdiv; + for (n=0; n < (int)(sizeof(factor)/sizeof(factor[0])); n++) { + double scale; + double x = delta/factor[n]; + if ((scale = (pow(10.0, ceil(log10(x)))*factor[n])) < minscale) + minscale = scale; + } + delta = minscale; + + lo = floor(min/delta); + for (n = 0; (v = delta*(lo+n)) < max+delta; ) + ticks[n++] = v; + + return (n); +} + +/* given an Obj *, return its type as a descriptive string. + * if it's of type fixed then return its class description. + * N.B. we return the address of static storage -- do not free or change. + */ +char * +obj_description (Obj *op) +{ + typedef struct { + char classcode; + char *desc; + } CC; + +#define NFCM ((int)(sizeof(fixed_class_map)/sizeof(fixed_class_map[0]))) + static CC fixed_class_map[] = { + {'A', "Cluster of Galaxies"}, + {'B', "Binary System"}, + {'C', "Globular Cluster"}, + {'D', "Double Star"}, + {'F', "Diffuse Nebula"}, + {'G', "Spiral Galaxy"}, + {'H', "Spherical Galaxy"}, + {'J', "Radio"}, + {'K', "Dark Nebula"}, + {'L', "Pulsar"}, + {'M', "Multiple Star"}, + {'N', "Bright Nebula"}, + {'O', "Open Cluster"}, + {'P', "Planetary Nebula"}, + {'Q', "Quasar"}, + {'R', "Supernova Remnant"}, + {'S', "Star"}, + {'T', "Star-like Object"}, + {'U', "Cluster, with nebulosity"}, + {'V', "Variable Star"}, + {'Y', "Supernova"}, + }; + +#define NBCM ((int)(sizeof(binary_class_map)/sizeof(binary_class_map[0]))) + static CC binary_class_map[] = { + {'a', "Astrometric binary"}, + {'c', "Cataclysmic variable"}, + {'e', "Eclipsing binary"}, + {'x', "High-mass X-ray binary"}, + {'y', "Low-mass X-ray binary"}, + {'o', "Occultation binary"}, + {'s', "Spectroscopic binary"}, + {'t', "1-line spectral binary"}, + {'u', "2-line spectral binary"}, + {'v', "Spectrum binary"}, + {'b', "Visual binary"}, + {'d', "Visual binary, apparent"}, + {'q', "Visual binary, optical"}, + {'r', "Visual binary, physical"}, + {'p', "Exoplanet"}, + }; + + switch (op->o_type) { + case FIXED: + if (op->f_class) { + int i; + for (i = 0; i < NFCM; i++) + if (fixed_class_map[i].classcode == op->f_class) + return (fixed_class_map[i].desc); + } + return ("Fixed"); + case PARABOLIC: + return ("Solar - Parabolic"); + case HYPERBOLIC: + return ("Solar - Hyperbolic"); + case ELLIPTICAL: + return ("Solar - Elliptical"); + case BINARYSTAR: + if (op->f_class) { + int i; + for (i = 0; i < NFCM; i++) + if (binary_class_map[i].classcode == op->f_class) + return (binary_class_map[i].desc); + } + return ("Binary system"); + case PLANET: { + static char nsstr[16]; + static Obj *biop; + + if (op->pl_code == SUN) + return ("Star"); + if (op->pl_code == MOON) + return ("Moon of Earth"); + if (op->pl_moon == X_PLANET) + return ("Planet"); + if (!biop) + getBuiltInObjs (&biop); + sprintf (nsstr, "Moon of %s", biop[op->pl_code].o_name); + return (nsstr); + } + case EARTHSAT: + return ("Earth Sat"); + default: + printf ("obj_description: unknown type: 0x%x\n", op->o_type); + abort(); + return (NULL); /* for lint */ + } +} + +/* given a Now *, find the local apparent sidereal time, in hours. + */ +void +now_lst (Now *np, double *lstp) +{ + static double last_mjd = -23243, last_lng = 121212, last_lst; + double eps, lst, deps, dpsi; + + if (last_mjd == mjd && last_lng == lng) { + *lstp = last_lst; + return; + } + + utc_gst (mjd_day(mjd), mjd_hr(mjd), &lst); + lst += radhr(lng); + + obliquity(mjd, &eps); + nutation(mjd, &deps, &dpsi); + lst += radhr(dpsi*cos(eps+deps)); + + range (&lst, 24.0); + + last_mjd = mjd; + last_lng = lng; + *lstp = last_lst = lst; +} + +/* convert ra to ha, in range 0..2*PI + * need dec too if not already apparent. + */ +void +radec2ha (Now *np, double ra, double dec, double *hap) +{ + double ha, lst; + + if (epoch != EOD) + as_ap (np, epoch, &ra, &dec); + now_lst (np, &lst); + ha = hrrad(lst) - ra; + if (ha < 0) + ha += 2*PI; + *hap = ha; +} + +/* find Greenwich Hour Angle of the given object at the given time, 0..2*PI. + */ +void +gha (Now *np, Obj *op, double *ghap) +{ + Now n = *np; + Obj o = *op; + double tmp; + + n.n_epoch = EOD; + n.n_lng = 0.0; + n.n_lat = 0.0; + obj_cir (&n, &o); + now_lst (&n, &tmp); + tmp = hrrad(tmp) - o.s_ra; + if (tmp < 0) + tmp += 2*PI; + *ghap = tmp; +} + +/* given a circle and a line segment, find a segment of the line inside the + * circle. + * return 0 and the segment end points if one exists, else -1. + * We use a parametric representation of the line: + * x = x1 + (x2-x1)*t and y = y1 + (y2-y1)*t, 0 < t < 1 + * and a centered representation of the circle: + * (x - xc)**2 + (y - yc)**2 = r**2 + * and solve for the t's that work, checking for usual conditions. + */ +int +lc ( +int cx, int cy, int cw, /* circle bbox corner and width */ +int x1, int y1, int x2, int y2, /* line segment endpoints */ +int *sx1, int *sy1, int *sx2, int *sy2) /* segment inside the circle */ +{ + int dx = x2 - x1; + int dy = y2 - y1; + int r = cw/2; + int xc = cx + r; + int yc = cy + r; + int A = x1 - xc; + int B = y1 - yc; + double a = dx*dx + dy*dy; /* O(2 * 2**16 * 2**16) */ + double b = 2*(dx*A + dy*B); /* O(4 * 2**16 * 2**16) */ + double c = A*A + B*B - r*r; /* O(2 * 2**16 * 2**16) */ + double d = b*b - 4*a*c; /* O(2**32 * 2**32) */ + double sqrtd; + double t1, t2; + + if (d <= 0) + return (-1); /* containing line is purely outside circle */ + + sqrtd = sqrt(d); + t1 = (-b - sqrtd)/(2.0*a); + t2 = (-b + sqrtd)/(2.0*a); + + if (t1 >= 1.0 || t2 <= 0.0) + return (-1); /* segment is purely outside circle */ + + /* we know now that some part of the segment is inside, + * ie, t1 < 1 && t2 > 0 + */ + + if (t1 <= 0.0) { + /* (x1,y1) is inside circle */ + *sx1 = x1; + *sy1 = y1; + } else { + *sx1 = (int)(x1 + dx*t1); + *sy1 = (int)(y1 + dy*t1); + } + + if (t2 >= 1.0) { + /* (x2,y2) is inside circle */ + *sx2 = x2; + *sy2 = y2; + } else { + *sx2 = (int)(x1 + dx*t2); + *sy2 = (int)(y1 + dy*t2); + } + + return (0); +} + +/* compute visual magnitude using the H/G parameters used in the Astro Almanac. + * these are commonly used for asteroids. + */ +void +hg_mag ( +double h, double g, +double rp, /* sun-obj dist, AU */ +double rho, /* earth-obj dist, AU */ +double rsn, /* sun-earth dist, AU */ +double *mp) +{ + double psi_t, Psi_1, Psi_2, beta; + double c; + double tb2; + + c = (rp*rp + rho*rho - rsn*rsn)/(2*rp*rho); + if (c <= -1) + beta = PI; + else if (c >= 1) + beta = 0; + else + beta = acos(c);; + tb2 = tan(beta/2.0); + /* psi_t = exp(log(tan(beta/2.0))*0.63); */ + psi_t = pow (tb2, 0.63); + Psi_1 = exp(-3.33*psi_t); + /* psi_t = exp(log(tan(beta/2.0))*1.22); */ + psi_t = pow (tb2, 1.22); + Psi_2 = exp(-1.87*psi_t); + *mp = h + 5.0*log10(rp*rho); + if (Psi_1 || Psi_2) *mp -= 2.5*log10((1-g)*Psi_1 + g*Psi_2); +} + +/* given faintest desired mag, mag step magstp, image scale and object + * magnitude and size, return diameter to draw object, in pixels, or 0 if + * dimmer than fmag. + */ +int +magdiam ( +int fmag, /* faintest mag */ +int magstp, /* mag range per dot size */ +double scale, /* rads per pixel */ +double mag, /* magnitude */ +double size) /* rads, or 0 */ +{ + int diam, sized; + + if (mag > fmag) + return (0); + diam = (int)((fmag - mag)/magstp + 1); + sized = (int)(size/scale + 0.5); + if (sized > diam) + diam = sized; + + return (diam); +} + +/* computer visual magnitude using the g/k parameters commonly used for comets. + */ +void +gk_mag ( +double g, double k, +double rp, /* sun-obj dist, AU */ +double rho, /* earth-obj dist, AU */ +double *mp) +{ + *mp = g + 5.0*log10(rho) + 2.5*k*log10(rp); +} + +/* given a string convert to floating point and return it as a double. + * this is to isolate possible unportabilities associated with declaring atof(). + * it's worth it because atof() is often some 50% faster than sscanf ("%lf"); + */ +double +atod (char *buf) +{ + return (strtod (buf, NULL)); +} + +/* solve a spherical triangle: + * A + * / \ + * / \ + * c / \ b + * / \ + * / \ + * B ____________ C + * a + * + * given A, b, c find B and a in range 0..B..2PI and 0..a..PI, respectively.. + * cap and Bp may be NULL if not interested in either one. + * N.B. we pass in cos(c) and sin(c) because in many problems one of the sides + * remains constant for many values of A and b. + */ +void +solve_sphere (double A, double b, double cc, double sc, double *cap, double *Bp) +{ + double cb = cos(b), sb = sin(b); + double sA, cA = cos(A); + double x, y; + double ca; + double B; + + ca = cb*cc + sb*sc*cA; + if (ca > 1.0) ca = 1.0; + if (ca < -1.0) ca = -1.0; + if (cap) + *cap = ca; + + if (!Bp) + return; + + if (sc < 1e-7) + B = cc < 0 ? A : PI-A; + else { + sA = sin(A); + y = sA*sb*sc; + x = cb - ca*cc; + B = y ? (x ? atan2(y,x) : (y>0 ? PI/2 : -PI/2)) : (x>=0 ? 0 : PI); + } + + *Bp = B; + range (Bp, 2*PI); +} + +/* #define WANT_MATHERR if your system supports it. it gives SGI fits. + */ +#undef WANT_MATHERR +#if defined(WANT_MATHERR) +/* attempt to do *something* reasonable when a math function blows. + */ +matherr (xp) +struct exception *xp; +{ + static char *names[8] = { + "acos", "asin", "atan2", "pow", + "exp", "log", "log10", "sqrt" + }; + int i; + + /* catch-all */ + xp->retval = 0.0; + + for (i = 0; i < sizeof(names)/sizeof(names[0]); i++) + if (strcmp (xp->name, names[i]) == 0) + switch (i) { + case 0: /* acos */ + xp->retval = xp->arg1 >= 1.0 ? 0.0 : -PI; + break; + case 1: /* asin */ + xp->retval = xp->arg1 >= 1.0 ? PI/2 : -PI/2; + break; + case 2: /* atan2 */ + if (xp->arg1 == 0.0) + xp->retval = xp->arg2 < 0.0 ? PI : 0.0; + else if (xp->arg2 == 0.0) + xp->retval = xp->arg1 < 0.0 ? -PI/2 : PI/2; + else + xp->retval = 0.0; + break; + case 3: /* pow */ + /* FALLTHRU */ + case 4: /* exp */ + xp->retval = xp->o_type == OVERFLOW ? 1e308 : 0.0; + break; + case 5: /* log */ + /* FALLTHRU */ + case 6: /* log10 */ + xp->retval = xp->arg1 <= 0.0 ? -1e308 : 0; + break; + case 7: /* sqrt */ + xp->retval = 0.0; + break; + } + + return (1); /* suppress default error handling */ +} +#endif + +/* given the difference in two RA's, in rads, return their difference, + * accounting for wrap at 2*PI. caller need *not* first force it into the + * range 0..2*PI. + */ +double +delra (double dra) +{ + double fdra = fmod(fabs(dra), 2*PI); + + if (fdra > PI) + fdra = 2*PI - fdra; + return (fdra); +} + +/* return 1 if object is considered to be "deep sky", else 0. + * The only things deep-sky are fixed objects other than stars. + */ +int +is_deepsky (Obj *op) +{ + int deepsky = 0; + + if (is_type(op, FIXEDM)) { + switch (op->f_class) { + case 'T': + case 'B': + case 'D': + case 'M': + case 'S': + case 'V': + break; + default: + deepsky = 1; + break; + } + } + + return (deepsky); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: misc.c,v $ $Date: 2005/03/11 16:47:46 $ $Revision: 1.18 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/mjd.c b/Common/Libraries/XEphemAstroLib/src/mjd.c new file mode 100644 index 000000000..b875a7b92 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/mjd.c @@ -0,0 +1,256 @@ +/* functions to manipulate the modified-julian-date used throughout xephem. */ + +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +/* given a date in months, mn, days, dy, years, yr, + * return the modified Julian date (number of days elapsed since 1900 jan 0.5), + * *mjd. + */ +void +cal_mjd (int mn, double dy, int yr, double *mjp) +{ + static double last_mjd, last_dy; + static int last_mn, last_yr; + int b, d, m, y; + long c; + + if (mn == last_mn && yr == last_yr && dy == last_dy) { + *mjp = last_mjd; + return; + } + + m = mn; + y = (yr < 0) ? yr + 1 : yr; + if (mn < 3) { + m += 12; + y -= 1; + } + + if (yr < 1582 || (yr == 1582 && (mn < 10 || (mn == 10 && dy < 15)))) + b = 0; + else { + int a; + a = y/100; + b = 2 - a + a/4; + } + + if (y < 0) + c = (long)((365.25*y) - 0.75) - 694025L; + else + c = (long)(365.25*y) - 694025L; + + d = (int)(30.6001*(m+1)); + + *mjp = b + c + d + dy - 0.5; + + last_mn = mn; + last_dy = dy; + last_yr = yr; + last_mjd = *mjp; +} + +/* given the modified Julian date (number of days elapsed since 1900 jan 0.5,), + * mj, return the calendar date in months, *mn, days, *dy, and years, *yr. + */ +void +mjd_cal (double mj, int *mn, double *dy, int *yr) +{ + static double last_mj, last_dy; + static int last_mn, last_yr; + double d, f; + double i, a, b, ce, g; + + /* we get called with 0 quite a bit from unused epoch fields. + * 0 is noon the last day of 1899. + */ + if (mj == 0.0) { + *mn = 12; + *dy = 31.5; + *yr = 1899; + return; + } + + if (mj == last_mj) { + *mn = last_mn; + *yr = last_yr; + *dy = last_dy; + return; + } + + d = mj + 0.5; + i = floor(d); + f = d-i; + if (f == 1) { + f = 0; + i += 1; + } + + if (i > -115860.0) { + a = floor((i/36524.25)+.99835726)+14; + i += 1 + a - floor(a/4.0); + } + + b = floor((i/365.25)+.802601); + ce = i - floor((365.25*b)+.750001)+416; + g = floor(ce/30.6001); + *mn = (int)(g - 1); + *dy = ce - floor(30.6001*g)+f; + *yr = (int)(b + 1899); + + if (g > 13.5) + *mn = (int)(g - 13); + if (*mn < 2.5) + *yr = (int)(b + 1900); + if (*yr < 1) + *yr -= 1; + + last_mn = *mn; + last_dy = *dy; + last_yr = *yr; + last_mj = mj; +} + +/* given an mjd, set *dow to 0..6 according to which day of the week it falls + * on (0=sunday). + * return 0 if ok else -1 if can't figure it out. + */ +int +mjd_dow (double mj, int *dow) +{ + /* cal_mjd() uses Gregorian dates on or after Oct 15, 1582. + * (Pope Gregory XIII dropped 10 days, Oct 5..14, and improved the leap- + * year algorithm). however, Great Britian and the colonies did not + * adopt it until Sept 14, 1752 (they dropped 11 days, Sept 3-13, + * due to additional accumulated error). leap years before 1752 thus + * can not easily be accounted for from the cal_mjd() number... + */ + if (mj < -53798.5) { + /* pre sept 14, 1752 too hard to correct |:-S */ + return (-1); + } + *dow = ((long)floor(mj-.5) + 1) % 7;/* 1/1/1900 (mj 0.5) is a Monday*/ + if (*dow < 0) + *dow += 7; + return (0); +} + +/* given a year, return whether it is a leap year */ +int +isleapyear (int y) +{ + return ((y%4==0 && y%100!=0) || y%400==0); +} + +/* given a mjd, return the the number of days in the month. */ +void +mjd_dpm (double mj, int *ndays) +{ + static short dpm[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int m, y; + double d; + + mjd_cal (mj, &m, &d, &y); + *ndays = (m==2 && isleapyear(y)) ? 29 : dpm[m-1]; +} + +/* given a mjd, return the year and number of days since 00:00 Jan 1 */ +void +mjd_dayno (double mj, int *yr, double *dy) +{ + double yrd; + int yri; + int dpy; + + mjd_year (mj, &yrd); + *yr = yri = (int)yrd; + dpy = isleapyear(yri) ? 366 : 365; + *dy = dpy*(yrd-yri); +} + +/* given a mjd, return the year as a double. */ +void +mjd_year (double mj, double *yr) +{ + static double last_mj, last_yr; + int m, y; + double d; + double e0, e1; /* mjd of start of this year, start of next year */ + + if (mj == last_mj) { + *yr = last_yr; + return; + } + + mjd_cal (mj, &m, &d, &y); + if (y == -1) y = -2; + cal_mjd (1, 1.0, y, &e0); + cal_mjd (1, 1.0, y+1, &e1); + *yr = y + (mj - e0)/(e1 - e0); + + last_mj = mj; + last_yr = *yr; +} + +/* given a decimal year, return mjd */ +void +year_mjd (double y, double *mjp) +{ + double e0, e1; /* mjd of start of this year, start of next year */ + int yf = (int)floor (y); + if (yf == -1) yf = -2; + + cal_mjd (1, 1.0, yf, &e0); + cal_mjd (1, 1.0, yf+1, &e1); + *mjp = e0 + (y - yf)*(e1-e0); +} + +/* round a time in days, *t, to the nearest second, IN PLACE. */ +void +rnd_second (double *t) +{ + *t = floor(*t*SPD+0.5)/SPD; +} + +/* given an mjd, truncate it to the beginning of the whole day */ +double +mjd_day(double mj) +{ + return (floor(mj-0.5)+0.5); +} + +/* given an mjd, return the number of hours past midnight of the whole day */ +double +mjd_hr(double mj) +{ + return ((mj-mjd_day(mj))*24.0); +} + +/* insure 0 <= *v < r. + */ +void +range (double *v, double r) +{ + *v -= r*floor(*v/r); +} + +/* insure 0 <= ra < 2PI and -PI/2 <= dec <= PI/2. if dec needs + * complimenting, reflect ra too + */ +void +radecrange (double *ra, double *dec) +{ + if (*dec < -PI/2) { + *dec = -PI - *dec; + *ra += PI; + } else if (*dec > PI/2) { + *dec = PI - *dec; + *ra += PI; + } + range (ra, 2*PI); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: mjd.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.6 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/moon.c b/Common/Libraries/XEphemAstroLib/src/moon.c new file mode 100644 index 000000000..bf5f3768a --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/moon.c @@ -0,0 +1,3467 @@ +/* geocentric moon polar coordinates re mean equinox and ecliptic of date + + S. L. Moshier + December, 1996 + +********************************************************************** + Adapted by Michael Sternberg <sternberg@physik.tu-chemnitz.de> + for xephem with minor modifications from the originals at: + ftp://ftp.std.com/pub/astronomy/selenog.zip + + Precision < 0.05" from -1369 to +2950. + Uses table lookup techniques to limit calls to trigonometric functions. + + NB: Uses International Earth Rotation System (IERS) which is + taken as equivalent to FK5 for the purposes of xephem. + + original files used: + chewtab.c mean.c mlr404.c + mlat404.c selenog.c + + changes: + added prototypes, grouped and cleaned up vars and #defines, + removed _MSC_VER #ifdefs, uniqed names in moonlr and moonlat, + included plantbl.h in .c file, dropped out librations for now. + + in struct plantbl, promoted "char *arg_tbl" to "short *". + reason: - more portable (BTW: this is the only place in xephem + where "signed char" would have been needed) + - using "short" costs a mere 7k memory but avoids core + dumps on a machine which we didn't anticipate. + +********************************************************************** + + + Residuals against JPL ephemeris DE404 (arc seconds) + +First date in file = 1221000.5 +Number of samples = 1053099 +Sampling interval = 1.515625 days + +Peak excursions from these mostly different test points +were consolidated with the above. They added .01" to a few +of the peak readings. +First date in file = 1221000.50 +Number of samples = 524290.0 +Sampling interval = 3.0 days + + + Julian Years Longitude Latitude Distance + 1 = 1.9 km + Peak RMS Ave Peak RMS Ave Peak RMS Ave + -1369.0 to -1000.0: 0.43 0.07 0.00 0.33 0.05 -0.00 0.18 0.03 0.00 + -1000.0 to -500.0: 0.49 0.06 -0.00 0.33 0.04 -0.00 0.18 0.03 0.00 + -500.0 to 0.0: 0.48 0.06 0.00 0.32 0.04 0.00 0.15 0.03 0.00 + 0.0 to 500.0: 0.45 0.05 0.00 0.30 0.04 -0.00 0.17 0.03 -0.00 + 500.0 to 1000.0: 0.48 0.05 -0.00 0.29 0.04 0.00 0.17 0.03 -0.00 + 1000.0 to 1500.0: 0.42 0.05 -0.00 0.28 0.04 -0.00 0.16 0.03 0.00 + 1500.0 to 2000.0: 0.35 0.05 -0.00 0.26 0.04 0.00 0.15 0.03 0.00 + 2000.0 to 2500.0: 0.39 0.06 0.00 0.25 0.04 -0.00 0.15 0.03 -0.00 + 2500.0 to 3000.0: 0.44 0.07 -0.00 0.30 0.05 -0.00 0.19 0.03 -0.00 + 3000.0 to 3000.8: 0.23 0.08 -0.04 0.11 0.04 -0.00 0.08 0.03 -0.00 + */ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +#define CHAR short + +#define NARGS 18 + +struct plantbl { + char max_harmonic[NARGS]; + char max_power_of_t; + CHAR *arg_tbl; + long *lon_tbl; + long *lat_tbl; + long *rad_tbl; + double distance; + double timescale; + double trunclvl; +}; + +static double mods3600 (double x); +static void mean_elements (double JED); +static int sscc (int k, double arg, int n); +static int g2plan (double J, struct plantbl *plan, double *pobj, int flag); +static double g1plan (double J, struct plantbl *plan); +static int gecmoon (double J, struct plantbl *lrtab, + struct plantbl *lattab, double *pobj); + +/* time points */ +#define MOSHIER_J2000 (2451545.0) + +#define MOSHIER_BEGIN (1221000.5 - MJD0) /* directly from above */ +#define MOSHIER_END (2798525.5 - MJD0) /* 2950.0; from libration table */ + + +static double Args[NARGS]; +static double LP_equinox; +static double NF_arcsec; +static double Ea_arcsec; +static double pA_precession; + + +/* This storage ought to be allocated dynamically. */ +double ss[NARGS][30]; +double cc[NARGS][30]; + +/* Time, in units of 10,000 Julian years from JED 2451545.0. */ +static double T; + +/* Conversion factors between degrees and radians */ +#define DTR 1.7453292519943295769e-2 +#define RTD 5.7295779513082320877e1 +#define RTS 2.0626480624709635516e5 /* arc seconds per radian */ +#define STR 4.8481368110953599359e-6 /* radians per arc second */ +#define AUKM 1.4959787e8 + + +static long lrtabl[] = { + 175667, 66453, 5249, -42, + 20057, 403, -2360, 6148, + -7644, 24646, -1273, 9127, + -1395, 1958, + 232, -289, + -97, 553, 69, 130, + -80, 6, + 129, -868, 26, -89, + 1042, 1172, 194, -112, + -47433, -241666, 224626, -103752, + 63419, 127606, + 2294, -691, -1827, -1254, + -1, -119, + 1057, 324, + 505, -195, 254, -641, + -36, 1008, -1082, -3, + -87, 122, + 161, 11, + 2, -106, + 29, -123, + -32, 41, + -524, -35, + 133, -595, + 225, 837, -108, -191, + -2294, 841, -340, -394, + -351, -1039, 238, -108, + -66, 21, + 1405, 869, 520, 2776, + -174, 71, + 425, 652, -1260, -80, + 249, 77, + -192, -17, + -97, 134, + -7, -54, + -802, -7436, -2824, 70869, + -35, 2481, + 1865, 1749, -2166, 2415, + 33, -183, + -835, 283, + 27, -45, + 56, 235, + 2, 718, + -1206, 275, -87, -158, + -7, -2534, 0, 10774, + 1, -324, + -208, 821, + 281, 1340, -797, 440, + 224, 72, + -65, -5, + -7, -44, + -48, 66, + -151, -40, + -41, -45, + 76, -108, + -18, 1202, 0, -2501, + 1438, -595, 900, 3040, + -3435, -5, + -100, -26, + 0, -13714, + -183, 68, + 453, -83, + -228, 325, + 97, 13, + 2, 105, + -61, 257, + 0, 57, + 88, -11, + -1, -8220, + 0, 275, + -43, -10, + -199, 105, + 1, -5849, 2, 24887, + -128, 48, + 712, 970, -1407, 845, + -266, 378, + 311, 1526, -1751, 27, + 0, -185858, + 133, 6383, + -108, 25, + -7, 1944, + 5, 390, + -11, 31, + 277, -384, 158, 72, + -81, -41, -13, -111, + -2332, -65804, -698, 505812, + 34, 1676716, -72, -6664384, + 154, -57, 52, 95, + -4, -5, + -7, 37, + -63, -32, + 4, 3349, 1, -14370, + 16, -83, + 0, -401, + 13, 3013, + 48, -20, + 0, 250, + 51, -79, + -7, -146, + 148, 9, + 0, -64, + -17, -59, + -67, -492, + -2, 2116601, + -12, -1848, + 8, -436, + -6, 324, 0, -1363, + -163, 9, + 0, -74, + 63, 8167, -29, 37587, + -22, -74501, + -71, 497, + -1, 551747, + -87, -22, + 0, -51, + -1, -463, + 0, -444, + 3, 89, + 15, -84, + -36, -6829, -5, -21663, + 0, 86058, + 0, -298, + -2, 751, -2, -1015, + 0, 69, + 1, -4989, 0, 21458, + 0, -330, + 0, -7, + 0, -226, + 0, -1407, 0, 2942, + 0, 66, + 0, 667, + 0, -155, + 0, 105, + 0, -107, + 0, -74, + 0, -52, + 0, 91, + 0, 59, + 0, 235, + -1, -1819, 0, 2470, + 71, 13, + 0, 1026, + 14, -54, + 0, -174, + -121, -19, + 0, -200, + 0, 3008, + -16, -8043, -10, -37136, + -3, 73724, + -157, -5, + 0, -854, + 8, 147, + -13, -893, + 0, 11869, + -23, -172, + 89, 14, + -1, 872, 0, -3744, + 11, 1606, + 0, -559, + -1, -2530, + 0, 454, + 0, -193, + -60, -10, + -82, -13, + -75, 6, + 36, 81, + 354, -162836, 148, -516569, + 4, 2054441, + 4, -94, + 39, 38, + 61, -30, + 2, 121, + -11, 590, + 62, 2108, + 0, -12242, + -476, -42, + -84, 113, + -394, 236, + 0, 276, + -49, 31, + 0, 86, + 1, -1313, + 1, 69, + -60, 88, + -46, 18, + 0, -63818, + 14, -93, + 113, 547, -618, 17, + -7, 12290, -1, -25679, + 0, 92, + -115, 50, + -48, 233, + 4, 1311, 1, -5567, + 3, 1251, + 29, 548, + -244, 257, + -2, 1825, + 42, 637, + -46, 68, + -62, 8, + 3, 110, + 445, -100, -316, -202, + 2925, -621, 763, 1495, + -169, -184, 20, -76, + -475, -138, 8, -141, + -197, 1351, -1284, 422, + -129, 1879, -102, 8382, + -9, 45864958, + -215, 1350, -1285, 422, + -481, -136, 8, -140, + 40, -53, + 2622, -543, 700, 1406, + 402, -95, -318, -194, + 122, 13, + -30, 147, + -121, -902, + 61, -23, + -63, 7, + 69, 479, + -224, 228, + -7, 500, + 0, -429, + -42, 193, + -92, 37, + 67, 5, + -350, -31, + 0, 67, + -55, -5, + 0, 47, + -36, 53, + 5, 561, + 0, -126, + 0, 871, + -52, 4, + -201, 116922, -22, 371352, + -12, -1473285, + 0, 87, + -164, 84, + -3, 422, + 30, 1434, + -26, 38, + 2, -1249943, + -404, -34, + -57, 79, + 5, 509, + 1, 131, + -344, 168, + 112, 22540, 30, 71218, + 18, -283983, + 0, -851, + 0, -1538, + 0, 1360, + -12, 51, + -48, 68, + 88, -20, + 1, 63, + 0, -568, + 303, 25, + 0, -122, + 87, 586, -606, -14, + 0, -100, + -85, 8, + -165, 54, + -45, 140, + 0, -54, + 4, -831, 1, 3495, + 31, 116, + -46, -11, + -371, 190, + -507, 399, + -2, 57, + -60, 36, + -198, -1174, -613, 4988, + -87, -4, + 141, 560, -276, 187, + 1876, 1379, 778, 4386, + 24, -15, + 167, -774, + -71, -9, + -62, 90, + 98, 580, -663, -7, + 34, -112, + 57, 15, + -355, -214, + -3240, -13605, 12229, -5723, + 3496, 7063, + 33, -51, + 1908, 1160, -226, 715, + 964, 1170, -1264, 623, + 14071, 5280, 5614, 3026, + 488, 1576, -2, 226395859, + 824, 1106, -1287, 617, + 1917, 1156, -214, 718, + 90, -97, + 12078, -2366, 3282, 6668, + -219, 9179, 593, 2015, + -282, -186, + 57, 25, + 31, -102, + -77, -4, + -268, -341, -7, -45, + -3, 74, + 15, -615, + -88, -7, + 234, -353, + 1, -119, + -163, -1159, -601, 4969, + 22, -58, + -17, -11434, + 17, 54, + 348, 348, -460, 434, + -371, 175, + -11, -204, + 4, -6440, + -5, -53, + -4, -14388, -37, -45231, + -7, 179562, + -44, 136, + -160, 49, + -101, 81, + -1, -188, + 0, 2, + -4, 12124, -11, -25217, + 71, 543, -557, -14, + -75, 526, + 0, 395274, + -233, -16, + 93, -20, + -43, 61, + 0, -1275, + 0, -824, + 1, -415, 0, 1762, + -261, 131, + -45, 64, + -297, -25, + 0, -17533, + -6, -56, + 21, 1100, + 1, 327, + 1, 66, + 23, -217, + -83, -7, + 83, 86847, 49, 275754, + -4, -1093857, + -46, 2, + 0, -24, + 0, -419, + 0, -5833, + 1, 506, + 0, -827, + -1, -377, + -11, -78, + 0, 131945, + -2, -334, + 1, -75, + 0, -72, + 0, -213, + -6, 5564, -2, -11618, + 0, 1790, + 0, -131, + 0, 6, + 0, -76, + 0, -130, + 0, -1115, 0, 4783, + 0, -195, + 0, -627, + 0, -55, + 0, -83, + 0, 163, + 0, -54, + 0, 82, + 0, 149, + 0, -754, 0, 1578, + 0, 138, + 0, 68, + 2, -2506, 0, 3399, + 0, -125, + 86, 16, + 0, -6350, 0, 27316, + 18, -63, + 0, -169, + -1, 46, + -136, -21, + 0, -239, + -30, -8788, -15, -40549, + -4, 80514, + -46, -8, + -168, -6, + -1, 536, 0, -2314, + 9, 148, + -13, -842, + -1, 307713, + -23, -175, + 95, 15, + 0, -297, + 11, 1341, + 0, -106, + 0, 5, + -4, 68, + -114, 10, + 32, 75, + 159, -130487, 98, -413967, + 2, 1647339, + -4, -85, + 100, -46, + 2, 95, + -11, 461, + 51, 1647, + 0, -32090, + -375, -33, + -65, 86, + -300, 180, + 0, 836, 0, -3576, + 0, -222, + 0, -993, + -41, 60, + 0, -4537, + -431, -34, + 2, 927, 0, -1931, + -79, 33, + -31, 144, + -1, 284, 0, -1207, + 0, 88, + -11, 315, + -178, 177, + -1, 144, + -58, 986, + 11, 86, + -228, -110, + 2636, -494, 718, 1474, + 28, -35, + -24, 782, -797, 277, + 2142, -1231, 856, 1853, + 74, 10797, 0, 23699298, + -21, 786, -796, 277, + 27, -34, + 2615, -494, 712, 1461, + -226, -109, + -11, 663, + 0, -123, + -169, 157, + -54, 266, + 0, -76, + 1, -634, 0, 2738, + -25, 106, + -63, 24, + 0, -372, + -221, -24, + 0, -5356, + 0, -219, + 0, 91, + -28, 7684, -6, 24391, + -1, -96795, + -77, 43, + 2, 95, + -47, -3, + 0, -84530, + 2, 310, + 1, 88, + 111, 19331, 32, 61306, + 4, -243595, + 0, 770, + 0, -103, + 0, 160, + 0, 356, + 0, 236, + -41, 354, + 39, 303, + 12, -56, + 873, -143, 238, 482, + -28, 35, + -93, 31, + -3, 7690211, + -91, 33, + -34, 43, + 824, -130, 226, 450, + -39, 341, + -1, -687, + 0, -303, + 11, -2935, 1, 12618, + 121, 924, 9, -1836, + -268, -1144, -678, 3685, + -69, -261, + 0, -4115951, + -69, -261, + 5, -151, + 0, -88, + 0, 91, + 0, 187, + 0, -1281, + 1, 77, + 1, 6059, 3, 19238, + 0, -76305, + 0, -90, + 0, -238, + 0, -962, 0, 4133, + 0, 96, + 0, 9483, + 0, 85, + 0, -688, + 0, -5607, + 0, 55, + 0, -752, + 0, 71, + 0, 303, + 0, -288, + 0, 57, + 0, 45, + 0, 189, + 0, 401, + 0, -1474, 0, 3087, + 0, -71, + 0, 2925, + 0, -75, + 0, 359, + 0, 55, + 1, -10155, 0, 43735, + 0, -572, + 0, -49, + 0, -660, + 0, -3591, 0, 7516, + 0, 668, + -1, -53, + -2, 384259, + 0, -163, + 0, -93, + 1, 112, + -95, -11528, -22, -36505, + -1, 145308, + 5, 145, + 0, 4047, + 1, 1483, 0, -6352, + 0, 991, 0, -4262, + 0, -93, + 0, -334, + 0, -160, + 0, -153, + -10, 127, + 51, 185, + -77, 18, + 56, 1217, 6, 1919574, + -74, 17, + 50, 180, + -5, 93, + 0, -104, + 0, -58, + -3, -353, -1, 1499, + 0, -229, + -15, 86, + 0, -93657, + 0, 1561, 0, -6693, + 0, -5839, + 1, 6791, 0, -29143, + 1, -701, 0, 3015, + 0, 2543, + 0, 693, + -1, 361233, + 0, -50, + 0, 946, + -1, -140, + -70, 407, + 0, -450995, + 0, -368, + 0, 54, + 0, -802, + 0, -96, + 0, 1274, 0, -5459, + 0, -614, 0, 2633, + 0, 685, + 0, -915, + 0, -85, + 0, 88, + 0, 106, + 0, 928, + 0, -726, 0, 1523, + 0, 5715, + 0, -4338, 0, 18706, + 0, -135, + 0, -132, + 0, -158, + 0, -98, + 0, 680, + -1, 138968, + 0, -192, + 0, -1698, + 0, -2734, 0, 11769, + 0, 4, + 0, 673, 0, -2891, + 0, 889, 0, -3821, + 0, 121, + -1, 143783, + 0, 231, + -9, 51, + 0, -57413, + 0, -483, + 0, -407, + 0, 676, 0, -2902, + 0, 531, + 0, 445, + 0, 672, + 0, 19336, + 0, 70, + 0, -39976, + 0, -68, + 0, 4203, + 0, -406, + 0, 446, + 0, -108, + 0, 79, + 0, 84, + 0, 734, + 0, 255, + 0, 3944, + 0, -655, 0, 2825, + 0, -109, + 0, -234, + 0, 57, + 0, 19773, + 0, -2013, + 0, 958, + 0, -521, + 0, -757, + 0, 10594, + 0, -9901, + 0, 199, + 0, -275, + 0, 64, + 0, 54, + 0, 165, + 0, 1110, + 0, -3286, + 0, 909, + 0, 54, + 0, 87, + 0, 258, + 0, 1261, + 0, -51, + 0, 336, + 0, -114, + 0, 2185, + 0, -850, + 0, 75, + 0, -69, + 0, -103, + 0, 776, + 0, -1238, + 0, 137, + 0, 67, + 0, -260, + 0, 130, + 0, 49, + 0, 228, + 0, 215, + 0, -178, + 0, 57, + 0, -133, +}; +static long lrtabb[] = {-1}; +static long lrtabr[] = { + -5422, -2120, 1077, 772, + 39, 75, 3, 10, + -468, -326, -113, -78, + -4, -2, + 1, 3, + 29, 24, 4, 2, + 1, 0, + -9, 7, -2, 0, + -32, -13, -3, -3, + 233, 126, 89, 77, + -33, 16, + 3, -3, 0, -1, + 2, 0, + 0, 1, + 4, 9, 1, 1, + 16, -1, 0, 18, + 3, 2, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, -1, + -22, -5, + 10, 3, 1, 1, + -15, 7, -2, 1, + -8, -11, -1, -2, + -1, 1, + 46, -58, 126, -23, + 4, 8, + 35, 8, 10, -17, + 0, 0, + 0, 0, + -10, -7, + 0, 0, + -23, 3, 151, 10, + -327, 0, + 4, -5, 6, 5, + 1, 0, + -1, -3, + 0, 0, + 0, 1, + -185, 0, + -3, -24, -5, -2, + -1062, 3, 4560, 0, + -3, 0, + 4, 1, + 8, -1, 2, 4, + 0, 1, + 0, -1, + 0, 0, + -1, 0, + 0, 1, + 0, 0, + -1, -1, + 277, 3, -583, 1, + -1, 4, -32, 7, + 0, -34, + 1, -1, + -23685, 0, + -1, -2, + -1, -7, + -5, -4, + 0, 2, + -2, 0, + -5, -1, + 35, 0, + 0, 2, + 202, 0, + 180, 0, + 0, -1, + -3, -6, + -193, 0, 770, -1, + -2, -4, + -32, 23, -28, -46, + -13, -9, + -54, 10, -1, -61, + -44895, 0, + -230, 5, + -1, -4, + -71, 0, + -15, 0, + 1, 0, + 15, 11, -3, 6, + 2, -3, 4, -1, + 2576, -138, -19881, -47, + -65906, -1, 261925, -4, + -2, -7, 4, -2, + 0, 0, + -1, 0, + 1, -3, + 172, -2, -727, 0, + 4, 1, + 324, 0, + -139, 1, + 1, 3, + -276, 0, + 5, 3, + 9, 0, + -1, 10, + -37, 0, + 5, -1, + 76, -10, + 1318810, 1, + 12, -1, + -38, 1, + -141, 0, 611, 0, + 0, -11, + 4, 0, + -627, 2, -2882, -3, + 5711, -2, + -48, -7, + 55294, 0, + 2, -7, + 31, 0, + 34, 0, + -259, 0, + -55, 2, + 6, 3, + -4273, 20, -13554, 3, + 53878, 0, + -46, 0, + -85, 0, 114, 0, + -45, 0, + -818, 0, 3520, 0, + 34, 0, + -157, 0, + 29, 0, + -878, 0, 1838, 0, + -428, 0, + 161, 0, + 24, 0, + 65, 0, + 19, 0, + 15, 0, + 12, 0, + -26, 0, + -14, 0, + -149, 0, + 584, 0, -793, 0, + 4, -23, + -238, 0, + -18, -5, + 45, 0, + -7, 42, + 79, 0, + -1723, 0, + 2895, -6, 13362, -4, + -26525, -1, + -2, 57, + 291, 0, + 52, -3, + -327, 5, + -2755, 0, + -63, 9, + 5, -33, + -261, -1, 1122, 0, + 621, -4, + -227, 0, + 1077, 0, + -167, 0, + 85, 0, + -4, 23, + -5, 32, + 3, 30, + -32, 14, + 64607, 141, 204958, 59, + -815115, 2, + -37, -1, + 15, -15, + 12, 24, + 48, -1, + 235, 4, + 843, -25, + 4621, 0, + -17, 191, + 45, 34, + 95, 159, + -132, 0, + 13, 20, + 32, 0, + -540, 0, + 29, 0, + 37, 25, + 8, 19, + 22127, 0, + -35, -5, + 232, -48, 7, 262, + 5428, 3, -11342, 1, + -45, 0, + -21, -49, + -100, -21, + -626, 1, 2665, 0, + 532, -2, + 235, -12, + -111, -105, + 774, 1, + -283, 17, + 29, 20, + 3, 27, + 47, -2, + -43, -192, -87, 136, + -269, -1264, 646, -330, + -79, 73, -33, -9, + 60, -205, 61, 4, + -584, -85, -182, -555, + -780, -57, -3488, -45, + -19818328, -4, + 583, 93, 182, 555, + -59, 208, -60, -4, + 23, 17, + 235, 1133, -608, 302, + 41, 174, 84, -137, + 6, -53, + 63, 13, + -392, 52, + -10, -27, + -3, -27, + 199, -31, + 99, 97, + -218, -3, + 209, 0, + 84, 18, + 16, 40, + 2, -30, + 14, -154, + 30, 0, + -2, 24, + -108, 0, + -24, -16, + 262, -2, + 55, 0, + -304, 0, + 2, 25, + 55112, 95, 175036, 11, + -694477, 5, + 41, 0, + -38, -76, + 199, 1, + 679, -14, + -17, -12, + 582619, 1, + -16, 191, + 38, 27, + -234, 2, + -60, 0, + 80, 163, + -10296, 48, -32526, 13, + 129703, 8, + -1366, 0, + -741, 0, + -646, 0, + 25, 6, + 33, 23, + 10, 43, + -31, 0, + -6, 0, + -12, 147, + 59, 0, + 287, -42, -7, 297, + -59, 0, + -4, -42, + -27, -81, + -69, -22, + 27, 0, + -423, -2, 1779, -1, + -57, 15, + 5, -23, + 94, 182, + -197, -250, + 24, 1, + -18, -30, + 581, -98, -2473, -303, + -2, 43, + -277, 70, -92, -136, + -681, 925, -2165, 384, + -8, -12, + 382, 82, + -4, 35, + -45, -31, + -286, 48, 3, -328, + -55, -17, + 8, -28, + -106, 175, + -6735, 1601, -2832, -6052, + 3495, -1730, + -25, -17, + -574, 944, -354, -112, + -579, 476, -308, -625, + -2411, 7074, -1529, 2828, + -1335, 247,-112000844, -1, + 545, -409, 305, 637, + 572, -950, 356, 106, + 48, 44, + 1170, 5974, -3298, 1624, + -4538, -106, -996, 294, + 92, -139, + -12, 28, + 50, 16, + 2, -38, + 169, -133, 22, -3, + 38, 1, + 305, 7, + 4, -44, + 175, 116, + 59, 1, + -573, 81, 2453, 297, + 29, 11, + 5674, -8, + -27, 9, + 173, -173, 215, 228, + -87, -184, + 102, -5, + 3206, 2, + -53, 2, + 7159, -7, 22505, -19, + -89344, -3, + 67, 22, + 24, 79, + -40, -50, + 94, 0, + 186, 0, + -6063, 0, 12612, -5, + -271, 35, 7, -278, + -479, -74, + 426754, 0, + 8, -116, + -10, -47, + -31, -22, + 645, 0, + 426, 0, + -213, 0, 903, 0, + -67, -133, + -33, -23, + 13, -152, + -9316, 0, + 29, -3, + -564, 11, + -167, 0, + -34, 0, + 114, 12, + 4, -44, + -44561, 42, -141493, 25, + 561256, -2, + -1, -24, + -261, 0, + 211, 0, + -4263, 0, + -262, 1, + 1842, 0, + 202, 0, + 41, -6, + 77165, 0, + 176, -1, + 39, 1, + -24, 0, + 118, 0, + -2991, -4, 6245, -1, + 46886, 0, + -75, 0, + -100, 0, + 40, 0, + 75, 0, + -618, 0, 2652, 0, + 112, 0, + 1780, 0, + 30, 0, + 49, 0, + 86, 0, + 33, 0, + -30, 0, + -95, 0, + 277, 0, -580, 0, + -35, 0, + -319, 0, + 1622, 1, -2201, 0, + 79, 0, + 10, -57, + 2363, 0, -10162, 0, + -41, -12, + 62, 0, + 30, 1, + -14, 89, + -2721, 0, + 5780, -19, 26674, -10, + -52964, -2, + -5, 30, + -4, 111, + -317, -1, 1369, 0, + 93, -6, + -564, 9, + -115913, 0, + -113, 15, + 10, -62, + 99, 0, + 891, -7, + 36, 0, + 108, 0, + -42, -2, + 7, 75, + -50, 21, + 86822, 104, 275441, 65, + -1096109, 1, + -56, 3, + 31, 66, + 63, -1, + 307, 7, + 1097, -34, + 17453, 0, + -22, 250, + 57, 43, + 120, 200, + -297, 0, 1269, 0, + 166, 0, + -662, 0, + 40, 28, + 1521, 0, + -23, 288, + 351, -2, -729, 0, + -22, -52, + -96, -21, + -139, -1, 589, 0, + 35, 0, + 210, 7, + -118, -119, + 62, 0, + -583, -26, + -42, 5, + -73, 152, + -330, -1759, 983, -479, + -23, -19, + -522, -15, -185, -533, + 739, 1559, -1300, 614, + -7332, 52, -15836758, 0, + 524, 16, 185, 532, + 23, 18, + 330, 1751, -978, 476, + 73, -151, + 519, 18, + 38, 0, + 105, 113, + -178, -37, + 26, 0, + 262, 1, -1139, 0, + 71, 17, + 16, 42, + 151, 0, + 16, -148, + 4147, 0, + 149, 0, + -30, 0, + 2980, 9, 9454, 2, + -37519, 0, + -28, -49, + 37, -1, + 2, -31, + 33870, 0, + -208, 1, + -59, 1, + -13105, 68, -41564, 21, + 165148, 3, + -1022, 0, + -40, 0, + -132, 0, + -228, 0, + 95, 0, + -138, -16, + -126, 16, + 24, 5, + -57, -346, 191, -94, + -14, -11, + -12, -37, + -3053364, -1, + 13, 36, + 17, 13, + 51, 327, -179, 90, + 138, 16, + 233, 0, + 62, 0, + 1164, 0, -5000, 0, + -407, 117, 770, 9, + -4, 1, 21, 2, + 1, 0, + -16869, 0, + -1, 0, + 1, 0, + 35, 0, + -78, 0, + 78, 0, + -533, 0, + -31, 1, + -2448, -6, -7768, -1, + 30812, 0, + 37, 0, + -227, 0, + 197, 0, -846, 0, + -77, 0, + 4171, 0, + -67, 0, + 287, 0, + 2532, 0, + -19, 0, + -40, 0, + -56, 0, + 128, 0, + 83, 0, + -45, 0, + -36, 0, + -92, 0, + -134, 0, + 714, 0, -1495, 0, + 32, 0, + -981, 0, + 15, 0, + -166, 0, + -59, 0, + 4923, 0, -21203, 0, + 246, 0, + 15, 0, + 104, 0, + 1683, 0, -3523, 0, + -865, 0, + -25, 1, + -186329, -1, + 10, 0, + 50, 0, + 53, 0, + 5455, -45, 17271, -10, + -68747, 0, + 69, -2, + -7604, 0, + -724, 1, 3101, 0, + -46, 0, 200, 0, + -44, 0, + 97, 0, + -53, 0, + 62, 0, + -54, -4, + 88, -24, + -9, -36, + -581, 27, -914711, 3, + 8, 35, + -86, 24, + 51, 3, + 48, 0, + 26, 0, + 133, 1, -577, 0, + 105, 0, + -3, -1, + 3194, 0, + 528, 0, -2263, 0, + 2028, 0, + -3266, 1, 14016, 0, + 10, 0, -41, 0, + -100, 0, + -32, 0, + -124348, 0, + 16, 0, + -325, 0, + 50, -1, + 1, 0, + -553, 0, + 0, 0, + 0, 0, + 2, 0, + -34, 0, + -444, 0, 1902, 0, + 9, 0, -37, 0, + 254, 0, + 156, 0, + -2, 0, + -35, 0, + -48, 0, + -368, 0, + 327, 0, -686, 0, + -2263, 0, + 1952, 0, -8418, 0, + -13, 0, + 52, 0, + 9, 0, + 21, 0, + -261, 0, + -62404, 0, + 0, 0, + 79, 0, + 1056, 0, -4547, 0, + -351, 0, + -305, 0, 1310, 0, + -1, 0, 6, 0, + 0, 0, + -55953, 0, + -80, 0, + 0, 0, + 168, 0, + -147, 0, + 127, 0, + -265, 0, 1138, 0, + -1, 0, + -9, 0, + -8, 0, + -5984, 0, + -22, 0, + -5, 0, + 0, 0, + 0, 0, + 127, 0, + -2, 0, + 10, 0, + -31, 0, + -29, 0, + -286, 0, + -98, 0, + -1535, 0, + 252, 0, -1087, 0, + 43, 0, + 4, 0, + -19, 0, + -7620, 0, + 29, 0, + -322, 0, + 203, 0, + 0, 0, + -3587, 0, + 10, 0, + 0, 0, + 94, 0, + 0, 0, + -1, 0, + -1, 0, + -315, 0, + 1, 0, + 0, 0, + 0, 0, + -30, 0, + -94, 0, + -460, 0, + 1, 0, + -114, 0, + 0, 0, + -746, 0, + 4, 0, + -23, 0, + 24, 0, + 0, 0, + -237, 0, + 1, 0, + 0, 0, + -18, 0, + 0, 0, + 0, 0, + -16, 0, + -76, 0, + -67, 0, + 0, 0, + -16, 0, + 0, 0, +}; +static CHAR lrargs[] = { + 0, 3, + 3, 4, 3, -8, 4, 3, 5, 1, + 2, 2, 5, -5, 6, 2, + 5, -1, 10, 2, 13, -1, 11, 3, 3, -7, 4, 0, + 3, 1, 13, -1, 11, 2, 5, 1, + 2, 4, 5,-10, 6, 0, + 4, 2, 10, -2, 13, 14, 3,-23, 4, 1, + 3, 3, 2, -7, 3, 4, 4, 1, + 3, -1, 13, 18, 2,-16, 3, 2, + 2, 8, 2,-13, 3, 1, + 5, 2, 10, -2, 13, 2, 3, -3, 5, 1, 6, 0, + 3, -1, 13, 26, 2,-29, 3, 0, + 3, 1, 10, -1, 11, 2, 4, 1, + 4, 1, 10, -1, 13, 3, 2, -4, 3, 1, + 4, 1, 10, -1, 13, 3, 3, -4, 4, 0, + 3, -1, 10, 15, 2,-12, 3, 0, + 4, 2, 10, -3, 13, 24, 2,-24, 3, 0, + 3, -1, 10, 23, 2,-25, 3, 0, + 4, 1, 10, -1, 11, 1, 3, 1, 6, 0, + 4, 2, 10, -2, 11, 5, 2, -6, 3, 0, + 4, 2, 10, -2, 13, 6, 2, -8, 3, 0, + 4, -2, 10, 1, 13, 12, 2, -8, 3, 1, + 5, -1, 10, 1, 13, -1, 11, 20, 2,-20, 3, 1, + 4, -2, 10, 1, 13, 3, 1, -1, 3, 1, + 5, 2, 10, -2, 13, 2, 3, -5, 5, 5, 6, 0, + 4, 2, 10, -2, 13, 2, 3, -3, 5, 1, + 4, 2, 10, -2, 13, 6, 3, -8, 4, 0, + 4, -2, 10, 1, 13, 20, 2,-21, 3, 1, + 4, 1, 10, -1, 11, 1, 3, 1, 5, 0, + 1, 1, 6, 0, + 4, 2, 10, -2, 13, 5, 3, -6, 4, 0, + 3, 3, 2, -5, 3, 2, 5, 0, + 2, -1, 11, 1, 14, 1, + 4, 2, 10, -2, 13, 2, 3, -2, 5, 0, + 2, 1, 3, -2, 4, 1, + 4, 1, 10, -1, 11, 5, 2, -7, 3, 0, + 1, 1, 5, 0, + 2, 7, 3,-13, 4, 0, + 4, -2, 10, 1, 13, 15, 2,-13, 3, 0, + 4, 2, 10, -2, 13, 3, 2, -3, 3, 0, + 2, -2, 11, 2, 14, 1, + 3, 1, 10, 1, 12, -1, 13, 1, + 3, -1, 13, 21, 2,-21, 3, 0, + 2, 3, 2, -5, 3, 0, + 2, 2, 3, -4, 4, 1, + 2, 5, 2, -8, 3, 0, + 3, -1, 13, 23, 2,-24, 3, 0, + 2, 6, 3,-11, 4, 0, + 1, 2, 5, 0, + 2, 3, 3, -6, 4, 0, + 2, 5, 3, -9, 4, 0, + 4, 1, 10, -1, 11, 1, 3, -2, 5, 0, + 3, 2, 10, 2, 12, -2, 13, 1, + 2, 2, 2, -3, 3, 2, + 2, 4, 3, -7, 4, 0, + 2, 2, 13, -2, 11, 0, + 2, 3, 3, -5, 4, 0, + 2, 1, 2, -2, 3, 0, + 2, 2, 3, -3, 4, 0, + 4, 1, 10, -1, 11, 4, 2, -5, 3, 0, + 2, 1, 3, -1, 4, 0, + 2, 4, 2, -6, 3, 0, + 4, 2, 10, -2, 13, 2, 2, -2, 3, 0, + 3, 1, 10, -1, 11, 1, 2, 0, + 2, 1, 2, -1, 3, 0, + 3, 1, 12, 2, 13, -2, 11, 0, + 2, 5, 3, -8, 4, 0, + 2, 1, 3, -3, 5, 0, + 3, 2, 10, 1, 12, -2, 13, 1, + 2, 4, 3, -6, 4, 0, + 2, 1, 3, -2, 5, 1, + 2, 3, 3, -4, 4, 0, + 2, 3, 2, -4, 3, 1, + 2, 1, 10, -1, 13, 0, + 2, 1, 3, -1, 5, 0, + 2, 1, 3, -2, 6, 0, + 2, 2, 3, -2, 4, 0, + 2, 1, 3, -1, 6, 0, + 2, 8, 2,-14, 3, 0, + 3, 1, 3, 2, 5, -5, 6, 1, + 3, 5, 3, -8, 4, 3, 5, 1, + 1, 1, 12, 3, + 3, 3, 3, -8, 4, 3, 5, 1, + 3, 1, 3, -2, 5, 5, 6, 0, + 2, 8, 2,-12, 3, 0, + 2, 1, 3, 1, 5, 0, + 3, 2, 10, 1, 12, -2, 11, 1, + 2, 5, 2, -7, 3, 0, + 3, 1, 10, 1, 13, -2, 11, 0, + 2, 2, 2, -2, 3, 0, + 2, 5, 3, -7, 4, 0, + 3, 1, 12, -2, 13, 2, 11, 0, + 2, 4, 3, -5, 4, 0, + 2, 3, 3, -3, 4, 0, + 1, 1, 2, 0, + 3, 3, 10, 1, 12, -3, 13, 0, + 2, 2, 3, -4, 5, 0, + 2, 2, 3, -3, 5, 0, + 2, 2, 10, -2, 13, 0, + 2, 2, 3, -2, 5, 0, + 2, 3, 2, -3, 3, 0, + 3, 1, 10, -1, 12, -1, 13, 1, + 2, 2, 3, -1, 5, 0, + 2, 2, 3, -2, 6, 0, + 1, 2, 12, 2, + 3, -2, 10, 1, 11, 1, 14, 0, + 2, 2, 10, -2, 11, 0, + 2, 2, 2, -1, 3, 0, + 4, -2, 10, 2, 13, 1, 2, -1, 3, 0, + 2, 4, 2, -4, 3, 0, + 2, 3, 10, -3, 13, 0, + 4, -2, 10, 2, 13, 1, 3, -1, 5, 0, + 2, 3, 3, -3, 5, 0, + 3, 2, 10, -1, 12, -2, 13, 2, + 3, 3, 10, -1, 13, -2, 11, 0, + 1, 3, 12, 1, + 4, -2, 10, 2, 13, 2, 2, -2, 3, 0, + 3, 2, 10, -1, 12, -2, 11, 1, + 2, 5, 2, -5, 3, 0, + 2, 4, 10, -4, 13, 0, + 2, 6, 2, -6, 3, 0, + 3, 2, 10, -2, 12, -2, 13, 1, + 3, 4, 10, -2, 13, -2, 11, 0, + 3, 2, 10, -2, 12, -2, 11, 0, + 2, 7, 2, -7, 3, 0, + 3, 2, 10, -3, 12, -2, 13, 0, + 2, 8, 2, -8, 3, 0, + 2, 9, 2, -9, 3, 0, + 2, 10, 2,-10, 3, 0, + 3, 2, 10, -4, 12, -1, 13, 0, + 3, 4, 10, -2, 12, -3, 13, 0, + 4, 4, 10, -1, 12, -1, 13, -2, 11, 0, + 3, 2, 10, -3, 12, -1, 13, 1, + 4, -2, 10, 1, 13, 3, 3, -2, 5, 0, + 3, 4, 10, -1, 12, -3, 13, 0, + 4, -2, 10, 1, 13, 3, 3, -3, 5, 0, + 4, 2, 10, -2, 12, 1, 13, -2, 11, 0, + 4, -2, 10, 1, 13, 2, 2, -1, 3, 0, + 3, 3, 10, -1, 12, -2, 11, 0, + 3, 4, 10, -1, 13, -2, 11, 0, + 3, 2, 10, -2, 12, -1, 13, 2, + 4, -2, 10, 1, 13, 2, 3, -1, 5, 0, + 3, 3, 10, -1, 12, -2, 13, 0, + 4, -2, 10, 1, 13, 3, 2, -3, 3, 0, + 4, -2, 10, 1, 13, 2, 3, -2, 5, 0, + 2, 4, 10, -3, 13, 0, + 4, -2, 10, 1, 13, 2, 3, -3, 5, 0, + 3, -2, 10, 1, 13, 1, 2, 0, + 4, 2, 10, -1, 12, 1, 13, -2, 11, 1, + 4, -2, 10, 1, 13, 2, 2, -2, 3, 0, + 2, 3, 12, -1, 13, 0, + 2, 3, 10, -2, 11, 0, + 2, 1, 10, -2, 12, 0, + 4, 4, 10, 1, 12, -1, 13, -2, 11, 0, + 3, -1, 13, 3, 2, -2, 3, 0, + 3, -1, 13, 3, 3, -2, 5, 0, + 3, -2, 10, 18, 2,-15, 3, 0, + 5, 2, 10, -1, 13, 3, 3, -8, 4, 3, 5, 0, + 3, 2, 10, -1, 12, -1, 13, 2, + 5, -2, 10, 1, 13, 5, 3, -8, 4, 3, 5, 0, + 5, -2, 10, 1, 13, 1, 3, 2, 5, -5, 6, 0, + 4, 2, 10, -2, 13, 18, 2,-17, 3, 0, + 4, -2, 10, 1, 13, 1, 3, -1, 6, 0, + 4, -2, 10, 1, 13, 2, 3, -2, 4, 0, + 4, -2, 10, 1, 13, 1, 3, -1, 5, 0, + 2, 3, 10, -2, 13, 0, + 4, -2, 10, 1, 13, 3, 2, -4, 3, 0, + 4, -2, 10, 1, 13, 3, 3, -4, 4, 0, + 4, -2, 10, 1, 13, 1, 3, -2, 5, 0, + 3, 4, 10, 1, 12, -3, 13, 0, + 4, -2, 10, 1, 13, 1, 3, -3, 5, 0, + 3, -1, 13, 4, 2, -4, 3, 0, + 4, -2, 10, 1, 13, 1, 2, -1, 3, 0, + 4, -2, 10, 1, 13, 1, 3, -1, 4, 0, + 4, -2, 10, 1, 13, 2, 3, -3, 4, 0, + 4, -2, 10, 1, 13, 3, 3, -5, 4, 0, + 3, 2, 10, 1, 13, -2, 11, 0, + 4, -2, 10, -1, 13, 1, 11, 1, 14, 0, + 4, -2, 10, 1, 13, 2, 2, -3, 3, 1, + 2, 2, 12, -1, 13, 1, + 3, 3, 10, 1, 12, -2, 11, 0, + 4, 2, 10, -1, 13, 2, 3, -4, 4, 0, + 4, 2, 10, -1, 13, 3, 2, -5, 3, 0, + 2, 1, 10, -1, 12, 1, + 3, -1, 13, 3, 2, -3, 3, 0, + 3, -2, 10, 1, 13, 1, 5, 0, + 4, 2, 10, -1, 13, 1, 3, -2, 4, 0, + 3, -1, 13, 2, 3, -2, 5, 0, + 4, 2, 10, -1, 13, -1, 11, 1, 14, 0, + 3, -1, 13, 5, 3, -6, 4, 0, + 3, -2, 10, 1, 13, 1, 6, 0, + 3, -1, 10, 1, 3, -1, 5, 0, + 4, -2, 10, 1, 13, 8, 2,-13, 3, 1, + 3, -2, 10, 18, 2,-16, 3, 1, + 5, -2, 10, 1, 13, 3, 2, -7, 3, 4, 4, 1, + 4, 2, 10, -1, 13, 2, 5, -5, 6, 1, + 5, 2, 10, -1, 13, 4, 3, -8, 4, 3, 5, 1, + 2, 2, 10, -1, 13, 2, + 5, -2, 10, 1, 13, 4, 3, -8, 4, 3, 5, 1, + 4, -2, 10, 1, 13, 2, 5, -5, 6, 1, + 5, 2, 10, -1, 13, 3, 2, -7, 3, 4, 4, 0, + 4, 2, 10, -2, 13, 18, 2,-16, 3, 1, + 4, 2, 10, -1, 13, 8, 2,-13, 3, 1, + 3, -1, 10, 3, 2, -4, 3, 0, + 3, -1, 13, 6, 2, -8, 3, 0, + 3, -1, 13, 2, 3, -3, 5, 0, + 3, -1, 13, 6, 3, -8, 4, 0, + 3, 2, 10, -1, 13, 1, 6, 0, + 4, -2, 10, 1, 13, -1, 11, 1, 14, 0, + 4, -2, 10, 1, 13, 1, 3, -2, 4, 0, + 3, 2, 10, -1, 13, 1, 5, 0, + 3, 3, 10, 1, 12, -2, 13, 0, + 4, -2, 10, 1, 13, 3, 2, -5, 3, 0, + 4, -2, 10, 1, 13, 2, 3, -4, 4, 0, + 2, -1, 13, 1, 2, 0, + 4, 2, 10, -1, 13, 2, 2, -3, 3, 0, + 3, -1, 10, 1, 2, -1, 3, 0, + 3, -1, 13, 4, 2, -5, 3, 0, + 3, 2, 10, -3, 13, 2, 11, 0, + 4, 2, 10, -1, 13, 2, 3, -3, 4, 0, + 3, -1, 13, 2, 2, -2, 3, 0, + 4, 2, 10, -1, 13, 1, 2, -1, 3, 0, + 4, 2, 10, 1, 12, 1, 13, -2, 11, 0, + 3, -2, 13, 18, 2,-15, 3, 0, + 2, 1, 12, -1, 13, 2, + 3, -1, 13, 1, 3, -1, 6, 0, + 4, 2, 10, -1, 13, 1, 3, -2, 5, 0, + 3, -1, 13, 2, 3, -2, 4, 0, + 3, -1, 13, 1, 3, -1, 5, 0, + 4, 2, 10, -1, 13, 3, 3, -4, 4, 0, + 1, 1, 10, 0, + 3, -1, 13, 3, 2, -4, 3, 0, + 3, -1, 13, 3, 3, -4, 4, 0, + 4, 2, 10, -1, 13, 1, 3, -1, 5, 0, + 4, 2, 10, -1, 13, 2, 3, -2, 4, 0, + 3, -1, 13, 1, 3, -2, 5, 0, + 3, 2, 10, 1, 12, -1, 13, 2, + 3, 1, 12, 1, 13, -2, 11, 0, + 3, -1, 13, 1, 2, -1, 3, 0, + 4, 2, 10, -1, 13, 2, 2, -2, 3, 0, + 3, -1, 13, 4, 2, -6, 3, 0, + 3, -1, 13, 2, 3, -3, 4, 0, + 3, 1, 13, 1, 2, -2, 3, 0, + 4, 2, 10, -1, 13, 3, 3, -3, 4, 0, + 2, 3, 13, -2, 11, 0, + 4, 2, 10, -1, 13, 4, 2, -5, 3, 0, + 3, 1, 10, 1, 2, -1, 3, 0, + 3, -1, 13, 2, 2, -3, 3, 1, + 3, 2, 10, 2, 12, -3, 13, 0, + 3, 2, 10, -1, 13, 1, 2, 0, + 3, 1, 13, 2, 3, -4, 4, 0, + 3, 1, 13, 3, 2, -5, 3, 0, + 2, 21, 2,-21, 3, 0, + 3, 1, 10, 1, 12, -2, 13, 1, + 4, 2, 10, -1, 13, 2, 3, -4, 5, 0, + 4, 2, 10, -1, 13, 7, 3,-10, 4, 0, + 2, -1, 13, 1, 5, 0, + 3, 1, 13, 1, 3, -2, 4, 0, + 4, 2, 10, -3, 13, 2, 3, -2, 5, 0, + 3, 1, 10, 1, 3, -2, 5, 0, + 3, 1, 13, -1, 11, 1, 14, 1, + 2, -1, 13, 1, 6, 0, + 4, 2, 10, -1, 13, 6, 3, -8, 4, 1, + 4, 2, 10, -1, 13, 2, 3, -3, 5, 1, + 3, -1, 13, 8, 3,-15, 4, 0, + 4, 2, 10, -1, 13, 6, 2, -8, 3, 0, + 5, 2, 10, -1, 13, -2, 11, 5, 2, -6, 3, 0, + 3, 1, 10, 3, 3, -4, 4, 0, + 3, 1, 10, 3, 2, -4, 3, 1, + 4, 1, 10, -1, 13, -1, 11, 2, 4, 0, + 3, -2, 13, 26, 2,-29, 3, 0, + 3, -1, 13, 8, 2,-13, 3, 0, + 3, -2, 13, 18, 2,-16, 3, 2, + 4, -1, 13, 3, 2, -7, 3, 4, 4, 0, + 3, 1, 13, 2, 5, -5, 6, 1, + 4, 1, 13, 4, 3, -8, 4, 3, 5, 1, + 1, 1, 13, 3, + 4, -1, 13, 4, 3, -8, 4, 3, 5, 1, + 3, -1, 13, 2, 5, -5, 6, 1, + 4, 1, 13, 3, 2, -7, 3, 4, 4, 0, + 2, 18, 2,-16, 3, 1, + 3, 1, 13, 8, 2,-13, 3, 2, + 2, 26, 2,-29, 3, 0, + 4, 1, 10, 1, 13, -1, 11, 2, 4, 0, + 5, 2, 10, 1, 13, -2, 11, 5, 2, -6, 3, 0, + 3, 1, 13, 8, 3,-15, 4, 1, + 4, 2, 10, -3, 13, 2, 3, -3, 5, 0, + 3, 1, 10, 1, 3, -1, 5, 0, + 2, 1, 13, 1, 6, 0, + 4, 2, 10, -1, 13, 5, 3, -6, 4, 0, + 3, 1, 10, 2, 3, -2, 4, 0, + 3, -1, 13, -1, 11, 1, 14, 1, + 4, 2, 10, -1, 13, 2, 3, -5, 6, 0, + 4, 2, 10, -1, 13, 2, 3, -2, 5, 0, + 5, 2, 10, -1, 13, 2, 3, -4, 5, 5, 6, 0, + 3, -1, 13, 1, 3, -2, 4, 1, + 2, 1, 13, 1, 5, 0, + 4, 2, 10, -1, 13, 4, 3, -4, 4, 0, + 4, 2, 10, -1, 13, 3, 2, -3, 3, 0, + 4, 2, 10, 2, 12, -1, 13, -2, 11, 0, + 2, 1, 10, 1, 12, 2, + 3, -1, 13, 3, 2, -5, 3, 0, + 3, -1, 13, 2, 3, -4, 4, 0, + 4, 2, 10, -1, 13, 2, 3, -1, 5, 0, + 4, 2, 10, -1, 13, 2, 3, -2, 6, 0, + 3, 1, 10, 1, 12, -2, 11, 0, + 3, 2, 10, 2, 12, -1, 13, 1, + 3, 1, 13, 2, 2, -3, 3, 1, + 3, -1, 13, 1, 11, 1, 14, 0, + 2, 1, 13, -2, 11, 0, + 4, 2, 10, -1, 13, 5, 2, -6, 3, 0, + 3, -1, 13, 1, 2, -2, 3, 0, + 3, 1, 13, 2, 3, -3, 4, 0, + 3, 1, 13, 1, 2, -1, 3, 0, + 4, 2, 10, -1, 13, 4, 2, -4, 3, 0, + 3, 2, 10, 1, 12, -3, 13, 1, + 3, 1, 13, 1, 3, -2, 5, 0, + 3, 1, 13, 3, 3, -4, 4, 0, + 3, 1, 13, 3, 2, -4, 3, 0, + 2, 1, 10, -2, 13, 0, + 4, 2, 10, -1, 13, 3, 3, -4, 5, 0, + 3, 1, 13, 1, 3, -1, 5, 0, + 3, 1, 13, 2, 3, -2, 4, 0, + 3, 1, 13, 1, 3, -1, 6, 0, + 4, 2, 10, -1, 13, 3, 3, -3, 5, 0, + 4, 2, 10, -1, 13, 6, 2, -7, 3, 0, + 2, 1, 12, 1, 13, 2, + 4, 2, 10, -1, 13, 3, 3, -2, 5, 0, + 4, 2, 10, 1, 12, -1, 13, -2, 11, 0, + 2, 1, 10, 2, 12, 0, + 2, 1, 10, -2, 11, 0, + 3, 1, 13, 2, 2, -2, 3, 0, + 3, 1, 12, -1, 13, 2, 11, 0, + 4, 2, 10, -1, 13, 5, 2, -5, 3, 0, + 3, 1, 13, 2, 3, -3, 5, 0, + 2, 2, 10, -3, 13, 0, + 3, 1, 13, 2, 3, -2, 5, 0, + 3, 1, 13, 3, 2, -3, 3, 0, + 3, 1, 10, -1, 12, -2, 13, 0, + 4, 2, 10, -1, 13, 6, 2, -6, 3, 0, + 2, 2, 12, 1, 13, 1, + 3, 2, 10, -1, 13, -2, 11, 0, + 3, 1, 10, -1, 12, -2, 11, 0, + 3, 2, 10, 1, 13, -4, 11, 0, + 3, 1, 13, 4, 2, -4, 3, 0, + 4, 2, 10, -1, 13, 7, 2, -7, 3, 0, + 3, 2, 10, -1, 12, -3, 13, 1, + 2, 3, 12, 1, 13, 0, + 4, 2, 10, -1, 12, -1, 13, -2, 11, 0, + 3, 1, 13, 5, 2, -5, 3, 0, + 4, 2, 10, -1, 13, 8, 2, -8, 3, 0, + 3, 2, 10, -2, 12, -3, 13, 0, + 4, 2, 10, -1, 13, 9, 2, -9, 3, 0, + 3, 4, 10, -3, 12, -2, 13, 0, + 2, 2, 10, -4, 12, 0, + 3, 4, 10, -2, 12, -2, 13, 1, + 2, 6, 10, -4, 13, 0, + 3, 4, 10, -1, 12, -2, 11, 0, + 2, 2, 10, -3, 12, 1, + 3, 3, 10, -2, 12, -1, 13, 0, + 3, -2, 10, 3, 3, -2, 5, 0, + 3, 4, 10, -1, 12, -2, 13, 1, + 3, -2, 10, 3, 3, -3, 5, 0, + 2, 5, 10, -3, 13, 0, + 3, -2, 10, 4, 2, -4, 3, 0, + 3, -2, 10, 2, 2, -1, 3, 0, + 2, 4, 10, -2, 11, 0, + 2, 2, 10, -2, 12, 2, + 3, -2, 10, 3, 3, -2, 4, 0, + 3, -2, 10, 2, 3, -1, 5, 0, + 3, 3, 10, -1, 12, -1, 13, 1, + 3, -2, 10, 3, 2, -3, 3, 0, + 3, -2, 10, 2, 3, -2, 5, 0, + 2, 4, 10, -2, 13, 0, + 3, -2, 10, 2, 3, -3, 5, 0, + 2, -2, 10, 1, 2, 0, + 4, 2, 10, -1, 12, 2, 13, -2, 11, 0, + 3, -2, 10, 2, 2, -2, 3, 0, + 3, 3, 10, 1, 13, -2, 11, 0, + 3, 4, 10, 1, 12, -2, 11, 0, + 4, 2, 10, -1, 12, -1, 11, 1, 14, 0, + 4, -2, 10, -1, 13, 18, 2,-15, 3, 0, + 4, 2, 10, 3, 3, -8, 4, 3, 5, 0, + 2, 2, 10, -1, 12, 2, + 4, -2, 10, 5, 3, -8, 4, 3, 5, 0, + 4, 2, 10, -1, 13, 18, 2,-17, 3, 0, + 3, -2, 10, 1, 3, -1, 6, 0, + 3, -2, 10, 2, 3, -2, 4, 0, + 3, -2, 10, 1, 3, -1, 5, 0, + 2, 3, 10, -1, 13, 0, + 3, -2, 10, 3, 2, -4, 3, 0, + 3, -2, 10, 3, 3, -4, 4, 0, + 3, -2, 10, 1, 3, -2, 5, 0, + 3, 4, 10, 1, 12, -2, 13, 1, + 4, 2, 10, -1, 12, -2, 13, 2, 11, 0, + 3, -2, 10, 1, 2, -1, 3, 0, + 3, -2, 10, 2, 3, -3, 4, 0, + 3, 2, 10, 2, 13, -2, 11, 0, + 3, -2, 10, 2, 2, -3, 3, 0, + 2, 2, 12, -2, 13, 1, + 3, 2, 10, 2, 3, -4, 4, 0, + 3, 2, 10, 3, 2, -5, 3, 0, + 3, 1, 10, -1, 12, 1, 13, 1, + 3, -2, 13, 3, 2, -3, 3, 0, + 2, -2, 10, 1, 5, 0, + 3, 2, 10, 1, 3, -2, 4, 0, + 3, -2, 13, 2, 3, -2, 5, 0, + 3, 2, 10, -1, 11, 1, 14, 0, + 4, 4, 10, -2, 13, 2, 3, -3, 5, 0, + 3, -2, 10, 8, 2,-13, 3, 0, + 4, -2, 10, -1, 13, 18, 2,-16, 3, 1, + 4, -2, 10, 3, 2, -7, 3, 4, 4, 0, + 4, 2, 10, 4, 3, -8, 4, 3, 5, 1, + 1, 2, 10, 3, + 4, -2, 10, 4, 3, -8, 4, 3, 5, 1, + 4, 2, 10, 3, 2, -7, 3, 4, 4, 0, + 4, 2, 10, -1, 13, 18, 2,-16, 3, 1, + 3, 2, 10, 8, 2,-13, 3, 0, + 3, -2, 10, -1, 11, 1, 14, 0, + 4, 4, 10, -2, 13, 2, 3, -2, 5, 0, + 3, -2, 10, 1, 3, -2, 4, 0, + 2, 2, 10, 1, 5, 0, + 4, 4, 10, -2, 13, 3, 2, -3, 3, 0, + 3, 3, 10, 1, 12, -1, 13, 1, + 3, -2, 10, 3, 2, -5, 3, 0, + 3, -2, 10, 2, 3, -4, 4, 0, + 3, 4, 10, 2, 12, -2, 13, 0, + 3, 2, 10, 2, 2, -3, 3, 0, + 3, 2, 10, -2, 13, 2, 11, 0, + 3, 2, 10, 1, 2, -1, 3, 0, + 4, 2, 10, 1, 12, 2, 13, -2, 11, 0, + 2, 1, 12, -2, 13, 2, + 3, 2, 10, 1, 3, -2, 5, 0, + 3, -2, 13, 1, 3, -1, 5, 0, + 3, 2, 10, 3, 2, -4, 3, 0, + 2, 1, 10, 1, 13, 0, + 3, 2, 10, 1, 3, -1, 5, 0, + 3, 2, 10, 2, 3, -2, 4, 0, + 2, 2, 10, 1, 12, 2, + 2, 1, 12, -2, 11, 0, + 3, -2, 13, 1, 2, -1, 3, 0, + 3, 1, 10, -1, 13, 2, 11, 0, + 3, 2, 10, 2, 2, -2, 3, 0, + 3, 1, 10, 1, 12, -3, 13, 0, + 3, 2, 13, -1, 11, 1, 14, 0, + 3, 2, 10, 2, 3, -3, 5, 0, + 3, 2, 10, 6, 2, -8, 3, 0, + 3, -3, 13, 18, 2,-16, 3, 1, + 3, 2, 13, 2, 5, -5, 6, 0, + 4, 2, 13, 4, 3, -8, 4, 3, 5, 0, + 1, 2, 13, 0, + 4, -2, 13, 4, 3, -8, 4, 3, 5, 0, + 3, -2, 13, 2, 5, -5, 6, 0, + 3, 1, 13, 18, 2,-16, 3, 1, + 3, -2, 13, -1, 11, 1, 14, 0, + 3, 2, 10, 2, 3, -2, 5, 0, + 3, 2, 10, 3, 2, -3, 3, 0, + 3, 1, 10, 1, 12, 1, 13, 1, + 2, 2, 10, 2, 12, 1, + 2, 1, 11, 1, 14, 1, + 4, -1, 13, -2, 11, 18, 2,-16, 3, 0, + 1, 2, 11, 0, + 4, -1, 13, 2, 11, 18, 2,-16, 3, 0, + 2, -3, 11, 1, 14, 0, + 3, 2, 13, 1, 2, -1, 3, 0, + 3, 2, 10, 4, 2, -4, 3, 0, + 3, 2, 10, 1, 12, -4, 13, 0, + 2, 1, 10, -3, 13, 0, + 3, 2, 13, 1, 3, -1, 5, 0, + 2, 1, 12, 2, 13, 2, + 3, 1, 10, 2, 12, 1, 13, 0, + 3, 1, 10, -1, 13, -2, 11, 0, + 2, 1, 12, 2, 11, 1, + 3, 2, 10, 5, 2, -5, 3, 0, + 2, 2, 10, -4, 13, 0, + 3, 2, 10, 6, 2, -6, 3, 0, + 2, 2, 12, 2, 13, 0, + 3, 2, 10, -2, 13, -2, 11, 0, + 2, 2, 12, 2, 11, 0, + 2, 2, 10, -4, 11, 0, + 3, 2, 10, 7, 2, -7, 3, 0, + 3, 2, 10, -1, 12, -4, 13, 0, + 4, 2, 10, -1, 12, -2, 13, -2, 11, 0, + 3, 2, 10, 8, 2, -8, 3, 0, + 3, 2, 10, 9, 2, -9, 3, 0, + 3, 4, 10, -3, 12, -1, 13, 0, + 3, 6, 10, -1, 12, -3, 13, 0, + 3, 4, 10, -2, 12, -1, 13, 1, + 3, 5, 10, -1, 12, -2, 13, 0, + 2, 6, 10, -3, 13, 0, + 4, 4, 10, -1, 12, 1, 13, -2, 11, 0, + 3, 2, 10, -3, 12, 1, 13, 0, + 2, 3, 10, -2, 12, 0, + 3, 4, 10, -1, 12, -1, 13, 1, + 2, 5, 10, -2, 13, 0, + 3, 6, 10, 1, 12, -3, 13, 0, + 3, 4, 10, 1, 13, -2, 11, 0, + 3, 2, 10, -2, 12, 1, 13, 1, + 2, 3, 10, -1, 12, 0, + 4, -2, 10, -1, 13, 2, 3, -2, 5, 0, + 2, 4, 10, -1, 13, 0, + 4, 2, 10, -2, 12, -1, 13, 2, 11, 0, + 3, 4, 10, -3, 13, 2, 11, 0, + 4, -2, 10, -1, 13, 2, 2, -2, 3, 0, + 3, 2, 10, -1, 12, 1, 13, 2, + 4, -2, 10, -1, 13, 1, 3, -1, 5, 0, + 1, 3, 10, 0, + 3, 4, 10, 1, 12, -1, 13, 1, + 4, 2, 10, -1, 12, -1, 13, 2, 11, 1, + 4, -2, 10, -1, 13, 1, 2, -1, 3, 0, + 3, 2, 10, 3, 13, -2, 11, 0, + 2, 2, 12, -3, 13, 0, + 3, 1, 10, -1, 12, 2, 13, 0, + 4, 2, 10, 1, 13, -1, 11, 1, 14, 0, + 4, -2, 10, -2, 13, 18, 2,-16, 3, 0, + 5, 2, 10, 1, 13, 4, 3, -8, 4, 3, 5, 0, + 2, 2, 10, 1, 13, 1, + 5, -2, 10, -1, 13, 4, 3, -8, 4, 3, 5, 0, + 3, 2, 10, 18, 2,-16, 3, 0, + 4, -2, 10, -1, 13, -1, 11, 1, 14, 0, + 4, 4, 10, -1, 13, 2, 3, -2, 5, 0, + 4, 4, 10, -1, 13, 3, 2, -3, 3, 0, + 2, 3, 10, 1, 12, 1, + 3, 4, 10, 2, 12, -1, 13, 0, + 4, 2, 10, -1, 13, 1, 11, 1, 14, 0, + 3, 2, 10, -1, 13, 2, 11, 0, + 2, 1, 12, -3, 13, 1, + 2, 1, 10, 2, 13, 0, + 3, 2, 10, 1, 12, 1, 13, 1, + 3, 1, 12, -1, 13, -2, 11, 1, + 2, 1, 10, 2, 11, 0, + 4, 2, 10, 1, 12, -1, 13, 2, 11, 0, + 1, 3, 13, 0, + 4, 2, 10, 1, 13, 2, 3, -2, 5, 0, + 3, 1, 10, 1, 12, 2, 13, 0, + 3, 2, 10, 2, 12, 1, 13, 0, + 3, 1, 13, 1, 11, 1, 14, 0, + 2, 1, 13, 2, 11, 0, + 3, 1, 10, 1, 12, 2, 11, 0, + 4, 2, 10, 2, 12, -1, 13, 2, 11, 0, + 2, 1, 13, -4, 11, 0, + 2, 1, 10, -4, 13, 0, + 2, 1, 12, 3, 13, 1, + 3, 1, 12, 1, 13, 2, 11, 1, + 2, 2, 10, -5, 13, 0, + 3, 2, 10, -3, 13, -2, 11, 0, + 3, 2, 10, -1, 13, -4, 11, 0, + 3, 6, 10, -2, 12, -2, 13, 0, + 2, 4, 10, -3, 12, 0, + 3, 6, 10, -1, 12, -2, 13, 0, + 2, 4, 10, -2, 12, 1, + 2, 6, 10, -2, 13, 0, + 2, 4, 10, -1, 12, 1, + 2, 5, 10, -1, 13, 0, + 3, 6, 10, 1, 12, -2, 13, 0, + 4, 4, 10, -1, 12, -2, 13, 2, 11, 0, + 3, 4, 10, 2, 13, -2, 11, 0, + 3, 2, 10, -2, 12, 2, 13, 0, + 1, 4, 10, 0, + 3, 2, 10, -2, 12, 2, 11, 0, + 3, 4, 10, -2, 13, 2, 11, 0, + 3, 2, 10, -1, 12, 2, 13, 1, + 2, 3, 10, 1, 13, 0, + 2, 4, 10, 1, 12, 1, + 3, 2, 10, -1, 12, 2, 11, 1, + 3, 3, 10, -1, 13, 2, 11, 0, + 2, 2, 10, 2, 13, 0, + 3, 3, 10, 1, 12, 1, 13, 0, + 3, 2, 10, 1, 11, 1, 14, 0, + 2, 2, 10, 2, 11, 0, + 2, 1, 12, -4, 13, 0, + 2, 1, 10, 3, 13, 0, + 3, 2, 10, 1, 12, 2, 13, 1, + 3, 1, 12, -2, 13, -2, 11, 0, + 3, 1, 10, 1, 13, 2, 11, 0, + 3, 2, 10, 1, 12, 2, 11, 0, + 1, 4, 13, 0, + 3, 1, 10, 1, 12, 3, 13, 0, + 2, 2, 13, 2, 11, 0, + 4, 1, 10, 1, 12, 1, 13, 2, 11, 0, + 1, 4, 11, 0, + 2, 1, 12, 4, 13, 0, + 3, 1, 12, 2, 13, 2, 11, 0, + 3, 2, 10, -4, 13, -2, 11, 0, + 3, 6, 10, -2, 12, -1, 13, 0, + 2, 8, 10, -3, 13, 0, + 3, 6, 10, -1, 12, -1, 13, 0, + 3, 4, 10, -2, 12, 1, 13, 0, + 2, 6, 10, -1, 13, 0, + 3, 4, 10, -1, 12, 1, 13, 1, + 3, 6, 10, 1, 12, -1, 13, 0, + 4, 4, 10, -1, 12, -1, 13, 2, 11, 0, + 3, 2, 10, -2, 12, 3, 13, 0, + 2, 4, 10, 1, 13, 0, + 3, 4, 10, -1, 13, 2, 11, 0, + 3, 2, 10, -1, 12, 3, 13, 0, + 3, 4, 10, 1, 12, 1, 13, 0, + 4, 2, 10, -1, 12, 1, 13, 2, 11, 0, + 2, 2, 10, 3, 13, 0, + 3, 2, 10, 1, 13, 2, 11, 0, + 3, 2, 10, -1, 13, 4, 11, 0, + 3, 2, 10, 1, 12, 3, 13, 0, + 3, 1, 12, -3, 13, -2, 11, 0, + 3, 1, 10, 2, 13, 2, 11, 0, + 4, 2, 10, 1, 12, 1, 13, 2, 11, 0, + 1, 5, 13, 0, + 2, 3, 13, 2, 11, 0, + 2, 1, 13, 4, 11, 0, + 3, 1, 12, 3, 13, 2, 11, 0, + 2, 8, 10, -2, 13, 0, + 2, 6, 10, -1, 12, 0, + 1, 6, 10, 0, + 3, 6, 10, -2, 13, 2, 11, 0, + 3, 4, 10, -1, 12, 2, 13, 0, + 3, 4, 10, -1, 12, 2, 11, 0, + 2, 4, 10, 2, 13, 0, + 2, 4, 10, 2, 11, 0, + 3, 2, 10, -1, 12, 4, 13, 0, + 3, 4, 10, 1, 12, 2, 13, 0, + 4, 2, 10, -1, 12, 2, 13, 2, 11, 0, + 2, 2, 10, 4, 13, 0, + 3, 2, 10, 2, 13, 2, 11, 0, + 2, 2, 10, 4, 11, 0, + 1, 6, 13, 0, + 2, 4, 13, 2, 11, 0, + 2, 2, 13, 4, 11, 0, + 3, 6, 10, -1, 12, 1, 13, 0, + 2, 6, 10, 1, 13, 0, + 2, 4, 10, 3, 13, 0, + 3, 4, 10, 1, 13, 2, 11, 0, + 2, 2, 10, 5, 13, 0, + 3, 2, 10, 3, 13, 2, 11, 0, + -1 +}; + +static long btabr[] = {-1}; +static long btabb[] = {-1}; +static long btabl[] = { + -3, -4, + 4, -1856, 0, 8043, + -9, -1082, + -1, -310, + -1, -522, + -330, -1449, -853, 4656, + -66, 7, + -1, 9996928, + -66, 6, + 23, 183, + 0, 173, + 0, -56, + 0, 50, + 0, -785, + 1, 51, + 0, -60, + 1, 11843, 0, -50754, + 0, 1834, 1, -7910, + 0, -48060, + 1, 56, + 0, 13141, -1, -56318, + 0, 2541, + -1, -649, + -133, 778, + -46, 8, + 1, 1665737, + -47, 7, + 0, 65, + 0, 45, + 0, -138, + 0, -1005, + 0, -2911, + 0, -47, + 0, 96, + 0, -394, + 2, 76, + 2, -17302, 0, 74337, + 0, -101, + 0, 58, + 0, -171, + 0, -77, + 0, -1283, 0, 2686, + 0, -55, + 0, 99, + 0, 55, + 0, 397, + 0, 540, + 0, 626, + -1, -5188, 0, 10857, + 0, -216, + -2, -123, + 0, 6337, + 2, 224, + -152, -23472, -29, -74336, 0, 295775, + -20, 149, + -2, 84, + 9, 304, + 0, -3051, + -70, -6, + -57, 34, + 0, -638, + 0, -201, + -73, 9, + 0, -100, + -101, -8, + 0, -57, + 0, -207, + -3, 80, + -45, 45, + -5, 102, + -59, -23, + 52, 201, + -48, 233, -220, 71, + 4, 2810, 0, 6236541, + -61, 218, -216, 67, + 51, 201, + -59, -23, + -144, -837, -457, 3029, + -45, 42, + -15, 73, + -6, -169, + 0, 135, + -64, -7, + 0, -16245, + 0, -81, + -74, -10, + 0, 702, 0, -3013, + 0, -5889, + 1, 141, + 58, 9598, 12, 30443, 1, -120946, + -1, -84, + -2, 11246, -1, -48391, + 0, 1393, + 0, 200, + -136, -17, + 0, 558, + -64, -8, + 0, -71, + 0, 317577, + -28, 183, + 1, 219, + 0, 421, + 0, -133, + 501, -139, + 3, 354, + -101, -13, + 74, 7, + 144, -84, + 59, -2, + 1, 64, + -2931, 12559, -4641, 2638, -303, -2058, + -13, -100, -123, -79, + -19214, 6084, 1494, 26993, 15213, -82219, + 42, 52, 48, -101, + -53, -4, + 4, 47, + 58, -131, + 46, 14, + -21, -6, + -1311, -8791, 10198, -4185, 2815, 5640, + 167, 422, -229, 83, + 3140, 39, 1221, 120, 96, -30, + -1, 184612405, + 187, 416, -226, 81, + -1985, -10083, 9983, -4464, 2807, 5643, + -21, -9, + 113, -367, + 120, 580, -667, 27, + 8, 66, + -56, -6, + 337, 95, + -87, 3303, + -1, 65, + 68, -374, + 0, -574, + 15, -94, + 0, -53, + 0, -1303, + 0, -236, + 283, 36, + -1, -54, + 269, -35, + 0, -83, + 0, -52, + 0, 730, 0, -3129, + 0, 813, + 0, -4299, + 1, 59, + -6, 5130, 1, 16239, -1, -64603, + 0, -80, + 91, 12, + 0, -561, + 133, -17, + 0, 250, + -12, 71, + 0, 155664, + 82, -11, + 0, 106, + 0, -604, + 0, 21862, + 55, -7, + 0, -1514, 0, 6501, + 0, 906, + 0, -68, + 0, 241, + 0, 366, + 0, 70, + 0, -1382, 0, 5957, + 0, 113, + 0, -51, + 0, -55, + 0, 731, + 0, -264, + 0, 65788, + 1, -1504, 0, 3147, + 0, 217, + 0, -4105, 0, 17658, + 1, 69, + 0, -3518, + 0, -1767, + -43, -7044, -10, -22304, 0, 88685, + 3, 91, + 0, -485, + 0, -57, + -1, 333548, + -24, 172, + 11, 544, 1, -1132, + 0, 353, + 0, -188, + 0, 53, + 0, 77, + 158, -887, + 35, 131, + -54, 13, + 0, 1994821, + -53, 14, + 36, 125, + 2, 56, + 0, -243, + 0, -364, + -2, 1916, 0, -8227, + 0, 15700, -1, -67308, + 1, 66, + 0, -53686, + 1, 3058, 1, -13177, + 0, -72, + 0, -72, + 0, 61, + 0, 15812, + 0, 165, + 8, -96, + 318, 1341, 803, -4252, + 24, 193, + 1137, -226, 310, 622, + -56, 30, + -3, 10101666, + -56, 30, + 1096, -225, 300, 600, + -31, 409, + -1, -507, + 0, -287, + 0, -1869, 0, 8026, + 1, 544, -1, -1133, + 0, 27984, + 0, -62, + 0, -249, + 0, 187, + 0, -1096, + 1, 53, + 2, 12388, 0, -53107, + 0, -322, + 0, -94, + 0, 15157, + 0, -582, + 0, 3291, + 0, 565, + 0, 106, + 0, 112, + 0, 306, + 0, 809, + 0, 130, + 0, -961, 0, 4149, + 0, 174, + 0, -105, + 0, 2196, + 0, 59, + 0, 36737, + -1, -1832, 0, 3835, + 0, -139, + 0, 24138, + 0, 1325, + 1, 64, + 0, -361, + 0, -1162, + -44, -6320, -10, -20003, 0, 79588, + 2, 80, + 0, -2059, + 0, -304, + 0, 21460, + 0, -166, + 0, -87, + 89, -493, + 32, 114, + 34, 510, 1, 1172616, + 31, 113, + -1, 57, + 0, 214, + 0, -656, + 0, -646, + 0, 1850, 0, -7931, + 0, -6674, + 0, 2944, 0, -12641, + 0, 916, + 45, -255, + 16, 60, + -1, 619116, + 16, 57, + 0, -58, + 0, 1045, + 0, -156, + -15, 88, + 0, -62964, + 0, -126, + 0, 1490, 0, -6387, + 0, 119, + 0, 1338, + 0, -56, + 0, 204, + 0, 153, + 0, 940, + 0, 251, + 0, 312, + 0, 584, + 0, -786, 0, 3388, + 0, -52, + 0, 4733, + 0, 618, + 0, 29982, + 0, 101, + 0, -174, + 0, -2637, 0, 11345, + 0, -284, + 0, -524, + 0, -121, + 0, 1464, + 11, -60, + -1, 151205, + 0, 139, + 0, -2448, + 0, -51, + 0, -768, + 0, -638, + 0, 552, 0, -2370, + 0, 70, + 0, 64, + 0, 57, + 0, 39840, + 0, 104, + 0, -10194, + 0, -635, + 0, 69, + 0, 113, + 0, 67, + 0, 96, + 0, 367, + 0, 134, + 0, 596, + 0, 63, + 0, 1622, + 0, 483, + 0, 72, + 0, 11917, + 0, -63, + 0, 1273, + 0, -66, + 0, -262, + 0, -97, + 0, 103, + 0, 15196, + 0, -1445, + 0, -66, + 0, -55, + 0, -323, + 0, 2632, + 0, -1179, + 0, 59, + 0, -56, + 0, 78, + 0, 65, + 0, 422, + 0, 309, + 0, 2125, + 0, -66, + 0, 124, + 0, -57, + 0, 1379, + 0, -304, + 0, 177, + 0, -118, + 0, 146, + 0, 283, + 0, 119, +}; +static CHAR bargs[] = { + 0, 1, + 3, 1, 10, 1, 12, -1, 11, 1, + 4, 2, 10, 2, 12, -1, 13, -1, 11, 0, + 5, 2, 10, -1, 13, -1, 11, 3, 2, -3, 3, 0, + 5, 2, 10, -1, 13, -1, 11, 2, 3, -2, 5, 0, + 2, -1, 13, 1, 14, 1, + 5, -1, 13, 1, 11, 4, 3, -8, 4, 3, 5, 0, + 2, 1, 13, -1, 11, 0, + 5, 1, 13, -1, 11, 4, 3, -8, 4, 3, 5, 0, + 5, 2, 10, -1, 13, -1, 11, 2, 3, -3, 5, 0, + 4, 1, 10, 1, 12, -2, 13, 1, 11, 0, + 4, 1, 13, -1, 11, 1, 2, -1, 3, 0, + 5, 2, 10, -1, 13, -1, 11, 2, 2, -2, 3, 0, + 3, 1, 10, -2, 13, 1, 11, 0, + 4, 1, 13, -1, 11, 1, 3, -1, 5, 0, + 4, -1, 13, 1, 11, 1, 2, -1, 3, 0, + 3, 1, 12, 1, 13, -1, 11, 1, + 4, 2, 10, 1, 12, -1, 13, -1, 11, 1, + 2, 1, 10, -1, 11, 0, + 4, -1, 13, 1, 11, 1, 3, -1, 5, 0, + 3, 1, 12, -1, 13, 1, 11, 1, + 3, 2, 10, -3, 13, 1, 11, 0, + 3, 2, 12, 1, 13, -1, 11, 0, + 3, -2, 10, 1, 13, 1, 14, 0, + 6, -2, 10, 1, 13, 1, 11, 4, 3, -8, 4, 3, 5, 0, + 3, 2, 10, -1, 13, -1, 11, 0, + 6, 2, 10, -1, 13, -1, 11, 4, 3, -8, 4, 3, 5, 0, + 4, -1, 13, 1, 11, 2, 3, -2, 5, 0, + 4, -1, 13, 1, 11, 3, 2, -3, 3, 0, + 3, 1, 10, -1, 12, -1, 11, 0, + 3, 2, 12, -1, 13, 1, 11, 0, + 3, 2, 10, 1, 13, -3, 11, 0, + 5, -2, 10, 1, 13, 1, 11, 1, 2, -1, 3, 0, + 4, 2, 10, -1, 12, -3, 13, 1, 11, 0, + 3, 3, 10, -2, 13, -1, 11, 0, + 5, -2, 10, 1, 13, 1, 11, 1, 3, -1, 5, 0, + 4, 2, 10, -1, 12, -1, 13, -1, 11, 1, + 2, 3, 10, -3, 11, 0, + 5, -2, 10, 1, 13, 1, 11, 2, 2, -2, 3, 0, + 4, 2, 10, -1, 12, 1, 13, -3, 11, 0, + 3, 4, 10, -3, 13, -1, 11, 0, + 4, 2, 10, -2, 12, -1, 13, -1, 11, 1, + 3, 4, 10, -1, 13, -3, 11, 0, + 4, 2, 10, -3, 12, -1, 13, -1, 11, 0, + 3, 4, 10, -1, 12, -3, 11, 0, + 3, 2, 10, -3, 12, -1, 11, 0, + 4, 4, 10, -1, 12, -2, 13, -1, 11, 0, + 2, 4, 10, -3, 11, 0, + 3, 2, 10, -2, 12, -1, 11, 1, + 4, 3, 10, -1, 12, -1, 13, -1, 11, 0, + 4, -2, 10, 1, 11, 2, 3, -2, 5, 0, + 3, 4, 10, -2, 13, -1, 11, 0, + 4, -2, 10, 1, 11, 2, 2, -2, 3, 0, + 3, 2, 10, -1, 12, -1, 11, 2, + 3, -2, 10, 1, 12, 1, 14, 0, + 4, -2, 10, 1, 11, 2, 3, -2, 4, 0, + 4, -2, 10, 1, 11, 1, 3, -1, 5, 0, + 3, 3, 10, -1, 13, -1, 11, 0, + 4, -2, 10, 1, 11, 3, 2, -4, 3, 0, + 4, -2, 10, 1, 11, 1, 3, -2, 5, 0, + 4, 2, 10, -1, 12, -2, 13, 1, 11, 0, + 4, -2, 10, 1, 11, 1, 2, -1, 3, 0, + 2, -1, 10, 1, 2, 0, + 3, 2, 10, 2, 13, -3, 11, 0, + 4, -2, 10, 1, 11, 2, 2, -3, 3, 0, + 3, 2, 12, -2, 13, 1, 11, 0, + 4, 1, 10, -1, 12, 1, 13, -1, 11, 0, + 3, -2, 10, 1, 11, 1, 5, 0, + 4, 2, 10, -1, 11, 1, 3, -2, 4, 0, + 3, 2, 10, -2, 11, 1, 14, 0, + 4, -2, 10, 1, 11, 8, 2,-13, 3, 0, + 5, -2, 10, -1, 13, 1, 11, 18, 2,-16, 3, 0, + 5, 2, 10, -1, 11, 4, 3, -8, 4, 3, 5, 1, + 2, 2, 10, -1, 11, 1, + 5, -2, 10, 1, 11, 4, 3, -8, 4, 3, 5, 1, + 5, 2, 10, -1, 13, -1, 11, 18, 2,-16, 3, 0, + 4, 2, 10, -1, 11, 8, 2,-13, 3, 0, + 2, -2, 10, 1, 14, 1, + 4, -2, 10, 1, 11, 1, 3, -2, 4, 0, + 3, 2, 10, -1, 11, 1, 5, 0, + 2, 2, 12, -1, 11, 0, + 4, 3, 10, 1, 12, -1, 13, -1, 11, 0, + 4, 2, 10, -1, 11, 2, 2, -3, 3, 0, + 3, 2, 10, -2, 13, 1, 11, 0, + 4, 2, 10, -1, 11, 1, 2, -1, 3, 0, + 3, 1, 10, 1, 2, -2, 3, 0, + 3, 1, 12, -2, 13, 1, 11, 1, + 3, 1, 10, 1, 13, -1, 11, 0, + 4, 2, 10, -1, 11, 1, 3, -1, 5, 0, + 3, 2, 10, 1, 12, -1, 11, 2, + 3, -2, 10, -1, 12, 1, 14, 0, + 2, 1, 12, -1, 11, 1, + 3, 1, 10, -1, 13, 1, 11, 0, + 4, 2, 10, -1, 11, 2, 2, -2, 3, 0, + 3, 1, 10, 2, 2, -3, 3, 0, + 4, 2, 10, 1, 12, -2, 13, 1, 11, 0, + 3, -1, 10, 1, 2, -2, 3, 0, + 3, -1, 11, 1, 2, -1, 3, 0, + 2, 2, 13, -1, 11, 0, + 2, -2, 13, 1, 14, 0, + 4, 2, 10, -1, 11, 2, 3, -2, 5, 0, + 4, 2, 10, -1, 11, 3, 2, -3, 3, 0, + 4, 2, 10, 2, 12, -2, 13, -1, 11, 0, + 3, 1, 10, 1, 3, -2, 5, 0, + 4, 1, 10, 1, 12, 1, 13, -1, 11, 0, + 3, 1, 10, 3, 2, -4, 3, 0, + 3, 1, 10, 1, 3, -1, 5, 0, + 3, 1, 10, 1, 3, -2, 6, 0, + 3, 1, 10, 2, 3, -2, 4, 0, + 4, 1, 10, 1, 12, -1, 13, -1, 11, 0, + 3, 2, 10, 2, 12, -1, 11, 2, + 4, 1, 10, 1, 3, 2, 5, -5, 6, 1, + 1, 1, 14, 2, + 3, 1, 10, 8, 2,-12, 3, 1, + 5, -2, 10, 1, 13, -1, 11, 20, 2,-21, 3, 0, + 5, 2, 10, -2, 13, 1, 11, 2, 3, -3, 5, 0, + 3, 1, 10, 1, 3, 1, 6, 0, + 4, -1, 13, -1, 11, 26, 2,-29, 3, 0, + 3, -1, 11, 8, 2,-13, 3, 0, + 4, -1, 13, -1, 11, 18, 2,-16, 3, 2, + 4, -1, 13, 1, 11, 10, 2, -3, 3, 1, + 1, 1, 11, 3, + 4, -1, 13, -1, 11, 10, 2, -3, 3, 1, + 4, -1, 13, 1, 11, 18, 2,-16, 3, 2, + 3, 1, 11, 8, 2,-13, 3, 0, + 2, 1, 10, 2, 4, 0, + 4, 2, 10, -1, 11, 5, 2, -6, 3, 1, + 5, 2, 10, -2, 13, -1, 11, 2, 3, -3, 5, 0, + 5, -2, 10, 1, 13, 1, 11, 20, 2,-21, 3, 0, + 3, 1, 10, 1, 3, 1, 5, 0, + 2, -2, 11, 1, 14, 0, + 5, 2, 10, -2, 13, 1, 11, 2, 3, -2, 5, 0, + 3, 1, 10, 5, 2, -7, 3, 0, + 4, 1, 10, 1, 12, -1, 13, 1, 11, 0, + 3, 1, 10, 2, 2, -2, 3, 0, + 4, 2, 10, 2, 12, -2, 13, 1, 11, 0, + 2, 2, 13, -3, 11, 0, + 4, 2, 10, -1, 11, 4, 2, -4, 3, 0, + 3, 1, 10, 4, 2, -5, 3, 0, + 3, 1, 10, -3, 13, 1, 11, 0, + 2, 1, 10, 1, 2, 0, + 3, 1, 11, 1, 2, -1, 3, 0, + 4, 2, 10, -1, 11, 3, 3, -3, 5, 0, + 3, 1, 12, 2, 13, -1, 11, 1, + 4, 2, 10, 1, 12, -2, 13, -1, 11, 0, + 3, 1, 10, -1, 13, -1, 11, 0, + 3, 1, 11, 1, 3, -1, 5, 0, + 2, 1, 12, 1, 11, 2, + 4, 2, 10, -1, 11, 5, 2, -5, 3, 0, + 3, 1, 10, 5, 2, -6, 3, 0, + 3, 2, 10, 1, 12, -3, 11, 0, + 3, 1, 10, 2, 2, -1, 3, 0, + 3, 2, 10, -4, 13, 1, 11, 0, + 3, -2, 10, 2, 13, 1, 14, 0, + 3, 2, 10, -2, 13, -1, 11, 0, + 3, 1, 10, 3, 2, -2, 3, 0, + 4, 1, 10, -1, 12, -1, 13, -1, 11, 0, + 2, 2, 12, 1, 11, 0, + 2, 2, 10, -3, 11, 0, + 3, 1, 10, 4, 2, -3, 3, 0, + 4, 2, 10, -1, 12, -2, 13, -1, 11, 1, + 3, 2, 10, -1, 12, -3, 11, 0, + 3, 4, 10, -4, 13, -1, 11, 0, + 4, 2, 10, -2, 12, -2, 13, -1, 11, 0, + 4, 4, 10, -2, 12, -1, 13, -1, 11, 0, + 3, 6, 10, -3, 13, -1, 11, 0, + 4, 4, 10, -1, 12, -1, 13, -1, 11, 1, + 4, 2, 10, -3, 12, -1, 13, 1, 11, 0, + 3, 5, 10, -2, 13, -1, 11, 0, + 3, 4, 10, 1, 13, -3, 11, 0, + 4, 2, 10, -2, 12, 1, 13, -1, 11, 0, + 3, 3, 10, -1, 12, -1, 11, 0, + 3, 4, 10, -1, 13, -1, 11, 0, + 4, 2, 10, -2, 12, -1, 13, 1, 11, 1, + 3, 4, 10, -3, 13, 1, 11, 0, + 4, 2, 10, -1, 12, 1, 13, -1, 11, 1, + 5, -2, 10, 1, 13, -1, 11, 2, 2, -2, 3, 0, + 2, 3, 10, -1, 11, 0, + 4, 4, 10, 1, 12, -1, 13, -1, 11, 0, + 4, 2, 10, -1, 12, -1, 13, 1, 11, 2, + 5, -2, 10, 1, 13, -1, 11, 1, 3, -1, 5, 0, + 3, 3, 10, -2, 13, 1, 11, 0, + 5, -2, 10, 1, 13, -1, 11, 1, 2, -1, 3, 0, + 3, 2, 10, 1, 13, -1, 11, 0, + 3, -2, 10, -1, 13, 1, 14, 0, + 3, 2, 12, -1, 13, -1, 11, 1, + 3, 3, 10, 1, 12, -1, 11, 0, + 3, 1, 10, -1, 12, 1, 11, 0, + 4, -1, 13, -1, 11, 3, 2, -3, 3, 0, + 4, -1, 13, -1, 11, 2, 3, -2, 5, 0, + 3, 2, 10, -1, 13, 1, 14, 0, + 4, -2, 10, -1, 11, 18, 2,-16, 3, 0, + 6, 2, 10, -1, 13, 1, 11, 4, 3, -8, 4, 3, 5, 0, + 3, 2, 10, -1, 13, 1, 11, 0, + 6, -2, 10, 1, 13, -1, 11, 4, 3, -8, 4, 3, 5, 0, + 5, 2, 10, -2, 13, 1, 11, 18, 2,-16, 3, 0, + 4, -2, 10, 1, 13, -2, 11, 1, 14, 0, + 3, 1, 12, -3, 13, 1, 11, 0, + 3, 1, 10, 2, 13, -1, 11, 0, + 4, 2, 10, 1, 12, 1, 13, -1, 11, 1, + 3, 1, 12, -1, 13, -1, 11, 1, + 4, -1, 13, -1, 11, 1, 3, -1, 5, 0, + 2, 1, 10, 1, 11, 0, + 4, 2, 10, 1, 12, -1, 13, 1, 11, 1, + 3, 1, 12, 1, 13, -3, 11, 0, + 4, -1, 13, -1, 11, 1, 2, -1, 3, 0, + 5, 2, 10, -1, 13, 1, 11, 2, 2, -2, 3, 0, + 2, 3, 13, -1, 11, 0, + 4, 1, 10, 1, 12, -2, 13, -1, 11, 0, + 4, 2, 10, 2, 12, 1, 13, -1, 11, 0, + 2, 1, 13, 1, 14, 1, + 5, 2, 10, -1, 13, 1, 11, 2, 3, -3, 5, 0, + 4, -2, 13, -1, 11, 18, 2,-16, 3, 1, + 5, 1, 13, 1, 11, 4, 3, -8, 4, 3, 5, 0, + 2, 1, 13, 1, 11, 0, + 5, -1, 13, -1, 11, 4, 3, -8, 4, 3, 5, 0, + 3, 1, 11, 18, 2,-16, 3, 1, + 3, -1, 13, -2, 11, 1, 14, 0, + 5, 2, 10, -1, 13, 1, 11, 2, 3, -2, 5, 0, + 5, 2, 10, -1, 13, 1, 11, 3, 2, -3, 3, 0, + 3, 1, 10, 1, 12, 1, 11, 1, + 4, 2, 10, 2, 12, -1, 13, 1, 11, 1, + 2, 1, 13, -3, 11, 0, + 4, 1, 13, 1, 11, 1, 2, -1, 3, 0, + 3, 1, 12, 3, 13, -1, 11, 0, + 4, 2, 10, 1, 12, -3, 13, -1, 11, 0, + 3, 1, 10, -2, 13, -1, 11, 0, + 4, 1, 13, 1, 11, 1, 3, -1, 5, 0, + 3, 1, 12, 1, 13, 1, 11, 1, + 2, 1, 10, -3, 11, 0, + 3, 1, 12, -1, 13, 3, 11, 0, + 3, 2, 10, -3, 13, -1, 11, 0, + 3, 2, 12, 1, 13, 1, 11, 0, + 3, 2, 10, -1, 13, -3, 11, 0, + 4, 2, 10, -1, 12, -3, 13, -1, 11, 0, + 4, 2, 10, -1, 12, -1, 13, -3, 11, 0, + 4, 6, 10, -1, 12, -2, 13, -1, 11, 0, + 3, 4, 10, -2, 12, -1, 11, 0, + 3, 6, 10, -2, 13, -1, 11, 0, + 4, 4, 10, -2, 12, -2, 13, 1, 11, 0, + 3, 4, 10, -1, 12, -1, 11, 1, + 3, 2, 10, -3, 12, 1, 11, 0, + 3, 5, 10, -1, 13, -1, 11, 0, + 4, 4, 10, -1, 12, -2, 13, 1, 11, 0, + 4, 2, 10, -2, 12, 2, 13, -1, 11, 0, + 2, 4, 10, -1, 11, 0, + 3, 2, 10, -2, 12, 1, 11, 1, + 4, 3, 10, -1, 12, -1, 13, 1, 11, 0, + 3, 4, 10, -2, 13, 1, 11, 0, + 4, 2, 10, -1, 12, 2, 13, -1, 11, 0, + 4, -2, 10, -1, 11, 2, 2, -2, 3, 0, + 3, 3, 10, 1, 13, -1, 11, 0, + 3, 4, 10, 1, 12, -1, 11, 0, + 3, 2, 10, -1, 12, 1, 11, 2, + 4, -2, 10, -1, 11, 1, 3, -1, 5, 0, + 3, 3, 10, -1, 13, 1, 11, 0, + 4, 4, 10, 1, 12, -2, 13, 1, 11, 0, + 3, 2, 10, 2, 13, -1, 11, 0, + 3, 2, 12, -2, 13, -1, 11, 0, + 4, 1, 10, -1, 12, 1, 13, 1, 11, 0, + 2, 2, 10, 1, 14, 0, + 5, -2, 10, -1, 13, -1, 11, 18, 2,-16, 3, 0, + 2, 2, 10, 1, 11, 1, + 5, 2, 10, -1, 13, 1, 11, 18, 2,-16, 3, 0, + 3, -2, 10, -2, 11, 1, 14, 0, + 4, 3, 10, 1, 12, -1, 13, 1, 11, 0, + 3, 2, 10, -2, 13, 3, 11, 0, + 4, 2, 10, 1, 12, 2, 13, -1, 11, 0, + 3, 1, 12, -2, 13, -1, 11, 1, + 3, 1, 10, 1, 13, 1, 11, 0, + 3, 2, 10, 1, 12, 1, 11, 1, + 2, 4, 13, -1, 11, 0, + 2, 2, 13, 1, 14, 0, + 4, -3, 13, -1, 11, 18, 2,-16, 3, 0, + 2, 2, 13, 1, 11, 0, + 4, 1, 13, 1, 11, 18, 2,-16, 3, 0, + 4, 2, 10, 1, 11, 2, 3, -2, 5, 0, + 4, 1, 10, 1, 12, 1, 13, 1, 11, 0, + 3, 2, 10, 2, 12, 1, 11, 0, + 2, 2, 11, 1, 14, 0, + 1, 3, 11, 0, + 3, 1, 10, -3, 13, -1, 11, 0, + 3, 1, 12, 2, 13, 1, 11, 1, + 2, 1, 12, 3, 11, 0, + 3, 2, 10, -4, 13, -1, 11, 0, + 3, 2, 12, 2, 13, 1, 11, 0, + 3, 2, 10, -2, 13, -3, 11, 0, + 4, 6, 10, -1, 12, -1, 13, -1, 11, 0, + 3, 6, 10, -1, 13, -1, 11, 0, + 4, 4, 10, -2, 12, -1, 13, 1, 11, 0, + 3, 6, 10, -3, 13, 1, 11, 0, + 4, 4, 10, -1, 12, 1, 13, -1, 11, 0, + 4, 4, 10, -1, 12, -1, 13, 1, 11, 1, + 3, 5, 10, -2, 13, 1, 11, 0, + 3, 4, 10, 1, 13, -1, 11, 0, + 4, 2, 10, -2, 12, 1, 13, 1, 11, 0, + 3, 4, 10, -1, 13, 1, 11, 0, + 4, 2, 10, -1, 12, 3, 13, -1, 11, 0, + 4, 4, 10, 1, 12, 1, 13, -1, 11, 0, + 4, 2, 10, -1, 12, 1, 13, 1, 11, 1, + 2, 3, 10, 1, 11, 0, + 4, 4, 10, 1, 12, -1, 13, 1, 11, 0, + 4, 2, 10, -1, 12, -1, 13, 3, 11, 0, + 3, 2, 10, 3, 13, -1, 11, 0, + 3, 2, 10, 1, 13, 1, 14, 0, + 3, 2, 10, 1, 13, 1, 11, 0, + 3, 3, 10, 1, 12, 1, 11, 0, + 3, 2, 10, -1, 13, 3, 11, 0, + 4, 2, 10, 1, 12, 3, 13, -1, 11, 0, + 3, 1, 12, -3, 13, -1, 11, 0, + 3, 1, 10, 2, 13, 1, 11, 0, + 4, 2, 10, 1, 12, 1, 13, 1, 11, 1, + 3, 1, 12, -1, 13, -3, 11, 0, + 2, 1, 10, 3, 11, 0, + 2, 5, 13, -1, 11, 0, + 2, 3, 13, 1, 11, 0, + 4, 1, 10, 1, 12, 2, 13, 1, 11, 0, + 2, 1, 13, 3, 11, 0, + 3, 1, 12, 3, 13, 1, 11, 0, + 3, 1, 12, 1, 13, 3, 11, 0, + 3, 2, 10, -5, 13, -1, 11, 0, + 3, 6, 10, -1, 12, -1, 11, 0, + 4, 6, 10, -1, 12, -2, 13, 1, 11, 0, + 2, 6, 10, -1, 11, 0, + 3, 4, 10, -2, 12, 1, 11, 0, + 3, 6, 10, -2, 13, 1, 11, 0, + 4, 4, 10, -1, 12, 2, 13, -1, 11, 0, + 3, 4, 10, -1, 12, 1, 11, 0, + 3, 4, 10, 2, 13, -1, 11, 0, + 4, 2, 10, -2, 12, 2, 13, 1, 11, 0, + 2, 4, 10, 1, 11, 0, + 3, 4, 10, -2, 13, 3, 11, 0, + 4, 2, 10, -1, 12, 2, 13, 1, 11, 0, + 3, 3, 10, 1, 13, 1, 11, 0, + 3, 4, 10, 1, 12, 1, 11, 0, + 3, 2, 10, -1, 12, 3, 11, 0, + 3, 2, 10, 4, 13, -1, 11, 0, + 3, 2, 10, 2, 13, 1, 11, 0, + 2, 2, 10, 3, 11, 0, + 3, 1, 12, -4, 13, -1, 11, 0, + 3, 1, 10, 3, 13, 1, 11, 0, + 4, 2, 10, 1, 12, 2, 13, 1, 11, 0, + 2, 4, 13, 1, 11, 0, + 2, 2, 13, 3, 11, 0, + 1, 5, 11, 0, + 3, 1, 12, 4, 13, 1, 11, 0, + 4, 6, 10, -1, 12, -1, 13, 1, 11, 0, + 3, 6, 10, 1, 13, -1, 11, 0, + 3, 6, 10, -1, 13, 1, 11, 0, + 4, 4, 10, -1, 12, 1, 13, 1, 11, 0, + 3, 4, 10, 1, 13, 1, 11, 0, + 3, 4, 10, -1, 13, 3, 11, 0, + 4, 2, 10, -1, 12, 3, 13, 1, 11, 0, + 4, 4, 10, 1, 12, 1, 13, 1, 11, 0, + 3, 2, 10, 3, 13, 1, 11, 0, + 3, 2, 10, 1, 13, 3, 11, 0, + 2, 5, 13, 1, 11, 0, + 2, 3, 13, 3, 11, 0, + 2, 6, 10, 1, 11, 0, + 3, 4, 10, 2, 13, 1, 11, 0, + 3, 2, 10, 4, 13, 1, 11, 0, + -1 +}; +struct plantbl moonlr = { + { 3, 26, 29, 23, 5, 10, 0, 0, 0, 8, 4, 4, 6, 2, 0, 0, 0, 0,}, + 3, + lrargs, + lrtabl, + lrtabb, + lrtabr, + 2.5735686895300000e-03, + 3.6525000000000000e+06, + 1.0000000000000000e-04, +}; + +struct plantbl moonlat = { + { 0, 26, 29, 8, 3, 5, 0, 0, 0, 6, 5, 3, 5, 1, 0, 0, 0, 0,}, + 3, + bargs, + btabl, + btabb, + btabr, + 0.0000000000000000e+00, + 3.6525000000000000e+06, + 1.0000000000000000e-04, +}; + + +/* Reduce arc seconds modulo 360 degrees + answer in arc seconds */ +static double +mods3600(double x) +{ + double y; +#if !defined(__STDC__) + double floor(); +#endif + + y = x - 1296000. * floor( x/1296000.); + return(y); +} + + +/* Time argument is Julian ephemeris date. */ + +static void +mean_elements (double JED) +{ + double x, T, T2; + + /* Time variables. T is in Julian centuries. */ + T = (JED - MOSHIER_J2000) / 36525.0; + T2 = T*T; + + /* Mean longitudes of planets (Simon et al, 1994) + .047" subtracted from constant term for offset to DE403 origin. */ + + /* Mercury */ + x = mods3600( 538101628.6889819 * T + 908103.213 ); + x += (6.39e-6 * T + - 0.0192789) * T2; + Args[0] = x; + + /* Venus */ + x = mods3600( 210664136.4335482 * T + 655127.236 ); + x += (-6.27e-6 * T + + 0.0059381) * T2; + Args[1] = x; + + /* Earth */ + x = mods3600( 129597742.283429 * T + 361679.198 ); + x += (-5.23e-6 * T + - 2.04411e-2 ) * T2; + Ea_arcsec = x; + Args[2] = x; + + /* Mars */ + x = mods3600( 68905077.493988 * T + 1279558.751 ); + x += (-1.043e-5 * T + + 0.0094264) * T2; + Args[3] = x; + + /* Jupiter */ + x = mods3600( 10925660.377991 * T + 123665.420 ); + x += ((((-3.4e-10 * T + + 5.91e-8) * T + + 4.667e-6) * T + + 5.706e-5) * T + - 3.060378e-1)*T2; + Args[4] = x; + + /* Saturn */ + x = mods3600( 4399609.855372 * T + 180278.752 ); + x += (((( 8.3e-10 * T + - 1.452e-7) * T + - 1.1484e-5) * T + - 1.6618e-4) * T + + 7.561614E-1)*T2; + Args[5] = x; + + /* Uranus */ + x = mods3600( 1542481.193933 * T + 1130597.971 ) + + (0.00002156*T - 0.0175083)*T2; + Args[6] = x; + + /* Neptune */ + x = mods3600( 786550.320744 * T + 1095655.149 ) + + (-0.00000895*T + 0.0021103)*T2; + Args[7] = x; + + /* Copied from cmoon.c, DE404 version. */ + /* Mean elongation of moon = D */ + x = mods3600( 1.6029616009939659e+09 * T + 1.0722612202445078e+06 ); + x += (((((-3.207663637426e-013 * T + + 2.555243317839e-011) * T + + 2.560078201452e-009) * T + - 3.702060118571e-005) * T + + 6.9492746836058421e-03) * T /* D, t^3 */ + - 6.7352202374457519e+00) * T2; /* D, t^2 */ + Args[9] = x; + + /* Mean distance of moon from its ascending node = F */ + x = mods3600( 1.7395272628437717e+09 * T + 3.3577951412884740e+05 ); + x += ((((( 4.474984866301e-013 * T + + 4.189032191814e-011) * T + - 2.790392351314e-009) * T + - 2.165750777942e-006) * T + - 7.5311878482337989e-04) * T /* F, t^3 */ + - 1.3117809789650071e+01) * T2; /* F, t^2 */ + NF_arcsec = x; + Args[10] = x; + +/* Mean anomaly of sun = l' (J. Laskar) */ + x = mods3600(1.2959658102304320e+08 * T + 1.2871027407441526e+06); + x += (((((((( + 1.62e-20 * T + - 1.0390e-17 ) * T + - 3.83508e-15 ) * T + + 4.237343e-13 ) * T + + 8.8555011e-11 ) * T + - 4.77258489e-8 ) * T + - 1.1297037031e-5 ) * T + + 8.7473717367324703e-05) * T + - 5.5281306421783094e-01) * T2; + Args[11] = x; + + /* Mean anomaly of moon = l */ + x = mods3600( 1.7179159228846793e+09 * T + 4.8586817465825332e+05 ); + x += (((((-1.755312760154e-012) * T + + 3.452144225877e-011 * T + - 2.506365935364e-008) * T + - 2.536291235258e-004) * T + + 5.2099641302735818e-02) * T /* l, t^3 */ + + 3.1501359071894147e+01) * T2; /* l, t^2 */ + Args[12] = x; + + /* Mean longitude of moon, re mean ecliptic and equinox of date = L */ + x = mods3600( 1.7325643720442266e+09 * T + 7.8593980921052420e+05); + x += ((((( 7.200592540556e-014 * T + + 2.235210987108e-010) * T + - 1.024222633731e-008) * T + - 6.073960534117e-005) * T + + 6.9017248528380490e-03) * T /* L, t^3 */ + - 5.6550460027471399e+00) * T2; /* L, t^2 */ + LP_equinox = x; + Args[13] = x; + + /* Precession of the equinox */ + x = ((((((((( -8.66e-20*T - 4.759e-17)*T + + 2.424e-15)*T + + 1.3095e-12)*T + + 1.7451e-10)*T + - 1.8055e-8)*T + - 0.0000235316)*T + + 0.000076)*T + + 1.105414)*T + + 5028.791959)*T; + /* Moon's longitude re fixed J2000 equinox. */ + /* + Args[13] -= x; + */ + pA_precession = x; + + /* OM = LP - NF; */ + + /* Free librations. */ + /* LB 2.891725 years, psi amplitude 1.8" */ + Args[14] = mods3600( 4.48175409e7 * T + 8.060457e5 ); + + /* 24.2 years */ + Args[15] = mods3600( 5.36486787e6 * T - 391702.8 ); + +#if 0 + /* 27.34907 days */ + Args[16] = mods3600( 1.7308227257e9 * T - 4.443583e5 ); +#endif + /* LA 74.7 years. */ +Args[17] = mods3600( 1.73573e6 * T ); +} + + +/* Prepare lookup table of sin and cos ( i*Lj ) + * for required multiple angles + */ +static int +sscc (int k, double arg, int n) +{ + double cu, su, cv, sv, s; + int i; + + s = STR * arg; + su = sin (s); + cu = cos (s); + ss[k][0] = su; /* sin(L) */ + cc[k][0] = cu; /* cos(L) */ + sv = 2.0 * su * cu; + cv = cu * cu - su * su; + ss[k][1] = sv; /* sin(2L) */ + cc[k][1] = cv; + for (i = 2; i < n; i++) + { + s = su * cv + cu * sv; + cv = cu * cv - su * sv; + sv = s; + ss[k][i] = sv; /* sin( i+1 L ) */ + cc[k][i] = cv; + } + return (0); +} + +/* Generic program to accumulate sum of trigonometric series + in two variables (e.g., longitude, radius) + of the same list of arguments. */ +static int +g2plan (double J, struct plantbl *plan, double pobj[], int flag) +{ + int i, j, k, m, k1, ip, np, nt; + /* On some systems such as Silicon Graphics, char is unsigned + by default. */ + CHAR *p; + long *pl, *pr; + double su, cu, sv, cv; + double t, sl, sr; + + mean_elements (J); + /* For librations, moon's longitude is sidereal. */ + if (flag) + Args[13] -= pA_precession; + + T = (J - MOSHIER_J2000) / plan->timescale; + /* Calculate sin( i*MM ), etc. for needed multiple angles. */ + for (i = 0; i < NARGS; i++) + { + if ((j = plan->max_harmonic[i]) > 0) + { + sscc (i, Args[i], j); + } + } + + /* Point to start of table of arguments. */ + p = plan->arg_tbl; + /* Point to tabulated cosine and sine amplitudes. */ + pl = plan->lon_tbl; + pr = plan->rad_tbl; + sl = 0.0; + sr = 0.0; + + for (;;) + { + /* argument of sine and cosine */ + /* Number of periodic arguments. */ + np = *p++; + if (np < 0) + break; + if (np == 0) + { /* It is a polynomial term. */ + nt = *p++; + /* Longitude polynomial. */ + cu = *pl++; + for (ip = 0; ip < nt; ip++) + { + cu = cu * T + *pl++; + } + /* sl += mods3600 (cu); */ + sl += cu; + /* Radius polynomial. */ + cu = *pr++; + for (ip = 0; ip < nt; ip++) + { + cu = cu * T + *pr++; + } + sr += cu; + continue; + } + k1 = 0; + cv = 0.0; + sv = 0.0; + for (ip = 0; ip < np; ip++) + { + /* What harmonic. */ + j = *p++; + /* Which planet. */ + m = *p++ - 1; + if (j) + { + k = abs (j); + k -= 1; + su = ss[m][k]; /* sin(k*angle) */ + if (j < 0) + su = -su; + cu = cc[m][k]; + if (k1 == 0) + { /* set first angle */ + sv = su; + cv = cu; + k1 = 1; + } + else + { /* combine angles */ + t = su * cv + cu * sv; + cv = cu * cv - su * sv; + sv = t; + } + } + } + /* Highest power of T. */ + nt = *p++; + /* Longitude. */ + cu = *pl++; + su = *pl++; + for (ip = 0; ip < nt; ip++) + { + cu = cu * T + *pl++; + su = su * T + *pl++; + } + sl += cu * cv + su * sv; + /* Radius. */ + cu = *pr++; + su = *pr++; + for (ip = 0; ip < nt; ip++) + { + cu = cu * T + *pr++; + su = su * T + *pr++; + } + sr += cu * cv + su * sv; + } + t = plan->trunclvl; + pobj[0] = t * sl; + pobj[2] = t * sr; + return (0); +} + + + +/* Generic program to accumulate sum of trigonometric series + in one variable. */ + +static double +g1plan (double J, struct plantbl *plan) +{ + int i, j, k, m, k1, ip, np, nt; + /* On some systems such as Silicon Graphics, char is unsigned + by default. */ + CHAR *p; + long *pl; + double su, cu, sv, cv; + double t, sl; + + T = (J - MOSHIER_J2000) / plan->timescale; + mean_elements (J); + /* Calculate sin( i*MM ), etc. for needed multiple angles. */ + for (i = 0; i < NARGS; i++) + { + if ((j = plan->max_harmonic[i]) > 0) + { + sscc (i, Args[i], j); + } + } + + /* Point to start of table of arguments. */ + p = plan->arg_tbl; + /* Point to tabulated cosine and sine amplitudes. */ + pl = plan->lon_tbl; + sl = 0.0; + + for (;;) + { + /* argument of sine and cosine */ + /* Number of periodic arguments. */ + np = *p++; + if (np < 0) + break; + if (np == 0) + { /* It is a polynomial term. */ + nt = *p++; + cu = *pl++; + for (ip = 0; ip < nt; ip++) + { + cu = cu * T + *pl++; + } + /* sl += mods3600 (cu); */ + sl += cu; + continue; + } + k1 = 0; + cv = 0.0; + sv = 0.0; + for (ip = 0; ip < np; ip++) + { + /* What harmonic. */ + j = *p++; + /* Which planet. */ + m = *p++ - 1; + if (j) + { + k = abs (j); + k -= 1; + su = ss[m][k]; /* sin(k*angle) */ + if (j < 0) + su = -su; + cu = cc[m][k]; + if (k1 == 0) + { /* set first angle */ + sv = su; + cv = cu; + k1 = 1; + } + else + { /* combine angles */ + t = su * cv + cu * sv; + cv = cu * cv - su * sv; + sv = t; + } + } + } + /* Highest power of T. */ + nt = *p++; + /* Cosine and sine coefficients. */ + cu = *pl++; + su = *pl++; + for (ip = 0; ip < nt; ip++) + { + cu = cu * T + *pl++; + su = su * T + *pl++; + } + sl += cu * cv + su * sv; + } + return (plan->trunclvl * sl); +} + + +/* geocentric moon, mean ecliptic and equinox of date + * J is Julian Epemeris Date + * output in pobj[]: + * pobj[0]: l in rad + * pobj[1]: b in rad + * pobj[2]: r in au + */ +static int +gecmoon (double J, struct plantbl *lrtab, struct plantbl *lattab, double pobj[]) +{ + double x; + + g2plan (J, lrtab, pobj, 0); + x = pobj[0]; + x += LP_equinox; + if (x < -6.45e5) + x += 1.296e6; + if (x > 6.45e5) + x -= 1.296e6; + pobj[0] = STR * x; + x = g1plan (J, lattab); + pobj[1] = STR * x; + pobj[2] = (STR * pobj[2] + 1.0) * lrtab->distance; + return 0; +} + +/*********** end stephen moshier's moon code ****************/ + +static void moon_fast (double mj, double *lam, double *bet, + double *hp, double *msp, double *mdp); + +/* previous version (elwood): + * + * given the mjd, find the geocentric ecliptic longitude, lam, and latitude, + * bet, and horizontal parallax, hp for the moon. also return the sun's + * mean anomaly, *msp, and the moon's mean anomaly, *mdp. + * N.B. series for long and lat are good to about 10 and 3 arcseconds. however, + * math errors cause up to 100 and 30 arcseconds error, even if use double. + * why?? suspect highly sensitive nature of difference used to get m1..6. + * N.B. still need to correct for nutation. then for topocentric location + * further correct for parallax and refraction. + */ +static void +moon_fast (double mj, double *lam, double *bet, double *hp, double *msp, +double *mdp) +{ + double t, t2; + double ld; + double ms; + double md; + double de; + double f; + double n; + double a, sa, sn, b, sb, c, sc, e, e2, l, g, w1, w2; + double m1, m2, m3, m4, m5, m6; + + t = mj/36525.; + t2 = t*t; + + m1 = mj/27.32158213; + m1 = 360.0*(m1-(long)m1); + m2 = mj/365.2596407; + m2 = 360.0*(m2-(long)m2); + m3 = mj/27.55455094; + m3 = 360.0*(m3-(long)m3); + m4 = mj/29.53058868; + m4 = 360.0*(m4-(long)m4); + m5 = mj/27.21222039; + m5 = 360.0*(m5-(long)m5); + m6 = mj/6798.363307; + m6 = 360.0*(m6-(long)m6); + + ld = 270.434164+m1-(.001133-.0000019*t)*t2; + ms = 358.475833+m2-(.00015+.0000033*t)*t2; + md = 296.104608+m3+(.009192+.0000144*t)*t2; + de = 350.737486+m4-(.001436-.0000019*t)*t2; + f = 11.250889+m5-(.003211+.0000003*t)*t2; + n = 259.183275-m6+(.002078+.000022*t)*t2; + + a = degrad(51.2+20.2*t); + sa = sin(a); + sn = sin(degrad(n)); + b = 346.56+(132.87-.0091731*t)*t; + sb = .003964*sin(degrad(b)); + c = degrad(n+275.05-2.3*t); + sc = sin(c); + ld = ld+.000233*sa+sb+.001964*sn; + ms = ms-.001778*sa; + md = md+.000817*sa+sb+.002541*sn; + f = f+sb-.024691*sn-.004328*sc; + de = de+.002011*sa+sb+.001964*sn; + e = 1-(.002495+7.52e-06*t)*t; + e2 = e*e; + + ld = degrad(ld); + ms = degrad(ms); + n = degrad(n); + de = degrad(de); + f = degrad(f); + md = degrad(md); + + l = 6.28875*sin(md)+1.27402*sin(2*de-md)+.658309*sin(2*de)+ + .213616*sin(2*md)-e*.185596*sin(ms)-.114336*sin(2*f)+ + .058793*sin(2*(de-md))+.057212*e*sin(2*de-ms-md)+ + .05332*sin(2*de+md)+.045874*e*sin(2*de-ms)+.041024*e*sin(md-ms); + l = l-.034718*sin(de)-e*.030465*sin(ms+md)+.015326*sin(2*(de-f))- + .012528*sin(2*f+md)-.01098*sin(2*f-md)+.010674*sin(4*de-md)+ + .010034*sin(3*md)+.008548*sin(4*de-2*md)-e*.00791*sin(ms-md+2*de)- + e*.006783*sin(2*de+ms); + l = l+.005162*sin(md-de)+e*.005*sin(ms+de)+.003862*sin(4*de)+ + e*.004049*sin(md-ms+2*de)+.003996*sin(2*(md+de))+ + .003665*sin(2*de-3*md)+e*.002695*sin(2*md-ms)+ + .002602*sin(md-2*(f+de))+e*.002396*sin(2*(de-md)-ms)- + .002349*sin(md+de); + l = l+e2*.002249*sin(2*(de-ms))-e*.002125*sin(2*md+ms)- + e2*.002079*sin(2*ms)+e2*.002059*sin(2*(de-ms)-md)- + .001773*sin(md+2*(de-f))-.001595*sin(2*(f+de))+ + e*.00122*sin(4*de-ms-md)-.00111*sin(2*(md+f))+.000892*sin(md-3*de); + l = l-e*.000811*sin(ms+md+2*de)+e*.000761*sin(4*de-ms-2*md)+ + e2*.000704*sin(md-2*(ms+de))+e*.000693*sin(ms-2*(md-de))+ + e*.000598*sin(2*(de-f)-ms)+.00055*sin(md+4*de)+.000538*sin(4*md)+ + e*.000521*sin(4*de-ms)+.000486*sin(2*md-de); + l = l+e2*.000717*sin(md-2*ms); + *lam = ld+degrad(l); + range (lam, 2*PI); + + g = 5.12819*sin(f)+.280606*sin(md+f)+.277693*sin(md-f)+ + .173238*sin(2*de-f)+.055413*sin(2*de+f-md)+.046272*sin(2*de-f-md)+ + .032573*sin(2*de+f)+.017198*sin(2*md+f)+.009267*sin(2*de+md-f)+ + .008823*sin(2*md-f)+e*.008247*sin(2*de-ms-f); + g = g+.004323*sin(2*(de-md)-f)+.0042*sin(2*de+f+md)+ + e*.003372*sin(f-ms-2*de)+e*.002472*sin(2*de+f-ms-md)+ + e*.002222*sin(2*de+f-ms)+e*.002072*sin(2*de-f-ms-md)+ + e*.001877*sin(f-ms+md)+.001828*sin(4*de-f-md)-e*.001803*sin(f+ms)- + .00175*sin(3*f); + g = g+e*.00157*sin(md-ms-f)-.001487*sin(f+de)-e*.001481*sin(f+ms+md)+ + e*.001417*sin(f-ms-md)+e*.00135*sin(f-ms)+.00133*sin(f-de)+ + .001106*sin(f+3*md)+.00102*sin(4*de-f)+.000833*sin(f+4*de-md)+ + .000781*sin(md-3*f)+.00067*sin(f+4*de-2*md); + g = g+.000606*sin(2*de-3*f)+.000597*sin(2*(de+md)-f)+ + e*.000492*sin(2*de+md-ms-f)+.00045*sin(2*(md-de)-f)+ + .000439*sin(3*md-f)+.000423*sin(f+2*(de+md))+ + .000422*sin(2*de-f-3*md)-e*.000367*sin(ms+f+2*de-md)- + e*.000353*sin(ms+f+2*de)+.000331*sin(f+4*de); + g = g+e*.000317*sin(2*de+f-ms+md)+e2*.000306*sin(2*(de-ms)-f)- + .000283*sin(md+3*f); + w1 = .0004664*cos(n); + w2 = .0000754*cos(c); + *bet = degrad(g)*(1-w1-w2); + + *hp = .950724+.051818*cos(md)+.009531*cos(2*de-md)+.007843*cos(2*de)+ + .002824*cos(2*md)+.000857*cos(2*de+md)+e*.000533*cos(2*de-ms)+ + e*.000401*cos(2*de-md-ms)+e*.00032*cos(md-ms)-.000271*cos(de)- + e*.000264*cos(ms+md)-.000198*cos(2*f-md); + *hp = *hp+.000173*cos(3*md)+.000167*cos(4*de-md)-e*.000111*cos(ms)+ + .000103*cos(4*de-2*md)-.000084*cos(2*md-2*de)- + e*.000083*cos(2*de+ms)+.000079*cos(2*de+2*md)+.000072*cos(4*de)+ + e*.000064*cos(2*de-ms+md)-e*.000063*cos(2*de+ms-md)+ + e*.000041*cos(ms+de); + *hp = *hp+e*.000035*cos(2*md-ms)-.000033*cos(3*md-2*de)- + .00003*cos(md+de)-.000029*cos(2*(f-de))-e*.000029*cos(2*md+ms)+ + e2*.000026*cos(2*(de-ms))-.000023*cos(2*(f-de)+md)+ + e*.000019*cos(4*de-ms-md); + *hp = degrad(*hp); + + *msp = ms; + *mdp = md; +} + + +#define EarthRadius 6378.16 /* Kilometers */ + +/* moon() - front end rountine to get moon position; stern + * + * given the mjd, find the geocentric ecliptic longitude, lam, and latitude, + * bet, and geocentric distance, rho in a.u. for the moon. also return + * the sun's mean anomaly, *msp, and the moon's mean anomaly, *mdp. + * + * now uses Stephen Moshier's expansion and code. + * + * TODO: - clarify lunar aberration for apparent places + * + * still need to correct for nutation. then for topocentric location + * further correct for parallax and refraction. + * NB: Do NOT correct for aberration - the geocentric moon frame moves + * along with the earth. + */ +void +moon (double mj, double *lam, double *bet, double *rho, double *msp, +double *mdp) +{ + double pobj[3], dt; + double hp; + + if (mj >= MOSHIER_BEGIN && mj <= MOSHIER_END) { + /* retard for light time */ + moon_fast (mj, lam, bet, &hp, msp, mdp); + *rho = EarthRadius/AUKM/sin(hp); + dt = *rho * 5.7755183e-3; /* speed of light in a.u/day */ + gecmoon(mj + MJD0 - dt, &moonlr, &moonlat, pobj); + + *lam = pobj[0]; + range (lam, 2*PI); + *bet = pobj[1]; + *rho = pobj[2]; + *msp = STR * Args[11]; /* don't need range correction here */ + *mdp = STR * Args[12]; + } else { + moon_fast (mj, lam, bet, &hp, msp, mdp); + *rho = EarthRadius/AUKM/sin(hp); + + } +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: moon.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/mooncolong.c b/Common/Libraries/XEphemAstroLib/src/mooncolong.c new file mode 100644 index 000000000..14e77b7db --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/mooncolong.c @@ -0,0 +1,236 @@ +/* code to compute lunar sunrise position and local sun angle. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +#include "astro.h" + +static void Librations (double RAD, double LAMH, double BH, double OM, + double F, double L, double L1, double *L0, double *B0); +static void Moon (double RAD, double T, double T2, double LAM0, double R, + double M, double *F, double *L1, double *OM, double *LAM, double *B, + double *DR, double *LAMH, double *BH); +static void Sun (double RAD, double T, double T2, double *L, double *M, + double *R, double *LAM0); + +/* given a Julian date and a lunar location, find selenographic colongitude of + * rising sun, lunar latitude of subsolar point, illuminated fraction, and alt + * of sun at the given location. Any pointer may be 0 if not interested. + * From Bruning and Talcott, October 1995 _Astronomy_, page 76. + * N.B. lunar coordinates use +E, but selenograhic colongs are +W. + */ +void +moon_colong ( +double jd, /* jd */ +double lt, /* lat of location on moon, rads +N +E */ +double lg, /* long of location on moon, rads +N +E */ +double *cp, /* selenographic colongitude (-lng of rising sun), rads */ +double *kp, /* illuminated fraction of surface from Earth */ +double *ap, /* sun altitude at location, rads */ +double *sp) /* lunar latitude of subsolar point, rads */ +{ + double RAD = .0174533; + double T; + double T2; + double L, M, R, LAM0; + double F, L1, OM, LAM, B, DR, LAMH, BH; + double L0, B0; + double TEMP; + double C0; + double PSI; + double NUM, DEN; + double I, K; + double THETA, ETA; + double H; + + T = (jd - 2451545)/36525.0; + T2 = T * T; + + Sun(RAD, T, T2, &L, &M, &R, &LAM0); + Moon(RAD, T, T2, LAM0, R, M, &F, &L1, &OM, &LAM, &B, &DR, &LAMH, &BH); + Librations(RAD, LAMH, BH, OM, F, L, L1, &L0, &B0); + if (sp) + *sp = B0; + + TEMP = L0 / 360; + L0 = ((TEMP) - (int)(TEMP)) * 360; + if (L0 < 0) L0 = L0 + 360; + if (L0 <= 90) C0 = 90 - L0; else C0 = 450 - L0; + if (cp) { + *cp = degrad(C0); + range (cp, 2*PI); /* prefer 0..360 +W */ + } + + if (kp) { + TEMP = cos(B * RAD) * cos(LAM - LAM0 * RAD); + PSI = acos(TEMP); + NUM = R * sin(PSI); + DEN = DR - R * TEMP; + I = atan(NUM / DEN); + if (NUM * DEN < 0) I = I + 3.14159; + if (NUM < 0) I = I + 3.14159; + K = (1 + cos(I)) / 2; + *kp = K; + } + + if (ap) { + THETA = lt; + ETA = lg; + C0 = C0 * RAD; + TEMP = sin(B0) * sin(THETA) + cos(B0) * cos(THETA) * sin(C0+ETA); + H = asin(TEMP); + *ap = H; + } +} + +static void +Librations (double RAD, double LAMH, double BH, double OM, double F, +double L, double L1, double *L0, double *B0) +{ + double I, PSI, W, NUM, DEN, A, TEMP; + + /* inclination of lunar equator */ + I = 1.54242 * RAD; + + /* nutation in longitude, in arcseconds */ + PSI = -17.2 * sin(OM) - 1.32 * sin(2 * L) - .23 * sin(2 * L1) + + .21 * sin(2 * OM); + PSI = PSI * RAD / 3600; + + /* optical librations */ + W = (LAMH - PSI) - OM; + NUM = sin(W) * cos(BH) * cos(I) - sin(BH) * sin(I); + DEN = cos(W) * cos(BH); + A = atan(NUM / DEN); + if (NUM * DEN < 0) A = A + 3.14159; + if (NUM < 0) A = A + 3.14159; + *L0 = (A - F) / RAD; + TEMP = -sin(W) * cos(BH) * sin(I) - sin(BH) * cos(I); + *B0 = asin(TEMP); +} + +static void +Moon (double RAD, double T, double T2, double LAM0, double R, double M, +double *F, double *L1, double *OM, double *LAM, double *B, double *DR, +double *LAMH, double *BH) +{ + double T3, M1, D2, SUMR, SUML, DIST; + + T3 = T * T2; + + /* argument of the latitude of the Moon */ + *F = (93.2721 + 483202 * T - .003403 * T2 - T3 / 3526000) * RAD; + + /* mean longitude of the Moon */ + *L1 = (218.316 + 481268. * T) * RAD; + + /* longitude of the ascending node of Moon's mean orbit */ + *OM = (125.045 - 1934.14 * T + .002071 * T2 + T3 / 450000) * RAD; + + /* Moon's mean anomaly */ + M1 = (134.963 + 477199 * T + .008997 * T2 + T3 / 69700) * RAD; + + /* mean elongation of the Moon */ + D2 = (297.85 + 445267 * T - .00163 * T2 + T3 / 545900) * 2 * RAD; + + /* Lunar distance */ + SUMR = -20954 * cos(M1) - 3699 * cos(D2 - M1) - 2956 * cos(D2); + *DR = 385000 + SUMR; + + /* geocentric latitude */ + *B = 5.128 * sin(*F) + .2806 * sin(M1 + *F) + .2777 * sin(M1 - *F) + + .1732 * sin(D2 - *F); + SUML = 6.289 * sin(M1) + 1.274 * sin(D2 - M1) + .6583 * sin(D2) + + .2136 * sin(2 * M1) - .1851 * sin(M) - .1143 * sin(2 * *F); + *LAM = *L1 + SUML * RAD; + DIST = *DR / R; + *LAMH = (LAM0 + 180 + DIST * cos(*B) * sin(LAM0 * RAD - *LAM) / RAD) + * RAD; + *BH = DIST * *B * RAD; +} + +static void +Sun (double RAD, double T, double T2, double *L, double *M, double *R, +double *LAM0) +{ + double T3, C, V, E, THETA, OM; + + T3 = T2 * T; + + /* mean longitude of the Sun */ + *L = 280.466 + 36000.8 * T; + + /* mean anomaly of the Sun */ + *M = 357.529 + 35999 * T - .0001536 * T2 + T3 / 24490000; + *M = *M * RAD; + + /* correction for Sun's elliptical orbit */ + C = (1.915 - .004817 * T - .000014 * T2) * sin(*M) + + (.01999 - .000101 * T) * sin(2 * *M) + .00029 * sin(3 * *M); + + /* true anomaly of the Sun */ + V = *M + C * RAD; + + /* eccentricity of Earth's orbit */ + E = .01671 - .00004204 * T - .0000001236 * T2; + + /* Sun-Earth distance */ + *R = .99972 / (1 + E * cos(V)) * 145980000; + + /* true geometric longitude of the Sun */ + THETA = *L + C; + + /* apparent longitude of the Sun */ + OM = 125.04 - 1934.1 * T; + *LAM0 = THETA - .00569 - .00478 * sin(OM * RAD); +} + +#ifdef TESTCOLONG + +/* insure 0 <= *v < r. + */ +void +range (v, r) +double *v, r; +{ + *v -= r*floor(*v/r); +} + +/* To be sure the program is functioning properly, try the test case + * 2449992.5 (1 Oct 1995): the colongitude should be 3.69 degrees. + */ +int +main (int ac, char *av[]) +{ + double jd, lt, lg; + double c, k, a; + + if (ac != 2) { + fprintf (stderr, "%s: JD\n", av[0]); + abort(); + } + + jd = atof(av[1]); + + printf ("Latitude of lunar feature: "); + fscanf (stdin, "%lf", <); + lt = degrad(lt); + printf ("Longitude: "); + fscanf (stdin, "%lf", &lg); + lg = degrad(lg); + + moon_colong (jd, lt, lg, &c, &k, &a); + + printf ("Selenographic colongitude is %g\n", raddeg(c)); + printf ("The illuminated fraction of the Moon is %g\n", k); + printf ("Altitude of Sun above feature is %g\n", raddeg(a)); + + return (0); +} + +#endif + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: mooncolong.c,v $ $Date: 2004/05/05 17:45:49 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/moonnf.c b/Common/Libraries/XEphemAstroLib/src/moonnf.c new file mode 100644 index 000000000..075aee7f8 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/moonnf.c @@ -0,0 +1,69 @@ +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +static void m (double t, double k, double *mj); + +#define unw(w,z) ((w)-floor((w)/(z))*(z)) + +/* given a modified Julian date, mj, return the mjd of the new + * and full moons about then, mjn and mjf. + * TODO: exactly which ones does it find? eg: + * 5/28/1988 yields 5/15 and 5/31 + * 5/29 6/14 6/29 + */ +void +moonnf (double mj, double *mjn, double *mjf) +{ + int mo, yr; + double dy; + double mj0; + double k, tn, tf, t; + + mjd_cal (mj, &mo, &dy, &yr); + cal_mjd (1, 0., yr, &mj0); + k = (yr-1900+((mj-mj0)/365))*12.3685; + k = floor(k+0.5); + tn = k/1236.85; + tf = (k+0.5)/1236.85; + t = tn; + m (t, k, mjn); + t = tf; + k += 0.5; + m (t, k, mjf); +} + +static void +m (double t, double k, double *mj) +{ + double t2, a, a1, b, b1, c, ms, mm, f, ddjd; + + t2 = t*t; + a = 29.53*k; + c = degrad(166.56+(132.87-9.173e-3*t)*t); + b = 5.8868e-4*k+(1.178e-4-1.55e-7*t)*t2+3.3e-4*sin(c)+7.5933E-1; + ms = 359.2242+360*unw(k/1.236886e1,1)-(3.33e-5+3.47e-6*t)*t2; + mm = 306.0253+360*unw(k/9.330851e-1,1)+(1.07306e-2+1.236e-5*t)*t2; + f = 21.2964+360*unw(k/9.214926e-1,1)-(1.6528e-3+2.39e-6*t)*t2; + ms = unw(ms,360); + mm = unw(mm,360); + f = unw(f,360); + ms = degrad(ms); + mm = degrad(mm); + f = degrad(f); + ddjd = (1.734e-1-3.93e-4*t)*sin(ms)+2.1e-3*sin(2*ms) + -4.068e-1*sin(mm)+1.61e-2*sin(2*mm)-4e-4*sin(3*mm) + +1.04e-2*sin(2*f)-5.1e-3*sin(ms+mm)-7.4e-3*sin(ms-mm) + +4e-4*sin(2*f+ms)-4e-4*sin(2*f-ms)-6e-4*sin(2*f+mm) + +1e-3*sin(2*f-mm)+5e-4*sin(ms+2*mm); + a1 = (long)a; + b = b+ddjd+(a-a1); + b1 = (long)b; + a = a1+b1; + b = b-b1; + *mj = a + b; +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: moonnf.c,v $ $Date: 2003/03/20 08:50:15 $ $Revision: 1.1 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/nutation.c b/Common/Libraries/XEphemAstroLib/src/nutation.c new file mode 100644 index 000000000..241bf67eb --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/nutation.c @@ -0,0 +1,441 @@ +/* nutation (in IAU (1980) expression) and abberation; stern + * on an HP PA processor, this reproduces the Almanac nutation values + * (given to 0.001") EXACTLY over 750 days (1995 and 1996) + */ +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +#define NUT_SCALE 1e4 +#define NUT_SERIES 106 +#define NUT_MAXMUL 4 +#define SECPERCIRC (3600.*360.) + +/* Delaunay arguments, in arc seconds; they differ slightly from ELP82B */ +static double delaunay[5][4] = { + {485866.733, 1717915922.633, 31.310, 0.064}, /* M', moon mean anom */ + {1287099.804, 129596581.224, -0.577, -0.012}, /* M, sun mean anom */ + {335778.877, 1739527263.137, -13.257, 0.011}, /* F, moon arg lat */ + {1072261.307, 1602961601.328, -6.891, 0.019}, /* D, elong moon sun */ + {450160.280, -6962890.539, 7.455, 0.008}, /* Om, moon l asc node */ +}; + +/* multipliers for Delaunay arguments */ +static short multarg[NUT_SERIES][5] = { + /* bounds: -2..3, -2..2, -2/0/2/4, -4..4, 0..2 */ + {0, 0, 0, 0, 1}, + {0, 0, 0, 0, 2}, + {-2, 0, 2, 0, 1}, + {2, 0, -2, 0, 0}, + {-2, 0, 2, 0, 2}, + {1, -1, 0, -1, 0}, + {0, -2, 2, -2, 1}, + {2, 0, -2, 0, 1}, + {0, 0, 2, -2, 2}, + {0, 1, 0, 0, 0}, + {0, 1, 2, -2, 2}, + {0, -1, 2, -2, 2}, + {0, 0, 2, -2, 1}, + {2, 0, 0, -2, 0}, + {0, 0, 2, -2, 0}, + {0, 2, 0, 0, 0}, + {0, 1, 0, 0, 1}, + {0, 2, 2, -2, 2}, + {0, -1, 0, 0, 1}, + {-2, 0, 0, 2, 1}, + {0, -1, 2, -2, 1}, + {2, 0, 0, -2, 1}, + {0, 1, 2, -2, 1}, + {1, 0, 0, -1, 0}, + {2, 1, 0, -2, 0}, + {0, 0, -2, 2, 1}, + {0, 1, -2, 2, 0}, + {0, 1, 0, 0, 2}, + {-1, 0, 0, 1, 1}, + {0, 1, 2, -2, 0}, + {0, 0, 2, 0, 2}, + {1, 0, 0, 0, 0}, + {0, 0, 2, 0, 1}, + {1, 0, 2, 0, 2}, + {1, 0, 0, -2, 0}, + {-1, 0, 2, 0, 2}, + {0, 0, 0, 2, 0}, + {1, 0, 0, 0, 1}, + {-1, 0, 0, 0, 1}, + {-1, 0, 2, 2, 2}, + {1, 0, 2, 0, 1}, + {0, 0, 2, 2, 2}, + {2, 0, 0, 0, 0}, + {1, 0, 2, -2, 2}, + {2, 0, 2, 0, 2}, + {0, 0, 2, 0, 0}, + {-1, 0, 2, 0, 1}, + {-1, 0, 0, 2, 1}, + {1, 0, 0, -2, 1}, + {-1, 0, 2, 2, 1}, + {1, 1, 0, -2, 0}, + {0, 1, 2, 0, 2}, + {0, -1, 2, 0, 2}, + {1, 0, 2, 2, 2}, + {1, 0, 0, 2, 0}, + {2, 0, 2, -2, 2}, + {0, 0, 0, 2, 1}, + {0, 0, 2, 2, 1}, + {1, 0, 2, -2, 1}, + {0, 0, 0, -2, 1}, + {1, -1, 0, 0, 0}, + {2, 0, 2, 0, 1}, + {0, 1, 0, -2, 0}, + {1, 0, -2, 0, 0}, + {0, 0, 0, 1, 0}, + {1, 1, 0, 0, 0}, + {1, 0, 2, 0, 0}, + {1, -1, 2, 0, 2}, + {-1, -1, 2, 2, 2}, + {-2, 0, 0, 0, 1}, + {3, 0, 2, 0, 2}, + {0, -1, 2, 2, 2}, + {1, 1, 2, 0, 2}, + {-1, 0, 2, -2, 1}, + {2, 0, 0, 0, 1}, + {1, 0, 0, 0, 2}, + {3, 0, 0, 0, 0}, + {0, 0, 2, 1, 2}, + {-1, 0, 0, 0, 2}, + {1, 0, 0, -4, 0}, + {-2, 0, 2, 2, 2}, + {-1, 0, 2, 4, 2}, + {2, 0, 0, -4, 0}, + {1, 1, 2, -2, 2}, + {1, 0, 2, 2, 1}, + {-2, 0, 2, 4, 2}, + {-1, 0, 4, 0, 2}, + {1, -1, 0, -2, 0}, + {2, 0, 2, -2, 1}, + {2, 0, 2, 2, 2}, + {1, 0, 0, 2, 1}, + {0, 0, 4, -2, 2}, + {3, 0, 2, -2, 2}, + {1, 0, 2, -2, 0}, + {0, 1, 2, 0, 1}, + {-1, -1, 0, 2, 1}, + {0, 0, -2, 0, 1}, + {0, 0, 2, -1, 2}, + {0, 1, 0, 2, 0}, + {1, 0, -2, -2, 0}, + {0, -1, 2, 0, 1}, + {1, 1, 0, -2, 1}, + {1, 0, -2, 2, 0}, + {2, 0, 0, 2, 0}, + {0, 0, 2, 4, 2}, + {0, 1, 0, 1, 0} +}; + +/* amplitudes which have secular terms; in 1/NUT_SCALE arc seconds + * {index, constant dPSI, T/10 in dPSI, constant in dEPS, T/10 in dEPS} + */ +static long ampsecul[][5] = { + {0 ,-171996 ,-1742 ,92025 ,89}, + {1 ,2062 ,2 ,-895 ,5}, + {8 ,-13187 ,-16 ,5736 ,-31}, + {9 ,1426 ,-34 ,54 ,-1}, + {10 ,-517 ,12 ,224 ,-6}, + {11 ,217 ,-5 ,-95 ,3}, + {12 ,129 ,1 ,-70 ,0}, + {15 ,17 ,-1 ,0 ,0}, + {17 ,-16 ,1 ,7 ,0}, + {30 ,-2274 ,-2 ,977 ,-5}, + {31 ,712 ,1 ,-7 ,0}, + {32 ,-386 ,-4 ,200 ,0}, + {33 ,-301 ,0 ,129 ,-1}, + {37 ,63 ,1 ,-33 ,0}, + {38 ,-58 ,-1 ,32 ,0}, + /* termination */ { -1, } +}; + +/* amplitudes which only have constant terms; same unit as above + * {dPSI, dEPS} + * indexes which are already in ampsecul[][] are zeroed + */ +static short ampconst[NUT_SERIES][2] = { + {0,0}, + {0,0}, + {46,-24}, + {11,0}, + {-3,1}, + {-3,0}, + {-2,1}, + {1,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {48,1}, + {-22,0}, + {0,0}, + {-15,9}, + {0,0}, + {-12,6}, + {-6,3}, + {-5,3}, + {4,-2}, + {4,-2}, + {-4,0}, + {1,0}, + {1,0}, + {-1,0}, + {1,0}, + {1,0}, + {-1,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {-158,-1}, + {123,-53}, + {63,-2}, + {0,0}, + {0,0}, + {-59,26}, + {-51,27}, + {-38,16}, + {29,-1}, + {29,-12}, + {-31,13}, + {26,-1}, + {21,-10}, + {16,-8}, + {-13,7}, + {-10,5}, + {-7,0}, + {7,-3}, + {-7,3}, + {-8,3}, + {6,0}, + {6,-3}, + {-6,3}, + {-7,3}, + {6,-3}, + {-5,3}, + {5,0}, + {-5,3}, + {-4,0}, + {4,0}, + {-4,0}, + {-3,0}, + {3,0}, + {-3,1}, + {-3,1}, + {-2,1}, + {-3,1}, + {-3,1}, + {2,-1}, + {-2,1}, + {2,-1}, + {-2,1}, + {2,0}, + {2,-1}, + {1,-1}, + {-1,0}, + {1,-1}, + {-2,1}, + {-1,0}, + {1,-1}, + {-1,1}, + {-1,1}, + {1,0}, + {1,0}, + {1,-1}, + {-1,0}, + {-1,0}, + {1,0}, + {1,0}, + {-1,0}, + {1,0}, + {1,0}, + {-1,0}, + {-1,0}, + {-1,0}, + {-1,0}, + {-1,0}, + {-1,0}, + {-1,0}, + {1,0}, + {-1,0}, + {1,0} +}; + +/* given the modified JD, mj, find the nutation in obliquity, *deps, and + * the nutation in longitude, *dpsi, each in radians. + */ +void +nutation ( +double mj, +double *deps, /* on input: precision parameter in arc seconds */ +double *dpsi) +{ + static double lastmj = -10000, lastdeps, lastdpsi; + double T, T2, T3, T10; /* jul cent since J2000 */ + double prec; /* series precis in arc sec */ + int i, isecul; /* index in term table */ + static double delcache[5][2*NUT_MAXMUL+1]; + /* cache for multiples of delaunay args + * [M',M,F,D,Om][-min*x, .. , 0, .., max*x] + * make static to have unfilled fields cleared on init + */ + + if (mj == lastmj) { + *deps = lastdeps; + *dpsi = lastdpsi; + return; + } + + prec = 0.0; + +#if 0 /* this is if deps should contain a precision value */ + prec =* deps; + if (prec < 0.0 || prec > 1.0) /* accept only sane value */ + prec = 1.0; +#endif + + /* augment for abundance of small terms */ + prec *= NUT_SCALE/10; + + T = (mj - J2000)/36525.; + T2 = T * T; + T3 = T2 * T; + T10 = T/10.; + + /* calculate delaunay args and place in cache */ + for (i = 0; i < 5; ++i) { + double x; + short j; + + x = delaunay[i][0] + + delaunay[i][1] * T + + delaunay[i][2] * T2 + + delaunay[i][3] * T3; + + /* convert to radians */ + x /= SECPERCIRC; + x -= floor(x); + x *= 2.*PI; + + /* fill cache table */ + for (j = 0; j <= 2*NUT_MAXMUL; ++j) + delcache[i][j] = (j - NUT_MAXMUL) * x; + } + + /* find dpsi and deps */ + lastdpsi = lastdeps = 0.; + for (i = isecul = 0; i < NUT_SERIES ; ++i) { + double arg = 0., ampsin, ampcos; + short j; + + if (ampconst[i][0] || ampconst[i][1]) { + /* take non-secular terms from simple array */ + ampsin = ampconst[i][0]; + ampcos = ampconst[i][1]; + } else { + /* secular terms from different array */ + ampsin = ampsecul[isecul][1] + ampsecul[isecul][2] * T10; + ampcos = ampsecul[isecul][3] + ampsecul[isecul][4] * T10; + ++isecul; + } + + for (j = 0; j < 5; ++j) + arg += delcache[j][NUT_MAXMUL + multarg[i][j]]; + + if (fabs(ampsin) >= prec) + lastdpsi += ampsin * sin(arg); + + if (fabs(ampcos) >= prec) + lastdeps += ampcos * cos(arg); + + } + + /* convert to radians. + */ + lastdpsi = degrad(lastdpsi/3600./NUT_SCALE); + lastdeps = degrad(lastdeps/3600./NUT_SCALE); + + lastmj = mj; + *deps = lastdeps; + *dpsi = lastdpsi; +} + +/* given the modified JD, mj, correct, IN PLACE, the right ascension *ra + * and declination *dec (both in radians) for nutation. + */ +void +nut_eq (double mj, double *ra, double *dec) +{ + static double lastmj = -10000; + static double a[3][3]; /* rotation matrix */ + double xold, yold, zold, x, y, z; + + if (mj != lastmj) { + double epsilon, dpsi, deps; + double se, ce, sp, cp, sede, cede; + + obliquity(mj, &epsilon); + nutation(mj, &deps, &dpsi); + + /* the rotation matrix a applies the nutation correction to + * a vector of equatoreal coordinates Xeq to Xeq' by 3 subsequent + * rotations: R1 - from equatoreal to ecliptic system by + * rotation of angle epsilon about x, R2 - rotate ecliptic + * system by -dpsi about its z, R3 - from ecliptic to equatoreal + * by rotation of angle -(epsilon + deps) + * + * Xeq' = A * Xeq = R3 * R2 * R1 * Xeq + * + * [ 1 0 0 ] + * R1 = [ 0 cos(eps) sin(eps) ] + * [ 0 - sin(eps) cos(eps) ] + * + * [ cos(dpsi) - sin(dpsi) 0 ] + * R2 = [ sin(dpsi) cos(dpsi) 0 ] + * [ 0 0 1 ] + * + * [ 1 0 0 ] + * R3 = [ 0 cos(eps + deps) - sin(eps + deps) ] + * [ 0 sin(eps + deps) cos(eps + deps) ] + * + * for efficiency, here is a explicitely: + */ + + se = sin(epsilon); + ce = cos(epsilon); + sp = sin(dpsi); + cp = cos(dpsi); + sede = sin(epsilon + deps); + cede = cos(epsilon + deps); + + a[0][0] = cp; + a[0][1] = -sp*ce; + a[0][2] = -sp*se; + + a[1][0] = cede*sp; + a[1][1] = cede*cp*ce+sede*se; + a[1][2] = cede*cp*se-sede*ce; + + a[2][0] = sede*sp; + a[2][1] = sede*cp*ce-cede*se; + a[2][2] = sede*cp*se+cede*ce; + + lastmj = mj; + } + + sphcart(*ra, *dec, 1.0, &xold, &yold, &zold); + x = a[0][0] * xold + a[0][1] * yold + a[0][2] * zold; + y = a[1][0] * xold + a[1][1] * yold + a[1][2] * zold; + z = a[2][0] * xold + a[2][1] * yold + a[2][2] * zold; + cartsph(x, y, z, ra, dec, &zold); /* radius should be 1.0 */ + if (*ra < 0.) *ra += 2.*PI; /* make positive for display */ +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: nutation.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/obliq.c b/Common/Libraries/XEphemAstroLib/src/obliq.c new file mode 100644 index 000000000..e1dfce702 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/obliq.c @@ -0,0 +1,27 @@ +#include <stdio.h> + +#include "astro.h" + +/* given the modified Julian date, mj, find the mean obliquity of the + * ecliptic, *eps, in radians. + * + * IAU expression (see e.g. Astron. Almanac 1984); stern + */ +void +obliquity (double mj, double *eps) +{ + static double lastmj = -16347, lasteps; + + if (mj != lastmj) { + double t = (mj - J2000)/36525.; /* centuries from J2000 */ + lasteps = degrad(23.4392911 + /* 23^ 26' 21".448 */ + t * (-46.8150 + + t * ( -0.00059 + + t * ( 0.001813 )))/3600.0); + lastmj = mj; + } + *eps = lasteps; +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: obliq.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/parallactic.c b/Common/Libraries/XEphemAstroLib/src/parallactic.c new file mode 100644 index 000000000..327298c12 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/parallactic.c @@ -0,0 +1,54 @@ +/* compure parallactic angle: angle formed by N pole - Object - Zenith + */ + +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +/* compute parallactic angle given latitude, object dec and alt. + * all angles in rads. + * N.B. always return >= 0, caller must determine sign and degenerate cases at + * pole or zenith. + */ +double +parallacticLDA (double lt, double dec, double alt) +{ + double ca = sin(lt); + double cb = sin(dec); + double sb = cos(dec); + double cc = sin(alt); + double sc = cos(alt); + double cpa; + + /* given three sides find an angle */ + if (sb==0 || sc==0) + return (0); + cpa = (ca - cb*cc)/(sb*sc); + if (cpa < -1) cpa = -1; + if (cpa > 1) cpa = 1; + return (acos (cpa)); +} + +/* compute parallactic angle given latitude, object HA and Dec. + * all angles in rads. + * return value is between -PI and PI, sign is like HA, ie +west + */ +double +parallacticLHD (double lt, double ha, double dec) +{ + double A, b, cc, sc, B; + + A = ha; + b = PI/2 - lt; + cc = sin(dec); + sc = cos(dec); + solve_sphere (A, b, cc, sc, NULL, &B); + + if (B > PI) + B -= 2*PI; + return (B); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: parallactic.c,v $ $Date: 2003/06/30 04:23:36 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/parallax.c b/Common/Libraries/XEphemAstroLib/src/parallax.c new file mode 100644 index 000000000..3e1738f24 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/parallax.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <math.h> + +#include "astro.h" + + +/* given true ha and dec, tha and tdec, the geographical latitude, phi, the + * height above sea-level (as a fraction of the earths radius, 6378.16km), + * ht, and the geocentric distance rho in Earth radii(!), find the apparent + * ha and dec, aha and adec allowing for parallax. + * all angles in radians. ehp is the angle subtended at the body by the + * earth's equator. + */ +void +ta_par (double tha, double tdec, double phi, double ht, double *rho, +double *aha, double *adec) +{ + static double last_phi = 1000.0, last_ht = -1000.0, xobs, zobs; + double x, y, z; /* obj cartesian coord, in Earth radii */ + + /* avoid calcs involving the same phi and ht */ + if (phi != last_phi || ht != last_ht) { + double cphi, sphi, robs, e2 = (2 - 1/298.257)/298.257; + cphi = cos(phi); + sphi = sin(phi); + robs = 1/sqrt(1 - e2 * sphi * sphi); + + /* observer coordinates: x to meridian, y east, z north */ + xobs = (robs + ht) * cphi; + zobs = (robs*(1-e2) + ht) * sphi; + last_phi = phi; + last_ht = ht; + } + + sphcart(-tha, tdec, *rho, &x, &y, &z); + cartsph(x - xobs, y, z - zobs, aha, adec, rho); + *aha *= -1; + range (aha, 2*PI); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: parallax.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/plans.c b/Common/Libraries/XEphemAstroLib/src/plans.c new file mode 100644 index 000000000..c769f39f1 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/plans.c @@ -0,0 +1,227 @@ +/* rewritten for Bureau des Longitude theories by Bretagnon and Chapront + * Michael Sternberg <sternberg@physik.tu-chemnitz.de> + */ +#include <stdio.h> +#include <math.h> + +#include "astro.h" +#include "vsop87.h" +#include "chap95.h" + +static void pluto_ell (double mj, double *ret); +static void chap_trans (double mj, double *ret); +//void planpos (double mj, int obj, double prec, double *ret); + +/* coordinate transformation + * from: + * J2000.0 rectangular equatoreal ret[{0,1,2}] = {x,y,z} + * to: + * mean equinox of date spherical ecliptical ret[{0,1,2}] = {l,b,r} + */ +static void +chap_trans ( +double mj, /* destination epoch */ +double *ret) /* vector to be transformed _IN PLACE_ */ +{ + double ra, dec, r, eps; + double sr, cr, sd, cd, se, ce; + + cartsph(ret[0], ret[1], ret[2], &ra, &dec, &r); + precess(J2000, mj, &ra, &dec); + obliquity(mj, &eps); + sr = sin(ra); cr = cos(ra); + sd = sin(dec); cd = cos(dec); + se = sin(eps); ce = cos(eps); + ret[0] = atan2( sr * ce + sd/cd * se, cr); /* long */ + ret[1] = asin( sd * ce - cd * se * sr); /* lat */ + ret[2] = r; /* radius */ +} + +/* low precision ecliptic coordinates of Pluto from mean orbit. + * Only for sake of completeness outside available perturbation theories. + */ +static void +pluto_ell ( +double mj, /* epoch */ +double *ret) /* ecliptic coordinates {l,b,r} at equinox of date */ +{ + /* mean orbital elements of Pluto. + * The origin of these is somewhat obscure. + */ + double a = 39.543, /* semimajor axis, au */ + e = 0.2490, /* excentricity */ + inc0 = 17.140, /* inclination, deg */ + Om0 = 110.307, /* long asc node, deg */ + omeg0 = 113.768, /* arg of perihel, deg */ + mjp = 2448045.539 - MJD0, /* epoch of perihel */ + mjeq = J2000, /* equinox of elements */ + n = 144.9600/36525.; /* daily motion, deg */ + + double inc, Om, omeg; /* orbital elements at epoch of date */ + double ma, ea, nu; /* mean, excentric and true anomaly */ + double lo, slo, clo; /* longitude in orbit from asc node */ + + reduce_elements(mjeq, mj, degrad(inc0), degrad(omeg0), degrad(Om0), + &inc, &omeg, &Om); + ma = degrad((mj - mjp) * n); + anomaly(ma, e, &nu, &ea); + ret[2] = a * (1.0 - e*cos(ea)); /* r */ + lo = omeg + nu; + slo = sin(lo); + clo = cos(lo); + ret[1] = asin(slo * sin(inc)); /* b */ + ret[0] = atan2(slo * cos(inc), clo) + Om; /* l */ +} + +/*************************************************************/ + +/* geometric heliocentric position of planet, mean ecliptic of date + * (not corrected for light-time) + */ +void +planpos (double mj, int obj, double prec, double *ret) +{ + if (mj >= CHAP_BEGIN && mj <= CHAP_END) { + if (obj >= JUPITER) { /* prefer Chapront */ + chap95(mj, obj, prec, ret); + chap_trans (mj, ret); + } else { /* VSOP for inner planets */ + vsop87(mj, obj, prec, ret); + } + } else { /* outside Chapront time: */ + if (obj != PLUTO) { /* VSOP for all but Pluto */ + vsop87(mj, obj, prec, ret); + } else { /* Pluto mean elliptic orbit */ + pluto_ell(mj, ret); + } + } +} + +/*************************************************************/ + +/* visual elements of planets + * [planet][0] = angular size at 1 AU + * [planet][1] = magnitude at 1 AU from sun and earth and 0 deg phase angle + * [planet][2] = A + * [planet][3] = B + * [planet][4] = C + * where mag correction = A*(i/100) + B*(i/100)^2 + C*(i/100)^3 + * i = angle between sun and earth from planet, degrees + * from Explanatory Supplement, 1992 + */ +static double vis_elements[8][5] = { + /* Mercury */ { 6.74, -0.36, 3.8, -2.73, 2.00}, + /* Venus */ { 16.92, -4.29, 0.09, 2.39, -.65}, + /* Mars */ { 9.36, -1.52, 1.60, 0., 0.}, + /* Jupiter */ { 196.74, -9.25, 0.50, 0., 0.}, + /* Saturn */ { 165.6, -8.88, 4.40, 0., 0.}, + /* Uranus */ { 65.8, -7.19, 0.28, 0., 0.}, + /* Neptune */ { 62.2, -6.87, 0., 0., 0.}, + /* Pluto */ { 8.2, -1.01, 4.1, 0., 0.} +}; + +/* given a modified Julian date, mj, and a planet, p, find: + * lpd0: heliocentric longitude, + * psi0: heliocentric latitude, + * rp0: distance from the sun to the planet, + * rho0: distance from the Earth to the planet, + * none corrected for light time, ie, they are the true values for the + * given instant. + * lam: geocentric ecliptic longitude, + * bet: geocentric ecliptic latitude, + * each corrected for light time, ie, they are the apparent values as + * seen from the center of the Earth for the given instant. + * dia: angular diameter in arcsec at 1 AU, + * mag: visual magnitude + * + * all angles are in radians, all distances in AU. + * + * corrections for nutation and abberation must be made by the caller. The RA + * and DEC calculated from the fully-corrected ecliptic coordinates are then + * the apparent geocentric coordinates. Further corrections can be made, if + * required, for atmospheric refraction and geocentric parallax. + */ +void +plans (double mj, PLCode p, double *lpd0, double *psi0, double *rp0, +double *rho0, double *lam, double *bet, double *dia, double *mag) +{ + static double lastmj = -10000; + static double lsn, bsn, rsn; /* geocentric coords of sun */ + static double xsn, ysn, zsn; /* cartesian " */ + double lp, bp, rp; /* heliocentric coords of planet */ + double xp, yp, zp, rho; /* rect. coords and geocentric dist. */ + double dt; /* light time */ + double *vp; /* vis_elements[p] */ + double ci, i; /* sun/earth angle: cos, degrees */ + int pass; + + /* get sun cartesian; needed only once at mj */ + if (mj != lastmj) { + sunpos (mj, &lsn, &rsn, &bsn); + sphcart (lsn, bsn, rsn, &xsn, &ysn, &zsn); + lastmj = mj; + } + + /* first find the true position of the planet at mj. + * then repeat a second time for a slightly different time based + * on the position found in the first pass to account for light-travel + * time. + */ + dt = 0.0; + for (pass = 0; pass < 2; pass++) { + double ret[6]; + + /* get spherical coordinates of planet from precision routines, + * retarded for light time in second pass; + * alternative option: vsop allows calculating rates. + */ + planpos(mj - dt, p, 0.0, ret); + + lp = ret[0]; + bp = ret[1]; + rp = ret[2]; + + sphcart (lp, bp, rp, &xp, &yp, &zp); + cartsph (xp + xsn, yp + ysn, zp + zsn, lam, bet, &rho); + + if (pass == 0) { + /* save heliocentric coordinates at first pass since, being + * true, they are NOT to be corrected for light-travel time. + */ + *lpd0 = lp; + range (lpd0, 2.*PI); + *psi0 = bp; + *rp0 = rp; + *rho0 = rho; + } + + /* when we view a planet we see it in the position it occupied + * dt days ago, where rho is the distance between it and earth, + * in AU. use this as the new time for the next pass. + */ + dt = rho * 5.7755183e-3; + } + + vp = vis_elements[p]; + *dia = vp[0]; + + /* solve plane triangle, assume sun/earth dist == 1 */ + ci = (rp*rp + rho*rho - 1)/(2*rp*rho); + + /* expl supp equation for mag */ + if (ci < -1) ci = -1; + if (ci > 1) ci = 1; + i = raddeg(acos(ci))/100.; + *mag = vp[1] + 5*log10(rho*rp) + i*(vp[2] + i*(vp[3] + i*vp[4])); + + /* rings contribution if SATURN */ + if (p == SATURN) { + double et, st, set; + satrings (bp, lp, rp, lsn+PI, rsn, mj+MJD0, &et, &st); + set = sin(fabs(et)); + *mag += (-2.60 + 1.25*set)*set; + } +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: plans.c,v $ $Date: 2003/11/15 04:07:36 $ $Revision: 1.5 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/plmoon.c b/Common/Libraries/XEphemAstroLib/src/plmoon.c new file mode 100644 index 000000000..9d5eeca9a --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/plmoon.c @@ -0,0 +1,284 @@ +/* compute Obj fields for natural satellites. + */ + +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include "astro.h" + +/* private cache of planet ephemerides and when they were computed + * N.B. don't use ones in builtin[] -- they are the user's responsibility. + */ +static ObjPl plobj[NOBJ]; +static Now plnow[NOBJ]; + +/* public builtin storage + */ +static Obj builtin[NBUILTIN]; + +static char *moondir; + +static void setMoon (Now *np, Obj *moonop, Obj *planop, MoonData *mdp); +static void init1BI (int idx, int pl, int moon, char *name); +static void initPlobj(void); +static void rotate (double a, double *x, double *y); + +/* directory in which to look for auxil moon data files. + * N.B. caller must supply persistent storage. + */ +void +setMoonDir (char *dir) +{ + moondir = dir; +} + +/* return set of builtin objects. + * caller can use this storage but should never try to free anything. + */ +int +getBuiltInObjs (Obj **opp) +{ + if (!builtin[MERCURY].o_name[0]) { + /* first time only */ + + init1BI (MERCURY, MERCURY, X_PLANET, "Mercury"); + + init1BI (VENUS, VENUS, X_PLANET, "Venus"); + + init1BI (MARS, MARS, X_PLANET, "Mars"); + init1BI (PHOBOS, MARS, M_PHOBOS, "Phobos"); + init1BI (DEIMOS, MARS, M_DEIMOS, "Deimos"); + + init1BI (JUPITER, JUPITER, X_PLANET, "Jupiter"); + init1BI (IO, JUPITER, J_IO, "Io"); + init1BI (EUROPA, JUPITER, J_EUROPA, "Europa"); + init1BI (GANYMEDE, JUPITER, J_GANYMEDE, "Ganymede"); + init1BI (CALLISTO, JUPITER, J_CALLISTO, "Callisto"); + + init1BI (SATURN, SATURN, X_PLANET, "Saturn"); + init1BI (MIMAS, SATURN, S_MIMAS, "Mimas"); + init1BI (ENCELADUS, SATURN, S_ENCELADUS, "Enceladus"); + init1BI (TETHYS, SATURN, S_TETHYS, "Tethys"); + init1BI (DIONE, SATURN, S_DIONE, "Dione"); + init1BI (RHEA, SATURN, S_RHEA, "Rhea"); + init1BI (TITAN, SATURN, S_TITAN, "Titan"); + init1BI (HYPERION, SATURN, S_HYPERION, "Hyperion"); + init1BI (IAPETUS, SATURN, S_IAPETUS, "Iapetus"); + + init1BI (URANUS, URANUS, X_PLANET, "Uranus"); + init1BI (ARIEL, URANUS, U_ARIEL, "Ariel"); + init1BI (UMBRIEL, URANUS, U_UMBRIEL, "Umbriel"); + init1BI (TITANIA, URANUS, U_TITANIA, "Titania"); + init1BI (OBERON, URANUS, U_OBERON, "Oberon"); + init1BI (MIRANDA, URANUS, U_MIRANDA, "Miranda"); + + init1BI (NEPTUNE, NEPTUNE, X_PLANET, "Neptune"); + + init1BI (PLUTO, PLUTO, X_PLANET, "Pluto"); + + init1BI (SUN, SUN, X_PLANET, "Sun"); + + init1BI (MOON, MOON, X_PLANET, "Moon"); + } + + *opp = builtin; + return (NBUILTIN); +} + +static void +init1BI (int idx, int pl, int moon, char *name) +{ + strcpy (builtin[idx].o_name, name); + builtin[idx].o_type = PLANET; + builtin[idx].pl_code = pl; + builtin[idx].pl_moon = moon; +} + +/* find the circumstances for natural satellite object op at np. + * TODO: distances and helio coords just copied from parent planet. + */ +int +plmoon_cir (Now *np, Obj *moonop) +{ + Obj *sunop = (Obj*)&plobj[SUN]; + MoonData md[X_MAXNMOONS]; + double sz, t1, t2; + double pra, pdec; + MoonData *mdp; + Obj *planop; + + /* init plobj[] */ + if (!((Obj *)&plobj[0])->o_type) + initPlobj(); + + /* get sun @ np */ + if (memcmp (&plnow[SUN], np, sizeof(Now))) { + obj_cir (np, (Obj*)&plobj[SUN]); + memcpy (&plnow[SUN], np, sizeof(Now)); + } + + /* get parent planet and moon info @ np */ + switch (moonop->pl_code) { + + case MARS: + case PHOBOS: + case DEIMOS: + + planop = (Obj*)&plobj[MARS]; + + if (memcmp (&plnow[MARS], np, sizeof(Now))) { + obj_cir (np, planop); + memcpy (&plnow[MARS], np, sizeof(Now)); + } + + /* don't worry, this already caches based on same mjd */ + marsm_data (mjd, moondir, sunop, planop, &sz, &pra, &pdec, md); + mdp = &md[moonop->pl_moon]; + break; + + case JUPITER: + case IO: + case EUROPA: + case GANYMEDE: + case CALLISTO: + + planop = (Obj*)&plobj[JUPITER]; + + if (memcmp (&plnow[JUPITER], np, sizeof(Now))) { + obj_cir (np, planop); + memcpy (&plnow[JUPITER], np, sizeof(Now)); + } + + /* don't worry, this already caches based on same mjd */ + jupiter_data (mjd,moondir,sunop,planop,&sz,&t1,&t2,&pra,&pdec,md); + mdp = &md[moonop->pl_moon]; + moonop->pl_aux1 = t1; + moonop->pl_aux2 = t2; + break; + + case SATURN: + case MIMAS: + case ENCELADUS: + case TETHYS: + case DIONE: + case RHEA: + case TITAN: + case HYPERION: + case IAPETUS: + + planop = (Obj*)&plobj[SATURN]; + + if (memcmp (&plnow[SATURN], np, sizeof(Now))) { + obj_cir (np, planop); + memcpy (&plnow[SATURN], np, sizeof(Now)); + } + + /* don't worry, this already caches based on same mjd */ + saturn_data (mjd,moondir,sunop,planop,&sz,&t1,&t2,&pra,&pdec,md); + mdp = &md[moonop->pl_moon]; + moonop->pl_aux1 = t1; + moonop->pl_aux2 = t2; + break; + + case URANUS: + case ARIEL: + case UMBRIEL: + case TITANIA: + case OBERON: + case MIRANDA: + + planop = (Obj*)&plobj[URANUS]; + + if (memcmp (&plnow[URANUS], np, sizeof(Now))) { + obj_cir (np, planop); + memcpy (&plnow[URANUS], np, sizeof(Now)); + } + + /* don't worry, this already caches based on same mjd */ + uranus_data (mjd, moondir, sunop, planop, &sz, &pra, &pdec, md); + mdp = &md[moonop->pl_moon]; + break; + + default: + + printf ("Called plmoon_cir with bad code: %d\n",moonop->pl_code); + return (-1); + + } + + /* set moonop */ + setMoon (np, moonop, planop, mdp); + + return (0); +} + +static void +initPlobj() +{ + int i; + + for (i = 0; i < NOBJ; i++) { + ((Obj*)&plobj[i])->o_type = PLANET; + ((Obj*)&plobj[i])->pl_code = i; + } +} + +/* set moonop->s_* fields. + * np is needed to get local parallactic angle. + */ +static void +setMoon (Now *np, Obj *moonop, Obj *planop, MoonData *mdp) +{ + double pa, dra, ddec; + + /* just copy most fields from planet for now */ + moonop->s_gaera = planop->s_gaera; /* TODO */ + moonop->s_gaedec = planop->s_gaedec; /* TODO */ + moonop->s_elong = planop->s_elong; /* TODO */ + moonop->s_size = 0; /* TODO */ + moonop->s_sdist = planop->s_sdist; /* TODO */ + moonop->s_edist = planop->s_edist; /* TODO */ + moonop->s_hlat = planop->s_hlat; /* TODO */ + moonop->s_hlong = planop->s_hlong; /* TODO */ + moonop->s_phase = planop->s_phase; /* TODO */ + + /* new ra/dec directly from mdp */ + moonop->s_ra = mdp->ra; + moonop->s_dec = mdp->dec; + + /* geoemtry info */ + moonop->pl_x = mdp->x; + moonop->pl_y = mdp->y; + moonop->pl_z = mdp->z; + moonop->pl_evis = mdp->evis; + moonop->pl_svis = mdp->svis; + + /* tweak alt/az by change in ra/dec rotated by pa */ + pa = parallacticLDA (lat, planop->s_dec, planop->s_alt); + if (planop->s_az < PI) + pa = -pa; /* rotation radec to altaz */ + dra = (moonop->s_ra - planop->s_ra)*cos(planop->s_dec); + ddec = moonop->s_dec - planop->s_dec; + rotate (pa, &dra, &ddec); + moonop->s_alt = planop->s_alt + ddec; + moonop->s_az = planop->s_az - dra/cos(planop->s_alt); + + /* new mag directly from mdp */ + set_smag (moonop, mdp->mag); + + /* name */ + strcpy (moonop->o_name, mdp->full); +} + +/* rotate ccw by a */ +static void +rotate (double a, double *x, double *y) +{ + double sa = sin(a); + double ca = cos(a); + double xp = (*x)*ca - (*y)*sa; + double yp = (*x)*sa + (*y)*ca; + *x = xp; + *y = yp; +} diff --git a/Common/Libraries/XEphemAstroLib/src/plshadow.c b/Common/Libraries/XEphemAstroLib/src/plshadow.c new file mode 100644 index 000000000..514adc9b3 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/plshadow.c @@ -0,0 +1,50 @@ +#include <math.h> + +#include "astro.h" + +#undef sqr +#define sqr(x) ((x)*(x)) + +/* given a planet, the sun, the planet's eq pole position and a + * position of a satellite (as eq x=+e y=+s z=front in planet radii) find x,y + * position of shadow. + * return 0 if ok else -1 if shadow not on planet + */ +int +plshadow (Obj *op, Obj *sop, double polera, double poledec, double x, +double y, double z, float *sxp, float *syp) +{ + /* equatorial to ecliptic sky-plane rotation */ + double sa = cos(op->s_dec) * cos(poledec) * + (cos(op->s_ra)*sin(polera) - sin(op->s_ra)*cos(polera)); + double ca = sqrt (1.0 - sa*sa); + + /* rotate moon from equatorial to ecliptic */ + double ex = x*ca + y*sa; + double ey = -x*sa + y*ca; + + /* find angle subtended by earth-sun from planet */ + double a = asin (sin(op->s_hlong - sop->s_hlong)/op->s_edist); + double b = asin (-sin(op->s_hlat)/op->s_edist); + + /* find displacement in sky plane */ + double x0 = ex - z*tan(a); + double y0 = ey - z*tan(b); + + /* projection onto unit sphere */ + double x1 = x0 + (ex-x0)/sqrt(sqr(ex-x0)+sqr(z)); + double y1 = y0 + (ey-y0)/sqrt(sqr(ey-y0)+sqr(z)); + + /* check behind or off edge */ + if (z < 0 || sqr(x1) + sqr(y1) > 1) + return (-1); + + /* rotate back to equatorial */ + *sxp = x1*ca - y1*sa; + *syp = x1*sa + y1*ca; + + return (0); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: plshadow.c,v $ $Date: 2004/12/17 20:53:43 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/precess.c b/Common/Libraries/XEphemAstroLib/src/precess.c new file mode 100644 index 000000000..33ed4f459 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/precess.c @@ -0,0 +1,146 @@ +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +static void precess_hiprec (double mjd1, double mjd2, double *ra, double *dec); + + +#define DCOS(x) cos(degrad(x)) +#define DSIN(x) sin(degrad(x)) +#define DASIN(x) raddeg(asin(x)) +#define DATAN2(y,x) raddeg(atan2((y),(x))) + +/* corrects ra and dec, both in radians, for precession from epoch 1 to epoch 2. + * the epochs are given by their modified JDs, mjd1 and mjd2, respectively. + * N.B. ra and dec are modifed IN PLACE. + */ +void +precess ( +double mjd1, double mjd2, /* initial and final epoch modified JDs */ +double *ra, double *dec) /* ra/dec for mjd1 in, for mjd2 out */ +{ + precess_hiprec (mjd1, mjd2, ra, dec); +} + +/* + * Copyright (c) 1990 by Craig Counterman. All rights reserved. + * + * This software may be redistributed freely, not sold. + * This copyright notice and disclaimer of warranty must remain + * unchanged. + * + * No representation is made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty, to the extent permitted by applicable law. + * + * Rigorous precession. From Astronomical Ephemeris 1989, p. B18 + * + * 96-06-20 Hayo Hase <hase@wettzell.ifag.de>: theta_a corrected + */ +static void +precess_hiprec ( +double mjd1, double mjd2, /* initial and final epoch modified JDs */ +double *ra, double *dec) /* ra/dec for mjd1 in, for mjd2 out */ +{ + static double last_mjd1 = -213.432, last_from; + static double last_mjd2 = -213.432, last_to; + double zeta_A, z_A, theta_A; + double T; + double A, B, C; + double alpha, delta; + double alpha_in, delta_in; + double from_equinox, to_equinox; + double alpha2000, delta2000; + + /* convert mjds to years; + * avoid the remarkably expensive calls to mjd_year() + */ + if (last_mjd1 == mjd1) + from_equinox = last_from; + else { + mjd_year (mjd1, &from_equinox); + last_mjd1 = mjd1; + last_from = from_equinox; + } + if (last_mjd2 == mjd2) + to_equinox = last_to; + else { + mjd_year (mjd2, &to_equinox); + last_mjd2 = mjd2; + last_to = to_equinox; + } + + /* convert coords in rads to degs */ + alpha_in = raddeg(*ra); + delta_in = raddeg(*dec); + + /* precession progresses about 1 arc second in .047 years */ + /* From from_equinox to 2000.0 */ + if (fabs (from_equinox-2000.0) > .02) { + T = (from_equinox - 2000.0)/100.0; + zeta_A = 0.6406161* T + 0.0000839* T*T + 0.0000050* T*T*T; + z_A = 0.6406161* T + 0.0003041* T*T + 0.0000051* T*T*T; + theta_A = 0.5567530* T - 0.0001185* T*T - 0.0000116* T*T*T; + + A = DSIN(alpha_in - z_A) * DCOS(delta_in); + B = DCOS(alpha_in - z_A) * DCOS(theta_A) * DCOS(delta_in) + + DSIN(theta_A) * DSIN(delta_in); + C = -DCOS(alpha_in - z_A) * DSIN(theta_A) * DCOS(delta_in) + + DCOS(theta_A) * DSIN(delta_in); + + alpha2000 = DATAN2(A,B) - zeta_A; + range (&alpha2000, 360.0); + delta2000 = DASIN(C); + } else { + /* should get the same answer, but this could improve accruacy */ + alpha2000 = alpha_in; + delta2000 = delta_in; + }; + + + /* From 2000.0 to to_equinox */ + if (fabs (to_equinox - 2000.0) > .02) { + T = (to_equinox - 2000.0)/100.0; + zeta_A = 0.6406161* T + 0.0000839* T*T + 0.0000050* T*T*T; + z_A = 0.6406161* T + 0.0003041* T*T + 0.0000051* T*T*T; + theta_A = 0.5567530* T - 0.0001185* T*T - 0.0000116* T*T*T; + + A = DSIN(alpha2000 + zeta_A) * DCOS(delta2000); + B = DCOS(alpha2000 + zeta_A) * DCOS(theta_A) * DCOS(delta2000) + - DSIN(theta_A) * DSIN(delta2000); + C = DCOS(alpha2000 + zeta_A) * DSIN(theta_A) * DCOS(delta2000) + + DCOS(theta_A) * DSIN(delta2000); + + alpha = DATAN2(A,B) + z_A; + range(&alpha, 360.0); + delta = DASIN(C); + } else { + /* should get the same answer, but this could improve accruacy */ + alpha = alpha2000; + delta = delta2000; + }; + + *ra = degrad(alpha); + *dec = degrad(delta); +} + +#if 0 +static void +precess_fast ( +double mjd1, double mjd2, /* initial and final epoch modified JDs */ +double *ra, double *dec) /* ra/dec for mjd1 in, for mjd2 out */ +{ +#define N degrad (20.0468/3600.0) +#define M hrrad (3.07234/3600.0) + double nyrs; + + nyrs = (mjd2 - mjd1)/365.2425; + *dec += N * cos(*ra) * nyrs; + *ra += (M + (N * sin(*ra) * tan(*dec))) * nyrs; + range (ra, 2.0*PI); +} +#endif + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: precess.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/preferences.h b/Common/Libraries/XEphemAstroLib/src/preferences.h new file mode 100644 index 000000000..c5786611f --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/preferences.h @@ -0,0 +1,41 @@ +/* global info for the preferences facility. + * N.B. many of these enums are used as indexes -- don't change without + * checking where they are used! + */ +#ifndef _PREFERENCES_H +#define _PREFERENCES_H + +#ifdef __cplusplus +extern "C" { +#endif + +// all of your legacy C code here + + +typedef enum { + PREF_EQUATORIAL, PREF_UNITS, PREF_DATE_FORMAT, PREF_ZONE, PREF_DPYPREC, + PREF_MSG_BELL, PREF_PRE_FILL, PREF_TIPS, PREF_CONFIRM, PREF_WEEKSTART, + NPREFS +} Preferences; + +typedef enum {PREF_GEO, PREF_TOPO} PrefEquatorial; +typedef enum {PREF_ENGLISH, PREF_METRIC} PrefUnits; +typedef enum {PREF_MDY, PREF_YMD, PREF_DMY} PrefDateFormat; +typedef enum {PREF_LOCALTZ, PREF_UTCTZ} PrefStampZone; +typedef enum {PREF_LOPREC, PREF_HIPREC} PrefDpyPrec; +typedef enum {PREF_NOMSGBELL, PREF_MSGBELL} PrefMsgBell; +typedef enum {PREF_PREFILL, PREF_NOPREFILL} PrefPreFill; +typedef enum {PREF_TIPSON, PREF_NOTIPS} PrefTips; +typedef enum {PREF_CONFIRMON, PREF_NOCONFIRM} PrefConfirm; +typedef enum {PREF_SAT, PREF_SUN, PREF_MON} PrefWeekStart; + +extern int pref_get (Preferences p); +extern int pref_set (Preferences p, int newp); +#ifdef __cplusplus +} +#endif +#endif /* _PREFERENCES_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: preferences.h,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.6 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/reduce.c b/Common/Libraries/XEphemAstroLib/src/reduce.c new file mode 100644 index 000000000..58ede03a8 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/reduce.c @@ -0,0 +1,78 @@ +#include <math.h> + +#include <stdio.h> + +#include "astro.h" + +/* convert those orbital elements that change from epoch mj0 to epoch mj. + */ +void +reduce_elements ( +double mj0, /* initial epoch */ +double mj, /* desired epoch */ +double inc0, /* initial inclination, rads */ +double ap0, /* initial argument of perihelion, as an mj */ +double om0, /* initial long of ascending node, rads */ +double *inc, /* resultant inclination, rads */ +double *ap, /* resultant arg of perihelion, as an mj */ +double *om) /* resultant long of ascending node, rads */ +{ + double t0, t1; + double tt, tt2, t02, tt3; + double eta, th, th0; + double a, b; + double dap; + double cinc, sinc; + double ot, sot, cot, ot1; + double seta, ceta; + + if (fabs(mj - mj0) < 1e-5) { + /* sin(eta) blows for inc < 10 degrees -- anyway, no need */ + *inc = inc0; + *ap = ap0; + *om = om0; + return; + } + + t0 = mj0/365250.0; + t1 = mj/365250.0; + + tt = t1-t0; + tt2 = tt*tt; + t02 = t0*t0; + tt3 = tt*tt2; + eta = (471.07-6.75*t0+.57*t02)*tt+(.57*t0-3.37)*tt2+.05*tt3; + th0 = 32869.0*t0+56*t02-(8694+55*t0)*tt+3*tt2; + eta = degrad(eta/3600.0); + th0 = degrad((th0/3600.0)+173.950833); + th = (50256.41+222.29*t0+.26*t02)*tt+(111.15+.26*t0)*tt2+.1*tt3; + th = th0+degrad(th/3600.0); + cinc = cos(inc0); + sinc = sin(inc0); + ot = om0-th0; + sot = sin(ot); + cot = cos(ot); + seta = sin(eta); + ceta = cos(eta); + a = sinc*sot; + b = ceta*sinc*cot-seta*cinc; + ot1 = atan(a/b); + if (b<0) ot1 += PI; + b = sinc*ceta-cinc*seta*cot; + a = -1*seta*sot; + dap = atan(a/b); + if (b<0) dap += PI; + + *ap = ap0+dap; + range (ap, 2*PI); + *om = ot1+th; + range (om, 2*PI); + + if (inc0<.175) + *inc = asin(a/sin(dap)); + else + *inc = 1.570796327-asin((cinc*ceta)+(sinc*seta*cot)); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: reduce.c,v $ $Date: 2003/03/28 10:23:35 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/refract.c b/Common/Libraries/XEphemAstroLib/src/refract.c new file mode 100644 index 000000000..4483cc93f --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/refract.c @@ -0,0 +1,96 @@ +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +static void unrefractLT15 (double pr, double tr, double aa, double *ta); +static void unrefractGE15 (double pr, double tr, double aa, double *ta); + +void +unrefract (double pr, double tr, double aa, double *ta) +{ +#define LTLIM 14.5 +#define GELIM 15.5 + + double aadeg = raddeg(aa); + + if (aadeg < LTLIM) + unrefractLT15 (pr, tr, aa, ta); + else if (aadeg >= GELIM) + unrefractGE15 (pr, tr, aa, ta); + else { + /* smooth blend -- important for inverse */ + double taLT, taGE, p; + + unrefractLT15 (pr, tr, aa, &taLT); + unrefractGE15 (pr, tr, aa, &taGE); + p = (aadeg - LTLIM)/(GELIM - LTLIM); + *ta = taLT + (taGE - taLT)*p; + } +} + +static void +unrefractGE15 (double pr, double tr, double aa, double *ta) +{ + double r; + + r = 7.888888e-5*pr/((273+tr)*tan(aa)); + *ta = aa - r; +} + +static void +unrefractLT15 (double pr, double tr, double aa, double *ta) +{ + double aadeg = raddeg(aa); + double r, a, b; + + a = ((2e-5*aadeg+1.96e-2)*aadeg+1.594e-1)*pr; + b = (273+tr)*((8.45e-2*aadeg+5.05e-1)*aadeg+1); + r = degrad(a/b); + + *ta = (aa < 0 && r < 0) ? aa : aa - r; /* 0 below ~5 degs */ +} + +/* correct the true altitude, ta, for refraction to the apparent altitude, aa, + * each in radians, given the local atmospheric pressure, pr, in mbars, and + * the temperature, tr, in degrees C. + */ +void +refract (double pr, double tr, double ta, double *aa) +{ +#define MAXRERR degrad(0.1/3600.) /* desired accuracy, rads */ + + double d, t, t0, a; + + if (isnan (ta)) { + *aa = ta; + return; + } + + /* first guess of error is to go backwards. + * make use that we know delta-apparent is always < delta-true. + */ + unrefract (pr, tr, ta, &t); + d = 0.8*(ta - t); + t0 = t; + a = ta; + + /* use secant method to discover a value that unrefracts to ta. + * max=7 ave=2.4 loops in hundreds of test cases. + */ + while (1) { + a += d; + unrefract (pr, tr, a, &t); + if (fabs(ta-t) <= MAXRERR) + break; + d *= -(ta - t)/(t0 - t); + t0 = t; + } + + *aa = a; + +#undef MAXRERR +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: refract.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.6 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/rings.c b/Common/Libraries/XEphemAstroLib/src/rings.c new file mode 100644 index 000000000..b09b6829b --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/rings.c @@ -0,0 +1,45 @@ +#include <stdio.h> +#include <math.h> +#include <stdlib.h> + +#include "astro.h" + +/* RINGS OF SATURN by Olson, et al, BASIC Code from Sky & Telescope, May 1995. + * As converted from BASIC to C by pmartz@dsd.es.com (Paul Martz) + * Adapted to xephem by Elwood Charles Downey. + */ +void +satrings ( +double sb, double sl, double sr, /* Saturn hlat, hlong, sun dist */ +double el, double er, /* Earth hlong, sun dist */ +double JD, /* Julian date */ +double *etiltp, double *stiltp) /* tilt from earth and sun, rads south*/ +{ + double t, i, om; + double x, y, z; + double la, be; + double s, b, sp, bp; + + t = (JD-2451545.)/365250.; + i = degrad(28.04922-.13*t+.0004*t*t); + om = degrad(169.53+13.826*t+.04*t*t); + + x = sr*cos(sb)*cos(sl)-er*cos(el); + y = sr*cos(sb)*sin(sl)-er*sin(el); + z = sr*sin(sb); + + la = atan(y/x); + if (x<0) la+=PI; + be = atan(z/sqrt(x*x+y*y)); + + s = sin(i)*cos(be)*sin(la-om)-cos(i)*sin(be); + b = atan(s/sqrt(1.-s*s)); + sp = sin(i)*cos(sb)*sin(sl-om)-cos(i)*sin(sb); + bp = atan(sp/sqrt(1.-sp*sp)); + + *etiltp = b; + *stiltp = bp; +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: rings.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/riset.c b/Common/Libraries/XEphemAstroLib/src/riset.c new file mode 100644 index 000000000..1629d9685 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/riset.c @@ -0,0 +1,100 @@ +#include <stdio.h> +#include <math.h> + +#include "astro.h" + +/* given the true geocentric ra and dec of an object, the observer's latitude, + * lt, and a horizon displacement correction, dis, all in radians, find the + * local sidereal times and azimuths of rising and setting, lstr/s + * and azr/s, also all in radians, respectively. + * dis is the vertical displacement from the true position of the horizon. it + * is positive if the apparent position is higher than the true position. + * said another way, it is positive if the shift causes the object to spend + * longer above the horizon. for example, atmospheric refraction is typically + * assumed to produce a vertical shift of 34 arc minutes at the horizon; dis + * would then take on the value +9.89e-3 (radians). On the other hand, if + * your horizon has hills such that your apparent horizon is, say, 1 degree + * above sea level, you would allow for this by setting dis to -1.75e-2 + * (radians). + * + * This version contributed by Konrad Bernloehr, Nov. 1996 + * + * status: 0=normal; 1=never rises; -1=circumpolar. + * In case of non-zero status, all other returned variables are undefined. + */ +void +riset (double ra, double dec, double lt, double dis, double *lstr, +double *lsts, double *azr, double *azs, int *status) +{ +#define EPS (1e-9) /* math rounding fudge - always the way, eh? */ + double h; /* hour angle */ + double cos_h; /* cos h */ + double z; /* zenith angle */ + double zmin, zmax; /* Minimum and maximum zenith angles */ + double xaz, yaz; /* components of az */ + int shemi; /* flag for southern hemisphere reflection */ + + /* reflect lt and dec if in southern hemisphere, then az back later */ + if ((shemi= (lt < 0.)) != 0) { + lt = -lt; + dec = -dec; + } + + /* establish zenith angle, and its extrema */ + z = (PI/2.) + dis; + zmin = fabs (dec - lt); + zmax = PI - fabs(dec + lt); + + /* first consider special cases. + * these also avoid any boundary problems in subsequent computations. + */ + if (zmax <= z + EPS) { + *status = -1; /* never sets */ + return; + } + if (zmin >= z - EPS) { + *status = 1; /* never rises */ + return; + } + + /* compute rising hour angle -- beware found off */ + cos_h = (cos(z)-sin(lt)*sin(dec))/(cos(lt)*cos(dec)); + if (cos_h >= 1.) + h = 0.; + else if (cos_h <= -1.) + h = PI; + else + h = acos (cos_h); + + /* compute setting azimuth -- beware found off */ + xaz = sin(dec)*cos(lt)-cos(dec)*cos(h)*sin(lt); + yaz = -1.*cos(dec)*sin(h); + if (xaz == 0.) { + if (yaz > 0) + *azs = PI/2; + else + *azs = -PI/2; + } else + *azs = atan2 (yaz, xaz); + + /* reflect az back if southern */ + if (shemi) + *azs = PI - *azs; + range(azs, 2.*PI); + + /* rising is just the opposite side */ + *azr = 2.*PI - *azs; + range(azr, 2.*PI); + + /* rise and set are just ha either side of ra */ + *lstr = radhr(ra-h); + range(lstr,24.0); + *lsts = radhr(ra+h); + range(lsts,24.0); + + /* OK */ + *status = 0; +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: riset.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/riset_cir.c b/Common/Libraries/XEphemAstroLib/src/riset_cir.c new file mode 100644 index 000000000..66f91c1f4 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/riset_cir.c @@ -0,0 +1,426 @@ +/* find rise and set circumstances, ie, riset_cir() and related functions. */ + +#include <stdio.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#include "astro.h" + + +static void e_riset_cir (Now *np, Obj *op, double dis, RiseSet *rp); +static int find_0alt (double dt, double fstep, double dis, Now *np, Obj *op); +static int find_transit (double dt, Now *np, Obj *op); +static int find_maxalt (Now *np, Obj *op, double tr, double ts, double *tp, + double *alp, double *azp); + +/* find where and when an object, op, will rise and set and + * it's transit circumstances. all times are utc mjd, angles rads e of n. + * dis is the angle down from an ideal horizon, in rads (see riset()). + * N.B. dis should NOT include refraction, we do that here. + */ +void +riset_cir (Now *np, Obj *op, double dis, RiseSet *rp) +{ + double mjdn; /* mjd of local noon */ + double lstn; /* lst at local noon */ + double lr, ls; /* lst rise/set times */ + double ar, as; /* az of rise/set */ + double ran; /* RA at noon */ + Now n; /* copy to move time around */ + Obj o; /* copy to get circumstances at n */ + int rss; /* temp status */ + + /* work with local copies so we can move the time around */ + (void) memcpy ((void *)&n, (void *)np, sizeof(n)); + (void) memcpy ((void *)&o, (void *)op, sizeof(o)); + + /* fast Earth satellites need a different approach. + * "fast" here is pretty arbitrary -- just too fast to work with the + * iterative approach based on refining the times for a "fixed" object. + */ + if (op->o_type == EARTHSAT && op->es_n > FAST_SAT_RPD) { + e_riset_cir (&n, &o, dis, rp); + return; + } + + /* assume no problems initially */ + rp->rs_flags = 0; + + /* start the iteration at local noon */ + mjdn = mjd_day(mjd - tz/24.0) + tz/24.0 + 0.5; + n.n_mjd = mjdn; + now_lst (&n, &lstn); + + /* first approximation is to find rise/set times of a fixed object + * at the current epoch in its position at local noon. + * N.B. add typical refraction if dis is above horizon for initial + * go/no-go test. if it passes, real code does refraction rigorously. + */ + n.n_mjd = mjdn; + if (obj_cir (&n, &o) < 0) { + rp->rs_flags = RS_ERROR; + return; + } + ran = o.s_gaera; + riset (o.s_gaera, o.s_gaedec, lat, dis+(dis>.01 ? 0 : .01), &lr, &ls, + &ar, &as, &rss); + switch (rss) { + case 0: break; + case 1: rp->rs_flags = RS_NEVERUP; return; + case -1: rp->rs_flags = RS_CIRCUMPOLAR; goto dotransit; + default: rp->rs_flags = RS_ERROR; return; + } + + /* iterate to find better rise time */ + n.n_mjd = mjdn; + switch (find_0alt ((lr - lstn)/SIDRATE, 60/SPD, dis, &n, &o)) { + case 0: /* ok */ + rp->rs_risetm = n.n_mjd; + rp->rs_riseaz = o.s_az; + break; + case -1: /* obj_cir error */ + rp->rs_flags |= RS_RISERR; + break; + case -2: /* converged but not today, err but give times anyway */ + rp->rs_risetm = n.n_mjd; + rp->rs_riseaz = o.s_az; + rp->rs_flags |= RS_NORISE; + break; + case -3: /* probably never up */ + rp->rs_flags |= RS_NEVERUP; + break; + } + + /* iterate to find better set time */ + n.n_mjd = mjdn; + switch (find_0alt ((ls - lstn)/SIDRATE, 60/SPD, dis, &n, &o)) { + case 0: /* ok */ + rp->rs_settm = n.n_mjd; + rp->rs_setaz = o.s_az; + break; + case -1: /* obj_cir error */ + rp->rs_flags |= RS_SETERR; + break; + case -2: /* converged but not today, err but give times anyway */ + rp->rs_settm = n.n_mjd; + rp->rs_setaz = o.s_az; + rp->rs_flags |= RS_NOSET; + break; + case -3: /* probably circumpolar */ + rp->rs_flags |= RS_CIRCUMPOLAR; + break; + } + + /* can try transit even if rise or set failed */ + dotransit: + n.n_mjd = mjdn; + switch (find_transit ((radhr(ran) - lstn)/SIDRATE, &n, &o)) { + case 0: /* ok */ + rp->rs_trantm = n.n_mjd; + rp->rs_tranalt = o.s_alt; + rp->rs_tranaz = o.s_az; + break; + case -1: /* did not converge */ + rp->rs_flags |= RS_TRANSERR; + break; + case -2: /* converged but not today */ + rp->rs_flags |= RS_NOTRANS; + break; + } +} + +/* find local times when sun is dis rads below horizon. + */ +void +twilight_cir (Now *np, double dis, double *dawn, double *dusk, int *status) +{ + RiseSet rs; + Obj o; + + memset (&o, 0, sizeof(o)); + o.o_type = PLANET; + o.pl_code = SUN; + (void) strcpy (o.o_name, "Sun"); + riset_cir (np, &o, dis, &rs); + *dawn = rs.rs_risetm; + *dusk = rs.rs_settm; + *status = rs.rs_flags; +} + +/* find where and when a fast-moving Earth satellite, op, will rise and set and + * it's transit circumstances. all times are mjd, angles rads e of n. + * dis is the angle down from the local topo horizon, in rads (see riset()). + * idea is to walk forward in time looking for alt+dis==0 crossings. + * initial time step is a few degrees (based on average daily motion). + * we stop as soon as we see both a rise and set. + * N.B. we assume *np and *op are working copies we can mess up. + */ +static void +e_riset_cir (Now *np, Obj *op, double dis, RiseSet *rp) +{ +#define DEGSTEP 2 /* time step is about this many degrees */ + int steps; /* max number of time steps */ + double dt; /* time change per step, days */ + double t0, t1; /* current and next mjd values */ + double a0, a1; /* altitude at t0 and t1 */ + int rise, set; /* flags to check when we find these events */ + int i; + + dt = DEGSTEP * (1.0/360.0/op->es_n); + steps = (int)(1.0/dt); + rise = set = 0; + rp->rs_flags = 0; + + if (obj_cir (np, op) < 0) { + rp->rs_flags |= RS_ERROR; + return; + } + + t0 = mjd; + a0 = op->s_alt + dis; + + for (i = 0; i < steps && (!rise || !set); i++) { + mjd = t1 = t0 + dt; + if (obj_cir (np, op) < 0) { + rp->rs_flags |= RS_ERROR; + return; + } + a1 = op->s_alt + dis; + + if (a0 < 0 && a1 > 0 && !rise) { + /* found a rise event -- interate to refine */ + switch (find_0alt (10./3600., 5./SPD, dis, np, op)) { + case 0: /* ok */ + rp->rs_risetm = np->n_mjd; + rp->rs_riseaz = op->s_az; + rise = 1; + break; + case -1: /* obj_cir error */ + rp->rs_flags |= RS_RISERR; + return; + case -2: /* converged but not today */ /* FALLTHRU */ + case -3: /* probably never up */ + rp->rs_flags |= RS_NORISE; + return; + } + } else if (a0 > 0 && a1 < 0 && !set) { + /* found a setting event -- interate to refine */ + switch (find_0alt (10./3600., 5./SPD, dis, np, op)) { + case 0: /* ok */ + rp->rs_settm = np->n_mjd; + rp->rs_setaz = op->s_az; + set = 1; + break; + case -1: /* obj_cir error */ + rp->rs_flags |= RS_SETERR; + return; + case -2: /* converged but not today */ /* FALLTHRU */ + case -3: /* probably circumpolar */ + rp->rs_flags |= RS_NOSET; + return; + } + } + + t0 = t1; + a0 = a1; + } + + /* instead of transit, for satellites we find time of maximum + * altitude, if we know both the rise and set times. + */ + if (rise && set) { + double tt, al, az; + if (find_maxalt (np, op, rp->rs_risetm, rp->rs_settm, &tt, &al, &az) < 0) { + rp->rs_flags |= RS_TRANSERR; + return; + } + rp->rs_trantm = tt; + rp->rs_tranalt = al; + rp->rs_tranaz = az; + } else + rp->rs_flags |= RS_NOTRANS; + + /* check for some bad conditions */ + if (!rise) { + if (a0 > 0) + rp->rs_flags |= RS_CIRCUMPOLAR; + else + rp->rs_flags |= RS_NORISE; + } + if (!set) { + if (a0 < 0) + rp->rs_flags |= RS_NEVERUP; + else + rp->rs_flags |= RS_NOSET; + } +} + +/* given a Now at noon and a dt from np, in hours, for a first approximation + * to a rise or set event, refine the event by searching for when alt+dis = 0. + * return 0: if find one within 12 hours of noon with np and op set to the + * better time and circumstances; + * return -1: if error from obj_cir; + * return -2: if converges but not today; + * return -3: if does not converge at all (probably circumpolar or never up); + */ +static int +find_0alt ( +double dt, /* hours from initial np to first guess at event */ +double fstep, /* first step size, days */ +double dis, /* horizon displacement, rads */ +Now *np, /* working Now -- starts with mjd is noon, returns as answer */ +Obj *op) /* working object -- returns as answer */ +{ +#define TMACC (0.01/SPD) /* convergence accuracy, days; tight for stable az */ +#define MAXPASSES 20 /* max iterations to try */ +#define MAXSTEP (12.0/24.0) /* max time step,days (to detect flat)*/ + + double a0 = 0; + double mjdn = mjd; + int npasses; + + /* insure initial guess is today -- if not, move by 24 hours */ + if (dt < -12.0 && !find_0alt (dt+24, fstep, dis, np, op)) + return (0); + mjd = mjdn; + if (dt > 12.0 && !find_0alt (dt-24, fstep, dis, np, op)) + return (0); + mjd = mjdn; + + /* convert dt to days for remainder of algorithm */ + dt /= 24.0; + + /* use secant method to look for s_alt + dis == 0 */ + npasses = 0; + do { + double a1; + + mjd += dt; + if (obj_cir (np, op) < 0) + return (-1); + a1 = op->s_alt; + + dt = (npasses == 0) ? fstep : (dis+a1)*dt/(a0-a1); + a0 = a1; + + if (++npasses > MAXPASSES || fabs(dt) >= MAXSTEP) + return (-3); + + } while (fabs(dt)>TMACC); + // fprintf (stderr, "%s 0alt npasses = %d\n", op->o_name, npasses); + + /* return codes */ + return (fabs(mjdn-mjd) < .5 ? 0 : -2); + +#undef MAXPASSES +#undef MAXSTEP +#undef TMACC +} + +/* find when the given object transits. start the search when LST matches the + * object's RA at noon. + * if ok, return 0 with np and op set to the transit conditions; if can't + * converge return -1; if converges ok but not today return -2. + * N.B. we assume np is passed set to local noon. + */ +static int +find_transit (double dt, Now *np, Obj *op) +{ +#define MAXLOOPS 10 +#define MAXERR (1./3600.) /* hours */ + double mjdn = mjd; + double lst; + int i; + + /* insure initial guess is today -- if not, move by 24 hours */ + if (dt < -12.0) + dt += 24.0; + if (dt > 12.0) + dt -= 24.0; + + i = 0; + do { + mjd += dt/24.0; + if (obj_cir (np, op) < 0) + return (-1); + now_lst (np, &lst); + dt = (radhr(op->s_gaera) - lst); + if (dt < -12.0) + dt += 24.0; + if (dt > 12.0) + dt -= 24.0; + } while (++i < MAXLOOPS && fabs(dt) > MAXERR); + + /* fprintf (stderr, "%s find_transit loops = %d, dt = %g seconds\n", op->o_name, i, dt*3600); */ + + /* return codes */ + if (i == MAXLOOPS) + return (-1); + return (fabs(mjd - mjdn) < 0.5 ? 0 : -2); + +#undef MAXLOOPS +#undef MAXERR +} + +/* find the mjd time of max altitude between the given rise and set times. + * N.B. we assume *np and *op are working copies we can modify. + * return 0 if ok, else -1. + */ +static int +find_maxalt ( +Now *np, +Obj *op, +double tr, double ts, /* mjd of rise and set */ +double *tp, /* time of max altitude */ +double *alp, double *azp) /* max altitude and transit az at said time */ +{ +#define MAXLOOPS 100 /* max loops */ +#define MAXERR (1.0/SPD) /* days */ + + double l, r; /* times known to bracket max alt */ + double m1, m2; /* intermediate range points inside l and r */ + double a1, a2; /* alt at m1 and m2 */ + int nloops; /* max loop check */ + + /* want rise before set */ + while (ts < tr) + tr -= 1.0/op->es_n; + + /* init time bracket */ + l = tr; + r = ts; + + /* ternary search for max */ + for (nloops = 0; r - l > MAXERR && nloops < MAXLOOPS; nloops++) { + + mjd = m1 = (2*l + r)/3; + obj_cir (np, op); + a1 = op->s_alt; + + mjd = m2 = (l + 2*r)/3; + obj_cir (np, op); + a2 = op->s_alt; + + if (a1 < a2) + l = m1; + else + r = m2; + } + // fprintf (stderr, "tern nloops = %d\n", nloops); + if (nloops >= MAXLOOPS) + return (-1); + + /* best is between l and r */ + mjd = *tp = (l+r)/2; + obj_cir (np, op); + *alp = op->s_alt; + *azp = op->s_az; + + return (0); +#undef MAXERR +#undef MAXLOOPS +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: riset_cir.c,v $ $Date: 2013/01/06 01:12:57 $ $Revision: 1.18 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/satlib.h b/Common/Libraries/XEphemAstroLib/src/satlib.h new file mode 100644 index 000000000..31c34675c --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/satlib.h @@ -0,0 +1,206 @@ +#ifndef __SATLIB_H +#define __SATLIB_H + +/* $Id: satlib.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + +typedef struct _SatElem { + float se_XMO; + float se_XNODEO; + float se_OMEGAO; + float se_EO; + float se_XINCL; + float se_XNDD60; + float se_BSTAR; + float pad1; + double se_XNO; + double se_XNDT20; + double se_EPOCH; + struct { + unsigned int catno : 21; + unsigned int classif : 5; + unsigned int elnum : 10; + unsigned int year : 14; + unsigned int launch : 10; + unsigned int piece : 15; + unsigned int ephtype : 4; + unsigned int orbit : 17; + } se_id; +} SatElem; + +#if 0 +struct sat_loc { + double sl_X; + double sl_XDOT; + double sl_Y; + double sl_YDOT; + double sl_Z; + double sl_ZDOT; +}; +#endif + +struct sgp4_data { + unsigned int sgp4_flags; + unsigned int pad; + double sgp4_AODP; + double sgp4_AYCOF; + double sgp4_C1; + double sgp4_C4; + double sgp4_C5; + double sgp4_COSIO; + double sgp4_D2; + double sgp4_D3; + double sgp4_D4; + double sgp4_DELMO; + double sgp4_ETA; + double sgp4_OMGCOF; + double sgp4_OMGDOT; + double sgp4_SINIO; + double sgp4_SINMO; + double sgp4_T2COF; + double sgp4_T3COF; + double sgp4_T4COF; + double sgp4_T5COF; + double sgp4_X1MTH2; + double sgp4_X3THM1; + double sgp4_X7THM1; + double sgp4_XLCOF; + double sgp4_XMCOF; + double sgp4_XMDOT; + double sgp4_XNODCF; + double sgp4_XNODOT; + double sgp4_XNODP; +}; + +struct deep_data { + struct { + unsigned int IRESFL : 1; + unsigned int ISYNFL : 1; + } deep_flags; + double deep_s_SINIQ; + double deep_s_COSIQ; + double deep_s_OMGDT; + double deep_ATIME; + double deep_D2201; + double deep_D2211; + double deep_D3210; + double deep_D3222; + double deep_D4410; + double deep_D4422; + double deep_D5220; + double deep_D5232; + double deep_D5421; + double deep_D5433; + double deep_DEL1; + double deep_DEL2; + double deep_DEL3; + double deep_E3; + double deep_EE2; + double deep_FASX2; + double deep_FASX4; + double deep_FASX6; + double deep_OMEGAQ; + double deep_PE; + double deep_PINC; + double deep_PL; + double deep_SAVTSN; + double deep_SE2; + double deep_SE3; + double deep_SGH2; + double deep_SGH3; + double deep_SGH4; + double deep_SGHL; + double deep_SGHS; + double deep_SH2; + double deep_SH3; + double deep_SHS; + double deep_SHL; + double deep_SI2; + double deep_SI3; + double deep_SL2; + double deep_SL3; + double deep_SL4; + double deep_SSE; + double deep_SSG; + double deep_SSH; + double deep_SSI; + double deep_SSL; + double deep_STEP2; + double deep_STEPN; + double deep_STEPP; + double deep_THGR; + double deep_XFACT; + double deep_XGH2; + double deep_XGH3; + double deep_XGH4; + double deep_XH2; + double deep_XH3; + double deep_XI2; + double deep_XI3; + double deep_XL2; + double deep_XL3; + double deep_XL4; + double deep_XLAMO; + double deep_XLI; + double deep_XNI; + double deep_XNQ; + double deep_XQNCL; + double deep_ZMOL; + double deep_ZMOS; +}; + +struct sdp4_data { + double sdp4_AODP; /* dpa */ + double sdp4_AYCOF; + double sdp4_BETAO; /* dpa */ + double sdp4_BETAO2; /* dpa */ + double sdp4_C1; + double sdp4_C4; + double sdp4_COSG; /* dpa */ + double sdp4_COSIO; /* dpa */ + double sdp4_EOSQ; /* dpa */ + double sdp4_OMGDOT; /* dpa */ + double sdp4_SING; /* dpa */ + double sdp4_SINIO; /* dpa */ + double sdp4_T2COF; + double sdp4_THETA2; /* dpa */ + double sdp4_X1MTH2; + double sdp4_X3THM1; + double sdp4_X7THM1; + double sdp4_XLCOF; + double sdp4_XMDOT; /* dpa */ + double sdp4_XNODCF; + double sdp4_XNODOT; /* dpa */ + double sdp4_XNODP; /* dpa */ + + double sdp4_XMDF_seco; + double sdp4_OMGADF_seco; + double sdp4_XNODE_seco; + double sdp4_EM_seco; + double sdp4_XINC_seco; + double sdp4_XN_seco; + + double sdp4_E_pero; + double sdp4_XINC_pero; + double sdp4_OMGADF_pero; + double sdp4_XNODE_pero; + double sdp4_XMAM_pero; +}; + +typedef struct _SatData { + struct _SatElem *elem; + union { + struct sgp4_data *sgp4; + struct sdp4_data *sdp4; + } prop; + struct deep_data *deep; +} SatData; + +void sgp4(SatData *sat, Vec3 *pos, Vec3 *dpos, double t); + +void sdp4(SatData *sat, Vec3 *pos, Vec3 *dpos, double TSINCE); + +#endif /* __SATLIB_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: satlib.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/satmoon.c b/Common/Libraries/XEphemAstroLib/src/satmoon.c new file mode 100644 index 000000000..6e401c208 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/satmoon.c @@ -0,0 +1,510 @@ +/* saturn moon info */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <math.h> + +#include "astro.h" +#include "bdl.h" + +static int use_bdl (double JD, char *dir, MoonData md[S_NMOONS]); +static void bruton_saturn (Obj *sop, double JD, MoonData md[S_NMOONS]); +static void moonradec (double satsize, MoonData md[S_NMOONS]); +static void moonSVis (Obj *eop, Obj *sop, MoonData md[S_NMOONS]); +static void moonEVis (MoonData md[S_NMOONS]); +static void moonPShad (Obj *eop, Obj *sop, MoonData md[S_NMOONS]); +static void moonTrans (MoonData md[S_NMOONS]); + +/* moon table and a few other goodies and when it was last computed */ +static double mdmjd = -123456; +static MoonData smd[S_NMOONS] = { + {"Saturn", NULL}, + {"Mimas", "I"}, + {"Enceladus","II"}, + {"Tethys", "III"}, + {"Dione", "IV"}, + {"Rhea", "V"}, + {"Titan", "VI"}, + {"Hyperion","VII"}, + {"Iapetus", "VIII"}, +}; +static double sizemjd; +static double etiltmjd; +static double stiltmjd; + +/* These values are from the Explanatory Supplement. + * Precession degrades them gradually over time. + */ +#define POLE_RA degrad(40.58) /* RA of Saturn's north pole */ +#define POLE_DEC degrad(83.54) /* Dec of Saturn's north pole */ + + +/* get saturn info in md[0], moon info in md[1..S_NMOONS-1]. + * if !dir always use bruton model. + * if !sop caller just wants md[] for names + * N.B. we assume eop and sop are updated. + */ +void +saturn_data ( +double Mjd, /* mjd */ +char dir[], /* dir in which to look for helper files */ +Obj *eop, /* earth == Sun */ +Obj *sop, /* saturn */ +double *sizep, /* saturn's angular diam, rads */ +double *etiltp, double *stiltp, /* earth and sun tilts -- +S */ +double *polera, double *poledec,/* pole location */ +MoonData md[S_NMOONS]) /* return info */ +{ + double JD; + + /* always copy back at least for name */ + memcpy (md, smd, sizeof(smd)); + + /* pole */ + if (polera) *polera = POLE_RA; + if (poledec) *poledec = POLE_DEC; + + /* nothing else if repeat call or just want names */ + if (Mjd == mdmjd || !sop) { + if (sop) { + *sizep = sizemjd; + *etiltp = etiltmjd; + *stiltp = stiltmjd; + } + return; + } + JD = Mjd + MJD0; + + /* planet in [0] */ + md[0].ra = sop->s_ra; + md[0].dec = sop->s_dec; + md[0].mag = get_mag(sop); + md[0].x = 0; + md[0].y = 0; + md[0].z = 0; + md[0].evis = 1; + md[0].svis = 1; + + /* size is straight from sop */ + *sizep = degrad(sop->s_size/3600.0); + + /* Visual Magnitude of the Satellites */ + + md[1].mag = 13; md[2].mag = 11.8; md[3].mag = 10.3; md[4].mag = 10.2; + md[5].mag = 9.8; md[6].mag = 8.4; md[7].mag = 14.3; md[8].mag = 11.2; + + /* get tilts from sky and tel code */ + satrings (sop->s_hlat, sop->s_hlong, sop->s_sdist, eop->s_hlong, + eop->s_edist, JD, etiltp, stiltp); + + /* get moon x,y,z from BDL if possible, else Bruton's model */ + if (!dir || use_bdl (JD, dir, md) < 0) + bruton_saturn (sop, JD, md); + + /* set visibilities */ + moonSVis (eop, sop, md); + moonPShad (eop, sop, md); + moonEVis (md); + moonTrans (md); + + /* fill in moon ra and dec */ + moonradec (*sizep, md); + + /* save */ + mdmjd = Mjd; + etiltmjd = *etiltp; + stiltmjd = *stiltp; + sizemjd = *sizep; + memcpy (smd, md, sizeof(smd)); +} + +/* hunt for BDL file in dir[] and use if possible. + * return 0 if ok, else -1 + */ +static int +use_bdl ( +double JD, /* julian date */ +char dir[], /* directory */ +MoonData md[S_NMOONS]) /* fill md[1..NM-1].x/y/z for each moon */ +{ +#define SATRAU .0004014253 /* saturn radius, AU */ + double x[S_NMOONS], y[S_NMOONS], z[S_NMOONS]; + char buf[1024]; + FILE *fp; + char *fn; + int i; + + /* check ranges and appropriate data file */ + if (JD < 2451179.50000) /* Jan 1 1999 UTC */ + return (-1); + if (JD < 2455562.5) /* Jan 1 2011 UTC */ + fn = "saturne.9910"; + else if (JD < 2459215.5) /* Jan 1 2021 UTC */ + fn = "saturne.1020"; + else + return (-1); + + /* open */ + (void) sprintf (buf, "%s/%s", dir, fn); + fp = fopen (buf, "r"); + if (!fp) { + fprintf (stderr, "%s: %s\n", fn, strerror(errno)); + return (-1); + } + + /* use it */ + if ((i = read_bdl (fp, JD, x, y, z, buf)) < 0) { + fprintf (stderr, "%s: %s\n", fn, buf); + fclose (fp); + return (-1); + } + if (i != S_NMOONS-1) { + fprintf (stderr, "%s: BDL says %d moons, code expects %d", fn, + i, S_NMOONS-1); + fclose (fp); + return (-1); + } + + /* copy into md[1..NM-1] with our scale and sign conventions */ + for (i = 1; i < S_NMOONS; i++) { + md[i].x = x[i-1]/SATRAU; /* we want sat radii +E */ + md[i].y = -y[i-1]/SATRAU; /* we want sat radii +S */ + md[i].z = -z[i-1]/SATRAU; /* we want sat radii +front */ + } + + /* ok */ + fclose (fp); + return (0); +} + +/* */ +/* SS2TXT.BAS Dan Bruton, astro@tamu.edu */ +/* */ +/* This is a text version of SATSAT2.BAS. It is smaller, */ +/* making it easier to convert other languages (250 lines */ +/* compared to 850 lines). */ +/* */ +/* This BASIC program computes and displays the locations */ +/* of Saturn's Satellites for a given date and time. See */ +/* "Practical Astronomy with your Calculator" by Peter */ +/* Duffett-Smith and the Astronomical Almanac for explanations */ +/* of some of the calculations here. The code is included so */ +/* that users can make changes or convert to other languages. */ +/* This code was made using QBASIC (comes with DOS 5.0). */ +/* */ +/* ECD: merged with Sky and Tel, below, for better earth and sun ring tilt */ +/* */ + +/* ECD: BASICeze */ +#define FOR for +#define IF if +#define ELSE else +#define COS cos +#define SIN sin +#define TAN tan +#define ATN atan +#define ABS fabs +#define SQR sqrt + +/* find saturn moon data from Bruton's model */ +/* this originally computed +X:East +Y:North +Z:behind in [1..8] indeces. + * and +tilt:front south, rads + * then we adjust things in md[].x/y/z/mag to fit into our MoonData format. + */ +static void +bruton_saturn ( +Obj *sop, /* saturn */ +double JD, /* julian date */ +MoonData md[S_NMOONS]) /* fill md[1..NM-1].x/y/z for each moon */ +{ + /* ECD: code does not use [0]. + * ECD and why 11 here? seems like 9 would do + */ + double SMA[11], U[11], U0[11], PD[11]; + double X[S_NMOONS], Y[S_NMOONS], Z[S_NMOONS]; + + double P,TP,TE,EP,EE,RE0,RP0,RS; + double JDE,LPE,LPP,LEE,LEP; + double NN,ME,MP,VE,VP; + double LE,LP,RE,RP,DT,II,F,F1; + double RA,DECL; + double TVA,PVA,TVC,PVC,DOT1,INC,TVB,PVB,DOT2,INCI; + double TRIP,GAM,TEMPX,TEMPY,TEMPZ; + int I; + + /* saturn */ + RA = sop->s_ra; + DECL = sop->s_dec; + + /* ******************************************************************** */ + /* * * */ + /* * Constants * */ + /* * * */ + /* ******************************************************************** */ + P = PI / 180; + /* Orbital Rate of Saturn in Radians per Days */ + TP = 2 * PI / (29.45771 * 365.2422); + /* Orbital Rate of Earth in Radians per Day */ + TE = 2 * PI / (1.00004 * 365.2422); + /* Eccentricity of Saturn's Orbit */ + EP = .0556155; + /* Eccentricity of Earth's Orbit */ + EE = .016718; + /* Semimajor axis of Earth's and Saturn's orbit in Astronomical Units */ + RE0 = 1; RP0 = 9.554747; + /* Semimajor Axis of the Satellites' Orbit in Kilometers */ + SMA[1] = 185600; SMA[2] = 238100; SMA[3] = 294700; SMA[4] = 377500; + SMA[5] = 527200; SMA[6] = 1221600; SMA[7] = 1483000; SMA[8] = 3560100; + /* Eccentricity of Satellites' Orbit [Program uses 0] */ + /* Synodic Orbital Period of Moons in Days */ + PD[1] = .9425049; + PD[2] = 1.3703731; + PD[3] = 1.8880926; + PD[4] = 2.7375218; + PD[5] = 4.5191631; + PD[6] = 15.9669028; + PD[7] = 21.3174647; + PD[8] = 79.9190206; /* personal mail 1/14/95 */ + RS = 60330; /* Radius of planet in kilometers */ + + /* ******************************************************************** */ + /* * * */ + /* * Epoch Information * */ + /* * * */ + /* ******************************************************************** */ + JDE = 2444238.5; /* Epoch Jan 0.0 1980 = December 31,1979 0:0:0 UT */ + LPE = 165.322242 * P; /* Longitude of Saturn at Epoch */ + LPP = 92.6653974 * P; /* Longitude of Saturn`s Perihelion */ + LEE = 98.83354 * P; /* Longitude of Earth at Epoch */ + LEP = 102.596403 * P; /* Longitude of Earth's Perihelion */ + /* U0[I] = Angle from inferior geocentric conjuction */ + /* measured westward along the orbit at epoch */ + U0[1] = 18.2919 * P; + U0[2] = 174.2135 * P; + U0[3] = 172.8546 * P; + U0[4] = 76.8438 * P; + U0[5] = 37.2555 * P; + U0[6] = 57.7005 * P; + U0[7] = 266.6977 * P; + U0[8] = 195.3513 * P; /* from personal mail 1/14/1995 */ + + /* ******************************************************************** */ + /* * * */ + /* * Orbit Calculations * */ + /* * * */ + /* ******************************************************************** */ + /* ****************** FIND MOON ORBITAL ANGLES ************************ */ + NN = JD - JDE; /* NN = Number of days since epoch */ + ME = ((TE * NN) + LEE - LEP); /* Mean Anomoly of Earth */ + MP = ((TP * NN) + LPE - LPP); /* Mean Anomoly of Saturn */ + VE = ME; VP = MP; /* True Anomolies - Solve Kepler's Equation */ + FOR (I = 1; I <= 3; I++) { + VE = VE - (VE - (EE * SIN(VE)) - ME) / (1 - (EE * COS(VE))); + VP = VP - (VP - (EP * SIN(VP)) - MP) / (1 - (EP * COS(VP))); + } + VE = 2 * ATN(SQR((1 + EE) / (1 - EE)) * TAN(VE / 2)); + IF (VE < 0) VE = (2 * PI) + VE; + VP = 2 * ATN(SQR((1 + EP) / (1 - EP)) * TAN(VP / 2)); + IF (VP < 0) VP = (2 * PI) + VP; + /* Heliocentric Longitudes of Earth and Saturn */ + LE = VE + LEP; IF (LE > (2 * PI)) LE = LE - (2 * PI); + LP = VP + LPP; IF (LP > (2 * PI)) LP = LP - (2 * PI); + /* Distances of Earth and Saturn from the Sun in AU's */ + RE = RE0 * (1 - EE * EE) / (1 + EE * COS(VE)); + RP = RP0 * (1 - EP * EP) / (1 + EP * COS(VP)); + /* DT = Distance from Saturn to Earth in AU's - Law of Cosines */ + DT = SQR((RE * RE) + (RP * RP) - (2 * RE * RP * COS(LE - LP))); + /* II = Angle between Earth and Sun as seen from Saturn */ + II = RE * SIN(LE - LP) / DT; + II = ATN(II / SQR(1 - II * II)); /* ArcSIN and Law of Sines */ + /* F = NN - (Light Time to Earth in days) */ + F = NN - (DT / 173.83); + F1 = II + MP - VP; + /* U(I) = Angle from inferior geocentric conjuction measured westward */ + FOR (I = 1; I < S_NMOONS; I++) { + U[I] = U0[I] + (F * 2 * PI / PD[I]) + F1; + U[I] = ((U[I] / (2 * PI)) - (int)(U[I] / (2 * PI))) * 2 * PI; + + } + + /* **************** FIND INCLINATION OF RINGS ************************* */ + /* Use dot product of Earth-Saturn vector and Saturn's rotation axis */ + TVA = (90 - 83.51) * P; /* Theta coordinate of Saturn's axis */ + PVA = 40.27 * P; /* Phi coordinate of Saturn's axis */ + TVC = (PI / 2) - DECL; + PVC = RA; + DOT1 = SIN(TVA) * COS(PVA) * SIN(TVC) * COS(PVC); + DOT1 = DOT1 + SIN(TVA) * SIN(PVA) * SIN(TVC) * SIN(PVC); + DOT1 = DOT1 + COS(TVA) * COS(TVC); + INC = ATN(SQR(1 - DOT1 * DOT1) / DOT1); /* ArcCOS */ + IF (INC > 0) INC = (PI / 2) - INC; ELSE INC = -(PI / 2) - INC; + + /* ************* FIND INCLINATION OF IAPETUS' ORBIT ******************* */ + /* Use dot product of Earth-Saturn vector and Iapetus' orbit axis */ + /* Vector B */ + TVB = (90 - 75.6) * P; /* Theta coordinate of Iapetus' orbit axis (estimate) */ + PVB = 21.34 * 2 * PI / 24; /* Phi coordinate of Iapetus' orbit axis (estimate) */ + DOT2 = SIN(TVB) * COS(PVB) * SIN(TVC) * COS(PVC); + DOT2 = DOT2 + SIN(TVB) * SIN(PVB) * SIN(TVC) * SIN(PVC); + DOT2 = DOT2 + COS(TVB) * COS(TVC); + INCI = ATN(SQR(1 - DOT2 * DOT2) / DOT2); /* ArcCOS */ + IF (INCI > 0) INCI = (PI / 2) - INCI; ELSE INCI = -(PI / 2) - INCI; + + /* ************* FIND ROTATION ANGLE OF IAPETUS' ORBIT **************** */ + /* Use inclination of Iapetus' orbit with respect to ring plane */ + /* Triple Product */ + TRIP = SIN(TVC) * COS(PVC) * SIN(TVA) * SIN(PVA) * COS(TVB); + TRIP = TRIP - SIN(TVC) * COS(PVC) * SIN(TVB) * SIN(PVB) * COS(TVA); + TRIP = TRIP + SIN(TVC) * SIN(PVC) * SIN(TVB) * COS(PVB) * COS(TVA); + TRIP = TRIP - SIN(TVC) * SIN(PVC) * SIN(TVA) * COS(PVA) * COS(TVB); + TRIP = TRIP + COS(TVC) * SIN(TVA) * COS(PVA) * SIN(TVB) * SIN(PVB); + TRIP = TRIP - COS(TVC) * SIN(TVB) * COS(PVB) * SIN(TVA) * SIN(PVA); + GAM = -1 * ATN(TRIP / SQR(1 - TRIP * TRIP)); /* ArcSIN */ + + /* ******************************************************************** */ + /* * * */ + /* * Compute Moon Positions * */ + /* * * */ + /* ******************************************************************** */ + FOR (I = 1; I < S_NMOONS - 1; I++) { + X[I] = -1 * SMA[I] * SIN(U[I]) / RS; + Z[I] = -1 * SMA[I] * COS(U[I]) / RS; /* ECD */ + Y[I] = SMA[I] * COS(U[I]) * SIN(INC) / RS; + } + /* ************************* Iapetus' Orbit *************************** */ + TEMPX = -1 * SMA[8] * SIN(U[8]) / RS; + TEMPZ = -1 * SMA[8] * COS(U[8]) / RS; + TEMPY = SMA[8] * COS(U[8]) * SIN(INCI) / RS; + X[8] = TEMPX * COS(GAM) + TEMPY * SIN(GAM); /* Rotation */ + Z[8] = TEMPZ * COS(GAM) + TEMPY * SIN(GAM); + Y[8] = -1 * TEMPX * SIN(GAM) + TEMPY * COS(GAM); + +#ifdef SHOWALL + /* ******************************************************************** */ + /* * * */ + /* * Show Results * */ + /* * * */ + /* ******************************************************************** */ + printf (" Julian Date : %g\n", JD); + printf (" Right Ascension of Saturn : %g Hours\n", RA * 24 / (2 * PI)); + printf (" Declination of Saturn : %g\n", DECL / P); + printf (" Ring Inclination as seen from Earth : %g\n", -1 * INC / P); + printf (" Heliocentric Longitude of Saturn : %g\n", LP / P); + printf (" Heliocentric Longitude of Earth : %g\n", LE / P); + printf (" Sun-Saturn-Earth Angle : %g\n", II / P); + printf (" Distance between Saturn and Earth : %g AU = %g million miles\n", DT, (DT * 93)); + printf (" Light time from Saturn to Earth : %g minutes\n", DT * 8.28); + TEMP = 2 * ATN(TAN(165.6 * P / (2 * 3600)) / DT) * 3600 / P; + printf (" Angular Size of Saturn : %g arcsec\n", TEMP); + printf (" Major Angular Size of Saturn's Rings : %g arcsec\n", RS4 * TEMP / RS); + printf (" Minor Angular Size of Saturn's Rings : %g arcsec\n", ABS(RS4 * TEMP * SIN(INC) / RS)); +#endif + + /* copy into md[1..S_NMOONS-1] with our sign conventions */ + for (I = 1; I < S_NMOONS; I++) { + md[I].x = X[I]; /* we want +E */ + md[I].y = -Y[I]; /* we want +S */ + md[I].z = -Z[I]; /* we want +front */ + } +} + +/* given saturn loc in md[0].ra/dec and size, and location of each moon in + * md[1..NM-1].x/y in sat radii, find ra/dec of each moon in md[1..NM-1].ra/dec. + */ +static void +moonradec ( +double satsize, /* sat diameter, rads */ +MoonData md[S_NMOONS]) /* fill in RA and Dec */ +{ + double satrad = satsize/2; + double satra = md[0].ra; + double satdec = md[0].dec; + int i; + + for (i = 1; i < S_NMOONS; i++) { + double dra = satrad * md[i].x; + double ddec = satrad * md[i].y; + md[i].ra = satra + dra; + md[i].dec = satdec - ddec; + } +} + +/* set svis according to whether moon is in sun light */ +static void +moonSVis( +Obj *eop, /* earth == SUN */ +Obj *sop, /* saturn */ +MoonData md[S_NMOONS]) +{ + double esd = eop->s_edist; + double eod = sop->s_edist; + double sod = sop->s_sdist; + double soa = degrad(sop->s_elong); + double esa = asin(esd*sin(soa)/sod); + double h = sod*sop->s_hlat; + double nod = h*(1./eod - 1./sod); + double sca = cos(esa), ssa = sin(esa); + int i; + + for (i = 1; i < S_NMOONS; i++) { + MoonData *mdp = &md[i]; + double xp = sca*mdp->x + ssa*mdp->z; + double yp = mdp->y; + double zp = -ssa*mdp->x + sca*mdp->z; + double ca = cos(nod), sa = sin(nod); + double xpp = xp; + double ypp = ca*yp - sa*zp; + double zpp = sa*yp + ca*zp; + int outside = xpp*xpp + ypp*ypp > 1.0; + int infront = zpp > 0.0; + mdp->svis = outside || infront; + } +} + +/* set evis according to whether moon is geometrically visible from earth */ +static void +moonEVis (MoonData md[S_NMOONS]) +{ + int i; + + for (i = 1; i < S_NMOONS; i++) { + MoonData *mdp = &md[i]; + int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0; + int infront = mdp->z > 0.0; + mdp->evis = outside || infront; + } +} + +/* set pshad and sx,sy shadow info */ +static void +moonPShad( +Obj *eop, /* earth == SUN */ +Obj *sop, /* saturn */ +MoonData md[S_NMOONS]) +{ + int i; + + for (i = 1; i < S_NMOONS; i++) { + MoonData *mdp = &md[i]; + mdp->pshad = !plshadow (sop, eop, POLE_RA, POLE_DEC, mdp->x, + mdp->y, mdp->z, &mdp->sx, &mdp->sy); + } +} + + +/* set whether moons are transiting */ +static void +moonTrans (MoonData md[S_NMOONS]) +{ + int i; + + for (i = 1; i < S_NMOONS; i++) { + MoonData *mdp = &md[i]; + mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1; + } +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: satmoon.c,v $ $Date: 2007/07/24 18:15:28 $ $Revision: 1.8 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/satspec.h b/Common/Libraries/XEphemAstroLib/src/satspec.h new file mode 100644 index 000000000..0986dd789 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/satspec.h @@ -0,0 +1,43 @@ +#ifndef __SATSPEC_H +#define __SATSPEC_H + +/* $Id: satspec.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + +#include "sattypes.h" +#include "satlib.h" + +#define SGP4_SIMPLE 0x00000001 + +extern void init_deep(struct deep_data *deep); +void init_sdp4(struct sdp4_data *sdp); +char *tleerr(int); +int readtle(char *, char *, SatElem *); + +double current_jd(); + +double ut1_to_gha(double); + +void smallsleep(double t); + +double epoch_jd(double); + +double actan(double sinx, double cosx); + +double thetag(double EP, double *DS50); + +void dpinit(SatData *sat, double EQSQ, double SINIQ, double COSIQ, + double RTEQSQ, double AO, double COSQ2, double SINOMO, + double COSOMO, double BSQ, double XLLDOT, double OMGDT, + double XNODOT, double XNODP); + +void dpsec(SatData *sat, double *XLL, double *OMGASM, double *XNODES, + double *EM, double *XINC, double *XN, double T); + +void dpper(SatData *sat, double *EM, double *XINC, double *OMGASM, + double *XNODES, double *XLL, double T); + +#endif /* __SATSPEC_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: satspec.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/sattypes.h b/Common/Libraries/XEphemAstroLib/src/sattypes.h new file mode 100644 index 000000000..61891ff03 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/sattypes.h @@ -0,0 +1,28 @@ +#ifndef __SATTYPES_H +#define __SATTYPES_H + +/* $Id: sattypes.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + +typedef struct _Vec3 { + double x, y, z; +} Vec3; + + +typedef struct _LookAngle { + double az; + double el; + double r; +} LookAngle; + + +typedef struct _Geoloc { + double lt; + double ln; + double h; +} GeoLoc; + +#endif /* __SATTYPES_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: sattypes.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/sdp4.c b/Common/Libraries/XEphemAstroLib/src/sdp4.c new file mode 100644 index 000000000..54e575ce3 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/sdp4.c @@ -0,0 +1,430 @@ +#include <stdlib.h> +#include <math.h> +#undef SING + +#include "sattypes.h" +#include "vector.h" +#include "satspec.h" + +/* SDP4 3 NOV 80 */ +/* SUBROUTINE SDP4(IFLAG,TSINCE) + COMMON/E1/XMO,XNODEO,OMEGAO,EO,XINCL,XNO,XNDT2O, + 1 XNDD6O,BSTAR,X,Y,Z,XDOT,YDOT,ZDOT,EPOCH,DS50 + COMMON/C1/CK2,CK4,E6A,QOMS2T,S,TOTHRD, + 1 XJ3,XKE,XKMPER,XMNPDA,AE + DOUBLE PRECISION EPOCH, DS50 + */ + +#define XMO (sat->elem->se_XMO) +#define XNODEO (sat->elem->se_XNODEO) +#define OMEGAO (sat->elem->se_OMEGAO) +#define EO (sat->elem->se_EO) +#define XINCL (sat->elem->se_XINCL) +#define XNO (sat->elem->se_XNO) +#define XNDT20 (sat->elem->se_XNDT20) +#define XNDD60 (sat->elem->se_XNDD60) +#define BSTAR (sat->elem->se_BSTAR) +#define EPOCH (sat->elem->se_EPOCH) + +#define CK2 (5.413080e-04) +#define CK4 (6.209887e-07) +#define QOMS2T (1.880279e-09) +#define S (1.012229e+00) + +#define AE (1.0) +#define DE2RA (.174532925E-1) +#define E6A (1.E-6) +#define PI (3.14159265) +#define PIO2 (1.57079633) +#define QO (120.0) +#define SO (78.0) +#define TOTHRD (.66666667) +#define TWOPI (6.2831853) +#define X3PIO2 (4.71238898) +#define XJ2 (1.082616E-3) +#define XJ3 (-.253881E-5) +#define XJ4 (-1.65597E-6) +#define XKE (.743669161E-1) +#define XKMPER (6378.135) +#define XMNPDA (1440.) + +/* int IFLAG; */ + +#define X (pos->sl_X) +#define XDOT (pos->sl_XDOT) +#define Y (pos->sl_Y) +#define YDOT (pos->sl_YDOT) +#define Z (pos->sl_Z) +#define ZDOT (pos->sl_ZDOT) + +/* sat->prop.sdp4-> */ +#define AODP (sat->prop.sdp4->sdp4_AODP) +#define AYCOF (sat->prop.sdp4->sdp4_AYCOF) +#define BETAO (sat->prop.sdp4->sdp4_BETAO) +#define BETAO2 (sat->prop.sdp4->sdp4_BETAO2) +#define C1 (sat->prop.sdp4->sdp4_C1) +#define C4 (sat->prop.sdp4->sdp4_C4) +#define COSG (sat->prop.sdp4->sdp4_COSG) +#define COSIO (sat->prop.sdp4->sdp4_COSIO) +#define EOSQ (sat->prop.sdp4->sdp4_EOSQ) +#define OMGDOT (sat->prop.sdp4->sdp4_OMGDOT) +#define SING (sat->prop.sdp4->sdp4_SING) +#define SINIO (sat->prop.sdp4->sdp4_SINIO) +#define T2COF (sat->prop.sdp4->sdp4_T2COF) +#define THETA2 (sat->prop.sdp4->sdp4_THETA2) +#define X1MTH2 (sat->prop.sdp4->sdp4_X1MTH2) +#define X3THM1 (sat->prop.sdp4->sdp4_X3THM1) +#define X7THM1 (sat->prop.sdp4->sdp4_X7THM1) +#define XLCOF (sat->prop.sdp4->sdp4_XLCOF) +#define XMDOT (sat->prop.sdp4->sdp4_XMDOT) +#define XNODCF (sat->prop.sdp4->sdp4_XNODCF) +#define XNODOT (sat->prop.sdp4->sdp4_XNODOT) +#define XNODP (sat->prop.sdp4->sdp4_XNODP) + +#define XMDF_seco (sat->prop.sdp4->sdp4_XMDF_seco) +#define OMGADF_seco (sat->prop.sdp4->sdp4_OMGADF_seco) +#define XNODE_seco (sat->prop.sdp4->sdp4_XNODE_seco) +#define EM_seco (sat->prop.sdp4->sdp4_EM_seco) +#define XINC_seco (sat->prop.sdp4->sdp4_XINC_seco) +#define XN_seco (sat->prop.sdp4->sdp4_XN_seco) + +#define E_pero (sat->prop.sdp4->sdp4_E_pero) +#define XINC_pero (sat->prop.sdp4->sdp4_XINC_pero) +#define OMGADF_pero (sat->prop.sdp4->sdp4_OMGADF_pero) +#define XNODE_pero (sat->prop.sdp4->sdp4_XNODE_pero) +#define XMAM_pero (sat->prop.sdp4->sdp4_XMAM_pero) + +void +sdp4 (SatData *sat, Vec3 *pos, Vec3 *dpos, double TSINCE) +{ + int i; + + /* private temporary variables used only in init section */ + double A1,A3OVK2,AO,C2,COEF,COEF1,DEL1,DELO,EETA,ETA, + ETASQ,PERIGE,PINVSQ,PSISQ,QOMS24,S4,THETA4,TSI,X1M5TH,XHDOT1; + + /* private temporary variables */ + double A,AXN,AYN,AYNL,BETA,BETAL,CAPU,COS2U,COSEPW=0, + COSIK,COSNOK,COSU,COSUK,E,ECOSE,ELSQ,EM=0,EPW,ESINE,OMGADF,PL, + R,RDOT,RDOTK,RFDOT,RFDOTK,RK,SIN2U,SINEPW=0,SINIK,SINNOK, + SINU,SINUK,TEMP,TEMP1,TEMP2,TEMP3=0,TEMP4=0,TEMP5=0,TEMP6=0,TEMPA, + TEMPE,TEMPL,TSQ,U,UK,UX,UY,UZ,VX,VY,VZ,XINC=0,XINCK,XL,XLL,XLT, + XMAM,XMDF,XMX,XMY,XN,XNODDF,XNODE,XNODEK; + +#if 0 + A1=A3OVK2=AO=C2=COEF=COEF1=DEL1=DELO=EETA=ETA = signaling_nan(); + ETASQ=PERIGE=PINVSQ=PSISQ=QOMS24=S4=THETA4=TSI=X1M5TH=XHDOT1 = signaling_nan(); + + A=AXN=AYN=AYNL=BETA=BETAL=CAPU=COS2U=COSEPW = signaling_nan(); + COSIK=COSNOK=COSU=COSUK=E=ECOSE=ELSQ=EM=EPW=ESINE=OMGADF=PL = signaling_nan(); + R=RDOT=RDOTK=RFDOT=RFDOTK=RK=SIN2U=SINEPW=SINIK=SINNOK = signaling_nan(); + SINU=SINUK=TEMP=TEMP1=TEMP2=TEMP3=TEMP4=TEMP5=TEMP6=TEMPA = signaling_nan(); + TEMPE=TEMPL=TSQ=U=UK=UX=UY=UZ=VX=VY=VZ=XINC=XINCK=XL=XLL=XLT = signaling_nan(); + XMAM=XMDF=XMX=XMY=XN=XNODDF=XNODE=XNODEK = signaling_nan(); +#endif + + if(TSINCE != 0.0 && !sat->prop.sdp4) { + /* + * Yes, this is a recursive call. + */ + sdp4(sat, pos, dpos, 0.0); + } + +/* IF (IFLAG .EQ. 0) GO TO 100 */ +/* if(!IFLAG) */ + if(!sat->prop.sdp4) { + sat->prop.sdp4 = (struct sdp4_data *) malloc(sizeof(struct sdp4_data)); + +/* init_sdp4(sat->prop.sdp4); */ + +/* RECOVER ORIGINAL MEAN MOTION (XNODP) AND SEMIMAJOR AXIS (AODP) */ +/* FROM INPUT ELEMENTS */ + + A1=pow((XKE/XNO), TOTHRD); + COSIO=cos(XINCL); + THETA2=COSIO*COSIO; + X3THM1=3.0 * THETA2 - 1.0; + EOSQ = EO * EO; + BETAO2 = 1.0 - EOSQ; + BETAO = sqrt(BETAO2); + DEL1 = 1.5 * CK2 * X3THM1 / (A1 * A1 * BETAO * BETAO2); + AO = A1 * (1.0 - DEL1 * (0.5 * TOTHRD + + DEL1 * (1.0 + 134.0 / 81.0 * DEL1))); + DELO = 1.5 * CK2 * X3THM1 / (AO * AO * BETAO * BETAO2); + XNODP = XNO / (1.0 + DELO); + AODP = AO / (1.0 - DELO); + +/* INITIALIZATION */ + +/* FOR PERIGEE BELOW 156 KM, THE VALUES OF +* S AND QOMS2T ARE ALTERED */ + + S4 = S; + QOMS24 = QOMS2T; + PERIGE = (AODP * (1.0 - EO) - AE) * XKMPER; + +/* IF(PERIGE .GE. 156.) GO TO 10 */ + + if(PERIGE < 156.0) { + S4 = PERIGE - 78.0; + + if(PERIGE <= 98.0) { /* GO TO 9 */ + S4 = 20.0; + } + + QOMS24 = pow((120.0 - S4) * AE / XKMPER, 4.0); /* 9 */ + S4 = S4 / XKMPER + AE; + } + PINVSQ = 1.0 / (AODP * AODP * BETAO2 * BETAO2); /* 10 */ + SING = sin(OMEGAO); + COSG = cos(OMEGAO); + TSI = 1.0 / (AODP - S4); + ETA = AODP * EO * TSI; + ETASQ = ETA * ETA; + EETA = EO * ETA; + PSISQ = fabs(1.0 - ETASQ); + COEF = QOMS24 * pow(TSI, 4.0); + COEF1 = COEF / pow(PSISQ, 3.5); + C2 = COEF1 * XNODP * (AODP * (1.0 + 1.5 * ETASQ + + EETA * (4.0 + ETASQ)) + + .75 * CK2 * TSI / PSISQ * X3THM1 * + (8.0 + 3.0 * ETASQ * (8.0 + ETASQ))); + C1 = BSTAR * C2; + SINIO = sin(XINCL); + A3OVK2 = -XJ3 / CK2 * AE * AE * AE; /* A3OVK2=-XJ3/CK2*AE**3; */ + X1MTH2 = 1.0 - THETA2; + C4 = 2.0 * XNODP * COEF1 * AODP * BETAO2 * + (ETA * (2.0 + .5 * ETASQ) + EO * (.5 + 2.0 * ETASQ) - + 2.0 * CK2 * TSI / (AODP * PSISQ) * + (-3.0 * X3THM1 * (1.0 - 2.0 * EETA + ETASQ * + (1.5 - .5 * EETA)) + + .75 * X1MTH2 * (2.0 * ETASQ - EETA * + (1.0 + ETASQ)) * cos(2.0 * OMEGAO))); + THETA4 = THETA2 * THETA2; + TEMP1 = 3.0 * CK2 * PINVSQ * XNODP; + TEMP2 = TEMP1 * CK2 * PINVSQ; + TEMP3 = 1.25 * CK4 * PINVSQ * PINVSQ * XNODP; + XMDOT = XNODP + 0.5 * TEMP1 * BETAO * X3THM1 + .0625 * TEMP2 * BETAO * + (13.0 - 78.0 * THETA2 + 137.0 * THETA4); + X1M5TH=1.0 - 5.0 * THETA2; + OMGDOT = -.5 * TEMP1 * X1M5TH + .0625 * TEMP2 * + (7.0 - 114.0 * THETA2 + 395.0 * THETA4) + + TEMP3 * (3.0 - 36.0 * THETA2 + 49.0 * THETA4); + XHDOT1 = -TEMP1 * COSIO; + XNODOT = XHDOT1 + (.5 * TEMP2 * (4.0 - 19.0 * THETA2) + + 2.0 * TEMP3 * (3.0 - 7.0 * THETA2)) * COSIO; + XNODCF = 3.5 * BETAO2 * XHDOT1 * C1; + T2COF = 1.5 * C1; + XLCOF = .125 * A3OVK2 * SINIO * (3.0 + 5.0 * COSIO) / (1.0 + COSIO); + AYCOF = .25 * A3OVK2 * SINIO; + X7THM1 = 7.0 * THETA2 - 1.0; +/* 90 IFLAG=0 */ + +#ifdef SDP_DEEP_DEBUG + printf("calling dpinit\n"); + printf("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n", + EOSQ,SINIO,COSIO,BETAO,AODP,THETA2, + SING,COSG,BETAO2,XMDOT,OMGDOT,XNODOT,XNODP); +#endif + dpinit(sat, EOSQ, SINIO, COSIO, BETAO, AODP, THETA2, + SING, COSG, BETAO2, XMDOT, OMGDOT, XNODOT, XNODP); + +/* CALL DPINIT(EOSQ,SINIO,COSIO,BETAO,AODP,THETA2, + 1 SING,COSG,BETAO2,XMDOT,OMGDOT,XNODOT,XNODP) */ + +/* UPDATE FOR SECULAR GRAVITY AND ATMOSPHERIC DRAG */ + } + + XMDF = XMO + XMDOT * TSINCE; /* 100 */ + OMGADF = OMEGAO + OMGDOT * TSINCE; + XNODDF = XNODEO + XNODOT * TSINCE; + TSQ = TSINCE * TSINCE; + XNODE = XNODDF + XNODCF * TSQ; + TEMPA = 1.0 - C1 * TSINCE; + TEMPE = BSTAR * C4 * TSINCE; + TEMPL = T2COF * TSQ; + XN = XNODP; + + if(TSINCE == 0.0) { + XMDF_seco = XMDF; + OMGADF_seco = OMGADF; + XNODE_seco = XNODE; + EM_seco = EM; + XINC_seco = XINC; + XN_seco = XN; + } + + dpsec(sat, &XMDF, &OMGADF, &XNODE, &EM, &XINC, &XN, TSINCE); + + if(TSINCE == 0.0) { + XMDF_seco = XMDF - XMDF_seco; + OMGADF_seco = OMGADF - OMGADF_seco; + XNODE_seco = XNODE - XNODE_seco; + EM_seco = EM - EM_seco; + XINC_seco = XINC - XINC_seco; + XN_seco = XN - XN_seco; + +#if 0 + printf("XMDF_seco = %e\n", XMDF_seco); + printf("OMGADF_seco = %e\n", OMGADF_seco); + printf("XNODE_seco = %e\n", XNODE_seco); + printf("EM_seco = %e\n", EM_seco); + printf("XINC_seco = %e\n", XINC_seco); + printf("XN_seco = %e\n", XN_seco); +#endif + } + + /* + XMDF -= XMDF_seco; + OMGADF -= OMGADF_seco; + XNODE -= XNODE_seco; + EM -= EM_seco; + XINC -= XINC_seco; + XN -= XN_seco; + */ + + A = pow(XKE/XN, TOTHRD) * TEMPA * TEMPA; + E = EM - TEMPE; +#ifdef SDP_DEEP_DEBUG + printf("*** E = %f\n", E); +#endif + XMAM = XMDF + XNODP * TEMPL; +/* CALL DPPER(E,XINC,OMGADF,XNODE,XMAM) */ + +#ifdef SDP_DEEP_DEBUG + printf("%12s %12s %12s %12s %12s\n", + "E", "XINC", "OMGADF", "XNODE", "XMAM"); + printf("%12f %12f %12f %12f %12f\n", + E, XINC, OMGADF, XNODE, XMAM); +#endif + + if(TSINCE == 0.0) { + E_pero = E; + XINC_pero = XINC; + OMGADF_pero = OMGADF; + XNODE_pero = XNODE; + XMAM_pero = XMAM; + } + + dpper(sat, &E, &XINC, &OMGADF, &XNODE, &XMAM, TSINCE); + + if(TSINCE == 0.0) { + E_pero = E - E_pero; + XINC_pero = XINC - XINC_pero; + OMGADF_pero = OMGADF - OMGADF_pero; + XNODE_pero = XNODE - XNODE_pero; + XMAM_pero = XMAM - XMAM_pero; + +#if 0 + printf("E_pero = %e\n", E_pero); + printf("XINC_pero = %e\n", XINC_pero); + printf("OMGADF_pero = %e\n", OMGADF_pero); + printf("XNODE_pero = %e\n", XNODE_pero); + printf("XMAM_pero = %e\n\n", XMAM_pero); +#endif + } + + /* + E -= E_pero; + XINC -= XINC_pero; + OMGADF -= OMGADF_pero; + XNODE -= XNODE_pero; + XMAM -= XMAM_pero; + */ + XL = XMAM + OMGADF + XNODE; + BETA = sqrt(1.0 - E * E); + XN = XKE / pow(A, 1.5); + +/* LONG PERIOD PERIODICS */ + + AXN = E * cos(OMGADF); + TEMP=1./(A*BETA*BETA); + XLL=TEMP*XLCOF*AXN; + AYNL=TEMP*AYCOF; + XLT=XL+XLL; + AYN=E*sin(OMGADF)+AYNL; + +/* SOLVE KEPLERS EQUATION */ + + CAPU=fmod(XLT-XNODE, TWOPI); + TEMP2=CAPU; +/* DO 130 I=1,10*/ + for(i = 1; i < 10; i++) { + SINEPW=sin(TEMP2); + COSEPW=cos(TEMP2); + TEMP3=AXN*SINEPW; + TEMP4=AYN*COSEPW; + TEMP5=AXN*COSEPW; + TEMP6=AYN*SINEPW; + EPW=(CAPU-TEMP4+TEMP3-TEMP2)/(1.-TEMP5-TEMP6)+TEMP2; +/* IF(ABS(EPW-TEMP2) .LE. E6A) GO TO 140 */ + if(fabs(EPW-TEMP2) <= E6A) + break; + TEMP2=EPW; /* 130 */ + } + +/* SHORT PERIOD PRELIMINARY QUANTITIES */ + + ECOSE=TEMP5+TEMP6; /* 140 */ + ESINE=TEMP3-TEMP4; + ELSQ=AXN*AXN+AYN*AYN; + TEMP=1.-ELSQ; + PL=A*TEMP; + R=A*(1.-ECOSE); + TEMP1=1./R; + RDOT=XKE*sqrt(A)*ESINE*TEMP1; + RFDOT=XKE*sqrt(PL)*TEMP1; + TEMP2=A*TEMP1; + BETAL=sqrt(TEMP); + TEMP3=1./(1.+BETAL); + COSU=TEMP2*(COSEPW-AXN+AYN*ESINE*TEMP3); + SINU=TEMP2*(SINEPW-AYN-AXN*ESINE*TEMP3); + U=actan(SINU,COSU); + SIN2U=2.*SINU*COSU; + COS2U=2.*COSU*COSU-1.0; + TEMP=1./PL; + TEMP1=CK2*TEMP; + TEMP2=TEMP1*TEMP; + +/* UPDATE FOR SHORT PERIODICS */ + + RK=R*(1.-1.5*TEMP2*BETAL*X3THM1)+.5*TEMP1*X1MTH2*COS2U; + UK=U - .25 * TEMP2 * X7THM1 * SIN2U; + XNODEK=XNODE+1.5*TEMP2*COSIO*SIN2U; + XINCK=XINC+1.5*TEMP2*COSIO*SINIO*COS2U; + RDOTK=RDOT-XN*TEMP1*X1MTH2*SIN2U; + RFDOTK=RFDOT+XN*TEMP1*(X1MTH2*COS2U+1.5*X3THM1); + +/* ORIENTATION VECTORS */ + SINUK=sin(UK); + COSUK=cos(UK); + SINIK=sin(XINCK); + COSIK=cos(XINCK); + SINNOK=sin(XNODEK); + COSNOK=cos(XNODEK); + XMX=-SINNOK*COSIK; + XMY=COSNOK*COSIK; + UX=XMX*SINUK+COSNOK*COSUK; + UY=XMY*SINUK+SINNOK*COSUK; + UZ=SINIK*SINUK; + VX=XMX*COSUK-COSNOK*SINUK; + VY=XMY*COSUK-SINNOK*SINUK; + VZ=SINIK*COSUK; +#if 0 + printf("UX = %f VX = %f RK = %f RDOTK = %f RFDOTK = %f\n", + UX, VX, RK, RDOTK, RFDOTK); +#endif +/* POSITION AND VELOCITY */ + + pos->x = RK*UX; + pos->y = RK*UY; + pos->z = RK*UZ; + dpos->x = RDOTK*UX+RFDOTK*VX; + dpos->y = RDOTK*UY+RFDOTK*VY; + dpos->z = RDOTK*UZ+RFDOTK*VZ; +/* RETURN + END */ +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: sdp4.c,v $ $Date: 2002/12/26 05:43:07 $ $Revision: 1.5 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/sgp4.c b/Common/Libraries/XEphemAstroLib/src/sgp4.c new file mode 100644 index 000000000..e1b191acf --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/sgp4.c @@ -0,0 +1,401 @@ +#include <stdlib.h> +#include <math.h> + +#include "sattypes.h" +#include "vector.h" +#include "satspec.h" + +#define XMO (sat->elem->se_XMO) +#define XNODEO (sat->elem->se_XNODEO) +#define OMEGAO (sat->elem->se_OMEGAO) +#define EO (sat->elem->se_EO) +#define XINCL (sat->elem->se_XINCL) +#define XNO (sat->elem->se_XNO) +#define XNDT20 (sat->elem->se_XNDT20) +#define XNDD60 (sat->elem->se_XNDD60) +#define BSTAR (sat->elem->se_BSTAR) +#define EPOCH (sat->elem->se_EPOCH) + +#define X (pos->sl_X) +#define XDOT (pos->sl_XDOT) +#define Y (pos->sl_Y) +#define YDOT (pos->sl_YDOT) +#define Z (pos->sl_Z) +#define ZDOT (pos->sl_ZDOT) + +#define AODP (sat->prop.sgp4->sgp4_AODP) +#define AYCOF (sat->prop.sgp4->sgp4_AYCOF) +#define C1 (sat->prop.sgp4->sgp4_C1) +#define C4 (sat->prop.sgp4->sgp4_C4) +#define C5 (sat->prop.sgp4->sgp4_C5) +#define COSIO (sat->prop.sgp4->sgp4_COSIO) +#define D2 (sat->prop.sgp4->sgp4_D2) +#define D3 (sat->prop.sgp4->sgp4_D3) +#define D4 (sat->prop.sgp4->sgp4_D4) +#define DELMO (sat->prop.sgp4->sgp4_DELMO) +#define ETA (sat->prop.sgp4->sgp4_ETA) +#define OMGCOF (sat->prop.sgp4->sgp4_OMGCOF) +#define OMGDOT (sat->prop.sgp4->sgp4_OMGDOT) +#define SINIO (sat->prop.sgp4->sgp4_SINIO) +#define SINMO (sat->prop.sgp4->sgp4_SINMO) +#define T2COF (sat->prop.sgp4->sgp4_T2COF) +#define T3COF (sat->prop.sgp4->sgp4_T3COF) +#define T4COF (sat->prop.sgp4->sgp4_T4COF) +#define T5COF (sat->prop.sgp4->sgp4_T5COF) +#define X1MTH2 (sat->prop.sgp4->sgp4_X1MTH2) +#define X3THM1 (sat->prop.sgp4->sgp4_X3THM1) +#define X7THM1 (sat->prop.sgp4->sgp4_X7THM1) +#define XLCOF (sat->prop.sgp4->sgp4_XLCOF) +#define XMCOF (sat->prop.sgp4->sgp4_XMCOF) +#define XMDOT (sat->prop.sgp4->sgp4_XMDOT) +#define XNODCF (sat->prop.sgp4->sgp4_XNODCF) +#define XNODOT (sat->prop.sgp4->sgp4_XNODOT) +#define XNODP (sat->prop.sgp4->sgp4_XNODP) + +#define CK2 (5.413080e-04) +#define CK4 (6.209887e-07) +#define QOMS2T (1.880279e-09) +#define S (1.012229e+00) + +#define AE (1.0) +#define DE2RA (.174532925E-1) +#define E6A (1.E-12) +#define PI (3.14159265) +#define PIO2 (1.57079633) +#define QO (120.0) +#define SO (78.0) +#define TOTHRD (.66666667) +#define TWOPI (6.2831853) +#define X3PIO2 (4.71238898) +#define XJ2 (1.082616E-3) +#define XJ3 (-.253881E-5) +#define XJ4 (-1.65597E-6) +#define XKE (.743669161E-1) +#define XKMPER (6378.135) +#define XMNPDA (1440.0) + +/* compute position and velocity vectors for the satellite defined in sat->elem + * at its epoch + TSINCE. + */ +void +sgp4(SatData *sat, Vec3 *pos, Vec3 *dpos, double TSINCE) +{ + int i; + + double A1, A3OVK2, AO, BETAO, BETAO2, C1SQ, C2, C3, COEF, COEF1, + DEL1, DELO, EETA, EOSQ, ETASQ, PERIGE, PINVSQ, PSISQ, QOMS24, + S4, TEMP, TEMP1, TEMP2, TEMP3=0, THETA2, THETA4, TSI, X1M5TH, + XHDOT1; + + double A, AXN, AYN, AYNL, BETA, BETAL, CAPU, COS2U, COSEPW=0, COSIK, + COSNOK, COSU, COSUK, DELM, DELOMG, E, ECOSE, ELSQ, EPW, ESINE, + OMEGA, OMGADF, PL, R, RDOT, RDOTK, RFDOT, RFDOTK, RK, SIN2U, + SINEPW=0, SINIK, SINNOK, SINU, SINUK, TCUBE, TEMP4=0, TEMP5=0, TEMP6=0, + TEMPA, TEMPE, TEMPL, TFOUR, TSQ, U, UK, UX, UY, UZ, VX, VY, VZ, + XINCK, XL, XLL, XLT, XMDF, XMP, XMX, XMY, XN, XNODDF, XNODE, + XNODEK; + +#if 0 + A1 = A3OVK2 = AO = BETAO = BETAO2 = C1SQ = C2 = C3 = COEF = COEF1 = + DEL1 = DELO = EETA = EOSQ = ETASQ = PERIGE = PINVSQ = PSISQ = QOMS24 = + S4 = TEMP = TEMP1 = TEMP2 = TEMP3 = THETA2 = THETA4 = TSI = X1M5TH = + XHDOT1 = signaling_nan(); + + A = AXN = AYN = AYNL = BETA = BETAL = CAPU = COS2U = COSEPW = COSIK = + COSNOK = COSU = COSUK = DELM = DELOMG = E = ECOSE = ELSQ = EPW = + ESINE = OMEGA = OMGADF = PL = R = RDOT = RDOTK = RFDOT = RFDOTK = + RK = SIN2U = SINEPW = SINIK = SINNOK = SINU = SINUK = TCUBE = TEMP4 = + TEMP5 = TEMP6 = TEMPA = TEMPE = TEMPL = TFOUR = TSQ = U = UK = UX = + UY = UZ = VX = VY = VZ = XINCK = XL = XLL = XLT = XMDF = XMP = XMX = + XMY = XN = XNODDF = XNODE = XNODEK = signaling_nan(); +#endif + + if(!sat->prop.sgp4) { + sat->prop.sgp4 = (struct sgp4_data *) malloc(sizeof(struct sgp4_data)); + + /* + * RECOVER ORIGINAL MEAN MOTION (XNODP) AND SEMIMAJOR AXIS (AODP) + * FROM INPUT ELEMENTS + */ + + A1 = pow((XKE/XNO), TOTHRD); + COSIO = cos(XINCL); + THETA2 = COSIO * COSIO; + X3THM1 = 3.0 * THETA2 - 1.0; + EOSQ = EO * EO; + BETAO2 = 1.0 - EOSQ; + BETAO = sqrt(BETAO2); + DEL1 = 1.5 * CK2 * X3THM1 / (A1 * A1 * BETAO * BETAO2); + AO = A1 * (1.0 - DEL1 * (.5 * TOTHRD + + DEL1 * (1.0 + 134.0 /81.0 * DEL1))); + DELO = 1.5 * CK2 * X3THM1 / (AO * AO * BETAO * BETAO2); + XNODP = XNO / (1.0 + DELO); + AODP=AO / (1.0 - DELO); + + /* + * INITIALIZATION + * + * FOR PERIGEE LESS THAN 220 KILOMETERS, THE ISIMP FLAG IS SET AND + * THE EQUATIONS ARE TRUNCATED TO LINEAR VARIATION IN SQRT A AND + * QUADRATIC VARIATION IN MEAN ANOMALY. ALSO, THE C3 TERM, THE + * DELTA OMEGA TERM, AND THE DELTA M TERM ARE DROPPED. + */ + + sat->prop.sgp4->sgp4_flags = 0; + + /* IF((AODP*(1.-EO)/AE) .LT. (220./XKMPER+AE)) ISIMP=1 */ + + if((AODP * (1.0 - EO) / AE) < (220.0 / XKMPER + AE)) + sat->prop.sgp4->sgp4_flags |= SGP4_SIMPLE; + + /* + * FOR PERIGEE BELOW 156 KM, THE VALUES OF + * S AND QOMS2T ARE ALTERED + */ + + S4 = S; + QOMS24 = QOMS2T; + PERIGE = (AODP * (1.0 - EO) - AE) * XKMPER; + + if(PERIGE < 156.0) { + S4 = PERIGE - 78.0; + + if(PERIGE <= 98.0) + S4 = 20.0; + + QOMS24 = pow(((120.0 - S4) * AE / XKMPER), 4.0); + S4 = S4 / XKMPER + AE; + } + + PINVSQ=1.0 / (AODP * AODP * BETAO2 * BETAO2); + TSI = 1.0 / (AODP - S4); + ETA = AODP * EO * TSI; + ETASQ = ETA * ETA; + EETA = EO * ETA; + + PSISQ = fabs(1.0 - ETASQ); + + COEF = QOMS24 * pow(TSI, 4.0); + COEF1 = COEF / pow(PSISQ, 3.5); + + C2 = COEF1 * XNODP * (AODP * (1.0 + 1.5 * ETASQ + + EETA * (4.0 + ETASQ)) + .75 * + CK2 * TSI / + PSISQ * X3THM1 * (8.0 + + 3.0 * ETASQ * (8.0 + ETASQ))); + + + C1 = BSTAR * C2; + + SINIO = sin(XINCL); + + A3OVK2 = -XJ3 / CK2 * pow(AE, 3.0); + + C3 = COEF * TSI * A3OVK2 * XNODP * AE * SINIO / EO; + + X1MTH2 = 1.0 - THETA2; + C4 = 2.0 * XNODP * COEF1 * AODP * BETAO2 * + (ETA * (2.0 + .5 * ETASQ) + + EO * (.5 + 2.0 * ETASQ) - + 2.0 * CK2 * TSI / (AODP * PSISQ) * + (-3.0 * X3THM1 * (1.0 - 2.0 * EETA + ETASQ * (1.5 - .5 * EETA)) + + .75 * X1MTH2 * (2.0 * ETASQ - EETA * (1.0 + ETASQ)) * + cos(2.0 * OMEGAO))); + + C5 = 2.0 * COEF1 * AODP * BETAO2 * (1.0 + + 2.75 * (ETASQ + EETA) + + EETA * ETASQ); + THETA4 = THETA2 * THETA2; + TEMP1 = 3.0 * CK2 * PINVSQ * XNODP; + TEMP2 = TEMP1 * CK2 * PINVSQ; + TEMP3 = 1.25 * CK4 * PINVSQ * PINVSQ * XNODP; + + XMDOT = XNODP + + .5 * TEMP1 * BETAO * X3THM1 + + .0625 * TEMP2 * BETAO * (13.0 - 78.0 * THETA2 + 137.0 * THETA4); + + X1M5TH = 1.0 - 5.0 * THETA2; + + OMGDOT = -.5 * TEMP1 * X1M5TH + + .0625 * TEMP2 * (7.0 - 114.0 * THETA2 + 395.0 * THETA4) + + TEMP3 * (3.0 - 36.0 * THETA2 + 49.0 * THETA4); + + XHDOT1 = -TEMP1 * COSIO; + + XNODOT = XHDOT1 + (.5 * TEMP2 * (4.0 - 19.0 * THETA2) + + 2.0 * TEMP3 * (3.0 - 7.0 * THETA2)) * COSIO; + + OMGCOF = BSTAR * C3 * cos(OMEGAO); + + XMCOF = -TOTHRD * COEF * BSTAR * AE / EETA; + XNODCF = 3.5 * BETAO2 * XHDOT1 * C1; + T2COF = 1.5 * C1; + XLCOF = .125 * A3OVK2 * SINIO * (3.0 + 5.0 *COSIO) / (1.0 + COSIO); + + AYCOF = .25 * A3OVK2 * SINIO; + DELMO = pow(1.0 + ETA * cos(XMO), 3.0); + SINMO = sin(XMO); + + X7THM1 = 7.0 * THETA2 - 1.0; + +/* IF(ISIMP .EQ. 1) GO TO 90 */ + if(!(sat->prop.sgp4->sgp4_flags & SGP4_SIMPLE)) { + C1SQ = C1 * C1; + D2 = 4.0 * AODP * TSI * C1SQ; + TEMP = D2 * TSI * C1 / 3.0; + D3 = (17.0 * AODP + S4) * TEMP; + D4 = .5 * TEMP * AODP * TSI * (221.0 * AODP + 31.0 * S4) * C1; + T3COF = D2 + 2.0 * C1SQ; + T4COF = .25 * (3.0 * D3 + C1 * (12.0 * D2 + 10.0 * C1SQ)); + T5COF = .2 * (3.0 * D4 + + 12.0 * C1 * D3 + + 6.0 * D2 * D2 + + 15.0 * C1SQ * (2.0 * D2 + C1SQ)); + } + } + + /* + * UPDATE FOR SECULAR GRAVITY AND ATMOSPHERIC DRAG + */ + + XMDF = XMO + XMDOT * TSINCE; + OMGADF = OMEGAO + OMGDOT * TSINCE; + XNODDF = XNODEO + XNODOT * TSINCE; + OMEGA = OMGADF; + XMP = XMDF; + TSQ = TSINCE * TSINCE; + XNODE = XNODDF + XNODCF * TSQ; + TEMPA = 1.0 - C1 * TSINCE; + TEMPE = BSTAR * C4 * TSINCE; + TEMPL = T2COF * TSQ; + if(!(sat->prop.sgp4->sgp4_flags & SGP4_SIMPLE)) { + DELOMG = OMGCOF * TSINCE; + DELM = XMCOF * (pow(1.0 + ETA * cos(XMDF), 3) - DELMO); + TEMP = DELOMG + DELM; + XMP = XMDF + TEMP; + OMEGA = OMGADF - TEMP; + TCUBE = TSQ * TSINCE; + TFOUR = TSINCE * TCUBE; + TEMPA = TEMPA - D2 * TSQ - D3 * TCUBE - D4 * TFOUR; + TEMPE = TEMPE + BSTAR * C5 * (sin(XMP) - SINMO); + TEMPL = TEMPL + T3COF * TCUBE + TFOUR * (T4COF + TSINCE * T5COF); + } + + A = AODP * TEMPA * TEMPA; + E = EO - TEMPE; + XL = XMP + OMEGA + XNODE + XNODP * TEMPL; + BETA = sqrt(1.0 - E * E); + XN = XKE / pow(A, 1.5); + + /* + * LONG PERIOD PERIODICS + */ + + AXN = E * cos(OMEGA); + TEMP = 1.0 / (A * BETA * BETA); + XLL = TEMP * XLCOF * AXN; + AYNL = TEMP * AYCOF; + XLT = XL + XLL; + AYN = E * sin(OMEGA) + AYNL; + + /* + * SOLVE KEPLERS EQUATION + */ + + CAPU = fmod(XLT - XNODE, TWOPI); + TEMP2 = CAPU; + + for(i = 0; i < 10; i++) { + SINEPW = sin(TEMP2); + COSEPW = cos(TEMP2); + TEMP3 = AXN * SINEPW; + TEMP4 = AYN * COSEPW; + TEMP5 = AXN * COSEPW; + TEMP6 = AYN * SINEPW; + EPW = (CAPU - TEMP4 + TEMP3 - TEMP2) / (1.0 - TEMP5 - TEMP6) + TEMP2; + + if(fabs(EPW - TEMP2) <= E6A) + break; + + TEMP2 = EPW; + } + + /* + * SHORT PERIOD PRELIMINARY QUANTITIES + */ + + ECOSE = TEMP5 + TEMP6; + ESINE = TEMP3 - TEMP4; + ELSQ = AXN * AXN + AYN * AYN; + TEMP = 1.0 - ELSQ; + PL = A * TEMP; + R = A * (1.0 - ECOSE); + + TEMP1 = 1.0 / R; + RDOT = XKE * sqrt(A) * ESINE * TEMP1; + RFDOT = XKE * sqrt(PL) * TEMP1; + TEMP2 = A * TEMP1; + BETAL = sqrt(TEMP); + TEMP3 = 1.0 / (1.0 + BETAL); + + COSU = TEMP2 * (COSEPW - AXN + AYN * ESINE * TEMP3); + SINU = TEMP2 * (SINEPW - AYN - AXN * ESINE * TEMP3); + + U = actan(SINU, COSU); + + SIN2U = 2.0 * SINU * COSU; + COS2U = 2.0 * COSU * COSU - 1.0; + + TEMP = 1.0 / PL; + TEMP1 = CK2 * TEMP; + TEMP2 = TEMP1 * TEMP; + + /* + * UPDATE FOR SHORT PERIODICS + */ + + RK = R * (1.0 - 1.5 * TEMP2 * BETAL * X3THM1) + + .5 * TEMP1 * X1MTH2 * COS2U; + + UK = U - .25 * TEMP2 * X7THM1 * SIN2U; + + XNODEK = XNODE + 1.5 * TEMP2 * COSIO * SIN2U; + XINCK = XINCL + 1.5 * TEMP2 * COSIO * SINIO * COS2U; + RDOTK = RDOT - XN * TEMP1 * X1MTH2 * SIN2U; + RFDOTK = RFDOT + XN * TEMP1 * (X1MTH2 * COS2U + 1.5 * X3THM1); + + /* + * ORIENTATION VECTORS + */ + + SINUK = sin(UK); + COSUK = cos(UK); + SINIK = sin(XINCK); + COSIK = cos(XINCK); + SINNOK = sin(XNODEK); + COSNOK = cos(XNODEK); + + XMX = -SINNOK * COSIK; + XMY = COSNOK * COSIK; + UX = XMX * SINUK + COSNOK * COSUK; + UY = XMY * SINUK + SINNOK * COSUK; + UZ = SINIK * SINUK; + VX = XMX * COSUK - COSNOK * SINUK; + VY = XMY * COSUK - SINNOK * SINUK; + VZ = SINIK * COSUK; + + /* + * POSITION AND VELOCITY + */ + + pos->x = RK * UX; + pos->y = RK * UY; + pos->z = RK * UZ; + + dpos->x = RDOTK * UX + RFDOTK * VX; + dpos->y = RDOTK * UY + RFDOTK * VY; + dpos->z = RDOTK * UZ + RFDOTK * VZ; +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: sgp4.c,v $ $Date: 2012/10/01 00:05:23 $ $Revision: 1.5 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/sphcart.c b/Common/Libraries/XEphemAstroLib/src/sphcart.c new file mode 100644 index 000000000..9d216a8af --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/sphcart.c @@ -0,0 +1,43 @@ +#include <math.h> +#include <stdio.h> + +#include "astro.h" + +/* transformation from spherical to cartesian coordinates */ +void +sphcart ( +double l, double b, double r, /* source: spherical coordinates */ +double *x, double *y, double *z) /* result: rectangular coordinates */ +{ + double rcb = r * cos(b); + + *x = rcb * cos(l); + *y = rcb * sin(l); + *z = r * sin(b); +} + +/* transformation from cartesian to spherical coordinates */ +void +cartsph ( +double x, double y, double z, /* source: rectangular coordinates */ +double *l, double *b, double *r) /* result: spherical coordinates */ +{ + double rho = x*x + y*y; + + if (rho > 0) { /* standard case: off axis */ + *l = atan2(y, x); + range (l, 2*PI); + *b = atan2(z, sqrt(rho)); + *r = sqrt(rho + z*z); + } else { /* degenerate case; avoid math error */ + *l = 0.0; + if (z == 0.0) + *b = 0.0; + else + *b = (z > 0.0) ? PI/2. : -PI/2.; + *r = fabs(z); + } +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: sphcart.c,v $ $Date: 2006/08/28 00:20:27 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/sun.c b/Common/Libraries/XEphemAstroLib/src/sun.c new file mode 100644 index 000000000..6d92d5ec5 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/sun.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <math.h> + +#include "astro.h" +#include "vsop87.h" + +/* given the modified JD, mj, return the true geocentric ecliptic longitude + * of the sun for the mean equinox of the date, *lsn, in radians, the + * sun-earth distance, *rsn, in AU, and the latitude *bsn, in radians + * (since this is always <= 1.2 arcseconds, in can be neglected by + * calling with bsn = NULL). + * + * if the APPARENT ecliptic longitude is required, correct the longitude for + * nutation to the true equinox of date and for aberration (light travel time, + * approximately -9.27e7/186000/(3600*24*365)*2*pi = -9.93e-5 radians). + */ +void +sunpos (double mj, double *lsn, double *rsn, double *bsn) +{ + static double last_mj = -3691, last_lsn, last_rsn, last_bsn; + double ret[6]; + + if (mj == last_mj) { + *lsn = last_lsn; + *rsn = last_rsn; + if (bsn) *bsn = last_bsn; + return; + } + + vsop87(mj, SUN, 0.0, ret); /* full precision earth pos */ + + *lsn = ret[0] - PI; /* revert to sun pos */ + range (lsn, 2*PI); /* normalise */ + + last_lsn = *lsn; /* memorise */ + last_rsn = *rsn = ret[2]; + last_bsn = -ret[1]; + last_mj = mj; + + if (bsn) *bsn = last_bsn; /* assign only if non-NULL pointer */ +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: sun.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/thetag.c b/Common/Libraries/XEphemAstroLib/src/thetag.c new file mode 100644 index 000000000..36a96a7ee --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/thetag.c @@ -0,0 +1,90 @@ +#include <math.h> + +#include "deepconst.h" + +/* @(#) $Id: thetag.c,v 1.3 2000/10/07 05:12:17 ecdowney Exp $ */ + + +/* + * FUNCTION THETAG(EP) + * COMMON /E1/XMO,XNODEO,OMEGAO,EO,XINCL,XNO,XNDT2O,XNDD6O,BSTAR, + * 1 X,Y,Z,XDOT,YDOT,ZDOT,EPOCH,DS50 + * DOUBLE PRECISION EPOCH,D,THETA,TWOPI,YR,TEMP,EP,DS50 + * TWOPI=6.28318530717959D0 + * YR=(EP+2.D-7)*1.D-3 + * JY=YR + * YR=JY + * D=EP-YR*1.D3 + * IF(JY.LT.10) JY=JY+80 + * N=(JY-69)/4 + * IF(JY.LT.70) N=(JY-72)/4 + * DS50=7305.D0 + 365.D0*(JY-70) +N + D + * THETA=1.72944494D0 + 6.3003880987D0*DS50 + * TEMP=THETA/TWOPI + * I=TEMP + * TEMP=I + * THETAG=THETA-TEMP*TWOPI + * IF(THETAG.LT.0.D0) THETAG=THETAG+TWOPI + * RETURN + * END + */ + +/* FUNCTION THETAG(EP) */ +double +thetag(double EP, double *DS50) +{ + int JY, N, I; + double YR, D, THETA, TEMP, THETAG; + + YR = (EP + 2.0E-7) * 1.0E-3; + + JY = (int) YR; + + YR = JY; + + D = EP - YR * 1.0E3; + + if(JY < 10) + JY += 80; + + N = (JY - 69) / 4; + + if(JY < 70) + N = (JY - 72) / 4; + +/* printf("N = %d\n", N); */ + + *DS50 = 7305.0 + 365.0 * (JY-70) + N + D; + +/* printf("DS50 = %f\n", *DS50); */ + + THETA = 1.72944494 + 6.3003880987 * *DS50; + +/* printf("THETA = %f\n", THETA); */ + + TEMP = THETA / TWOPI; + + I = (int)TEMP; + TEMP = I; + + THETAG = THETA - TEMP * TWOPI; + + if(THETAG < 0.0) + THETAG += TWOPI; + + return THETAG; +} + +#if 0 +void main(int argc, char **argv) { + double ds50, gwa; + + if(argc >= 2) { + gwa = thetag(atof(argv[1]), &ds50); + printf("%f, %f\n", gwa, ds50); + } +} +#endif + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: thetag.c,v $ $Date: 2000/10/07 05:12:17 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/twobody.c b/Common/Libraries/XEphemAstroLib/src/twobody.c new file mode 100644 index 000000000..086bc577a --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/twobody.c @@ -0,0 +1,243 @@ +/* + * + * TWOBODY.C + * + * Computation of planetary position, two-body computation + * + * Paul Schlyter, 1987-06-15 + * + * Decreased EPSILON from 2E-4 to 3E-8, 1988-12-05 + * + * 1990-01-01: Bug fix in almost parabolic orbits: now the routine + * doesn't bomb there (an if block was too large) + * + * 2000-12-06: Donated to Elwood Downey if he wants to use it in XEphem + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + + +/* Constants used when solving Kepler's equation */ +#undef EPSILON +#define EPSILON 3E-8 +#undef INFINITY +#define INFINITY 1E+10 + +/* Math constants */ +#undef PI +#define PI 3.14159265358979323846 +#define RADEG ( 180.0 / PI ) +#define DEGRAD ( PI / 180.0 ) + +/* Trig functions in degrees */ +#define sind(x) sin(x*DEGRAD) +#define cosd(x) cos(x*DEGRAD) +#define atand(x) (RADEG*atan(x)) +#define atan2d(y,x) (RADEG*atan2(y,x)) + +/* Gauss' grav.-konstant */ +#define K 1.720209895E-2 +#define KD ( K * 180.0 / PI ) +#define K2 ( K / 2.0 ) + + + + +static double cubroot( double x ) +/* Cubic root */ +{ + double a,b; + + if ( x == 0.0 ) + return 0.0; + else + { + a = fabs(x); + b = exp( log(a) / 3.0 ); + return x > 0.0 ? b : -b; + } +} /* cubroot */ + + +static double rev180( double ang ) +/* Normalize angle to between +180 and -180 degrees */ +{ + return ang - 360.0 * floor(ang*(1.0/360.0) + 0.5); +} /* rev180 */ + + + +static double kepler( double m, double ex ) +/* + * Solves Kepler's equation + * m = mean anomaly + * ex = eccentricity + * kepler = eccentric anomaly + */ +{ + double m1, sinm, cosm, exd, exan, dexan, lim1, adko, adk, denom; + int converged; + + m1 = rev180(m); + sinm = sind(m1); + cosm = cosd(m1); + /* 1st approximation: */ + exan = atan2d(sinm,cosm-ex); + if ( ex > 0.008 ) + { /* Iteration formula: */ + exd = ex * RADEG; + lim1 = 1E-3 / ex; + adko = INFINITY; + denom = 1.0 - ex * cosd(exan); + do + { + dexan = (m1 + exd * sind(exan) - exan) / denom; + exan = exan + dexan; + adk = fabs(dexan); + converged = adk < EPSILON || adk >= adko ; + adko = adk; + if ( !converged && adk > lim1 ) + denom = 1.0 - ex * cosd(exan); + } while ( !converged ); + } + return exan; +} /* kepler */ + + +static void vr( double *v, double *r, double m, double e, double a ) +/* + * Elliptic orbits only: + * computes: v = true anomaly (degrees) + * r = radius vector (a.u.) + * from: m = mean anomaly (degrees) + * e = eccentricity + * a = semimajor axis (a.u.) + */ +{ + double ean, x, y; + + ean = kepler(m,e); + x = a*(cosd(ean)-e); + y = a*sqrt(1.-e*e)*sind(ean); + *r = sqrt(x*x+y*y); + *v = atan2d(y,x); +} /* vr */ + + +/* return 0 if ok, else -1 */ +int vrc( double *v, double *r, double tp, double e, double q ) +/* + * Elliptic, hyperbolic and near-parabolic orbits: + * computes: v = true anomaly (degrees) + * r = radius vector (a.u.) + * from: tp = time from perihelion (days) + * e = eccentricity + * q = perihelion distance (a.u.) + */ +{ + + double lambda; + + double a, b, w, w2, w4, c, c1, c2, c3, c5, a0, a1, a2, + a3, m, n, g, adgg, adgg2, gs, dg; + + if ( tp == 0.0 ) /* In perihelion */ + { + *v = 0.0; + *r = q; + return 0; + } + + + lambda = (1.0-e) / (1.0+e); + + if ( fabs(lambda) < 0.01 ) + { /* Near-parabolic orbits */ + a = K2 * sqrt((1.0+e)/(q*q*q)) * tp; + b = sqrt( 1.0 + 2.25*a*a ); + w = cubroot( b + 1.5*a ) - cubroot( b - 1.5*a ); + + /* Test if it's accuate enough to compute this as a near-parabolic orbit */ + if ( fabs(w*w*lambda) > 0.2 ) + { + if ( fabs(lambda) < 0.0002 ) + { + /* Sorry, but we cannot compute this at all -- we must give up! + * + * This happens very rarely, in orbits having an eccentricity + * some 2% away from 1.0 AND if the body is very very far from + * perihelion. E.g. a Kreutz sun-grazing comet having + * eccentricity near 0.98 or 1.02, and being outside + * the orbit of Pluto. For any reasonable orbit this will + * never happen in practice. + * + * You might want to code a more graceful error exit here though. + * + */ + printf( "\nNear-parabolic orbit: inaccurate result." + "\n e = %f, lambda = %f, w = %f", e, lambda, w ); + return -1; + } + else + { + /* We cannot compute this as a near-parabolic orbit, so let's + compute it as an elliptic or hyperbolic orbit instead. */ + goto ellipse_hyperbola; + } + } + + /* Go ahead computing the near-parabolic case */ + c = 1.0 + 1.0 / (w*w); + c1 = 1.0 / c; + c2 = c1*c1; + c3 = c1*c2; + c5 = c3*c2; + w2 = w*w; + w4 = w2*w2; + a0 = w; + a1 = 2.0 * w * (0.33333333 + 0.2*w2) * c1; + a2 = 0.2 * w * (7.0 + 0.14285714 * (33.0*w2+7.4*w4)) * c3; + a3 = 0.022857143 * (108.0 + 37.177777*w2 + 5.1111111*w4) * c5; + w = (( lambda * a3 + a2 ) * lambda + a1 ) * lambda + a0; + w2 = w*w; + *v = 2.0 * atand(w); + *r = q * (1+w2) / ( 1.0 + w2*lambda ); + return 0; /* Near-parabolic orbit */ + } + + +ellipse_hyperbola: + + if ( lambda > 0.0 ) + { /* Elliptic orbit: */ + a = q / (1.0-e); /* Semi-major axis */ + m = KD * tp / sqrt(a*a*a); /* Mean Anomaly */ + vr( v, r, m, e, a ); /* Solve Kepler's equation, etc */ + } + else + { /* Hyperbolic orbit: */ + a = q / (e-1.0); /* Semi-major axis */ + n = K * tp / sqrt(a*a*a); /* "Daily motion" */ + g = n/e; + adgg = INFINITY; + do + { + adgg2 = adgg; + gs = sqrt(g*g+1.0); + dg = -( e*g - log(g+gs) - n ) / ( e - 1.0/gs ); + g = g + dg; + adgg = fabs(dg/g); + } while ( adgg < adgg2 && adgg > 1E-5 ); + gs = sqrt(g*g+1.0); + *v = 2.0 * atand( sqrt( (e+1.0)/(e-1.0) ) * g / (gs+1.0) ); + *r = q * (1.0+e) / ( 1.0 + e*cosd(*v) ); + } + return 0; + +} /* vrc */ + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: twobody.c,v $ $Date: 2004/04/20 04:17:08 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/umoon.c b/Common/Libraries/XEphemAstroLib/src/umoon.c new file mode 100644 index 000000000..7b0c98257 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/umoon.c @@ -0,0 +1,270 @@ +/* uranus moon info */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <math.h> + +#include "astro.h" +#include "bdl.h" + +static int use_bdl (double jd, char *dir, MoonData md[U_NMOONS]); +static void moonradec (double usize, MoonData md[U_NMOONS]); +static void moonSVis (Obj *sop, Obj *uop, MoonData md[U_NMOONS]); +static void moonEVis (MoonData md[U_NMOONS]); +static void moonPShad (Obj *sop, Obj *uop, MoonData md[U_NMOONS]); +static void moonTrans (MoonData md[U_NMOONS]); + +/* moon table and a few other goodies and when it was last computed */ +static double mdmjd = -123456; +static MoonData umd[U_NMOONS] = { + {"Uranus", NULL}, + {"Ariel", "I"}, + {"Umbriel", "II"}, + {"Titania", "III"}, + {"Oberon", "IV"}, + {"Miranda", "V"}, +}; +static double sizemjd; /* size at last mjd */ + +/* These values are from the Explanatory Supplement. + * Precession degrades them gradually over time. + */ +#define POLE_RA degrad(257.43) /* RA of Uranus' north pole */ +#define POLE_DEC degrad(-15.10) /* Dec of Uranus' north pole */ + + +/* get uranus info in md[0], moon info in md[1..U_NMOONS-1]. + * if !uop caller just wants md[] for names + * N.B. we assume sop and uop are updated. + */ +void +uranus_data ( +double Mjd, /* mjd */ +char dir[], /* dir in which to look for helper files */ +Obj *sop, /* Sun */ +Obj *uop, /* uranus */ +double *sizep, /* u angular diam, rads */ +double *polera, double *poledec, /* pole location */ +MoonData md[U_NMOONS]) /* return info */ +{ + double JD; + + /* always copy back at least for name */ + memcpy (md, umd, sizeof(umd)); + + /* pole */ + if (polera) *polera = POLE_RA; + if (poledec) *poledec = POLE_DEC; + + /* nothing else if repeat call or just want names */ + if (Mjd == mdmjd || !uop) { + if (uop) { + *sizep = sizemjd; + } + return; + } + JD = Mjd + MJD0; + + /* planet in [0] */ + md[0].ra = uop->s_ra; + md[0].dec = uop->s_dec; + md[0].mag = get_mag(uop); + md[0].x = 0; + md[0].y = 0; + md[0].z = 0; + md[0].evis = 1; + md[0].svis = 1; + + /* size is straight from uop */ + *sizep = degrad(uop->s_size/3600.0); + + /* from Pasachoff/Menzel */ + + md[1].mag = 14.2; + md[2].mag = 14.8; + md[3].mag = 13.7; + md[4].mag = 14.0; + md[5].mag = 16.3; + + /* get moon x,y,z from BDL if possible */ + if (!dir || use_bdl (JD, dir, md) < 0) { + int i; + for (i = 1; i < U_NMOONS; i++) + md[i].x = md[i].y = md[i].z = 0.0; + fprintf (stderr, "No uranus model available\n"); + } + + /* set visibilities */ + moonSVis (sop, uop, md); + moonPShad (sop, uop, md); + moonEVis (md); + moonTrans (md); + + /* fill in moon ra and dec */ + moonradec (*sizep, md); + + /* save */ + mdmjd = Mjd; + sizemjd = *sizep; + memcpy (umd, md, sizeof(umd)); +} + +/* hunt for BDL file in dir[] and use if possible + * return 0 if ok, else -1 + */ +static int +use_bdl ( +double JD, /* julian date */ +char dir[], /* directory */ +MoonData md[U_NMOONS]) /* fill md[1..NM-1].x/y/z for each moon */ +{ +#define URAU .0001597 /* Uranus radius, AU */ + double x[U_NMOONS], y[U_NMOONS], z[U_NMOONS]; + char buf[1024]; + FILE *fp; + char *fn; + int i; + + /* check ranges and appropriate data file */ + if (JD < 2451179.50000) /* Jan 1 1999 UTC */ + return (-1); + if (JD < 2455562.5) /* Jan 1 2011 UTC */ + fn = "uranus.9910"; + else if (JD < 2459215.5) /* Jan 1 2021 UTC */ + fn = "uranus.1020"; + else + return (-1); + + /* open */ + (void) sprintf (buf, "%s/%s", dir, fn); + fp = fopen (buf, "r"); + if (!fp) { + fprintf (stderr, "%s: %s\n", fn, strerror(errno)); + return (-1); + } + + /* use it */ + if ((i = read_bdl (fp, JD, x, y, z, buf)) < 0) { + fprintf (stderr, "%s: %s\n", fn, buf); + fclose (fp); + return (-1); + } + if (i != U_NMOONS-1) { + fprintf (stderr, "%s: BDL says %d moons, code expects %d", fn, + i, U_NMOONS-1); + fclose (fp); + return (-1); + } + + /* copy into md[1..NM-1] with our scale and sign conventions */ + for (i = 1; i < U_NMOONS; i++) { + md[i].x = x[i-1]/URAU; /* we want u radii +E */ + md[i].y = -y[i-1]/URAU; /* we want u radii +S */ + md[i].z = -z[i-1]/URAU; /* we want u radii +front */ + } + + /* ok */ + fclose (fp); + return (0); +} + +/* given uranus loc in md[0].ra/dec and size, and location of each moon in + * md[1..NM-1].x/y in ura radii, find ra/dec of each moon in md[1..NM-1].ra/dec. + */ +static void +moonradec ( +double usize, /* ura diameter, rads */ +MoonData md[U_NMOONS]) /* fill in RA and Dec */ +{ + double urad = usize/2; + double ura = md[0].ra; + double udec = md[0].dec; + int i; + + for (i = 1; i < U_NMOONS; i++) { + double dra = urad * md[i].x; + double ddec = urad * md[i].y; + md[i].ra = ura + dra; + md[i].dec = udec - ddec; + } +} + +/* set svis according to whether moon is in sun light */ +static void +moonSVis( +Obj *sop, /* SUN */ +Obj *uop, /* uranus */ +MoonData md[U_NMOONS]) +{ + double esd = sop->s_edist; + double eod = uop->s_edist; + double sod = uop->s_sdist; + double soa = degrad(uop->s_elong); + double esa = asin(esd*sin(soa)/sod); + double h = sod*uop->s_hlat; + double nod = h*(1./eod - 1./sod); + double sca = cos(esa), ssa = sin(esa); + int i; + + for (i = 1; i < U_NMOONS; i++) { + MoonData *mdp = &md[i]; + double xp = sca*mdp->x + ssa*mdp->z; + double yp = mdp->y; + double zp = -ssa*mdp->x + sca*mdp->z; + double ca = cos(nod), sa = sin(nod); + double xpp = xp; + double ypp = ca*yp - sa*zp; + double zpp = sa*yp + ca*zp; + int outside = xpp*xpp + ypp*ypp > 1.0; + int infront = zpp > 0.0; + mdp->svis = outside || infront; + } +} + +/* set evis according to whether moon is geometrically visible from earth */ +static void +moonEVis (MoonData md[U_NMOONS]) +{ + int i; + + for (i = 1; i < U_NMOONS; i++) { + MoonData *mdp = &md[i]; + int outside = mdp->x*mdp->x + mdp->y*mdp->y > 1.0; + int infront = mdp->z > 0.0; + mdp->evis = outside || infront; + } +} + +/* set pshad and sx,sy shadow info */ +static void +moonPShad( +Obj *sop, /* SUN */ +Obj *uop, /* uranus */ +MoonData md[U_NMOONS]) +{ + int i; + + for (i = 1; i < U_NMOONS; i++) { + MoonData *mdp = &md[i]; + mdp->pshad = !plshadow (uop, sop, POLE_RA, POLE_DEC, mdp->x, + mdp->y, mdp->z, &mdp->sx, &mdp->sy); + } +} + +/* set whether moons are transiting */ +static void +moonTrans (MoonData md[U_NMOONS]) +{ + int i; + + for (i = 1; i < U_NMOONS; i++) { + MoonData *mdp = &md[i]; + mdp->trans = mdp->z > 0 && mdp->x*mdp->x + mdp->y*mdp->y < 1; + } +} + + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: umoon.c,v $ $Date: 2006/08/29 03:16:47 $ $Revision: 1.10 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/utc_gst.c b/Common/Libraries/XEphemAstroLib/src/utc_gst.c new file mode 100644 index 000000000..bc4d3bbf7 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/utc_gst.c @@ -0,0 +1,95 @@ +#include "astro.h" + +static double gmst0 (double mj); + +/* given a modified julian date, mj, and a universally coordinated time, utc, + * return greenwich mean siderial time, *gst. + * N.B. mj must be at the beginning of the day. + */ +void +utc_gst (double mj, double utc, double *gst) +{ + static double lastmj = -18981; + static double t0; + + if (mj != lastmj) { + t0 = gmst0(mj); + lastmj = mj; + } + *gst = (1.0/SIDRATE)*utc + t0; + range (gst, 24.0); +} + +/* given a modified julian date, mj, and a greenwich mean siderial time, gst, + * return universally coordinated time, *utc. + * N.B. mj must be at the beginning of the day. + */ +void +gst_utc (double mj, double gst, double *utc) +{ + static double lastmj = -10000; + static double t0; + + if (mj != lastmj) { + t0 = gmst0 (mj); + lastmj = mj; + } + *utc = gst - t0; + range (utc, 24.0); + *utc *= SIDRATE; +} + +/* gmst0() - return Greenwich Mean Sidereal Time at 0h UT; stern + */ +static double +gmst0 ( +double mj) /* date at 0h UT in julian days since MJD0 */ +{ + double T, x; + + T = ((int)(mj - 0.5) + 0.5 - J2000)/36525.0; + x = 24110.54841 + + (8640184.812866 + (0.093104 - 6.2e-6 * T) * T) * T; + x /= 3600.0; + range(&x, 24.0); + return (x); +} + +#ifdef TEST_GMST + +/* original routine by elwood; has a secular drift of 0.08s/cty */ +static double +tnaught (mj) +double mj; /* julian days since 1900 jan 0.5 */ +{ + double dmj; + int m, y; + double d; + double t, t0; + + mjd_cal (mj, &m, &d, &y); + cal_mjd (1, 0., y, &dmj); + t = dmj/36525; + t0 = 6.57098e-2 * (mj - dmj) - + (24 - (6.6460656 + (5.1262e-2 + (t * 2.581e-5))*t) - + (2400 * (t - (((double)y - 1900)/100)))); + range(&t0, 24.0); + return (t0); +} + +#include <stdlib.h> +main(argc, argv) + int argc; + char *argv[]; +{ + double mj, gst; + while (scanf("%lf", &mj) == 1) { + mj -= MJD0; + gst = tnaught(mj); + printf("%17.9f %10.7f %10.7f\n", mj + MJD0, gst, gmst0(mj)); + } +} +#endif + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: utc_gst.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.3 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/vector.h b/Common/Libraries/XEphemAstroLib/src/vector.h new file mode 100644 index 000000000..be1ec56c2 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/vector.h @@ -0,0 +1,19 @@ +#ifndef __SATVECTOR_H +#define __SATVECTOR_H + +/* $Id: vector.h,v 1.1 2000/09/25 17:21:25 ecdowney Exp $ */ + +#define dotp(A,B) ((A).x*(B).x+(A).y*(B).y+(A).z*(B).z) + +#define crossp(A,B,C) {(C).x=(A).y*(B).z-(A).z*(B).y;(C).y=(A).z*(B).x-(A).x*(B).z;(C).z=(A).x*(B).y-(A).y*(B).x;} + +#define vecabs(V) (sqrt((V).x*(V).x+(V).y*(V).y+(V).z*(V).z)) +#define vecsq(V) ((V).x*(V).x+(V).y*(V).y+(V).z*(V).z) +#define vecsub(A,B,C) {(C).x=(A).x-(B).x;(C).y=(A).y-(B).y;(C).z=(A).z-(B).z;} +#define vecscale(A,k) {(A).x*=(k);(A).y*=(k);(A).z*=(k);} + +#endif /* __SATVECTOR_H */ + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: vector.h,v $ $Date: 2000/09/25 17:21:25 $ $Revision: 1.1 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/vsop87.c b/Common/Libraries/XEphemAstroLib/src/vsop87.c new file mode 100644 index 000000000..57c2c8d79 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/vsop87.c @@ -0,0 +1,209 @@ +/* VSOP87 planetary theory + * + * currently uses version VSOP87D: + * heliocentric spherical, mean ecliptic of date. + * + * calculation of rates (daily changes) is optional; + * see header file for the necessary #define's + * + * rough orientation on calculation time, miliseconds + * on an HP 715/75, all planets Mercury to Neptune, prec=0.0: + * + * terms with rates without rates + * 3598 11 7.1 + * 31577 51 44 + * + * with secular terms for JD 2232395.0 19/12/1399 0h TDB: + * + * FULL PRECISION code (31577 terms), milliseconds + * prec terms rates no rates + * 1e-8 15086 62 36 + * 1e-7 10105 44 25 + * 1e-6 3725 20 13 + * 1e-5 1324 11 7.8 + * 1e-4 443 7.0 6.0 + * 1e-3 139 6.0 5.0 + * + * REDUCED PRECISION code (3598 terms), milliseconds + * prec terms rates no rates + * 1e-7 2463 9.9 5.5 + * 1e-6 1939 8.0 4.5 + * 1e-5 1131 4.9 2.9 + * 1e-4 443 2.2 1.5 + * 1e-3 139 1.0 0.9 + */ + +#include <math.h> + +#include "astro.h" +#include "vsop87.h" + +#define VSOP_A1000 365250.0 /* days per millenium */ +#define VSOP_MAXALPHA 5 /* max degree of time */ + +/****************************************************************** + * adapted from BdL FORTRAN Code; stern + * + * Reference : Bureau des Longitudes - PBGF9502 + * + * Object : calculate a VSOP87 position for a given time. + * + * Input : + * + * mj modified julian date, counted from J1900.0 + * time scale : dynamical time TDB. + * + * obj object number as in astro.h, NB: not for pluto + * + * prec relative precision + * + * if prec is equal to 0 then the precision is the precision + * p0 of the complete solution VSOP87. + * Mercury p0 = 0.6 10**-8 + * Venus p0 = 2.5 10**-8 + * Earth p0 = 2.5 10**-8 + * Mars p0 = 10.0 10**-8 + * Jupiter p0 = 35.0 10**-8 + * Saturn p0 = 70.0 10**-8 + * Uranus p0 = 8.0 10**-8 + * Neptune p0 = 42.0 10**-8 + * + * if prec is not equal to 0, let us say in between p0 and + * 10**-3, the precision is : + * for the positions : + * - prec*a0 au for the distances. + * - prec rad for the other variables. + * for the velocities : + * - prec*a0 au/day for the distances. + * - prec rad/day for the other variables. + * a0 is the semi-major axis of the body. + * + * Output : + * + * ret[6] array of the results (double). + * + * for spherical coordinates : + * 1: longitude (rd) + * 2: latitude (rd) + * 3: radius (au) + * #if VSOP_GETRATE: + * 4: longitude velocity (rad/day) + * 5: latitude velocity (rad/day) + * 6: radius velocity (au/day) + * + * return: error index (int) + * 0: no error. + * 2: object out of range [MERCURY .. NEPTUNE, SUN] + * 3: precision out of range [0.0 .. 1e-3] + ******************************************************************/ +int +vsop87 (double mj, int obj, double prec, double *ret) +{ + static double (*vx_map[])[3] = { /* data tables */ + vx_mercury, vx_venus, vx_mars, vx_jupiter, + vx_saturn, vx_uranus, vx_neptune, 0, vx_earth, + }; + static int (*vn_map[])[3] = { /* indexes */ + vn_mercury, vn_venus, vn_mars, vn_jupiter, + vn_saturn, vn_uranus, vn_neptune, 0, vn_earth, + }; + static double a0[] = { /* semimajor axes; for precision ctrl only */ + 0.39, 0.72, 1.5, 5.2, 9.6, 19.2, 30.1, 39.5, 1.0, + }; + double (*vx_obj)[3] = vx_map[obj]; /* VSOP87 data and indexes */ + int (*vn_obj)[3] = vn_map[obj]; + + double t[VSOP_MAXALPHA+1]; /* powers of time */ + double t_abs[VSOP_MAXALPHA+1]; /* powers of abs(time) */ + double q; /* aux for precision control */ + int i, cooidx, alpha; /* misc indexes */ + + if (obj == PLUTO || obj > SUN) + return (2); + + if (prec < 0.0 || prec > 1e-3) + return(3); + + /* zero result array */ + for (i = 0; i < 6; ++i) ret[i] = 0.0; + + /* time and its powers */ + t[0] = 1.0; + t[1] = (mj - J2000)/VSOP_A1000; + for (i = 2; i <= VSOP_MAXALPHA; ++i) t[i] = t[i-1] * t[1]; + t_abs[0] = 1.0; + for (i = 1; i <= VSOP_MAXALPHA; ++i) t_abs[i] = fabs(t[i]); + + /* precision control */ + q = -log10(prec + 1e-35) - 2; /* decades below 1e-2 */ + q = VSOP_ASCALE * prec / 10.0 / q; /* reduce threshold progressively + * for higher precision */ + + /* do the term summation; first the spatial dimensions */ + for (cooidx = 0; cooidx < 3; ++cooidx) { + + /* then the powers of time */ + for (alpha = 0; vn_obj[alpha+1][cooidx] ; ++alpha) { + double p, term, termdot; + + /* precision threshold */ + p= alpha ? q/(t_abs[alpha] + alpha*t_abs[alpha-1]*1e-4 + 1e-35) : q; +#if VSOP_SPHERICAL + if (cooidx == 2) /* scale by semimajor axis for radius */ +#endif + p *= a0[obj]; + + term = termdot = 0.0; + for (i = vn_obj[alpha][cooidx]; i < vn_obj[alpha+1][cooidx]; ++i) { + double a, b, c, arg; + + a = vx_obj[i][0]; + if (a < p) continue; /* ignore small terms */ + + b = vx_obj[i][1]; + c = vx_obj[i][2]; + + arg = b + c * t[1]; + term += a * cos(arg); +#if VSOP_GETRATE + termdot += -c * a * sin(arg); +#endif + } + + ret[cooidx] += t[alpha] * term; +#if VSOP_GETRATE + ret[cooidx + 3] += t[alpha] * termdot + + ((alpha > 0) ? alpha * t[alpha - 1] * term : 0.0); +#endif + } /* alpha */ + } /* cooidx */ + + for (i = 0; i < 6; ++i) ret[i] /= VSOP_ASCALE; + +#if VSOP_SPHERICAL + /* reduce longitude to 0..2pi */ + ret[0] -= floor(ret[0]/(2.*PI)) * (2.*PI); +#endif + +#if VSOP_GETRATE + /* convert millenium rate to day rate */ + for (i = 3; i < 6; ++i) ret[i] /= VSOP_A1000; +#endif + +#if VSOP_SPHERICAL + /* reduction from dynamical equinox of VSOP87 to FK5; + */ + if (prec < 5e-7) { /* 5e-7 rad = 0.1 arc seconds */ + double L1, c1, s1; + L1 = ret[0] - degrad(13.97 * t[1] - 0.031 * t[2]); + c1 = cos(L1); s1 = sin(L1); + ret[0] += degrad(-0.09033 + 0.03916 * (c1 + s1) * tan(ret[1]))/3600.0; + ret[1] += degrad(0.03916 * (c1 - s1))/3600.0; + } +#endif + + return (0); +} + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: vsop87.c,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.4 $ $Name: $"}; diff --git a/Common/Libraries/XEphemAstroLib/src/vsop87.h b/Common/Libraries/XEphemAstroLib/src/vsop87.h new file mode 100644 index 000000000..b5cb958f5 --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/vsop87.h @@ -0,0 +1,93 @@ +/* Position of planets mercury to neptune; from: +ftp://ftp.bdl.fr/pub/ephem/planets/vsop87/ +from README: + +========================== =========================== + BUREAU DES LONGITUDES + PLANETARY SOLUTION VSOP87 + 1996, January +========================== =========================== + +These files and programs are associated to : + +Planetary Theories in rectangular and spherical variables: VSOP87 solution. + Bretagnon P., Francou G. + Astron. Astrophys. 202, 309 (1988). + +Theorie du mouvement de l'ensemble des planetes (VSOP82). + Bretagnon P. + Astron. Astrophys. 114, 278 (1982). + +============================================================================== + +Description: + The Planetary solutions VSOP87 (Variations Seculaires des Orbites + Planetaires) are analytical solutions of the motion of the planets in + different versions. The main version VSOP87 consists of the series in + elliptic elements as in the case of VSOP82 solution and the other + versions VSOP87 (A-B-C-D-E) are built in rectangular and spherical + variables. + +Authors' Address: + P. Bretagnon, G. Francou + Bureau des Longitudes, CNRS URA 707 + 77, Avenue Denfert-Rochereau + 75014, Paris, France + Tel : (33) 1 40 51 22 69 (33) 1 40 51 22 60 + Fax : (33) 1 46 33 28 34 + E-mail : pierre@bdl.fr francou@bdl.fr + +Contents: + The main version of VSOP87 is similar to the previous theory VSOP82. + In the both cases the constants of integration have been determined by + fitting to the numerical integration DE200 of the Jet Propulsion + Laboratory. The various versions of VSOP87 are different from one to + another in the type of coordinates and the reference frame. + VSOP87 : heliocentric elliptic variables; equinox and ecliptic J2000. + VSOP87A : heliocentric rectangular variables; equinox and ecliptic J2000. + VSOP87B : heliocentric spherical variables; equinox and ecliptic J2000. + VSOP87C : heliocentric rectangular variables; equinox and ecliptic of date. + VSOP87D : heliocentric spherical variables; equinox and ecliptic of date. + VSOP87E : barycentric rectangular variables; equinox and ecliptic J2000. +... +============================================================================== +User feed-back is encouraged. Unless otherwise specified, send comments and bug +reports to: E-mail : comments@bdl.fr + Fax : (33) 1 46 33 28 34 + Postal mail: Bureau des longitudes + 77 avenue Denfert Rochereau + F-75014 PARIS +============================================================================== + implemented for C: stern +*/ + +#define VSOP_ASCALE 1e8 /* amplitude factor as stored */ + +/* coding flags */ +#define VSOP_SPHERICAL 1 /* version in data.c uses spherical coords */ +#define VSOP_GETRATE 0 /* calculate time derivatives of coordinates */ + +/* data tables */ +extern double vx_mercury[][3]; +extern int vn_mercury[][3]; +extern double vx_venus[][3]; +extern int vn_venus[][3]; +extern double vx_earth[][3]; +extern int vn_earth[][3]; +extern double vx_mars[][3]; +extern int vn_mars[][3]; +extern double vx_jupiter[][3]; +extern int vn_jupiter[][3]; +extern double vx_saturn[][3]; +extern int vn_saturn[][3]; +extern double vx_uranus[][3]; +extern int vn_uranus[][3]; +extern double vx_neptune[][3]; +extern int vn_neptune[][3]; + +extern int vsop87 (double mj, int obj, double prec, double *ret); + + +/* For RCS Only -- Do Not Edit + * @(#) $RCSfile: vsop87.h,v $ $Date: 2003/03/20 08:51:37 $ $Revision: 1.2 $ $Name: $ + */ diff --git a/Common/Libraries/XEphemAstroLib/src/vsop87_data.c b/Common/Libraries/XEphemAstroLib/src/vsop87_data.c new file mode 100644 index 000000000..360c3865e --- /dev/null +++ b/Common/Libraries/XEphemAstroLib/src/vsop87_data.c @@ -0,0 +1,6988 @@ +/* data tables for planetary solution VSOP87 + * + * created by automatic conversion from original distribution files at + * ftp://ftp.bdl.fr/pub/ephem/planets/vsop87/ + * + * Each coordinate is calculated as: + * + * x = Sum{ T^alpha * A * cos( B + C*T ) } + * + * x is the coordinate in rad or a.u. + * T is the VSOP time in Julian Millenia(!) since J2000.0 + * Note: the time argument in VSOP87 theory is equal to TAI + 32.184 s + * + * A (scaled by VSOP_ASCALE), B, C given below for each x and alpha + * run-of-the mill for each planet in one array vx_planet[][3]. + * The block-boundary indices for each spatial dimension are then listed + * in a separate array vn_planet[][3]. + * + * Truncation errors given in comments are from the authors' empirical + * formula: 2*sqrt(number of retained terms)*A[last retained] + */ + +/* version d4 (lbr) + * heliocentric dynamical ecliptic and equinox of the date + */ + +double vx_earth[][3] = { + /* earth l, T^0 */ + { 175347045.7, 0, 0 }, + { 3341656.5, 4.66925680, 6283.07584999 }, + { 34894.3, 4.626102, 12566.151700 }, + { 3417.6, 2.82887, 3.52312 }, + { 3497.1, 2.74412, 5753.38488 }, + { 3135.9, 3.62767, 77713.77147 }, + { 2676.2, 4.41808, 7860.41939 }, + { 2342.7, 6.13516, 3930.20970 }, + { 1273.2, 2.03710, 529.69097 }, + { 1324.3, 0.74246, 11506.76977 }, + { 901.9, 2.0451, 26.2983 }, + { 1199.2, 1.10963, 1577.34354 }, + { 857.2, 3.5085, 398.1490 }, + { 779.8, 1.1788, 5223.6939 }, + { 990.2, 5.2327, 5884.9268 }, + { 753.1, 2.5334, 5507.5532 }, + { 505.3, 4.5829, 18849.2275 }, + { 492.4, 4.2051, 775.5226 }, + { 356.7, 2.9195, 0.0673 }, + { 284.1, 1.8987, 796.2980 }, + { 242.8, 0.3448, 5486.7778 }, + { 317.1, 5.8490, 11790.6291 }, + { 271.0, 0.3149, 10977.0788 }, + { 206.2, 4.8065, 2544.3144 }, + { 205.4, 1.8695, 5573.1428 }, + { 202.3, 2.4577, 6069.7768 }, + { 126.2, 1.0830, 20.7754 }, + { 155.5, 0.8331, 213.2991 }, + { 115.1, 0.6454, 0.9803 }, + { 102.9, 0.6360, 4694.0030 }, + { 101.7, 4.2668, 7.1135 }, + { 99.2, 6.210, 2146.165 }, + { 132.2, 3.4112, 2942.4634 }, + { 97.6, 0.681, 155.420 }, + { 85.1, 1.299, 6275.962 }, + { 74.7, 1.755, 5088.629 }, + { 101.9, 0.9757, 15720.8388 }, + { 84.7, 3.671, 71430.696 }, + { 73.5, 4.679, 801.821 }, + { 73.9, 3.503, 3154.687 }, + { 78.8, 3.037, 12036.461 }, + { 79.6, 1.808, 17260.155 }, + { 85.8, 5.983, 161000.686 }, + { 57.0, 2.784, 6286.599 }, + { 61.1, 1.818, 7084.897 }, + { 69.6, 0.833, 9437.763 }, + { 56.1, 4.387, 14143.495 }, + { 62.4, 3.978, 8827.390 }, + { 51.1, 0.283, 5856.478 }, + { 55.6, 3.470, 6279.553 }, + { 41.0, 5.368, 8429.241 }, + { 51.6, 1.333, 1748.016 }, + { 52.0, 0.189, 12139.554 }, + { 49.0, 0.487, 1194.447 }, + { 39.2, 6.168, 10447.388 }, + { 35.6, 1.776, 6812.767 }, + { 36.8, 6.041, 10213.286 }, + { 36.6, 2.570, 1059.382 }, + { 33.3, 0.593, 17789.846 }, + { 36.0, 1.709, 2352.866 }, + { 40.9, 2.399, 19651.048 }, + { 30.0, 2.740, 1349.867 }, + { 30.4, 0.443, 83996.847 }, + { 23.7, 0.485, 8031.092 }, + { 23.6, 2.065, 3340.612 }, + { 21.1, 4.148, 951.718 }, + { 24.7, 0.215, 3.590 }, + { 25.4, 3.165, 4690.480 }, + { 22.8, 5.222, 4705.732 }, + { 21.4, 1.426, 16730.464 }, + { 21.9, 5.556, 553.569 }, + { 17.5, 4.561, 135.065 }, + { 19.9, 5.222, 12168.003 }, + { 19.9, 5.775, 6309.374 }, + { 20.3, 0.371, 283.859 }, + { 14.4, 4.193, 242.729 }, + { 16.2, 5.988, 11769.854 }, + { 15.1, 4.196, 6256.778 }, + { 19.1, 3.822, 23581.258 }, + { 18.9, 5.386, 149854.400 }, + { 14.3, 3.724, 38.028 }, + { 17.9, 2.215, 13367.973 }, + { 12.1, 2.622, 955.600 }, + { 11.3, 0.177, 4164.312 }, + { 14.0, 4.401, 6681.225 }, + { 13.6, 1.889, 7632.943 }, + { 12.5, 1.131, 5.523 }, + { 10.5, 5.359, 1592.596 }, + { 9.8, 1.00, 11371.70 }, + { 9.2, 4.57, 4292.33 }, + { 10.3, 6.200, 6438.496 }, + { 12.0, 1.004, 632.784 }, + { 10.8, 0.327, 103.093 }, + { 8.4, 4.54, 25132.30 }, + { 10.0, 6.029, 5746.271 }, + { 8.4, 3.30, 7234.79 }, + { 8.0, 5.82, 28.45 }, + { 10.5, 0.939, 11926.254 }, + { 7.7, 3.12, 7238.68 }, + { 9.4, 2.62, 5760.50 }, + { 8.1, 6.11, 4732.03 }, + { 9.2, 0.48, 522.58 }, + { 9.8, 5.24, 27511.47 }, + { 7.9, 1.00, 5643.18 }, + { 8.1, 6.27, 426.60 }, + { 9.0, 5.34, 6386.17 }, + { 8.6, 4.17, 7058.60 }, + { 6.3, 4.72, 6836.65 }, + { 7.6, 3.97, 11499.66 }, + { 7.8, 2.96, 23013.54 }, + { 7.3, 0.61, 11513.88 }, + { 6.5, 5.79, 18073.70 }, + { 7.2, 4.00, 74.78 }, + { 7.3, 4.39, 316.39 }, + { 7.1, 0.32, 263.08 }, + { 6.6, 3.66, 17298.18 }, + { 6.8, 5.91, 90955.55 }, + /* 117 terms retained, 442 terms dropped, error 0.3" */ + + /* earth l, T^1 */ + { 628331966747.5, 0, 0 }, + { 206058.9, 2.6782346, 6283.0758500 }, + { 4303.4, 2.63513, 12566.15170 }, + { 425.3, 1.5905, 3.5231 }, + { 109.0, 2.9662, 1577.3435 }, + { 93.5, 2.592, 18849.228 }, + { 119.3, 5.7956, 26.2983 }, + { 72.1, 1.138, 529.691 }, + { 67.8, 1.875, 398.149 }, + { 67.3, 4.409, 5507.553 }, + { 59.0, 2.888, 5223.694 }, + { 56.0, 2.175, 155.420 }, + { 45.4, 0.398, 796.298 }, + { 36.4, 0.466, 775.523 }, + { 29.0, 2.647, 7.114 }, + { 19.1, 1.846, 5486.778 }, + { 20.8, 5.341, 0.980 }, + { 18.5, 4.969, 213.299 }, + { 16.2, 0.032, 2544.314 }, + { 17.3, 2.991, 6275.962 }, + { 15.8, 1.430, 2146.165 }, + { 14.6, 1.205, 10977.079 }, + { 11.9, 3.258, 5088.629 }, + { 11.5, 2.075, 4694.003 }, + { 9.7, 4.24, 1349.87 }, + { 10.0, 1.303, 6286.599 }, + { 9.5, 2.70, 242.73 }, + { 12.5, 2.834, 1748.016 }, + { 11.8, 5.274, 1194.447 }, + { 8.6, 5.64, 951.72 }, + { 10.6, 0.766, 553.569 }, + { 7.6, 5.30, 2352.87 }, + { 5.8, 1.77, 1059.38 }, + { 6.4, 2.65, 9437.76 }, + { 5.2, 5.66, 71430.70 }, + { 5.3, 0.91, 3154.69 }, + { 6.1, 4.67, 4690.48 }, + { 4.3, 0.24, 6812.77 }, + { 5.0, 1.42, 6438.50 }, + { 4.3, 0.77, 10447.39 }, + { 5.2, 1.85, 801.82 }, + { 3.7, 2.00, 8031.09 }, + { 3.6, 2.43, 14143.50 }, + { 3.4, 3.86, 1592.60 }, + { 3.4, 0.89, 12036.46 }, + { 3.2, 3.19, 4705.73 }, + { 3.2, 0.62, 8429.24 }, + { 4.1, 5.24, 7084.90 }, + { 3.0, 6.07, 4292.33 }, + { 2.9, 2.32, 20.36 }, + { 3.5, 4.80, 6279.55 }, + { 2.9, 1.43, 5746.27 }, + { 2.7, 4.80, 7234.79 }, + { 2.5, 6.22, 6836.65 }, + { 2.7, 0.93, 5760.50 }, + { 3.2, 3.40, 7632.94 }, + { 2.3, 5.00, 17789.85 }, + { 2.1, 3.96, 10213.29 }, + { 2.1, 2.22, 5856.48 }, + { 2.3, 5.67, 11499.66 }, + { 2.1, 5.20, 11513.88 }, + { 1.9, 0.53, 3340.61 }, + { 1.9, 4.74, 83996.85 }, + { 2.1, 2.55, 25132.30 }, + { 1.8, 1.47, 4164.31 }, + { 1.8, 3.02, 5.52 }, + { 2.0, 0.91, 6256.78 }, + { 2.1, 2.27, 522.58 }, + { 1.8, 3.03, 5753.38 }, + { 1.6, 6.12, 5216.58 }, + { 1.6, 4.64, 3.29 }, + /* 71 terms retained, 270 terms dropped, error 0.056"*T */ + + /* earth l, T^2 */ + { 52918.9, 0, 0 }, + { 8719.8, 1.07210, 6283.07585 }, + { 309.1, 0.8673, 12566.1517 }, + { 27.3, 0.053, 3.523 }, + { 16.3, 5.188, 26.298 }, + { 15.8, 3.685, 155.420 }, + { 9.5, 0.76, 18849.23 }, + { 8.9, 2.06, 77713.77 }, + { 7.0, 0.83, 775.52 }, + { 5.1, 4.66, 1577.34 }, + { 4.1, 1.03, 7.11 }, + { 3.5, 5.14, 796.30 }, + { 3.2, 6.05, 5507.55 }, + { 3.0, 1.19, 242.73 }, + { 2.9, 6.12, 529.69 }, + { 3.8, 3.44, 5573.14 }, + { 2.7, 0.31, 398.15 }, + { 2.4, 4.38, 5223.69 }, + { 2.5, 2.28, 553.57 }, + { 2.1, 3.75, 0.98 }, + { 1.7, 0.90, 951.72 }, + { 1.5, 5.76, 1349.87 }, + { 1.2, 2.97, 2146.17 }, + { 1.4, 4.36, 1748.02 }, + { 1.3, 3.72, 1194.45 }, + { 1.3, 2.95, 6438.50 }, + { 1.0, 5.99, 6286.60 }, + { 0.9, 4.80, 5088.63 }, + { 0.8, 3.31, 213.30 }, + { 1.1, 1.27, 161000.69 }, + { 0.8, 3.42, 5486.78 }, + { 1.0, 0.60, 3154.69 }, + { 0.9, 5.23, 7084.90 }, + { 0.6, 1.60, 2544.31 }, + { 0.7, 3.43, 4694.00 }, + { 0.6, 2.48, 10977.08 }, + { 0.7, 6.19, 4690.48 }, + { 0.6, 1.98, 801.82 }, + { 0.5, 1.44, 6836.65 }, + { 0.5, 2.34, 1592.60 }, + { 0.5, 1.31, 4292.33 }, + { 0.4, 0.04, 7234.79 }, + { 0.5, 3.81, 149854.40 }, + { 0.4, 4.94, 7632.94 }, + /* 44 terms retained, 98 terms dropped, error 0.011"*T^2 */ + + /* earth l, T^3 */ + { 289.2, 5.8438, 6283.0758 }, + { 35.0, 0, 0 }, + { 16.8, 5.488, 12566.152 }, + { 3.0, 5.20, 155.42 }, + { 1.3, 4.72, 3.52 }, + { 0.6, 5.97, 242.73 }, + { 0.7, 5.30, 18849.23 }, + { 0.4, 3.79, 553.57 }, + /* 8 terms retained, 14 terms dropped, error 0.005"*T^3 */ + + /* earth l, T^4 */ + { 114.1, 3.1416, 0 }, + { 7.7, 4.13, 6283.08 }, + { 0.8, 3.84, 12566.15 }, + { 0.4, 0.42, 155.42 }, + /* 4 terms retained, 7 terms dropped, error 0.00032"*T^4 */ + + /* earth l, T^5 */ + { 0.9, 3.14, 0 }, + { 0.2, 2.77, 6283.08 }, + { 0.1, 2.01, 155.42 }, + /* 3 terms retained, 2 terms dropped, error 0.00023"*T^5 */ + /* end earth l */ + + /* earth b, T^0 */ + { 279.6, 3.1987, 84334.6616 }, + { 101.6, 5.4225, 5507.5532 }, + { 80.4, 3.880, 5223.694 }, + { 43.8, 3.704, 2352.866 }, + { 31.9, 4.000, 1577.344 }, + { 22.7, 3.985, 1047.747 }, + { 16.4, 3.565, 5856.478 }, + { 18.1, 4.984, 6283.076 }, + { 14.4, 3.703, 9437.763 }, + { 14.3, 3.411, 10213.286 }, + { 11.2, 4.828, 14143.495 }, + { 10.9, 2.086, 6812.767 }, + { 9.7, 3.47, 4694.00 }, + { 10.4, 4.057, 71092.881 }, + { 8.8, 4.44, 5753.38 }, + { 8.4, 4.99, 7084.90 }, + { 6.9, 4.33, 6275.96 }, + { 9.1, 1.14, 6620.89 }, + { 7.2, 3.60, 529.69 }, + { 7.7, 5.55, 167621.58 }, + /* 20 terms retained, 164 terms dropped, error 0.15" */ + + /* earth b, T^1 */ + { 9.0, 3.90, 5507.55 }, + { 6.2, 1.73, 5223.69 }, + { 3.8, 5.24, 2352.87 }, + { 2.8, 2.47, 1577.34 }, + { 1.8, 0.42, 6283.08 }, + /* 5 terms retained, 94 terms dropped, error 0.018"*T */ + + /* earth b, T^2 */ + { 1.7, 1.63, 84334.66 }, + { 0.5, 2.41, 1047.75 }, + /* 2 terms retained, 47 terms dropped, error 0.0035"*T^2 */ + + /* earth b, T^3 */ + /* 0 terms retained, 11 terms dropped, error 4.5e-05"*T^3 */ + + /* earth b, T^4 */ + /* 0 terms retained, 5 terms dropped, error 1.7e-05"*T^4 */ + /* end earth b */ + + /* earth r, T^0 */ + { 100013988.8, 0, 0 }, + { 1670699.6, 3.09846351, 6283.07584999 }, + { 13956.0, 3.055246, 12566.151700 }, + { 3083.7, 5.19847, 77713.77147 }, + { 1628.5, 1.17388, 5753.38488 }, + { 1575.6, 2.84685, 7860.41939 }, + { 924.8, 5.4529, 11506.7698 }, + { 542.4, 4.5641, 3930.2097 }, + { 472.1, 3.6610, 5884.9268 }, + { 328.8, 5.8998, 5223.6939 }, + { 346.0, 0.9637, 5507.5532 }, + { 306.8, 0.2987, 5573.1428 }, + { 174.8, 3.0119, 18849.2275 }, + { 243.2, 4.2735, 11790.6291 }, + { 211.8, 5.8471, 1577.3435 }, + { 185.8, 5.0219, 10977.0788 }, + { 109.8, 5.0551, 5486.7778 }, + { 98.3, 0.887, 6069.777 }, + { 86.5, 5.690, 15720.839 }, + { 85.8, 1.271, 161000.686 }, + { 62.9, 0.922, 529.691 }, + { 57.1, 2.014, 83996.847 }, + { 64.9, 0.273, 17260.155 }, + { 49.4, 3.245, 2544.314 }, + { 55.7, 5.242, 71430.696 }, + { 42.5, 6.011, 6275.962 }, + { 47.0, 2.578, 775.523 }, + { 39.0, 5.361, 4694.003 }, + { 44.7, 5.537, 9437.763 }, + { 35.7, 1.675, 12036.461 }, + { 31.9, 0.184, 5088.629 }, + { 31.8, 1.778, 398.149 }, + { 33.2, 0.244, 7084.897 }, + { 38.2, 2.393, 8827.390 }, + { 28.5, 1.213, 6286.599 }, + { 37.5, 0.830, 19651.048 }, + { 37.0, 4.901, 12139.554 }, + { 34.5, 1.843, 2942.463 }, + { 26.3, 4.589, 10447.388 }, + { 24.6, 3.787, 8429.241 }, + { 23.6, 0.269, 796.298 }, + { 27.8, 1.899, 6279.553 }, + { 23.9, 4.996, 5856.478 }, + { 20.3, 4.653, 2146.165 }, + { 23.3, 2.808, 14143.495 }, + { 22.1, 1.950, 3154.687 }, + { 19.5, 5.382, 2352.866 }, + { 18.0, 0.199, 6812.767 }, + { 17.2, 4.433, 10213.286 }, + { 16.2, 5.232, 17789.846 }, + { 17.3, 6.152, 16730.464 }, + { 13.8, 5.190, 8031.092 }, + { 18.8, 0.673, 149854.400 }, + { 18.3, 2.253, 23581.258 }, + { 13.6, 3.685, 4705.732 }, + { 13.1, 0.653, 13367.973 }, + { 10.4, 4.333, 11769.854 }, + { 10.0, 4.201, 6309.374 }, + { 10.2, 1.594, 4690.480 }, + { 7.6, 2.63, 6256.78 }, + { 9.7, 3.68, 27511.47 }, + { 6.7, 0.56, 3340.61 }, + { 8.7, 6.06, 1748.02 }, + { 7.8, 3.67, 12168.00 }, + { 6.6, 5.66, 11371.70 }, + { 7.7, 0.31, 7632.94 }, + { 6.6, 3.14, 801.82 }, + { 7.5, 5.65, 11926.25 }, + { 6.9, 2.92, 6681.22 }, + { 6.8, 1.42, 23013.54 }, + { 6.5, 2.65, 19804.83 }, + /* 71 terms retained, 455 terms dropped, error 1.1e-06 a.u. */ + + /* earth r, T^1 */ + { 103018.6, 1.1074897, 6283.0758500 }, + { 1721.2, 1.06442, 12566.15170 }, + { 702.2, 3.1416, 0 }, + { 32.3, 1.022, 18849.228 }, + { 30.8, 2.844, 5507.553 }, + { 25.0, 1.319, 5223.694 }, + { 18.5, 1.424, 1577.344 }, + { 10.1, 5.914, 10977.079 }, + { 8.6, 0.27, 5486.78 }, + { 8.7, 1.42, 6275.96 }, + { 5.1, 1.69, 5088.63 }, + { 5.0, 6.01, 6286.60 }, + { 4.7, 5.99, 529.69 }, + { 4.4, 0.52, 4694.00 }, + { 3.9, 4.75, 2544.31 }, + { 3.8, 5.07, 796.30 }, + { 4.1, 1.08, 9437.76 }, + { 3.5, 0.02, 83996.85 }, + { 3.4, 0.95, 71430.70 }, + { 3.2, 6.16, 2146.17 }, + { 3.4, 5.41, 775.52 }, + { 2.9, 5.48, 10447.39 }, + { 2.5, 0.24, 398.15 }, + { 2.2, 4.95, 6812.77 }, + { 2.2, 0.42, 8031.09 }, + { 2.8, 3.42, 2352.87 }, + { 2.6, 6.13, 6438.50 }, + { 1.9, 5.31, 8429.24 }, + { 2.4, 3.09, 4690.48 }, + { 1.7, 1.54, 4705.73 }, + { 2.2, 3.69, 7084.90 }, + { 2.1, 1.28, 1748.02 }, + { 1.8, 3.23, 6279.55 }, + { 1.6, 4.10, 11499.66 }, + { 1.6, 5.54, 3154.69 }, + { 1.8, 1.82, 7632.94 }, + /* 36 terms retained, 256 terms dropped, error 2.2e-07 a.u.*T */ + + /* earth r, T^2 */ + { 4359.4, 5.78455, 6283.07585 }, + { 123.6, 5.5793, 12566.1517 }, + { 12.3, 3.142, 0 }, + { 8.8, 3.63, 77713.77 }, + { 5.7, 1.87, 5573.14 }, + { 3.3, 5.47, 18849.23 }, + { 1.5, 4.48, 5507.55 }, + { 1.0, 2.81, 5223.69 }, + { 0.9, 3.11, 1577.34 }, + { 1.1, 2.84, 161000.69 }, + { 0.6, 5.47, 775.52 }, + { 0.6, 1.38, 6438.50 }, + { 0.5, 4.42, 6286.60 }, + { 0.4, 0.90, 10977.08 }, + { 0.4, 3.20, 5088.63 }, + { 0.5, 3.66, 7084.90 }, + { 0.5, 5.39, 149854.40 }, + /* 17 terms retained, 122 terms dropped, error 3.9e-08 a.u.*T^2 */ + + /* earth r, T^3 */ + { 144.6, 4.2732, 6283.0758 }, + { 6.7, 3.92, 12566.15 }, + { 0.8, 0, 0 }, + { 0.2, 3.73, 18849.23 }, + /* 4 terms retained, 23 terms dropped, error 1.1e-08 a.u.*T^3 */ + + /* earth r, T^4 */ + { 3.9, 2.56, 6283.08 }, + { 0.3, 2.27, 12566.15 }, + { 0.1, 3.44, 5573.14 }, + /* 3 terms retained, 7 terms dropped, error 2.1e-09 a.u.*T^4 */ + + /* earth r, T^5 */ + { 0.1, 1.22, 6283.08 }, + /* 1 terms retained, 2 terms dropped, error 2.4e-09 a.u.*T^5 */ + /* end earth */ +}; + +int vn_earth[][3] = { + /* addresses for earth l, b, r */ + /* T^0 */ { 0, 247, 274, }, + /* T^1 */ { 117, 267, 345, }, + /* T^2 */ { 188, 272, 381, }, + /* T^3 */ { 232, 274, 398, }, + /* T^4 */ { 240, 0, 402, }, + /* T^5 */ { 244, 0, 405, }, + /* end */ { 247, 0, 406, }, + /* termination */ { 0, } +}; + +/* version d4 (lbr) + * heliocentric dynamical ecliptic and equinox of the date + */ + +double vx_jupiter[][3] = { + /* jupiter l, T^0 */ + { 59954691.5, 0, 0 }, + { 9695898.7, 5.06191793, 529.69096509 }, + { 573610.1, 1.4440621, 7.1135470 }, + { 306389.2, 5.4173473, 1059.3819302 }, + { 97178.3, 4.142647, 632.783739 }, + { 72903.1, 3.640429, 522.577418 }, + { 64264.0, 3.411452, 103.092774 }, + { 39806.1, 2.293767, 419.484644 }, + { 38857.8, 1.272317, 316.391870 }, + { 27964.6, 1.784546, 536.804512 }, + { 13589.7, 5.774810, 1589.072895 }, + { 8246.4, 3.58228, 206.18555 }, + { 8768.7, 3.63000, 949.17561 }, + { 7368.1, 5.08101, 735.87651 }, + { 6263.2, 0.02498, 213.29910 }, + { 6114.0, 4.51320, 1162.47470 }, + { 4905.4, 1.32085, 110.20632 }, + { 5305.3, 1.30671, 14.22709 }, + { 5305.5, 4.18625, 1052.26838 }, + { 4647.2, 4.69958, 3.93215 }, + { 3045.0, 4.31676, 426.59819 }, + { 2610.0, 1.56668, 846.08283 }, + { 2028.2, 1.06377, 3.18139 }, + { 1764.8, 2.14148, 1066.49548 }, + { 1723.0, 3.88036, 1265.56748 }, + { 1921.0, 0.97169, 639.89729 }, + { 1633.2, 3.58201, 515.46387 }, + { 1432.0, 4.29684, 625.67019 }, + { 973.3, 4.0976, 95.9792 }, + { 884.4, 2.4370, 412.3711 }, + { 732.9, 6.0853, 838.9693 }, + { 731.1, 3.8059, 1581.9593 }, + { 691.9, 6.1337, 2118.7639 }, + { 709.2, 1.2927, 742.9901 }, + { 614.5, 4.1085, 1478.8666 }, + { 495.2, 3.7557, 323.5054 }, + { 581.9, 4.5397, 309.2783 }, + { 375.7, 4.7030, 1368.6603 }, + { 389.9, 4.8972, 1692.1657 }, + { 341.0, 5.7145, 533.6231 }, + { 330.5, 4.7405, 0.0482 }, + { 440.9, 2.9582, 454.9094 }, + { 417.3, 1.0355, 2.4477 }, + { 244.2, 5.2202, 728.7630 }, + { 261.5, 1.8765, 0.9632 }, + { 256.6, 3.7241, 199.0720 }, + { 261.0, 0.8205, 380.1278 }, + { 220.4, 1.6512, 543.9181 }, + { 202.0, 1.8068, 1375.7738 }, + { 207.3, 1.8546, 525.7588 }, + { 197.0, 5.2925, 1155.3612 }, + { 235.1, 1.2269, 909.8187 }, + { 174.8, 5.9097, 956.2892 }, + { 149.4, 4.3775, 1685.0521 }, + { 175.2, 3.2263, 1898.3512 }, + { 175.2, 3.7297, 942.0621 }, + { 157.9, 4.3648, 1795.2584 }, + { 137.9, 1.3180, 1169.5883 }, + { 117.5, 2.5002, 1596.1864 }, + { 150.5, 3.9063, 74.7816 }, + { 116.8, 3.3892, 0.5213 }, + { 105.9, 4.5544, 526.5096 }, + { 130.5, 4.1687, 1045.1548 }, + { 141.4, 3.1357, 491.5579 }, + { 99.5, 1.421, 532.872 }, + { 96.1, 1.182, 117.320 }, + { 91.8, 0.858, 1272.681 }, + { 87.7, 1.217, 453.425 }, + { 68.5, 2.352, 2.921 }, + { 66.1, 5.344, 1471.753 }, + { 77.4, 4.427, 39.357 }, + { 72.0, 4.238, 2111.650 }, + { 63.4, 4.977, 0.751 }, + { 59.4, 4.111, 2001.444 }, + { 62.5, 0.512, 220.413 }, + { 66.5, 2.989, 2214.743 }, + { 60.2, 4.126, 4.193 }, + { 56.0, 1.155, 21.341 }, + { 52.9, 0.912, 10.295 }, + { 70.3, 5.142, 835.037 }, + { 51.9, 4.100, 1258.454 }, + { 46.4, 4.665, 5.629 }, + { 58.2, 5.866, 5753.385 }, + { 40.1, 4.688, 0.160 }, + { 46.7, 4.794, 305.346 }, + { 39.3, 4.254, 853.196 }, + { 46.0, 5.110, 4.666 }, + { 54.5, 1.571, 983.116 }, + { 38.9, 6.076, 518.645 }, + { 38.4, 2.438, 433.712 }, + { 46.8, 3.546, 5.417 }, + { 41.8, 4.680, 302.165 }, + { 35.9, 2.451, 430.530 }, + { 37.9, 0.211, 2648.455 }, + { 39.2, 1.718, 11.046 }, + { 37.6, 6.195, 831.856 }, + { 35.8, 4.615, 2008.558 }, + { 43.4, 0.150, 528.206 }, + { 31.6, 5.141, 1788.145 }, + { 29.8, 5.344, 2221.857 }, + { 32.8, 5.289, 88.866 }, + { 27.7, 1.852, 0.212 }, + { 25.8, 3.859, 2317.836 }, + { 33.8, 1.006, 9683.595 }, + { 27.1, 2.808, 18.159 }, + { 26.8, 1.776, 532.139 }, + { 26.1, 2.744, 2531.135 }, + { 30.8, 0.423, 1.484 }, + { 30.5, 3.667, 508.350 }, + /* 109 terms retained, 651 terms dropped, error 1.3" */ + + /* jupiter l, T^1 */ + { 52993480757.5, 0, 0 }, + { 489741.2, 4.2206669, 529.6909651 }, + { 228918.5, 6.0264746, 7.1135470 }, + { 27655.4, 4.572660, 1059.381930 }, + { 20720.9, 5.459389, 522.577418 }, + { 12105.7, 0.169858, 536.804512 }, + { 6068.1, 4.42420, 103.09277 }, + { 5433.9, 3.98478, 419.48464 }, + { 4237.8, 5.89009, 14.22709 }, + { 2211.9, 5.26771, 206.18555 }, + { 1295.8, 5.55133, 3.18139 }, + { 1745.9, 4.92669, 1589.07290 }, + { 1163.4, 0.51451, 3.93215 }, + { 1007.2, 0.46478, 735.87651 }, + { 1173.1, 5.85647, 1052.26838 }, + { 847.7, 5.7581, 110.2063 }, + { 827.3, 4.8031, 213.2991 }, + { 1003.6, 3.15040, 426.59819 }, + { 1098.7, 5.30705, 515.46387 }, + { 816.4, 0.5864, 1066.4955 }, + { 725.4, 5.5183, 639.8973 }, + { 567.8, 5.9887, 625.6702 }, + { 474.2, 4.1325, 412.3711 }, + { 412.9, 5.7365, 95.9792 }, + { 335.8, 3.7325, 1162.4747 }, + { 345.2, 4.2416, 632.7837 }, + { 234.1, 6.2430, 309.2783 }, + { 194.8, 2.2188, 323.5054 }, + { 234.3, 4.0347, 949.1756 }, + { 183.9, 6.2796, 543.9181 }, + { 198.5, 1.5046, 838.9693 }, + { 186.9, 6.0862, 742.9901 }, + { 171.4, 5.4166, 199.0720 }, + { 130.8, 0.6264, 728.7630 }, + { 107.6, 4.4928, 956.2892 }, + { 115.4, 0.6802, 846.0828 }, + { 115.0, 5.2864, 2118.7639 }, + { 66.8, 5.734, 21.341 }, + { 69.6, 5.973, 532.872 }, + { 64.9, 6.088, 1581.959 }, + { 79.7, 5.824, 1045.155 }, + { 57.9, 0.995, 1596.186 }, + { 65.6, 0.129, 526.510 }, + { 58.5, 0.586, 1155.361 }, + { 56.6, 1.412, 533.623 }, + { 71.6, 5.342, 942.062 }, + { 57.4, 5.969, 1169.588 }, + { 54.9, 5.428, 10.295 }, + { 52.0, 0.230, 1368.660 }, + { 52.3, 5.727, 117.320 }, + { 50.4, 6.081, 525.759 }, + { 47.4, 3.626, 1478.867 }, + { 39.9, 4.162, 1692.166 }, + { 46.7, 0.511, 1265.567 }, + { 32.8, 5.036, 220.413 }, + { 33.6, 0.099, 302.165 }, + { 29.4, 3.359, 4.666 }, + { 29.3, 0.759, 88.866 }, + { 32.4, 5.375, 508.350 }, + { 29.5, 5.422, 1272.681 }, + { 21.8, 6.151, 1685.052 }, + { 25.2, 1.607, 831.856 }, + { 21.1, 5.863, 1258.454 }, + { 19.7, 2.172, 316.392 }, + { 17.9, 0.828, 433.712 }, + { 17.7, 5.955, 5.417 }, + { 17.2, 2.764, 853.196 }, + { 17.5, 0.707, 1471.753 }, + { 17.5, 0.498, 1375.774 }, + { 14.4, 0.915, 18.159 }, + { 14.1, 0.630, 2.921 }, + { 11.6, 4.304, 405.258 }, + { 11.7, 1.764, 380.128 }, + { 11.1, 5.567, 1574.846 }, + { 10.4, 0.314, 1361.547 }, + { 9.8, 5.90, 519.40 }, + { 9.8, 0.39, 1073.61 }, + { 9.3, 3.22, 1795.26 }, + { 8.9, 0.54, 1788.14 }, + { 8.4, 5.88, 2001.44 }, + { 8.1, 5.10, 1485.98 }, + { 7.7, 5.65, 2648.45 }, + { 6.7, 2.41, 4.19 }, + { 7.3, 6.19, 11.05 }, + { 6.3, 1.36, 1148.25 }, + /* 85 terms retained, 284 terms dropped, error 0.24"*T */ + + /* jupiter l, T^2 */ + { 47233.6, 4.321483, 7.113547 }, + { 30629.1, 2.930214, 529.690965 }, + { 38965.5, 0, 0 }, + { 3189.3, 1.05505, 522.57742 }, + { 2723.4, 3.41412, 1059.38193 }, + { 2729.3, 4.84545, 536.80451 }, + { 1721.1, 4.18734, 14.22709 }, + { 383.3, 5.7679, 419.4846 }, + { 367.5, 6.0551, 103.0928 }, + { 377.5, 0.7605, 515.4639 }, + { 337.4, 3.7864, 3.1814 }, + { 308.2, 0.6936, 206.1855 }, + { 218.4, 3.8139, 1589.0729 }, + { 198.9, 5.3400, 1066.4955 }, + { 197.4, 2.4836, 3.9322 }, + { 146.2, 3.8137, 639.8973 }, + { 155.9, 1.4064, 1052.2684 }, + { 129.6, 5.8374, 412.3711 }, + { 141.9, 1.6344, 426.5982 }, + { 117.3, 1.4144, 625.6702 }, + { 96.7, 4.034, 110.206 }, + { 90.8, 1.106, 95.979 }, + { 78.8, 4.637, 543.918 }, + { 72.4, 2.217, 735.877 }, + { 87.3, 2.522, 632.784 }, + { 56.9, 3.123, 213.299 }, + { 48.6, 1.673, 309.278 }, + { 58.5, 0.832, 199.072 }, + { 40.1, 4.025, 21.341 }, + { 39.8, 0.624, 323.505 }, + { 35.7, 2.326, 728.763 }, + { 25.6, 2.512, 1162.475 }, + { 29.3, 3.608, 10.295 }, + { 23.6, 3.005, 956.289 }, + { 27.8, 3.240, 838.969 }, + { 26.0, 4.501, 742.990 }, + { 25.2, 1.219, 1045.155 }, + { 19.5, 4.290, 532.872 }, + { 17.7, 0.810, 508.350 }, + { 15.4, 5.810, 1596.186 }, + { 17.1, 4.200, 2118.764 }, + { 17.0, 1.834, 526.510 }, + { 14.7, 4.000, 117.320 }, + { 13.6, 1.803, 302.165 }, + { 13.2, 2.519, 88.866 }, + { 12.8, 4.369, 1169.588 }, + { 15.3, 0.682, 942.062 }, + { 11.0, 4.436, 525.759 }, + { 13.9, 5.952, 316.392 }, + { 9.4, 2.18, 1155.36 }, + { 8.8, 3.29, 220.41 }, + { 7.8, 5.76, 846.08 }, + { 7.5, 2.71, 533.62 }, + { 9.7, 1.72, 1581.96 }, + { 8.7, 3.32, 831.86 }, + { 6.3, 0.50, 949.18 }, + { 6.7, 2.18, 1265.57 }, + { 5.4, 6.01, 405.26 }, + { 4.7, 1.41, 1258.45 }, + { 4.4, 3.02, 1692.17 }, + { 4.4, 5.48, 433.71 }, + { 4.3, 5.07, 1073.61 }, + { 4.2, 5.29, 18.16 }, + { 3.9, 1.27, 853.20 }, + { 5.4, 3.65, 1272.68 }, + { 4.4, 2.27, 1368.66 }, + { 3.5, 1.54, 519.40 }, + { 2.7, 2.10, 1478.87 }, + { 2.7, 1.06, 1574.85 }, + { 2.9, 2.05, 1361.55 }, + { 3.1, 0.99, 191.96 }, + { 2.5, 2.37, 1471.75 }, + { 2.2, 2.48, 721.65 }, + { 2.1, 3.71, 1485.98 }, + { 2.0, 1.88, 1685.05 }, + { 2.3, 3.03, 1148.25 }, + { 2.0, 6.17, 330.62 }, + /* 77 terms retained, 114 terms dropped, error 0.074"*T^2 */ + + /* jupiter l, T^3 */ + { 6501.7, 2.59863, 7.11355 }, + { 1356.5, 1.34636, 529.69097 }, + { 470.7, 2.4750, 14.2271 }, + { 417.0, 3.2445, 536.8045 }, + { 352.9, 2.9736, 522.5774 }, + { 154.9, 2.0757, 1059.3819 }, + { 86.8, 2.514, 515.464 }, + { 33.5, 3.826, 1066.495 }, + { 44.4, 0, 0 }, + { 22.6, 2.982, 543.918 }, + { 23.7, 1.277, 412.371 }, + { 28.5, 2.448, 206.186 }, + { 19.8, 2.101, 639.897 }, + { 19.7, 1.403, 419.485 }, + { 18.8, 1.594, 103.093 }, + { 17.0, 2.302, 21.341 }, + { 16.8, 2.598, 1589.073 }, + { 16.2, 3.145, 625.670 }, + { 16.1, 3.360, 1052.268 }, + { 13.4, 2.760, 95.979 }, + { 13.2, 2.539, 199.072 }, + { 12.6, 6.266, 426.598 }, + { 8.6, 2.27, 110.21 }, + { 6.7, 3.43, 309.28 }, + { 8.7, 1.76, 10.29 }, + { 6.5, 4.04, 728.76 }, + { 5.4, 5.25, 323.51 }, + { 5.7, 2.52, 508.35 }, + { 5.4, 2.91, 1045.15 }, + { 4.0, 4.30, 88.87 }, + { 3.9, 3.52, 302.16 }, + { 3.8, 4.09, 735.88 }, + { 3.3, 1.43, 956.29 }, + { 2.8, 4.36, 1596.19 }, + { 2.7, 1.25, 213.30 }, + { 2.6, 2.24, 117.32 }, + { 2.4, 2.90, 742.99 }, + { 2.7, 5.02, 838.97 }, + { 1.9, 2.77, 1169.59 }, + { 2.3, 2.36, 942.06 }, + { 1.5, 1.61, 220.41 }, + { 1.5, 3.09, 2118.76 }, + { 1.9, 5.01, 831.86 }, + { 1.6, 1.40, 405.26 }, + { 1.3, 3.98, 1155.36 }, + { 1.2, 3.46, 1073.61 }, + { 1.0, 3.39, 532.87 }, + { 0.9, 2.70, 191.96 }, + { 0.8, 1.48, 632.78 }, + { 0.8, 1.11, 1162.47 }, + { 0.8, 3.30, 1258.45 }, + { 0.7, 5.90, 853.20 }, + { 0.8, 3.66, 1581.96 }, + { 0.7, 3.75, 433.71 }, + { 0.7, 2.93, 1574.85 }, + { 0.7, 3.53, 525.76 }, + { 0.6, 4.15, 721.65 }, + { 0.6, 4.69, 81.75 }, + { 0.7, 1.96, 1272.68 }, + { 0.5, 1.57, 949.18 }, + { 0.7, 2.02, 526.51 }, + { 0.5, 4.36, 1368.66 }, + { 0.5, 4.96, 1148.25 }, + { 0.5, 4.31, 330.62 }, + { 0.6, 2.28, 551.03 }, + { 0.5, 3.87, 1361.55 }, + { 0.4, 2.95, 1038.04 }, + { 0.4, 4.08, 1471.75 }, + { 0.4, 2.22, 539.99 }, + { 0.4, 4.53, 1464.64 }, + /* 70 terms retained, 39 terms dropped, error 0.014"*T^3 */ + + /* jupiter l, T^4 */ + { 669.5, 0.8528, 7.1135 }, + { 100.0, 0.7426, 14.2271 }, + { 114.0, 3.1416, 0 }, + { 50.0, 1.653, 536.805 }, + { 43.6, 5.820, 529.691 }, + { 31.8, 4.858, 522.577 }, + { 14.7, 4.291, 515.464 }, + { 8.9, 0.71, 1059.38 }, + { 5.0, 1.30, 543.92 }, + { 4.5, 2.32, 1066.50 }, + { 4.3, 0.48, 21.34 }, + { 3.1, 3.00, 412.37 }, + { 2.1, 0.40, 639.90 }, + { 1.8, 4.91, 625.67 }, + { 1.9, 4.26, 199.07 }, + { 1.7, 4.26, 206.19 }, + { 1.4, 5.26, 1052.27 }, + { 1.2, 4.72, 95.98 }, + { 1.1, 1.29, 1589.07 }, + { 1.0, 4.78, 1045.15 }, + { 0.9, 6.06, 88.87 }, + { 0.9, 5.78, 728.76 }, + { 0.9, 4.55, 426.60 }, + { 0.8, 3.40, 419.48 }, + { 0.8, 3.55, 103.09 }, + { 0.7, 0.52, 110.21 }, + { 0.4, 5.23, 302.16 }, + { 0.4, 6.24, 956.29 }, + { 0.4, 5.25, 309.28 }, + { 0.4, 0.60, 117.32 }, + { 0.3, 4.78, 508.35 }, + { 0.3, 3.48, 323.51 }, + { 0.3, 2.96, 1596.19 }, + { 0.3, 4.33, 942.06 }, + { 0.3, 0.48, 831.86 }, + { 0.3, 1.80, 1073.61 }, + { 0.2, 0.44, 220.41 }, + { 0.2, 1.13, 1169.59 }, + { 0.2, 2.16, 1361.55 }, + { 0.2, 3.43, 1148.25 }, + { 0.2, 1.93, 2118.76 }, + { 0.2, 3.03, 1272.68 }, + /* 42 terms retained, 3 terms dropped, error 0.0042"*T^4 */ + + /* jupiter l, T^5 */ + { 49.6, 5.257, 7.114 }, + { 15.8, 5.251, 14.227 }, + { 4.3, 0.01, 536.80 }, + { 1.5, 1.10, 522.58 }, + { 0.7, 5.86, 543.92 }, + { 0.7, 0.87, 515.46 }, + { 0.8, 3.14, 0 }, + { 0.5, 0.82, 1066.50 }, + { 0.3, 5.63, 1059.38 }, + /* 9 terms retained, 1 terms dropped, error 0.0038"*T^5 */ + /* end jupiter l */ + + /* jupiter b, T^0 */ + { 2268615.7, 3.55852607, 529.69096509 }, + { 109971.6, 3.9080935, 1059.3819302 }, + { 110090.4, 0, 0 }, + { 8101.4, 3.60510, 522.57742 }, + { 6044.0, 4.25883, 1589.07290 }, + { 6437.8, 0.30627, 536.80451 }, + { 1106.9, 2.98534, 1162.47470 }, + { 941.7, 2.9362, 1052.2684 }, + { 894.1, 1.7545, 7.1135 }, + { 767.3, 2.1547, 632.7837 }, + { 944.3, 1.6752, 426.5982 }, + { 684.2, 3.6781, 213.2991 }, + { 629.2, 0.6434, 1066.4955 }, + { 835.9, 5.1788, 103.0928 }, + { 531.7, 2.7031, 110.2063 }, + { 558.5, 0.0135, 846.0828 }, + { 464.4, 1.1734, 949.1756 }, + { 431.1, 2.6083, 419.4846 }, + { 351.4, 4.6106, 2118.7639 }, + { 123.1, 3.3497, 1692.1657 }, + { 115.0, 5.0489, 316.3919 }, + { 132.2, 4.7782, 742.9901 }, + { 103.4, 2.3188, 1478.8666 }, + { 116.4, 1.3869, 323.5054 }, + { 102.4, 3.1529, 1581.9593 }, + { 103.8, 3.7010, 515.4639 }, + { 78.7, 3.983, 1265.567 }, + { 69.9, 2.560, 956.289 }, + { 55.6, 0.375, 1375.774 }, + { 52.0, 0.990, 1596.186 }, + { 55.2, 0.402, 525.759 }, + { 63.5, 4.501, 735.877 }, + { 49.7, 0.186, 543.918 }, + { 48.8, 3.573, 533.623 }, + { 28.4, 1.535, 625.670 }, + { 29.2, 5.431, 206.186 }, + /* 36 terms retained, 213 terms dropped, error 0.73" */ + + /* jupiter b, T^1 */ + { 177351.8, 5.7016649, 529.6909651 }, + { 3230.2, 5.77942, 1059.38193 }, + { 3081.4, 5.47464, 522.57742 }, + { 2211.9, 4.73477, 536.80451 }, + { 1694.2, 3.14159, 0 }, + { 346.4, 4.7460, 1052.2684 }, + { 234.3, 5.1886, 1066.4955 }, + { 196.2, 6.1855, 7.1135 }, + { 150.5, 3.9272, 1589.0729 }, + { 114.1, 3.4390, 632.7837 }, + { 96.7, 2.914, 949.176 }, + { 76.6, 2.505, 103.093 }, + { 81.7, 5.077, 1162.475 }, + { 76.6, 0.613, 419.485 }, + { 73.9, 5.500, 515.464 }, + { 49.9, 3.948, 735.877 }, + { 60.5, 5.447, 213.299 }, + { 36.6, 4.698, 543.918 }, + { 46.0, 0.539, 110.206 }, + { 45.1, 1.895, 846.083 }, + { 36.0, 6.110, 316.392 }, + { 32.0, 4.925, 1581.959 }, + { 21.0, 5.630, 1596.186 }, + { 23.2, 5.848, 323.505 }, + { 24.7, 3.941, 2118.764 }, + { 17.3, 5.653, 533.623 }, + { 16.5, 5.898, 526.510 }, + { 16.7, 5.667, 1265.567 }, + { 15.8, 4.433, 1045.155 }, + { 13.4, 4.302, 532.872 }, + { 11.7, 1.810, 956.289 }, + { 11.9, 4.301, 525.759 }, + { 9.5, 2.03, 206.19 }, + { 10.5, 6.155, 14.227 }, + { 8.4, 3.93, 1478.87 }, + { 8.1, 4.20, 1169.59 }, + { 7.7, 2.99, 942.06 }, + { 8.8, 1.56, 426.60 }, + { 8.9, 4.87, 1155.36 }, + { 7.8, 3.85, 625.67 }, + /* 40 terms retained, 101 terms dropped, error 0.21"*T */ + + /* jupiter b, T^2 */ + { 8094.1, 1.46323, 529.69097 }, + { 742.4, 0.9569, 522.5774 }, + { 813.2, 3.1416, 0 }, + { 399.0, 2.8989, 536.8045 }, + { 342.2, 1.4468, 1059.3819 }, + { 73.9, 0.407, 1052.268 }, + { 46.2, 3.480, 1066.495 }, + { 29.3, 0.991, 515.464 }, + { 29.7, 1.925, 1589.073 }, + { 22.8, 4.271, 7.114 }, + { 13.9, 2.922, 543.918 }, + { 12.1, 5.222, 632.784 }, + { 10.7, 4.880, 949.176 }, + { 6.1, 6.21, 1045.15 }, + { 5.9, 0.53, 1581.96 }, + { 5.0, 1.43, 526.51 }, + { 4.6, 0.92, 1162.47 }, + { 4.5, 4.02, 1596.19 }, + { 5.1, 6.03, 735.88 }, + { 3.6, 4.54, 110.21 }, + { 3.4, 1.39, 533.62 }, + { 3.3, 4.40, 14.23 }, + { 3.4, 0.42, 419.48 }, + { 2.9, 2.06, 316.39 }, + { 2.5, 3.98, 323.51 }, + { 3.1, 2.48, 2118.76 }, + { 3.1, 2.40, 532.87 }, + { 2.2, 4.78, 942.06 }, + { 2.1, 3.89, 426.60 }, + { 2.3, 0.37, 1155.36 }, + { 2.0, 3.90, 846.08 }, + { 1.9, 1.20, 103.09 }, + { 1.7, 1.42, 1265.57 }, + { 2.3, 0.88, 213.30 }, + { 1.8, 5.80, 625.67 }, + { 1.7, 2.24, 525.76 }, + /* 36 terms retained, 45 terms dropped, error 0.043"*T^2 */ + + /* jupiter b, T^3 */ + { 251.6, 3.3809, 529.6910 }, + { 121.7, 2.7331, 522.5774 }, + { 48.7, 1.037, 536.805 }, + { 11.0, 2.315, 1052.268 }, + { 8.1, 2.77, 515.46 }, + { 6.2, 1.78, 1066.50 }, + { 7.3, 4.25, 1059.38 }, + { 3.6, 1.13, 543.92 }, + { 2.8, 3.14, 0 }, + { 1.9, 2.29, 7.11 }, + { 1.6, 1.78, 1045.15 }, + { 0.9, 0.45, 632.78 }, + { 0.8, 0.31, 949.18 }, + { 0.7, 2.64, 14.23 }, + { 0.9, 0.33, 1589.07 }, + { 0.7, 2.37, 1581.96 }, + { 0.6, 2.48, 1596.19 }, + { 0.7, 1.53, 735.88 }, + { 0.5, 3.68, 419.48 }, + { 0.5, 0.27, 942.06 }, + { 0.5, 3.18, 526.51 }, + { 0.4, 2.88, 110.21 }, + /* 22 terms retained, 20 terms dropped, error 0.0081"*T^3 */ + + /* jupiter b, T^4 */ + { 15.1, 4.530, 522.577 }, + { 5.4, 4.47, 529.69 }, + { 4.5, 5.44, 536.80 }, + { 3.4, 0, 0 }, + { 1.8, 4.52, 515.46 }, + { 1.3, 4.20, 1052.27 }, + { 0.8, 5.59, 543.92 }, + { 0.5, 0.06, 1066.50 }, + { 0.3, 3.67, 1059.38 }, + { 0.1, 3.56, 1045.15 }, + { 0.1, 5.70, 7.11 }, + { 0.1, 1.17, 14.23 }, + /* 12 terms retained, 0 terms dropped, error 0.0017"*T^4 */ + + /* jupiter b, T^5 */ + { 1.4, 0.09, 522.58 }, + { 0.4, 0.01, 515.46 }, + { 0.3, 3.28, 536.80 }, + { 0.1, 0.34, 529.69 }, + /* 4 terms retained, 1 terms dropped, error 0.0012"*T^5 */ + /* end jupiter b */ + + /* jupiter r, T^0 */ + { 520887429.5, 0, 0 }, + { 25209327.0, 3.491086400, 529.690965095 }, + { 610599.9, 3.8411537, 1059.3819302 }, + { 282029.5, 2.5741988, 632.7837393 }, + { 187647.4, 2.0759038, 522.5774181 }, + { 86792.9, 0.710011, 419.484644 }, + { 72062.9, 0.214657, 536.804512 }, + { 65517.2, 5.979959, 316.391870 }, + { 29134.6, 1.677592, 103.092774 }, + { 30135.3, 2.161321, 949.175609 }, + { 23453.2, 3.540231, 735.876514 }, + { 22283.7, 4.193628, 1589.072895 }, + { 23947.3, 0.274579, 7.113547 }, + { 13032.6, 2.960431, 1162.474704 }, + { 9703.3, 1.90670, 206.18555 }, + { 12749.0, 2.715501, 1052.268383 }, + { 9161.4, 4.41353, 213.29910 }, + { 7894.5, 2.47908, 426.59819 }, + { 7058.0, 2.18185, 1265.56748 }, + { 6137.8, 6.26418, 846.08283 }, + { 5477.1, 5.65729, 639.89729 }, + { 3502.5, 0.56531, 1066.49548 }, + { 4136.9, 2.72220, 625.67019 }, + { 4170.0, 2.01605, 515.46387 }, + { 2500.0, 4.55182, 838.96929 }, + { 2617.0, 2.00994, 1581.95935 }, + { 1911.9, 0.85622, 412.37110 }, + { 2127.6, 6.12751, 742.99006 }, + { 1610.5, 3.08868, 1368.66025 }, + { 1479.5, 2.68026, 1478.86657 }, + { 1230.7, 1.89043, 323.50542 }, + { 1216.8, 1.80172, 110.20632 }, + { 961.1, 4.5488, 2118.7639 }, + { 885.7, 4.1479, 533.6231 }, + { 776.7, 3.6770, 728.7630 }, + { 998.6, 2.8721, 309.2783 }, + { 1015.0, 1.38673, 454.90937 }, + { 727.2, 3.9882, 1155.3612 }, + { 655.3, 2.7907, 1685.0521 }, + { 821.5, 1.5934, 1898.3512 }, + { 620.8, 4.8228, 956.2892 }, + { 654.0, 3.3815, 1692.1657 }, + { 812.0, 5.9409, 909.8187 }, + { 562.1, 0.0810, 543.9181 }, + { 542.2, 0.2836, 525.7588 }, + { 457.9, 0.1272, 1375.7738 }, + { 614.8, 2.2762, 942.0621 }, + { 435.8, 2.6027, 95.9792 }, + { 496.1, 5.5301, 380.1278 }, + { 470.0, 2.8190, 1795.2584 }, + { 445.0, 0.1462, 14.2271 }, + { 290.9, 3.8934, 1471.7530 }, + { 276.6, 2.5224, 2001.4440 }, + { 275.1, 2.9886, 526.5096 }, + { 293.9, 2.0494, 199.0720 }, + { 291.0, 6.0313, 1169.5883 }, + { 338.3, 2.7987, 1045.1548 }, + { 257.5, 6.1340, 532.8724 }, + { 319.0, 1.3480, 2214.7431 }, + { 309.4, 5.3686, 1272.6810 }, + { 345.8, 1.5640, 491.5579 }, + { 303.4, 1.1541, 5753.3849 }, + { 192.3, 0.9200, 1596.1864 }, + { 215.4, 2.6357, 2111.6503 }, + { 200.7, 2.3726, 1258.4539 }, + { 239.0, 3.5740, 835.0371 }, + { 197.1, 5.9286, 453.4249 }, + { 139.4, 3.6396, 1788.1449 }, + { 191.4, 6.2825, 983.1159 }, + { 176.6, 2.5767, 9683.5946 }, + { 123.6, 2.2616, 2317.8359 }, + { 128.2, 4.6659, 831.8557 }, + { 112.4, 0.8560, 433.7117 }, + { 128.8, 1.1057, 2531.1350 }, + { 99.4, 4.503, 518.645 }, + { 93.9, 2.726, 853.196 }, + { 106.5, 5.8146, 220.4126 }, + { 120.2, 2.9516, 3.9322 }, + { 104.0, 2.2222, 74.7816 }, + { 81.7, 3.235, 1361.547 }, + { 112.5, 4.8622, 528.2065 }, + { 79.5, 0.885, 430.530 }, + { 85.8, 2.115, 1574.846 }, + { 85.7, 2.338, 2428.042 }, + { 68.3, 3.357, 2104.537 }, + { 69.6, 3.042, 302.165 }, + { 69.8, 3.224, 305.346 }, + { 69.6, 0.205, 532.139 }, + { 57.0, 2.002, 2634.228 }, + { 77.1, 2.098, 508.350 }, + { 56.7, 3.917, 2221.857 }, + { 58.3, 5.724, 628.852 }, + { 52.5, 4.025, 527.243 }, + { 63.6, 1.100, 1364.728 }, + { 53.6, 0.874, 2847.527 }, + { 59.6, 0.958, 494.266 }, + { 58.0, 3.458, 2008.558 }, + { 41.5, 3.520, 529.739 }, + { 44.7, 1.623, 984.600 }, + { 44.9, 4.901, 2648.455 }, + { 53.2, 1.198, 760.256 }, + { 44.4, 4.426, 1063.314 }, + { 37.6, 2.930, 1677.939 }, + { 41.5, 0.322, 529.643 }, + { 42.9, 0.031, 1439.510 }, + { 46.0, 2.543, 636.716 }, + { 40.2, 4.394, 1148.248 }, + { 38.8, 4.317, 149.563 }, + { 40.3, 2.101, 2744.434 }, + { 48.9, 5.603, 2810.921 }, + { 37.1, 5.078, 1905.465 }, + { 43.9, 1.245, 621.738 }, + { 34.0, 3.094, 2420.929 }, + { 36.8, 0.842, 530.654 }, + { 31.1, 5.358, 1485.980 }, + { 39.3, 4.708, 569.048 }, + { 39.7, 2.462, 355.749 }, + { 31.5, 6.193, 3.181 }, + { 28.4, 2.485, 519.396 }, + { 32.4, 2.733, 604.473 }, + { 27.1, 3.923, 2324.949 }, + { 26.8, 1.750, 2950.620 }, + { 29.0, 1.835, 1891.238 }, + { 26.5, 0.604, 1055.450 }, + { 33.5, 0.761, 643.829 }, + { 26.6, 1.036, 405.258 }, + { 25.5, 3.463, 458.842 }, + { 32.9, 3.186, 528.728 }, + { 25.7, 0.524, 511.532 }, + { 26.0, 1.336, 330.619 }, + /* 130 terms retained, 615 terms dropped, error 6e-06 a.u. */ + + /* jupiter r, T^1 */ + { 1271801.6, 2.64937511, 529.69096509 }, + { 61661.8, 3.000763, 1059.381930 }, + { 53443.6, 3.897176, 522.577418 }, + { 31185.2, 4.882767, 536.804512 }, + { 41390.3, 0, 0 }, + { 11847.2, 2.413296, 419.484644 }, + { 9166.4, 4.75979, 7.11355 }, + { 3175.8, 2.79298, 103.09277 }, + { 3203.4, 5.21083, 735.87651 }, + { 3403.6, 3.34689, 1589.07290 }, + { 2600.0, 3.63435, 206.18555 }, + { 2412.2, 1.46947, 426.59819 }, + { 2806.1, 3.74224, 515.46387 }, + { 2676.6, 4.33053, 1052.26838 }, + { 2100.5, 3.92763, 639.89729 }, + { 1646.2, 5.30954, 1066.49548 }, + { 1641.3, 4.41629, 625.67019 }, + { 1049.9, 3.16114, 213.29910 }, + { 1024.8, 2.55433, 412.37110 }, + { 741.0, 2.1709, 1162.4747 }, + { 806.4, 2.6775, 632.7837 }, + { 676.9, 6.2495, 838.9693 }, + { 468.9, 4.7097, 543.9181 }, + { 444.7, 0.4028, 323.5054 }, + { 567.1, 4.5766, 742.9901 }, + { 415.9, 5.3684, 728.7630 }, + { 484.7, 2.4688, 949.1756 }, + { 337.6, 3.1678, 956.2892 }, + { 401.7, 4.6053, 309.2783 }, + { 347.4, 4.6815, 14.2271 }, + { 260.8, 5.3429, 846.0828 }, + { 220.1, 4.8421, 1368.6603 }, + { 203.2, 5.6000, 1155.3612 }, + { 246.6, 3.9231, 942.0621 }, + { 183.5, 4.2653, 95.9792 }, + { 180.1, 4.4017, 532.8724 }, + { 197.1, 3.7055, 2118.7639 }, + { 196.0, 3.7588, 199.0720 }, + { 200.2, 4.4389, 1045.1548 }, + { 170.2, 4.8465, 526.5096 }, + { 146.3, 6.1296, 533.6231 }, + { 133.5, 1.3225, 110.2063 }, + { 132.1, 4.5119, 525.7588 }, + { 123.9, 2.0429, 1478.8666 }, + { 121.9, 4.4058, 1169.5883 }, + { 115.3, 4.4674, 1581.9593 }, + { 98.5, 5.728, 1596.186 }, + { 91.6, 4.530, 1685.052 }, + { 110.6, 3.6250, 1272.6810 }, + { 80.5, 4.113, 1258.454 }, + { 79.6, 2.719, 1692.166 }, + { 100.2, 5.2469, 1265.5675 }, + { 77.9, 5.567, 1471.753 }, + { 85.8, 0.079, 831.856 }, + { 82.1, 3.808, 508.350 }, + { 55.3, 0.352, 316.392 }, + { 52.3, 5.531, 433.712 }, + { 55.8, 4.751, 302.165 }, + { 50.6, 4.856, 1375.774 }, + { 43.6, 4.944, 1361.547 }, + { 42.2, 1.224, 853.196 }, + { 37.7, 4.268, 2001.444 }, + { 49.4, 4.014, 220.413 }, + { 38.3, 5.330, 1788.145 }, + { 35.6, 1.762, 1795.258 }, + { 36.3, 3.850, 1574.846 }, + { 29.3, 5.166, 3.932 }, + { 25.2, 4.338, 519.396 }, + { 24.8, 2.729, 405.258 }, + { 27.0, 6.097, 1148.248 }, + { 22.6, 0.192, 380.128 }, + { 20.5, 4.329, 3.181 }, + { 19.9, 4.630, 1677.939 }, + { 19.5, 5.106, 1073.609 }, + { 18.4, 3.765, 1485.980 }, + { 18.9, 5.053, 2104.537 }, + { 17.0, 4.018, 2317.836 }, + { 16.7, 5.429, 88.866 }, + { 15.3, 2.927, 2008.558 }, + { 14.5, 3.633, 628.852 }, + { 14.6, 5.508, 721.649 }, + { 13.7, 4.876, 629.602 }, + { 18.5, 6.030, 330.619 }, + { 13.5, 1.385, 518.645 }, + { 15.7, 2.930, 1905.465 }, + { 12.5, 1.586, 2111.650 }, + { 12.3, 3.377, 635.965 }, + { 11.8, 4.085, 2648.455 }, + { 11.2, 4.626, 636.716 }, + { 14.3, 2.742, 2221.857 }, + { 11.2, 3.553, 1891.238 }, + { 13.1, 5.838, 1464.639 }, + { 11.4, 2.576, 511.532 }, + { 10.5, 0.499, 453.425 }, + { 9.7, 4.39, 1994.33 }, + { 10.1, 2.764, 423.417 }, + { 8.6, 5.16, 1056.20 }, + { 9.0, 4.79, 2420.93 }, + { 8.1, 3.73, 2634.23 }, + { 8.1, 1.29, 2428.04 }, + { 8.9, 1.86, 750.10 }, + { 8.9, 4.81, 1062.56 }, + { 8.6, 4.54, 21.34 }, + { 9.5, 4.33, 1802.37 }, + { 6.9, 5.97, 540.74 }, + { 7.3, 4.98, 1699.28 }, + { 7.1, 4.99, 1055.45 }, + { 7.2, 4.98, 1898.35 }, + { 6.5, 1.39, 422.67 }, + { 6.8, 2.91, 2324.95 }, + { 6.5, 4.57, 1038.04 }, + { 7.3, 3.02, 416.30 }, + { 6.6, 5.55, 1781.03 }, + /* 113 terms retained, 268 terms dropped, error 1.4e-06 a.u.*T */ + + /* jupiter r, T^2 */ + { 79644.8, 1.358659, 529.690965 }, + { 8251.6, 5.77774, 522.57742 }, + { 7029.9, 3.27477, 536.80451 }, + { 5314.0, 1.83835, 1059.38193 }, + { 1860.8, 2.97682, 7.11355 }, + { 836.3, 4.1989, 419.4846 }, + { 964.5, 5.4803, 515.4639 }, + { 406.5, 3.7825, 1066.4955 }, + { 426.6, 2.2275, 639.8973 }, + { 377.3, 2.2425, 1589.0729 }, + { 497.9, 3.1416, 0 }, + { 339.0, 6.1269, 625.6702 }, + { 362.9, 5.3676, 206.1855 }, + { 342.0, 6.0992, 1052.2684 }, + { 279.9, 4.2616, 412.3711 }, + { 332.6, 0.0033, 426.5982 }, + { 229.8, 0.7053, 735.8765 }, + { 200.8, 3.0685, 543.9181 }, + { 199.8, 4.4288, 103.0928 }, + { 257.3, 0.9630, 632.7837 }, + { 138.6, 2.9324, 14.2271 }, + { 113.5, 0.7871, 728.7630 }, + { 86.0, 5.144, 323.505 }, + { 94.6, 1.705, 838.969 }, + { 83.5, 0.058, 309.278 }, + { 75.2, 1.605, 956.289 }, + { 70.5, 1.510, 213.299 }, + { 80.3, 2.981, 742.990 }, + { 56.2, 0.955, 1162.475 }, + { 61.6, 6.101, 1045.155 }, + { 66.6, 5.473, 199.072 }, + { 50.1, 2.721, 532.872 }, + { 51.9, 5.584, 942.062 }, + { 39.8, 5.946, 95.979 }, + { 44.5, 5.524, 508.350 }, + { 44.3, 0.271, 526.510 }, + { 29.9, 0.936, 1155.361 }, + { 28.4, 2.878, 525.759 }, + { 26.3, 4.269, 1596.186 }, + { 27.0, 2.806, 1169.588 }, + { 27.5, 2.648, 2118.764 }, + { 22.7, 0.178, 302.165 }, + { 29.3, 1.786, 831.856 }, + { 20.0, 0.043, 949.176 }, + { 19.9, 1.161, 533.623 }, + { 21.7, 1.888, 1272.681 }, + { 17.6, 4.150, 846.083 }, + { 17.1, 5.892, 1258.454 }, + { 21.4, 4.355, 316.392 }, + { 21.3, 0.544, 1265.567 }, + { 19.9, 0.065, 1581.959 }, + { 17.0, 0.534, 1368.660 }, + { 12.8, 3.900, 433.712 }, + { 13.1, 0.795, 110.206 }, + { 11.9, 0.407, 1361.547 }, + { 11.7, 4.444, 405.258 }, + { 12.0, 2.229, 220.413 }, + { 9.6, 6.01, 853.20 }, + { 10.2, 0.995, 1471.753 }, + { 9.0, 1.60, 1692.17 }, + { 8.7, 3.52, 1073.61 }, + { 8.3, 5.60, 1574.85 }, + { 9.0, 6.27, 519.40 }, + { 7.8, 0.65, 1478.87 }, + { 7.8, 0.18, 1685.05 }, + { 7.5, 0.88, 88.87 }, + { 7.3, 0.89, 721.65 }, + { 9.1, 1.51, 1148.25 }, + { 6.1, 2.50, 3.18 }, + { 7.0, 4.44, 330.62 }, + { 5.2, 2.79, 21.34 }, + { 5.1, 2.98, 1375.77 }, + { 4.9, 0.05, 1677.94 }, + { 4.7, 2.28, 1485.98 }, + { 4.7, 0.86, 3.93 }, + { 5.3, 0.85, 1788.14 }, + { 4.2, 0.41, 629.60 }, + { 4.2, 1.61, 635.97 }, + { 3.6, 2.71, 551.03 }, + { 3.3, 0.55, 1795.26 }, + { 4.4, 1.28, 1464.64 }, + { 3.3, 1.19, 1905.46 }, + { 3.2, 6.19, 1038.04 }, + { 3.1, 6.23, 2001.44 }, + { 3.4, 2.45, 539.99 }, + { 3.2, 5.55, 191.96 }, + { 2.6, 3.24, 1062.56 }, + { 2.6, 0.55, 2104.54 }, + { 2.2, 5.33, 1891.24 }, + { 2.7, 4.82, 416.30 }, + { 2.2, 1.72, 628.85 }, + { 2.3, 6.19, 1994.33 }, + { 2.3, 4.28, 963.40 }, + { 2.6, 0.03, 1898.35 }, + { 2.1, 3.33, 1699.28 }, + { 2.5, 2.40, 227.53 }, + { 2.5, 0.07, 750.10 }, + { 2.0, 0.29, 636.72 }, + { 1.9, 0.32, 295.05 }, + { 1.9, 3.44, 647.01 }, + { 1.9, 0.29, 2111.65 }, + { 1.9, 3.14, 611.44 }, + { 2.3, 1.95, 824.74 }, + { 1.9, 4.72, 2125.88 }, + { 2.5, 1.24, 2221.86 }, + { 1.8, 1.60, 2008.56 }, + { 1.6, 5.83, 422.67 }, + { 1.7, 2.32, 440.83 }, + { 1.6, 0.37, 1056.20 }, + { 1.6, 2.42, 10.29 }, + { 1.6, 3.52, 1055.45 }, + { 1.6, 5.76, 117.32 }, + { 1.6, 5.89, 2317.84 }, + { 2.0, 4.62, 423.42 }, + { 2.1, 1.05, 1781.03 }, + { 1.9, 1.12, 618.56 }, + { 1.9, 2.79, 1802.37 }, + { 1.8, 3.01, 2648.45 }, + /* 118 terms retained, 72 terms dropped, error 3.9e-07 a.u.*T^2 */ + + /* jupiter r, T^3 */ + { 3519.3, 6.05801, 529.69097 }, + { 1073.2, 1.67321, 536.80451 }, + { 915.7, 1.4133, 522.5774 }, + { 341.6, 0.5230, 1059.3819 }, + { 254.9, 1.1963, 7.1135 }, + { 221.5, 0.9523, 515.4639 }, + { 69.1, 2.269, 1066.495 }, + { 89.7, 3.142, 0 }, + { 57.8, 1.414, 543.918 }, + { 57.7, 0.526, 639.897 }, + { 51.1, 5.980, 412.371 }, + { 46.9, 1.579, 625.670 }, + { 42.8, 6.117, 419.485 }, + { 37.5, 1.183, 14.227 }, + { 33.8, 1.667, 1052.268 }, + { 31.2, 1.043, 1589.073 }, + { 30.0, 4.632, 426.598 }, + { 33.5, 0.848, 206.186 }, + { 20.8, 2.501, 728.763 }, + { 14.5, 0.960, 508.350 }, + { 13.0, 1.502, 1045.155 }, + { 11.7, 3.555, 323.505 }, + { 12.3, 2.610, 735.877 }, + { 15.0, 0.891, 199.072 }, + { 11.2, 1.790, 309.278 }, + { 10.6, 6.278, 956.289 }, + { 9.8, 6.26, 103.09 }, + { 9.3, 3.45, 838.97 }, + { 6.7, 1.87, 302.16 }, + { 7.4, 1.28, 742.99 }, + { 7.2, 0.92, 942.06 }, + { 5.6, 1.38, 95.98 }, + { 6.8, 3.45, 831.86 }, + { 4.6, 2.83, 1596.19 }, + { 4.0, 1.21, 1169.59 }, + { 3.9, 5.99, 213.30 }, + { 3.6, 6.11, 405.26 }, + { 2.9, 2.33, 1155.36 }, + { 2.4, 1.87, 532.87 }, + { 2.4, 0.43, 220.41 }, + { 2.3, 1.95, 1073.61 }, + { 2.3, 0.09, 632.78 }, + { 2.2, 1.59, 2118.76 }, + { 2.4, 5.97, 1162.47 }, + { 2.1, 1.07, 21.34 }, + { 2.1, 1.51, 1258.45 }, + { 2.5, 0.35, 1272.68 }, + { 2.0, 5.94, 110.21 }, + { 2.0, 2.55, 88.87 }, + { 2.0, 2.16, 433.71 }, + { 2.0, 2.70, 721.65 }, + { 1.7, 4.46, 853.20 }, + { 1.9, 2.26, 1361.55 }, + { 1.7, 1.98, 525.76 }, + { 1.5, 0.12, 949.18 }, + { 2.0, 3.17, 1148.25 }, + { 1.7, 2.71, 330.62 }, + { 1.6, 0.47, 526.51 }, + { 1.2, 3.02, 963.40 }, + { 1.7, 0.44, 533.62 }, + { 1.2, 1.16, 1574.85 }, + { 1.1, 2.55, 846.08 }, + { 1.4, 1.17, 1038.04 }, + { 1.0, 2.70, 519.40 }, + { 1.4, 0.67, 551.03 }, + { 1.0, 4.17, 2627.11 }, + { 1.1, 1.07, 227.53 }, + { 0.9, 2.93, 1368.66 }, + { 0.8, 4.87, 611.44 }, + { 1.1, 1.79, 1581.96 }, + { 0.9, 4.91, 1670.83 }, + { 0.9, 3.69, 824.74 }, + { 0.8, 3.23, 2125.88 }, + { 0.8, 2.39, 2317.84 }, + { 0.9, 0.60, 539.99 }, + { 0.9, 4.52, 750.10 }, + { 0.8, 0.21, 1141.13 }, + { 0.8, 0.94, 191.96 }, + { 0.8, 2.25, 2538.25 }, + { 0.7, 0.67, 440.83 }, + { 0.7, 5.80, 1485.98 }, + { 0.6, 2.48, 1265.57 }, + { 0.6, 6.14, 1279.79 }, + { 0.6, 5.51, 2413.82 }, + { 0.6, 4.41, 1382.89 }, + { 0.6, 2.18, 1062.56 }, + { 0.6, 1.93, 2634.23 }, + { 0.5, 2.05, 295.05 }, + { 0.5, 2.32, 1471.75 }, + { 0.7, 2.27, 1699.28 }, + { 0.5, 1.96, 1677.94 }, + { 0.5, 4.36, 1692.17 }, + { 0.5, 2.50, 2207.63 }, + { 0.5, 5.77, 1478.87 }, + { 0.4, 5.99, 934.95 }, + { 0.4, 2.80, 81.75 }, + { 0.4, 3.94, 316.39 }, + { 0.5, 0.19, 10.29 }, + /* 98 terms retained, 0 terms dropped, error 1e-07 a.u.*T^3 */ + + /* jupiter r, T^4 */ + { 128.6, 0.0842, 536.8045 }, + { 113.5, 4.2486, 529.6910 }, + { 82.7, 3.298, 522.577 }, + { 37.9, 2.733, 515.464 }, + { 26.7, 5.691, 7.114 }, + { 17.6, 5.400, 1059.382 }, + { 12.6, 6.016, 543.918 }, + { 9.3, 0.77, 1066.50 }, + { 8.1, 5.68, 14.23 }, + { 6.3, 5.12, 639.90 }, + { 7.0, 1.43, 412.37 }, + { 5.4, 3.34, 625.67 }, + { 2.9, 3.40, 1052.27 }, + { 2.6, 4.16, 728.76 }, + { 2.6, 2.90, 426.60 }, + { 2.3, 6.22, 1589.07 }, + { 2.1, 3.12, 1045.15 }, + { 1.7, 2.81, 206.19 }, + { 1.8, 2.60, 199.07 }, + { 1.8, 1.89, 419.48 }, + { 1.5, 1.33, 1596.19 }, + { 1.7, 0, 0 }, + { 1.0, 4.42, 956.29 }, + { 1.2, 5.16, 831.86 }, + { 0.9, 3.17, 508.35 }, + { 0.9, 5.79, 1169.59 }, + { 0.9, 1.87, 1148.25 }, + { 1.0, 0.67, 1361.55 }, + { 0.8, 1.48, 1272.68 }, + { 1.0, 5.47, 220.41 }, + { 0.8, 2.42, 117.32 }, + { 0.7, 0.50, 1073.61 }, + { 0.7, 3.53, 302.16 }, + { 0.7, 2.85, 191.96 }, + { 0.8, 2.20, 942.06 }, + { 0.8, 5.31, 551.03 }, + { 0.7, 3.72, 88.87 }, + { 0.5, 1.83, 647.01 }, + { 0.6, 0.86, 330.62 }, + { 0.5, 5.26, 21.34 }, + { 0.6, 3.82, 618.56 }, + { 0.5, 4.44, 110.21 }, + { 0.6, 1.59, 3.18 }, + { 0.6, 1.84, 10.29 }, + { 0.5, 1.53, 405.26 }, + { 0.5, 0.24, 433.71 }, + /* 46 terms retained, 0 terms dropped, error 7.1e-08 a.u.*T^4 */ + + /* jupiter r, T^5 */ + { 11.2, 4.752, 536.805 }, + { 4.3, 5.92, 522.58 }, + { 2.1, 5.57, 515.46 }, + { 1.9, 4.30, 543.92 }, + { 1.9, 3.69, 7.11 }, + { 1.6, 5.49, 1066.50 }, + { 1.6, 4.13, 1059.38 }, + { 1.2, 3.78, 14.23 }, + { 1.0, 4.51, 529.69 }, + /* 9 terms retained, 0 terms dropped, error 6.5e-08 a.u.*T^5 */ + /* end jupiter */ +}; + +int vn_jupiter[][3] = { + /* addresses for jupiter l, b, r */ + /* T^0 */ { 0, 392, 542, }, + /* T^1 */ { 109, 428, 672, }, + /* T^2 */ { 194, 468, 785, }, + /* T^3 */ { 271, 504, 903, }, + /* T^4 */ { 341, 526, 1001, }, + /* T^5 */ { 383, 538, 1047, }, + /* end */ { 392, 542, 1056, }, + /* termination */ { 0, } +}; + +/* version d4 (lbr) + * heliocentric dynamical ecliptic and equinox of the date + */ + +double vx_mars[][3] = { + /* mars l, T^0 */ + { 620347711.6, 0, 0 }, + { 18656368.1, 5.050371003, 3340.612426700 }, + { 1108216.8, 5.40099837, 6681.22485340 }, + { 91798.4, 5.754787, 10021.837280 }, + { 27745.0, 5.970495, 3.523118 }, + { 10610.2, 2.939585, 2281.230497 }, + { 12315.9, 0.849561, 2810.921462 }, + { 8926.8, 4.15698, 0.01725 }, + { 8715.7, 6.11005, 13362.44971 }, + { 6797.6, 0.36462, 398.14900 }, + { 7774.9, 3.33969, 5621.84292 }, + { 3575.1, 1.66187, 2544.31442 }, + { 4161.1, 0.22815, 2942.46342 }, + { 3075.2, 0.85697, 191.44827 }, + { 2628.1, 0.64806, 3337.08931 }, + { 2937.5, 6.07894, 0.06731 }, + { 2389.4, 5.03896, 796.29801 }, + { 2579.8, 0.02997, 3344.13555 }, + { 1528.1, 1.14979, 6151.53389 }, + { 1798.8, 0.65634, 529.69097 }, + { 1264.4, 3.62275, 5092.15196 }, + { 1286.2, 3.06796, 2146.16542 }, + { 1546.4, 2.91580, 1751.53953 }, + { 1024.9, 3.69334, 8962.45535 }, + { 891.6, 0.1829, 16703.0621 }, + { 858.8, 2.4009, 2914.0142 }, + { 832.7, 2.4642, 3340.5952 }, + { 832.7, 4.4950, 3340.6297 }, + { 712.9, 3.6634, 1059.3819 }, + { 748.7, 3.8225, 155.4204 }, + { 723.9, 0.6750, 3738.7614 }, + { 635.6, 2.9218, 8432.7644 }, + { 655.2, 0.4886, 3127.3133 }, + { 550.5, 3.8100, 0.9803 }, + { 552.7, 4.4748, 1748.0164 }, + { 426.0, 0.5537, 6283.0758 }, + { 415.1, 0.4966, 213.2991 }, + { 472.2, 3.6255, 1194.4470 }, + { 306.6, 0.3805, 6684.7480 }, + { 312.1, 0.9985, 6677.7017 }, + { 293.2, 4.2213, 20.7754 }, + { 302.4, 4.4862, 3532.0607 }, + { 274.0, 0.5422, 3340.5451 }, + { 281.1, 5.8816, 1349.8674 }, + { 231.2, 1.2824, 3870.3034 }, + { 283.6, 5.7689, 3149.1642 }, + { 236.1, 5.7550, 3333.4989 }, + { 274.0, 0.1337, 3340.6797 }, + { 299.4, 2.7832, 6254.6267 }, + { 204.2, 2.8213, 1221.8486 }, + { 238.9, 5.3716, 4136.9104 }, + { 188.6, 1.4910, 9492.1463 }, + { 221.2, 3.5047, 382.8965 }, + { 179.2, 1.0056, 951.7184 }, + { 172.1, 0.4394, 5486.7778 }, + { 193.1, 3.3572, 3.5904 }, + { 144.3, 1.4187, 135.0651 }, + { 160.0, 3.9485, 4562.4610 }, + { 174.1, 2.4136, 553.5694 }, + { 131.0, 4.0449, 12303.0678 }, + { 138.2, 4.3015, 7.1135 }, + { 128.1, 1.8067, 5088.6288 }, + { 139.9, 3.3259, 2700.7151 }, + { 128.1, 2.2081, 1592.5960 }, + { 116.9, 3.1281, 7903.0734 }, + { 110.4, 1.0520, 242.7286 }, + { 113.5, 3.7007, 1589.0729 }, + { 100.1, 3.2434, 11773.3768 }, + { 95.6, 0.540, 20043.675 }, + { 98.9, 4.846, 6681.242 }, + { 104.5, 0.7854, 8827.3903 }, + { 84.2, 3.990, 4399.994 }, + { 86.9, 2.202, 11243.686 }, + { 71.4, 2.803, 3185.192 }, + { 72.1, 5.847, 5884.927 }, + { 73.5, 2.184, 8429.241 }, + { 98.9, 2.815, 6681.208 }, + { 68.4, 2.738, 2288.344 }, + { 86.8, 1.021, 7079.374 }, + { 65.3, 2.681, 28.449 }, + { 83.7, 3.203, 4690.480 }, + { 75.0, 0.766, 6467.926 }, + { 69.0, 3.764, 6041.328 }, + { 66.7, 0.736, 3723.509 }, + { 63.3, 4.528, 426.598 }, + { 61.7, 6.168, 2274.117 }, + { 52.3, 0.899, 9623.688 }, + { 55.5, 4.606, 4292.331 }, + { 51.3, 4.148, 3341.593 }, + { 56.6, 5.063, 15.252 }, + { 63.4, 0.913, 3553.912 }, + { 45.8, 0.788, 1990.745 }, + { 48.5, 3.957, 4535.059 }, + { 41.2, 6.020, 3894.182 }, + { 41.9, 3.583, 8031.092 }, + { 56.4, 1.687, 6872.673 }, + { 55.9, 3.463, 263.084 }, + { 51.7, 2.813, 3339.632 }, + { 40.7, 3.138, 9595.239 }, + { 38.1, 0.734, 10025.360 }, + { 39.5, 5.632, 3097.884 }, + { 44.2, 3.195, 5628.956 }, + { 36.7, 2.637, 692.158 }, + { 45.9, 0.287, 5614.729 }, + { 38.4, 5.829, 3191.049 }, + { 38.2, 2.348, 162.467 }, + { 32.6, 0.484, 6681.292 }, + { 37.1, 0.685, 2818.035 }, + { 31.2, 3.982, 20.355 }, + { 32.6, 0.893, 6681.158 }, + { 37.8, 4.155, 2803.808 }, + { 33.6, 6.120, 6489.777 }, + { 29.0, 2.427, 3319.837 }, + { 38.8, 1.352, 10018.314 }, + { 33.1, 1.140, 5.523 }, + { 27.6, 1.597, 7210.916 }, + { 28.7, 5.721, 7477.523 }, + { 34.0, 2.595, 11769.854 }, + { 25.4, 0.521, 10.637 }, + { 26.4, 1.345, 3496.033 }, + { 25.6, 0.250, 522.577 }, + { 27.3, 4.556, 3361.388 }, + { 27.5, 6.084, 6674.111 }, + { 25.5, 3.432, 3443.705 }, + /* 124 terms retained, 1093 terms dropped, error 1.2" */ + + /* mars l, T^1 */ + { 334085627474.3, 0, 0 }, + { 1458227.1, 3.60426054, 3340.61242670 }, + { 164901.3, 3.9263125, 6681.2248534 }, + { 19963.3, 4.265941, 10021.837280 }, + { 3452.4, 4.73210, 3.52312 }, + { 2485.5, 4.61278, 13362.44971 }, + { 841.6, 4.4586, 2281.2305 }, + { 537.6, 5.0159, 398.1490 }, + { 521.0, 4.9942, 3344.1355 }, + { 432.6, 2.5607, 191.4483 }, + { 429.7, 5.3165, 155.4204 }, + { 381.7, 3.5388, 796.2980 }, + { 314.1, 4.9634, 16703.0621 }, + { 282.8, 3.1597, 2544.3144 }, + { 205.7, 4.5689, 2146.1654 }, + { 168.8, 1.3289, 3337.0893 }, + { 157.6, 4.1850, 1751.5395 }, + { 133.7, 2.2333, 0.9803 }, + { 116.6, 2.2135, 1059.3819 }, + { 117.6, 6.0241, 6151.5339 }, + { 113.6, 5.4280, 3738.7614 }, + { 133.6, 5.9742, 1748.0164 }, + { 91.1, 1.096, 1349.867 }, + { 83.3, 5.296, 6684.748 }, + { 113.9, 2.1287, 1194.4470 }, + { 80.8, 4.428, 529.691 }, + { 79.5, 2.249, 8962.455 }, + { 72.5, 5.842, 242.729 }, + { 72.9, 2.502, 951.718 }, + { 71.5, 3.856, 2914.014 }, + { 85.3, 3.909, 553.569 }, + { 67.6, 5.023, 382.897 }, + { 65.1, 1.018, 3340.595 }, + { 65.1, 3.049, 3340.630 }, + { 61.5, 4.152, 3149.164 }, + { 48.5, 4.874, 213.299 }, + { 46.6, 1.315, 3185.192 }, + { 56.5, 3.888, 4136.910 }, + { 47.6, 1.182, 3333.499 }, + { 41.3, 0.714, 1592.596 }, + { 40.1, 5.316, 20043.675 }, + { 40.3, 2.725, 7.114 }, + { 32.9, 5.411, 6283.076 }, + { 28.2, 0.045, 9492.146 }, + { 22.3, 5.885, 3870.303 }, + { 22.4, 5.466, 20.355 }, + { 22.6, 0.838, 3097.884 }, + { 21.4, 5.379, 3340.545 }, + { 23.3, 6.168, 3532.061 }, + { 26.6, 3.890, 1221.849 }, + { 22.8, 1.545, 2274.117 }, + { 20.4, 2.364, 1589.073 }, + { 20.2, 3.364, 5088.629 }, + { 26.6, 5.113, 2700.715 }, + { 19.7, 2.578, 12303.068 }, + { 19.5, 0.492, 6677.702 }, + { 21.1, 3.525, 15.252 }, + { 21.4, 4.971, 3340.680 }, + { 18.5, 5.579, 1990.745 }, + { 17.8, 6.125, 4292.331 }, + { 16.5, 2.603, 3341.593 }, + { 16.6, 1.255, 3894.182 }, + { 19.5, 2.531, 4399.994 }, + { 15.0, 1.035, 2288.344 }, + { 20.0, 4.731, 4690.480 }, + { 15.4, 2.470, 4535.059 }, + { 20.0, 5.787, 7079.374 }, + { 15.3, 2.265, 3723.509 }, + { 14.7, 3.370, 6681.242 }, + { 13.5, 2.123, 5486.778 }, + { 12.9, 5.619, 10025.360 }, + { 12.7, 2.950, 3496.033 }, + { 13.6, 1.977, 5614.729 }, + { 13.0, 1.514, 5628.956 }, + { 14.7, 1.339, 6681.208 }, + { 11.4, 6.234, 135.065 }, + { 13.3, 3.422, 5621.843 }, + { 10.9, 5.282, 2818.035 }, + { 11.8, 3.127, 426.598 }, + { 10.5, 2.736, 2787.043 }, + { 11.1, 5.842, 2803.808 }, + { 11.8, 2.586, 8432.764 }, + { 11.9, 5.476, 3553.912 }, + { 8.5, 1.91, 11773.38 }, + { 9.7, 4.53, 6489.78 }, + { 8.6, 3.16, 162.47 }, + { 11.0, 4.158, 2388.894 }, + { 8.1, 1.61, 2957.72 }, + { 8.8, 4.23, 7477.52 }, + { 8.0, 5.70, 6041.33 }, + { 8.3, 2.18, 23.88 }, + { 7.7, 5.72, 9623.69 }, + { 8.7, 4.44, 5092.15 }, + { 8.4, 3.16, 3347.73 }, + { 6.7, 5.08, 8031.09 }, + { 8.7, 4.33, 3339.63 }, + { 7.4, 6.18, 3583.34 }, + { 6.4, 2.12, 5884.93 }, + /* 98 terms retained, 588 terms dropped, error 0.26"*T */ + + /* mars l, T^2 */ + { 58015.8, 2.049795, 3340.612427 }, + { 54187.6, 0, 0 }, + { 13908.4, 2.457424, 6681.224853 }, + { 2465.1, 2.80000, 10021.83728 }, + { 398.4, 3.1412, 13362.4497 }, + { 222.0, 3.1944, 3.5231 }, + { 121.0, 0.5433, 155.4204 }, + { 61.5, 3.485, 16703.062 }, + { 53.6, 3.542, 3344.136 }, + { 34.3, 6.002, 2281.230 }, + { 31.7, 4.140, 191.448 }, + { 29.8, 1.999, 796.298 }, + { 23.2, 4.334, 242.729 }, + { 21.7, 3.445, 398.149 }, + { 16.0, 6.110, 2146.165 }, + { 20.4, 5.422, 553.569 }, + { 14.9, 6.095, 3185.192 }, + { 16.2, 0.657, 0.980 }, + { 14.3, 2.619, 1349.867 }, + { 14.4, 4.019, 951.718 }, + { 11.9, 3.861, 6684.748 }, + { 15.6, 1.221, 1748.016 }, + { 11.3, 4.718, 2544.314 }, + { 13.4, 0.602, 1194.447 }, + { 10.4, 0.250, 382.897 }, + { 9.5, 0.68, 1059.38 }, + { 9.2, 3.83, 20043.67 }, + { 9.0, 3.88, 3738.76 }, + { 7.5, 5.46, 1751.54 }, + { 6.5, 5.48, 1592.60 }, + { 6.3, 2.34, 3097.88 }, + { 6.9, 2.58, 3149.16 }, + { 5.9, 1.15, 7.11 }, + { 6.7, 2.38, 4136.91 }, + { 4.6, 4.43, 6151.53 }, + { 4.2, 3.69, 5614.73 }, + { 4.8, 2.90, 3333.50 }, + { 4.0, 6.12, 5628.96 }, + { 3.7, 4.07, 1990.75 }, + { 3.6, 2.47, 529.69 }, + { 3.3, 0.68, 8962.46 }, + { 3.3, 2.80, 3894.18 }, + { 3.1, 4.57, 3496.03 }, + { 2.9, 5.41, 2914.01 }, + { 2.9, 1.23, 2787.04 }, + { 2.8, 1.39, 4292.33 }, + { 2.6, 1.04, 3341.59 }, + { 2.9, 3.41, 3337.09 }, + { 2.4, 0.96, 4535.06 }, + { 2.4, 4.85, 9492.15 }, + { 2.6, 5.75, 3340.60 }, + { 2.2, 3.26, 213.30 }, + { 2.6, 1.50, 3340.63 }, + { 2.3, 4.18, 10025.36 }, + { 2.6, 4.68, 3583.34 }, + { 2.6, 2.65, 2388.89 }, + { 1.8, 0.97, 1589.07 }, + { 2.4, 1.05, 4399.99 }, + { 2.4, 4.27, 7079.37 }, + { 2.2, 0.16, 6525.80 }, + { 2.3, 0.01, 4690.48 }, + { 1.6, 4.96, 5088.63 }, + { 1.6, 1.11, 12303.07 }, + { 2.1, 0.48, 2700.72 }, + { 1.6, 4.94, 1221.85 }, + { 1.8, 3.81, 3723.51 }, + { 1.8, 2.52, 2810.92 }, + /* 67 terms retained, 243 terms dropped, error 0.06"*T^2 */ + + /* mars l, T^3 */ + { 1482.4, 0.44435, 3340.61243 }, + { 662.1, 0.8847, 6681.2249 }, + { 188.3, 1.2880, 10021.8373 }, + { 41.5, 1.649, 13362.450 }, + { 22.7, 2.053, 155.420 }, + { 26.0, 0, 0 }, + { 8.0, 2.00, 16703.06 }, + { 10.5, 1.580, 3.523 }, + { 4.9, 2.82, 242.73 }, + { 3.8, 2.02, 3344.14 }, + { 3.2, 4.59, 3185.19 }, + { 3.1, 0.65, 553.57 }, + { 1.7, 5.54, 951.72 }, + { 1.5, 5.72, 191.45 }, + { 1.4, 0.46, 796.30 }, + { 1.4, 2.34, 20043.67 }, + { 1.3, 5.36, 0.98 }, + { 1.2, 4.15, 1349.87 }, + { 1.1, 2.38, 6684.75 }, + { 1.0, 1.77, 382.90 }, + { 0.9, 5.34, 1194.45 }, + { 0.8, 2.75, 1748.02 }, + { 0.6, 6.11, 3496.03 }, + { 0.6, 1.85, 398.15 }, + { 0.6, 5.86, 7.11 }, + { 0.6, 3.18, 3583.34 }, + { 0.5, 5.98, 2787.04 }, + { 0.5, 1.01, 3149.16 }, + { 0.5, 4.93, 6525.80 }, + { 0.4, 1.27, 2281.23 }, + { 0.4, 2.33, 3738.76 }, + { 0.5, 0.84, 4136.91 }, + /* 32 terms retained, 97 terms dropped, error 0.011"*T^3 */ + + /* mars l, T^4 */ + { 114.0, 3.1416, 0 }, + { 28.7, 5.637, 6681.225 }, + { 24.4, 5.139, 3340.612 }, + { 11.2, 6.032, 10021.837 }, + { 3.2, 3.56, 155.42 }, + { 3.3, 0.13, 13362.45 }, + { 0.8, 0.49, 16703.06 }, + { 0.8, 1.32, 242.73 }, + { 0.5, 3.06, 3185.19 }, + { 0.4, 2.16, 553.57 }, + { 0.3, 6.23, 3.52 }, + { 0.2, 0.44, 3344.14 }, + { 0.2, 0.82, 20043.67 }, + { 0.2, 3.74, 3496.03 }, + { 0.1, 1.67, 3583.34 }, + /* 15 terms retained, 21 terms dropped, error 0.0019"*T^4 */ + + /* mars l, T^5 */ + { 0.7, 4.04, 6681.22 }, + { 0.9, 3.14, 0 }, + { 0.5, 4.49, 10021.84 }, + { 0.4, 5.07, 155.42 }, + { 0.2, 3.51, 3340.61 }, + { 0.2, 4.85, 13362.45 }, + { 0.1, 6.09, 242.73 }, + /* 7 terms retained, 8 terms dropped, error 0.0012"*T^5 */ + /* end mars l */ + + /* mars b, T^0 */ + { 3197135.0, 3.76832042, 3340.61242670 }, + { 298033.2, 4.1061700, 6681.2248534 }, + { 289104.7, 0, 0 }, + { 31365.5, 4.446511, 10021.837280 }, + { 3484.1, 4.78813, 13362.44971 }, + { 443.0, 5.6523, 3337.0893 }, + { 443.4, 5.0264, 3344.1355 }, + { 399.1, 5.1306, 16703.0621 }, + { 292.5, 3.7929, 2281.2305 }, + { 182.0, 6.1365, 6151.5339 }, + { 163.2, 4.2640, 529.6910 }, + { 159.7, 2.2319, 1059.3819 }, + { 139.3, 2.4180, 8962.4553 }, + { 149.3, 2.1650, 5621.8429 }, + { 142.7, 1.1822, 3340.5952 }, + { 142.7, 3.2129, 3340.6297 }, + { 82.5, 5.367, 6684.748 }, + { 73.6, 5.092, 398.149 }, + { 72.7, 5.538, 6283.076 }, + { 86.4, 5.744, 3738.761 }, + { 83.3, 5.989, 6677.702 }, + { 60.1, 3.680, 796.298 }, + { 63.1, 0.730, 5884.927 }, + { 62.3, 4.851, 2942.463 }, + { 47.0, 5.543, 3340.545 }, + { 47.0, 5.135, 3340.680 }, + { 46.6, 5.474, 20043.675 }, + { 45.6, 2.133, 2810.921 }, + { 41.3, 0.200, 9492.146 }, + { 47.2, 4.522, 3149.164 }, + { 38.5, 4.080, 4136.910 }, + { 33.1, 4.066, 1751.540 }, + { 29.7, 5.922, 3532.061 }, + { 32.7, 2.621, 2914.014 }, + { 29.5, 2.753, 12303.068 }, + { 28.2, 2.063, 5486.778 }, + { 28.6, 4.947, 3870.303 }, + { 26.6, 3.551, 6681.242 }, + { 26.6, 1.520, 6681.208 }, + { 26.1, 2.601, 4399.994 }, + /* 40 terms retained, 401 terms dropped, error 0.69" */ + + /* mars b, T^1 */ + { 350068.8, 5.3684784, 3340.6124267 }, + { 14116.0, 3.141593, 0 }, + { 9670.8, 5.47878, 6681.22485 }, + { 1471.9, 3.20206, 10021.83728 }, + { 425.9, 3.4084, 13362.4497 }, + { 102.0, 0.7762, 3337.0893 }, + { 78.8, 3.718, 16703.062 }, + { 26.2, 2.483, 2281.230 }, + { 32.7, 3.458, 5621.843 }, + { 20.7, 1.441, 6151.534 }, + { 18.3, 6.031, 529.691 }, + { 15.7, 3.931, 8962.455 }, + { 17.0, 4.811, 3344.136 }, + { 13.1, 0.973, 6677.702 }, + { 15.6, 2.782, 3340.595 }, + { 15.6, 4.813, 3340.630 }, + { 13.8, 1.680, 3532.061 }, + { 12.7, 4.045, 20043.675 }, + { 14.3, 0.246, 2942.463 }, + { 12.5, 2.256, 5884.927 }, + { 8.8, 0.34, 398.15 }, + { 8.6, 1.75, 2544.31 }, + { 8.9, 5.95, 2810.92 }, + { 8.1, 0.84, 6283.08 }, + { 9.2, 4.35, 3496.03 }, + { 8.1, 4.30, 6684.75 }, + /* 26 terms retained, 261 terms dropped, error 0.17"*T */ + + /* mars b, T^2 */ + { 16726.7, 0.602214, 3340.612427 }, + { 4986.8, 3.14159, 0 }, + { 302.1, 5.5587, 6681.2249 }, + { 25.8, 1.897, 13362.450 }, + { 21.5, 0.917, 10021.837 }, + { 11.8, 2.242, 3337.089 }, + { 8.0, 2.25, 16703.06 }, + { 3.0, 5.89, 3496.03 }, + { 2.4, 5.19, 5621.84 }, + { 1.8, 2.59, 20043.67 }, + /* 10 terms retained, 120 terms dropped, error 0.024"*T^2 */ + + /* mars b, T^3 */ + { 606.5, 1.9805, 3340.6124 }, + { 42.6, 0, 0 }, + { 13.7, 1.796, 6681.225 }, + { 2.7, 3.45, 10021.84 }, + { 0.9, 3.75, 3337.09 }, + { 0.6, 0.11, 13362.45 }, + { 0.6, 1.14, 3496.03 }, + { 0.5, 0.71, 16703.06 }, + /* 8 terms retained, 33 terms dropped, error 0.0059"*T^3 */ + + /* mars b, T^4 */ + { 11.3, 3.457, 3340.612 }, + { 13.4, 0, 0 }, + { 0.7, 0.50, 6681.22 }, + { 0.1, 1.05, 10021.84 }, + { 0.1, 2.66, 3496.03 }, + /* 5 terms retained, 6 terms dropped, error 0.001"*T^4 */ + + /* mars b, T^5 */ + { 0.5, 4.87, 3340.61 }, + /* 1 terms retained, 4 terms dropped, error 0.0027"*T^5 */ + /* end mars b */ + + /* mars r, T^0 */ + { 153033488.3, 0, 0 }, + { 14184953.2, 3.479712835, 3340.612426700 }, + { 660776.4, 3.8178344, 6681.2248534 }, + { 46179.1, 4.155953, 10021.837280 }, + { 8109.7, 5.55958, 2810.92146 }, + { 7485.3, 1.77239, 5621.84292 }, + { 5523.2, 1.36436, 2281.23050 }, + { 3825.2, 4.49407, 13362.44971 }, + { 2306.5, 0.09082, 2544.31442 }, + { 1999.4, 5.36060, 3337.08931 }, + { 2484.4, 4.92546, 2942.46342 }, + { 1960.2, 4.74249, 3344.13555 }, + { 1167.1, 2.11262, 5092.15196 }, + { 1102.8, 5.00908, 398.14900 }, + { 899.1, 4.4079, 529.6910 }, + { 992.3, 5.8386, 6151.5339 }, + { 807.3, 2.1022, 1059.3819 }, + { 797.9, 3.4484, 796.2980 }, + { 741.0, 1.4991, 2146.1654 }, + { 692.3, 2.1338, 8962.4553 }, + { 633.1, 0.8935, 3340.5952 }, + { 725.6, 1.2452, 8432.7644 }, + { 633.1, 2.9243, 3340.6297 }, + { 574.4, 0.8290, 2914.0142 }, + { 526.2, 5.3829, 3738.7614 }, + { 630.0, 1.2874, 1751.5395 }, + { 472.8, 5.1985, 3127.3133 }, + { 348.1, 4.8322, 16703.0621 }, + { 283.7, 2.9069, 3532.0607 }, + { 279.6, 5.2575, 6283.0758 }, + { 233.8, 5.1055, 5486.7778 }, + { 219.4, 5.5834, 191.4483 }, + { 269.9, 3.7639, 5884.9268 }, + { 208.3, 5.2548, 3340.5451 }, + { 275.2, 2.9082, 1748.0164 }, + { 275.5, 1.2177, 6254.6267 }, + { 239.1, 2.0367, 1194.4470 }, + { 223.2, 4.1986, 3149.1642 }, + { 182.7, 5.0806, 6684.7480 }, + { 186.2, 5.6987, 6677.7017 }, + { 176.0, 5.9534, 3870.3034 }, + { 178.6, 4.1842, 3333.4989 }, + { 208.3, 4.8463, 3340.6797 }, + { 228.1, 3.2553, 6872.6731 }, + { 144.3, 0.2130, 5088.6288 }, + { 163.5, 3.7989, 4136.9104 }, + { 133.1, 1.5391, 7903.0734 }, + { 141.8, 2.4779, 4562.4610 }, + { 114.9, 4.3175, 1349.8674 }, + { 118.8, 2.1218, 1589.0729 }, + { 102.1, 6.1814, 9492.1463 }, + { 128.6, 5.4988, 8827.3903 }, + { 111.5, 0.5534, 11243.6858 }, + { 82.5, 1.622, 11773.377 }, + { 83.2, 0.616, 8429.241 }, + { 84.5, 0.623, 1592.596 }, + { 86.7, 1.750, 2700.715 }, + { 71.8, 2.475, 12303.068 }, + { 85.3, 1.616, 4690.480 }, + { 63.6, 2.673, 426.598 }, + { 68.6, 2.402, 4399.994 }, + { 58.6, 4.721, 213.299 }, + { 62.0, 1.101, 1221.849 }, + { 66.5, 2.213, 6041.328 }, + { 55.8, 1.233, 3185.192 }, + { 55.0, 5.727, 951.718 }, + { 52.4, 3.024, 4292.331 }, + { 55.7, 5.447, 3723.509 }, + { 59.0, 3.262, 6681.242 }, + { 44.6, 2.015, 8031.092 }, + { 59.0, 1.232, 6681.208 }, + { 42.4, 2.266, 155.420 }, + { 39.0, 2.578, 3341.593 }, + { 51.6, 5.723, 7079.374 }, + { 48.9, 5.616, 3553.912 }, + { 45.4, 5.433, 6467.926 }, + { 36.4, 4.439, 3894.182 }, + { 36.0, 1.160, 2288.344 }, + { 35.3, 5.490, 1990.745 }, + { 42.2, 1.633, 5628.956 }, + { 44.3, 5.003, 5614.729 }, + { 33.6, 5.170, 20043.675 }, + { 43.3, 1.037, 11769.854 }, + { 39.2, 1.242, 3339.632 }, + { 31.9, 4.593, 2274.117 }, + { 30.3, 2.442, 11371.705 }, + { 32.3, 2.382, 4535.059 }, + { 31.9, 4.375, 3.523 }, + { 29.3, 4.060, 3097.884 }, + { 32.0, 1.940, 382.897 }, + { 26.2, 5.585, 9623.688 }, + { 27.9, 4.258, 3191.049 }, + { 33.1, 0.855, 553.569 }, + { 27.5, 1.577, 9595.239 }, + { 25.2, 0.814, 10713.995 }, + /* 95 terms retained, 1023 terms dropped, error 4.9e-06 a.u. */ + + /* mars r, T^1 */ + { 1107433.3, 2.03250525, 3340.61242670 }, + { 103175.9, 2.3707185, 6681.2248534 }, + { 12877.2, 0, 0 }, + { 10815.9, 2.708881, 10021.837280 }, + { 1194.5, 3.04702, 13362.44971 }, + { 438.6, 2.8884, 2281.2305 }, + { 395.7, 3.4232, 3344.1355 }, + { 182.6, 1.5843, 2544.3144 }, + { 135.8, 3.3851, 16703.0621 }, + { 128.2, 0.6299, 1059.3819 }, + { 127.1, 1.9539, 796.2980 }, + { 118.4, 2.9976, 2146.1654 }, + { 128.4, 6.0434, 3337.0893 }, + { 87.5, 3.421, 398.149 }, + { 83.0, 3.856, 3738.761 }, + { 75.6, 4.451, 6151.534 }, + { 72.0, 2.764, 529.691 }, + { 66.5, 2.549, 1751.540 }, + { 54.3, 0.678, 8962.455 }, + { 51.0, 3.726, 6684.748 }, + { 66.4, 4.406, 1748.016 }, + { 47.9, 2.285, 2914.014 }, + { 49.4, 5.730, 3340.595 }, + { 49.4, 1.477, 3340.630 }, + { 57.5, 0.544, 1194.447 }, + { 48.3, 2.581, 3149.164 }, + { 36.4, 6.027, 3185.192 }, + { 37.2, 5.814, 1349.867 }, + { 36.0, 5.895, 3333.499 }, + { 31.1, 0.978, 191.448 }, + { 39.0, 2.319, 4136.910 }, + { 27.2, 5.414, 1592.596 }, + { 24.3, 3.758, 155.420 }, + { 22.8, 1.748, 5088.629 }, + { 22.3, 0.939, 951.718 }, + { 21.7, 3.836, 6283.076 }, + { 21.3, 0.780, 1589.073 }, + { 21.6, 4.569, 3532.061 }, + { 18.0, 4.219, 3870.303 }, + { 18.2, 0.413, 5486.778 }, + { 16.3, 3.808, 3340.545 }, + { 16.8, 5.549, 3097.884 }, + { 16.9, 4.537, 4292.331 }, + { 15.8, 4.757, 9492.146 }, + { 15.7, 3.724, 20043.675 }, + { 20.4, 3.135, 4690.480 }, + { 14.7, 5.953, 3894.182 }, + { 16.3, 3.399, 3340.680 }, + { 14.3, 3.999, 1990.745 }, + { 16.5, 0.968, 4399.994 }, + { 13.0, 5.142, 6677.702 }, + { 12.5, 1.032, 3341.593 }, + { 16.5, 3.539, 2700.715 }, + { 16.2, 2.349, 553.569 }, + { 13.2, 0.415, 5614.729 }, + { 11.3, 1.024, 12303.068 }, + { 12.4, 6.231, 5628.956 }, + { 12.7, 0.690, 3723.509 }, + { 11.8, 6.253, 2274.117 }, + { 10.4, 1.233, 426.598 }, + { 11.2, 1.318, 3496.033 }, + { 10.3, 0.901, 4535.059 }, + { 12.2, 4.223, 7079.374 }, + { 9.8, 3.45, 382.90 }, + { 8.6, 1.16, 2787.04 }, + { 7.9, 5.74, 2288.34 }, + { 9.2, 1.82, 6681.24 }, + { 7.8, 4.15, 6041.33 }, + { 9.2, 6.07, 6681.21 }, + { 9.0, 2.58, 2388.89 }, + { 6.8, 0.24, 11773.38 }, + { 7.1, 3.51, 8031.09 }, + { 9.2, 3.90, 3553.91 }, + { 6.7, 4.26, 242.73 }, + { 7.2, 3.70, 2818.04 }, + { 6.5, 0.04, 2957.72 }, + { 8.8, 2.20, 1221.85 }, + { 6.5, 2.12, 8429.24 }, + { 6.8, 4.05, 10025.36 }, + { 7.3, 4.27, 2803.81 }, + { 7.7, 1.01, 8432.76 }, + { 6.3, 1.90, 5621.84 }, + { 6.3, 1.60, 3347.73 }, + { 6.5, 2.76, 3339.63 }, + /* 84 terms retained, 512 terms dropped, error 1.2e-06 a.u.*T */ + + /* mars r, T^2 */ + { 44242.2, 0.479306, 3340.612427 }, + { 8138.0, 0.86998, 6681.22485 }, + { 1274.9, 1.22594, 10021.83728 }, + { 187.4, 1.5730, 13362.4497 }, + { 40.7, 1.971, 3344.136 }, + { 52.4, 3.142, 0 }, + { 26.6, 1.917, 16703.062 }, + { 17.8, 4.435, 2281.230 }, + { 11.7, 4.525, 3185.192 }, + { 10.2, 5.391, 1059.382 }, + { 9.9, 0.42, 796.30 }, + { 9.2, 4.54, 2146.17 }, + { 7.3, 3.14, 2544.31 }, + { 7.2, 2.29, 6684.75 }, + { 6.8, 5.27, 155.42 }, + { 6.5, 2.31, 3738.76 }, + { 7.8, 5.93, 1748.02 }, + { 5.8, 1.05, 1349.87 }, + { 6.7, 5.30, 1194.45 }, + { 4.7, 0.77, 3097.88 }, + { 5.4, 1.00, 3149.16 }, + { 4.4, 2.46, 951.72 }, + { 4.3, 3.90, 1592.60 }, + { 3.5, 1.85, 398.15 }, + { 3.7, 2.26, 20043.67 }, + { 3.4, 3.82, 1751.54 }, + { 4.6, 0.81, 4136.91 }, + { 3.2, 2.12, 5614.73 }, + { 3.6, 1.32, 3333.50 }, + { 2.9, 1.19, 529.69 }, + { 3.0, 2.86, 6151.53 }, + { 3.1, 4.55, 5628.96 }, + { 2.9, 1.20, 3894.18 }, + { 3.9, 3.86, 553.57 }, + { 2.8, 2.49, 1990.75 }, + { 2.7, 6.07, 4292.33 }, + { 2.7, 2.92, 3496.03 }, + { 2.4, 5.94, 2787.04 }, + { 2.3, 2.56, 191.45 }, + { 2.2, 5.37, 8962.46 }, + { 2.1, 2.75, 242.73 }, + { 2.2, 1.85, 3337.09 }, + { 2.0, 5.76, 3341.59 }, + { 2.0, 3.82, 2914.01 }, + { 1.8, 5.69, 1589.07 }, + { 1.8, 3.32, 5088.63 }, + { 2.4, 4.68, 4690.48 }, + { 2.0, 4.17, 3340.60 }, + { 2.0, 6.21, 3340.63 }, + { 1.6, 5.68, 4535.06 }, + { 2.2, 1.07, 2388.89 }, + { 2.0, 3.11, 3583.34 }, + { 2.0, 5.76, 4399.99 }, + /* 53 terms retained, 260 terms dropped, error 2.9e-07 a.u.*T^2 */ + + /* mars r, T^3 */ + { 1113.1, 5.14987, 3340.61243 }, + { 424.4, 5.6134, 6681.2249 }, + { 100.0, 5.9973, 10021.8373 }, + { 19.6, 0.076, 13362.450 }, + { 3.5, 0.43, 16703.06 }, + { 4.7, 3.14, 0 }, + { 2.9, 0.45, 3344.14 }, + { 2.4, 3.02, 3185.19 }, + { 0.7, 0.81, 6684.75 }, + { 0.5, 3.87, 1059.38 }, + { 0.6, 0.78, 20043.67 }, + { 0.5, 4.52, 3496.03 }, + { 0.5, 1.61, 3583.34 }, + { 0.4, 5.72, 3149.16 }, + /* 14 terms retained, 97 terms dropped, error 3.1e-08 a.u.*T^3 */ + + /* mars r, T^4 */ + { 19.6, 3.582, 3340.612 }, + { 16.3, 4.051, 6681.225 }, + { 5.8, 4.46, 10021.84 }, + { 1.5, 4.84, 13362.45 }, + { 0.4, 1.51, 3185.19 }, + { 0.3, 5.21, 16703.06 }, + { 0.2, 5.16, 3344.14 }, + { 0.1, 2.19, 3496.03 }, + { 0.1, 0, 0 }, + /* 9 terms retained, 19 terms dropped, error 9.4e-09 a.u.*T^4 */ + + /* mars r, T^5 */ + { 0.5, 2.48, 6681.22 }, + { 0.3, 2.92, 10021.84 }, + { 0.1, 1.77, 3340.61 }, + /* 3 terms retained, 6 terms dropped, error 4.6e-09 a.u.*T^5 */ + /* end mars */ +}; + +int vn_mars[][3] = { + /* addresses for mars l, b, r */ + /* T^0 */ { 0, 343, 433, }, + /* T^1 */ { 124, 383, 528, }, + /* T^2 */ { 222, 409, 612, }, + /* T^3 */ { 289, 419, 665, }, + /* T^4 */ { 321, 427, 679, }, + /* T^5 */ { 336, 432, 688, }, + /* end */ { 343, 433, 691, }, + /* termination */ { 0, } +}; + +/* version d4 (lbr) + * heliocentric dynamical ecliptic and equinox of the date + */ + +double vx_mercury[][3] = { + /* mercury l, T^0 */ + { 440250710.1, 0, 0 }, + { 40989415.0, 1.483020342, 26087.903141574 }, + { 5046294.2, 4.47785490, 52175.80628315 }, + { 855346.8, 1.1652032, 78263.7094247 }, + { 165590.4, 4.1196916, 104351.6125663 }, + { 34561.9, 0.779308, 130439.515708 }, + { 7583.5, 3.71348, 156527.41885 }, + { 3559.7, 1.51203, 1109.37855 }, + { 1726.0, 0.35832, 182615.32199 }, + { 1803.5, 4.10333, 5661.33205 }, + { 1364.7, 4.59918, 27197.28169 }, + { 1589.9, 2.99510, 25028.52121 }, + { 1017.3, 0.88031, 31749.23519 }, + { 714.2, 1.5414, 24978.5246 }, + { 643.8, 5.3027, 21535.9496 }, + { 404.2, 3.2823, 208703.2251 }, + { 352.4, 5.2416, 20426.5711 }, + { 343.3, 5.7653, 955.5997 }, + { 339.2, 5.8633, 25558.2122 }, + { 451.1, 6.0499, 51116.4244 }, + { 325.3, 1.3367, 53285.1848 }, + { 259.6, 0.9873, 4551.9535 }, + { 345.2, 2.7921, 15874.6176 }, + { 272.9, 2.4945, 529.6910 }, + { 234.8, 0.2667, 11322.6641 }, + { 238.8, 0.1134, 1059.3819 }, + { 264.3, 3.9171, 57837.1383 }, + { 216.6, 0.6599, 13521.7514 }, + { 183.4, 2.6288, 27043.5029 }, + { 176.0, 4.5364, 51066.4277 }, + { 181.6, 2.4341, 25661.3050 }, + { 209.0, 2.0918, 47623.8528 }, + { 172.6, 2.4520, 24498.8302 }, + { 142.3, 3.3600, 37410.5672 }, + { 137.9, 0.2910, 10213.2855 }, + { 118.2, 2.7815, 77204.3275 }, + { 96.9, 6.204, 234791.128 }, + { 125.2, 3.7208, 39609.6546 }, + { 86.8, 2.642, 51646.115 }, + { 86.7, 1.960, 46514.474 }, + { 88.3, 5.413, 26617.594 }, + { 106.4, 4.2057, 19804.8273 }, + { 90.0, 5.852, 41962.521 }, + { 85.0, 4.331, 79373.088 }, + { 69.2, 4.194, 19.670 }, + { 63.5, 3.147, 7238.676 }, + { 68.5, 0.634, 83925.041 }, + { 69.7, 3.572, 25132.303 }, + { 59.5, 2.747, 16983.996 }, + { 64.8, 0.048, 33326.579 }, + { 55.4, 4.053, 30639.857 }, + { 54.4, 3.143, 27147.285 }, + { 47.6, 5.497, 3.881 }, + { 49.6, 3.990, 6770.711 }, + { 56.5, 5.119, 73711.756 }, + { 41.8, 5.642, 53131.406 }, + { 51.5, 5.478, 50586.733 }, + { 44.7, 1.224, 77154.331 }, + { 41.9, 5.193, 6283.076 }, + { 38.0, 2.431, 12566.152 }, + { 35.6, 0.814, 32858.614 }, + { 48.0, 5.493, 51749.208 }, + { 35.4, 3.370, 36301.189 }, + { 34.0, 2.786, 14765.239 }, + { 30.6, 5.840, 43071.899 }, + { 36.0, 1.424, 2218.757 }, + { 34.0, 0.475, 65697.558 }, + { 30.8, 5.770, 103292.231 }, + { 28.5, 0.650, 426.598 }, + { 26.2, 5.242, 22645.328 }, + { 26.3, 0.648, 1589.073 }, + { 29.5, 0.698, 213.299 }, + { 27.5, 0.980, 45892.730 }, + { 26.8, 1.061, 3442.575 }, + { 27.1, 0.085, 63498.470 }, + /* 75 terms retained, 1305 terms dropped, error 0.97" */ + + /* mercury l, T^1 */ + { 2608814706222.7, 0, 0 }, + { 1126007.8, 6.21703971, 26087.90314157 }, + { 303471.4, 3.0556547, 52175.8062831 }, + { 80538.5, 6.104547, 78263.709425 }, + { 21245.0, 2.835319, 104351.612566 }, + { 5592.1, 5.82676, 130439.51571 }, + { 1472.2, 2.51845, 156527.41885 }, + { 352.2, 3.0524, 1109.3786 }, + { 388.3, 5.4804, 182615.3220 }, + { 93.5, 6.118, 27197.282 }, + { 90.6, 0.000, 24978.525 }, + { 102.7, 2.1488, 208703.2251 }, + { 51.9, 5.621, 5661.332 }, + { 44.4, 4.573, 25028.521 }, + { 28.1, 3.042, 51066.428 }, + { 22.0, 0.865, 955.600 }, + { 27.3, 5.092, 234791.128 }, + { 20.4, 3.715, 20426.571 }, + { 20.2, 0.519, 21535.950 }, + { 17.5, 5.727, 4551.953 }, + { 16.7, 1.351, 529.691 }, + { 15.3, 1.792, 11322.664 }, + { 15.4, 5.743, 19.670 }, + { 14.0, 3.594, 24498.830 }, + { 12.8, 2.696, 53285.185 }, + { 12.6, 3.895, 3.881 }, + { 12.6, 4.705, 1059.382 }, + { 8.0, 4.18, 26617.59 }, + { 7.9, 0.50, 46514.47 }, + { 8.0, 3.93, 27043.50 }, + { 7.7, 2.48, 57837.14 }, + { 8.6, 6.06, 77154.33 }, + { 6.8, 2.77, 7.11 }, + { 6.6, 5.53, 6770.71 }, + { 7.3, 1.75, 260879.03 }, + { 7.2, 2.98, 2218.76 }, + { 6.4, 2.14, 25132.30 }, + /* 37 terms retained, 802 terms dropped, error 0.16"*T */ + + /* mercury l, T^2 */ + { 53049.8, 0, 0 }, + { 16903.7, 4.690723, 26087.903142 }, + { 7396.7, 1.34736, 52175.80628 }, + { 3018.3, 4.45644, 78263.70942 }, + { 1107.4, 1.26227, 104351.61257 }, + { 378.2, 4.3200, 130439.5157 }, + { 123.0, 1.0687, 156527.4188 }, + { 38.7, 4.080, 182615.322 }, + { 14.9, 4.633, 1109.379 }, + { 11.9, 0.792, 208703.225 }, + { 5.2, 4.72, 24978.52 }, + { 3.6, 3.77, 234791.13 }, + { 2.6, 1.44, 27197.28 }, + { 2.0, 1.50, 51066.43 }, + /* 14 terms retained, 381 terms dropped, error 0.033"*T^2 */ + + /* mercury l, T^3 */ + { 188.1, 0.0347, 52175.8063 }, + { 142.2, 3.1251, 26087.9031 }, + { 96.9, 3.004, 78263.709 }, + { 43.7, 6.019, 104351.613 }, + { 35.4, 0, 0 }, + { 18.0, 2.775, 130439.516 }, + { 7.0, 5.82, 156527.42 }, + { 2.6, 2.57, 182615.32 }, + { 0.9, 5.59, 208703.23 }, + /* 9 terms retained, 144 terms dropped, error 0.012"*T^3 */ + + /* mercury l, T^4 */ + { 114.1, 3.1416, 0 }, + { 3.2, 2.03, 26087.90 }, + { 1.9, 1.42, 78263.71 }, + { 1.7, 4.50, 52175.81 }, + { 1.2, 4.50, 104351.61 }, + { 0.6, 1.27, 130439.52 }, + { 0.3, 4.31, 156527.42 }, + { 0.1, 1.06, 182615.32 }, + /* 8 terms retained, 20 terms dropped, error 0.0016"*T^4 */ + + /* mercury l, T^5 */ + { 0.9, 3.14, 0 }, + /* 1 terms retained, 12 terms dropped, error 0.0051"*T^5 */ + /* end mercury l */ + + /* mercury b, T^0 */ + { 11737529.0, 1.983574988, 26087.903141574 }, + { 2388077.0, 5.03738960, 52175.80628315 }, + { 1222839.5, 3.14159265, 0 }, + { 543251.8, 1.7964436, 78263.7094247 }, + { 129778.8, 4.8323250, 104351.6125663 }, + { 31866.9, 1.580885, 130439.515708 }, + { 7963.3, 4.60972, 156527.41885 }, + { 2014.2, 1.35324, 182615.32199 }, + { 514.0, 4.3784, 208703.2251 }, + { 207.7, 4.9177, 27197.2817 }, + { 208.6, 2.0202, 24978.5246 }, + { 132.0, 1.1191, 234791.1283 }, + { 100.5, 5.6568, 20426.5711 }, + { 121.4, 1.8127, 53285.1848 }, + { 91.6, 2.282, 25028.521 }, + { 99.2, 0.094, 51116.424 }, + { 94.6, 1.242, 31749.235 }, + { 78.8, 4.407, 57837.138 }, + { 77.7, 0.526, 1059.382 }, + { 84.3, 5.085, 51066.428 }, + { 49.9, 3.498, 5661.332 }, + { 46.5, 3.237, 77204.327 }, + { 44.8, 4.878, 79373.088 }, + { 40.8, 2.466, 46514.474 }, + { 37.4, 4.458, 4551.953 }, + { 34.1, 4.142, 260879.031 }, + { 35.9, 1.091, 1109.379 }, + { 32.0, 1.185, 83925.041 }, + { 31.0, 3.503, 21535.950 }, + { 31.8, 2.415, 47623.853 }, + { 28.7, 1.848, 77154.331 }, + { 25.8, 2.776, 27043.503 }, + { 25.2, 3.591, 27147.285 }, + /* 33 terms retained, 785 terms dropped, error 0.61" */ + + /* mercury b, T^1 */ + { 429151.4, 3.5016978, 26087.9031416 }, + { 146233.7, 3.1415927, 0 }, + { 22675.3, 0.015154, 52175.806283 }, + { 10895.0, 0.485402, 78263.709425 }, + { 6353.5, 3.42944, 104351.61257 }, + { 2495.7, 0.16051, 130439.51571 }, + { 859.6, 3.1845, 156527.4188 }, + { 277.5, 6.2102, 182615.3220 }, + { 86.2, 2.952, 208703.225 }, + { 26.1, 5.977, 234791.128 }, + { 27.7, 0.291, 27197.282 }, + { 12.8, 3.377, 53285.185 }, + { 12.7, 0.538, 24978.525 }, + { 7.8, 2.72, 260879.03 }, + { 7.5, 3.58, 51066.43 }, + /* 15 terms retained, 479 terms dropped, error 0.12"*T */ + + /* mercury b, T^2 */ + { 11830.9, 4.790656, 26087.903142 }, + { 1913.5, 0, 0 }, + { 1044.8, 1.21217, 52175.80628 }, + { 266.2, 4.4342, 78263.7094 }, + { 170.3, 1.6226, 104351.6126 }, + { 96.3, 4.800, 130439.516 }, + { 44.7, 1.608, 156527.419 }, + { 18.3, 4.669, 182615.322 }, + { 6.9, 1.43, 208703.23 }, + { 2.5, 4.47, 234791.13 }, + { 1.7, 1.83, 27197.28 }, + /* 11 terms retained, 219 terms dropped, error 0.025"*T^2 */ + + /* mercury b, T^3 */ + { 235.4, 0.3539, 26087.9031 }, + { 160.5, 0, 0 }, + { 18.9, 4.363, 52175.806 }, + { 6.4, 2.51, 78263.71 }, + { 4.6, 6.14, 104351.61 }, + { 3.1, 3.12, 130439.52 }, + { 1.7, 6.27, 156527.42 }, + { 0.9, 3.08, 182615.32 }, + /* 8 terms retained, 45 terms dropped, error 0.011"*T^3 */ + + /* mercury b, T^4 */ + { 4.3, 1.75, 26087.90 }, + { 1.0, 3.14, 0 }, + { 0.4, 4.03, 52175.81 }, + { 0.3, 0.21, 78263.71 }, + { 0.1, 3.75, 104351.61 }, + /* 5 terms retained, 10 terms dropped, error 0.0012"*T^4 */ + + /* mercury b, T^5 */ + { 0.1, 3.95, 26087.90 }, + /* 1 terms retained, 9 terms dropped, error 0.00062"*T^5 */ + /* end mercury b */ + + /* mercury r, T^0 */ + { 39528271.7, 0, 0 }, + { 7834131.8, 6.19233723, 26087.90314157 }, + { 795525.6, 2.9598969, 52175.8062831 }, + { 121281.8, 6.0106415, 78263.7094247 }, + { 21922.0, 2.778201, 104351.612566 }, + { 4354.1, 5.82895, 130439.51571 }, + { 918.2, 2.5965, 156527.4188 }, + { 260.0, 3.0282, 27197.2817 }, + { 290.0, 1.4244, 25028.5212 }, + { 201.9, 5.6473, 182615.3220 }, + { 201.5, 5.5923, 31749.2352 }, + { 142.0, 6.2526, 24978.5246 }, + { 100.1, 3.7344, 21535.9496 }, + { 77.6, 3.670, 20426.571 }, + { 63.3, 4.299, 25558.212 }, + { 63.0, 4.766, 1059.382 }, + { 66.8, 2.525, 5661.332 }, + { 75.5, 4.474, 51116.424 }, + { 48.3, 6.068, 53285.185 }, + { 45.7, 2.415, 208703.225 }, + { 35.2, 1.059, 27043.503 }, + { 40.8, 2.359, 57837.138 }, + { 44.2, 1.220, 15874.618 }, + { 33.9, 0.864, 25661.305 }, + { 37.2, 0.517, 47623.853 }, + { 30.1, 1.795, 37410.567 }, + { 28.4, 3.021, 51066.428 }, + { 30.9, 0.884, 24498.830 }, + { 26.1, 2.150, 39609.655 }, + /* 29 terms retained, 1186 terms dropped, error 2.9e-06 a.u. */ + + /* mercury r, T^1 */ + { 217347.7, 4.6561716, 26087.9031416 }, + { 44141.8, 1.423855, 52175.806283 }, + { 10094.5, 4.474663, 78263.709425 }, + { 2432.8, 1.24226, 104351.61257 }, + { 1624.4, 0, 0 }, + { 604.0, 4.2930, 130439.5157 }, + { 152.9, 1.0606, 156527.4188 }, + { 39.2, 4.111, 182615.322 }, + { 17.8, 4.544, 27197.282 }, + { 18.0, 4.712, 24978.525 }, + { 10.2, 0.879, 208703.225 }, + { 8.1, 3.01, 25028.52 }, + /* 12 terms retained, 699 terms dropped, error 5.8e-07 a.u.*T */ + + /* mercury r, T^2 */ + { 3117.9, 3.08232, 26087.90314 }, + { 1245.4, 6.15183, 52175.80628 }, + { 424.8, 2.9258, 78263.7094 }, + { 136.1, 5.9798, 104351.6126 }, + { 42.2, 2.749, 130439.516 }, + { 21.8, 3.142, 0 }, + { 12.8, 5.801, 156527.419 }, + { 3.8, 2.57, 182615.32 }, + /* 8 terms retained, 318 terms dropped, error 2.3e-07 a.u.*T^2 */ + + /* mercury r, T^3 */ + { 32.7, 1.680, 26087.903 }, + { 24.2, 4.634, 52175.806 }, + { 12.1, 1.390, 78263.709 }, + { 5.1, 4.44, 104351.61 }, + { 2.0, 1.21, 130439.52 }, + { 1.5, 3.14, 0 }, + { 0.7, 4.26, 156527.42 }, + /* 7 terms retained, 112 terms dropped, error 4.1e-08 a.u.*T^3 */ + + /* mercury r, T^4 */ + { 0.4, 0.37, 26087.90 }, + { 0.4, 3.19, 52175.81 }, + { 0.3, 6.17, 78263.71 }, + { 0.1, 2.92, 104351.61 }, + /* 4 terms retained, 14 terms dropped, error 6.7e-09 a.u.*T^4 */ + + /* mercury r, T^5 */ + /* 0 terms retained, 10 terms dropped, error 1.2e-10 a.u.*T^5 */ + /* end mercury */ +}; + +int vn_mercury[][3] = { + /* addresses for mercury l, b, r */ + /* T^0 */ { 0, 144, 217, }, + /* T^1 */ { 75, 177, 246, }, + /* T^2 */ { 112, 192, 258, }, + /* T^3 */ { 126, 203, 266, }, + /* T^4 */ { 135, 211, 273, }, + /* T^5 */ { 143, 216, 277, }, + /* end */ { 144, 217, 0, }, + /* termination */ { 0, } +}; + +/* version d4 (lbr) + * heliocentric dynamical ecliptic and equinox of the date + */ + +double vx_neptune[][3] = { + /* neptune l, T^0 */ + { 531188633.0, 0, 0 }, + { 1798475.5, 2.90101273, 38.13303564 }, + { 1019727.7, 0.48580924, 1.48447271 }, + { 124531.8, 4.8300809, 36.6485629 }, + { 42064.4, 5.410550, 2.968945 }, + { 37714.6, 6.092218, 35.164090 }, + { 33784.7, 1.244889, 76.266071 }, + { 16482.7, 0.000077, 491.557929 }, + { 9198.6, 4.93747, 39.61751 }, + { 8994.2, 0.27462, 175.16606 }, + { 4216.2, 1.98712, 73.29713 }, + { 3364.8, 1.03590, 33.67962 }, + { 2284.8, 4.20607, 4.45342 }, + { 1433.5, 2.78340, 74.78160 }, + { 900.2, 2.0761, 109.9457 }, + { 745.0, 3.1903, 71.8127 }, + { 506.2, 5.7479, 114.3991 }, + { 399.6, 0.3497, 1021.2489 }, + { 345.2, 3.4619, 41.1020 }, + { 306.3, 0.4968, 0.5213 }, + { 287.3, 4.5052, 0.0482 }, + { 323.0, 2.2482, 32.1951 }, + { 340.3, 3.3037, 77.7505 }, + { 266.6, 4.8893, 0.9632 }, + { 227.1, 1.7971, 453.4249 }, + { 244.7, 1.2469, 9.5612 }, + { 232.9, 2.5046, 137.0330 }, + { 282.2, 2.2457, 146.5943 }, + { 251.9, 5.7817, 388.4652 }, + { 150.2, 2.9971, 5.9379 }, + { 170.4, 3.3239, 108.4612 }, + { 151.4, 2.1915, 33.9402 }, + { 148.3, 0.8595, 111.4302 }, + { 118.7, 3.6771, 2.4477 }, + { 101.8, 5.7054, 0.1119 }, + { 97.9, 2.805, 8.077 }, + { 103.1, 4.4044, 70.3282 }, + { 103.3, 0.0408, 0.2606 }, + { 109.3, 2.4160, 183.2428 }, + { 73.9, 1.328, 529.691 }, + { 77.7, 4.164, 4.193 }, + { 86.4, 4.228, 490.073 }, + { 81.5, 5.199, 493.042 }, + { 71.5, 5.295, 350.332 }, + { 64.4, 3.545, 168.053 }, + { 62.6, 0.150, 182.280 }, + { 58.5, 3.501, 145.110 }, + { 48.3, 1.113, 112.915 }, + { 47.2, 4.574, 46.210 }, + { 39.1, 1.666, 213.299 }, + { 47.7, 0.129, 484.444 }, + { 46.9, 3.017, 498.671 }, + { 38.7, 2.387, 2.921 }, + { 47.0, 4.498, 173.682 }, + { 47.6, 2.584, 219.891 }, + { 44.7, 5.473, 176.651 }, + { 32.3, 3.458, 30.711 }, + { 28.2, 4.133, 6.592 }, + /* 58 terms retained, 365 terms dropped, error 0.9" */ + + /* neptune l, T^1 */ + { 3837687716.7, 0, 0 }, + { 16604.2, 4.863191, 1.484473 }, + { 15807.1, 2.279235, 38.133036 }, + { 3334.7, 3.68200, 76.26607 }, + { 1305.8, 3.67321, 2.96895 }, + { 604.8, 1.5048, 35.1641 }, + { 178.6, 3.4532, 39.6175 }, + { 106.5, 2.4513, 4.4534 }, + { 105.7, 2.7548, 33.6796 }, + { 72.7, 5.487, 36.649 }, + { 57.1, 5.216, 0.521 }, + { 57.4, 1.858, 114.399 }, + { 35.4, 4.517, 74.782 }, + { 32.2, 5.904, 77.751 }, + { 29.9, 3.670, 388.465 }, + { 28.9, 5.169, 9.561 }, + { 28.7, 5.167, 2.448 }, + { 25.5, 5.245, 168.053 }, + { 24.9, 4.732, 182.280 }, + { 20.2, 5.789, 1021.249 }, + { 19.0, 1.830, 484.444 }, + { 18.7, 1.316, 498.671 }, + { 15.1, 4.950, 137.033 }, + { 15.1, 3.987, 32.195 }, + { 10.7, 2.441, 4.193 }, + { 11.7, 4.893, 71.813 }, + { 9.6, 1.23, 5.94 }, + { 9.6, 1.89, 41.10 }, + { 9.0, 0.02, 8.08 }, + { 9.9, 6.08, 7.11 }, + { 7.6, 5.51, 73.30 }, + { 7.0, 0.62, 2.92 }, + /* 32 terms retained, 151 terms dropped, error 0.17"*T */ + + /* neptune l, T^2 */ + { 53892.6, 0, 0 }, + { 281.3, 1.1908, 38.1330 }, + { 295.7, 1.8552, 1.4845 }, + { 270.2, 5.7214, 76.2661 }, + { 23.0, 1.210, 2.969 }, + { 7.3, 0.54, 2.45 }, + { 9.1, 4.43, 35.16 }, + { 5.2, 0.67, 168.05 }, + { 5.2, 3.02, 182.28 }, + { 4.3, 3.84, 114.40 }, + { 3.9, 3.53, 484.44 }, + { 3.7, 5.90, 498.67 }, + { 3.0, 0.31, 4.45 }, + { 3.4, 0.56, 74.78 }, + { 3.3, 1.85, 175.17 }, + { 2.2, 1.89, 388.47 }, + { 2.2, 4.38, 7.11 }, + { 1.8, 3.49, 9.56 }, + { 2.5, 4.69, 491.56 }, + { 1.8, 5.12, 33.68 }, + { 2.2, 1.69, 77.75 }, + { 1.7, 2.56, 36.65 }, + /* 22 terms retained, 35 terms dropped, error 0.033"*T^2 */ + + /* neptune l, T^3 */ + { 31.3, 0, 0 }, + { 12.5, 6.044, 1.484 }, + { 14.5, 1.353, 76.266 }, + { 11.5, 6.113, 38.133 }, + { 1.4, 4.94, 2.97 }, + { 0.7, 2.36, 168.05 }, + { 0.7, 1.27, 182.28 }, + { 0.5, 5.24, 484.44 }, + { 0.5, 4.17, 498.67 }, + { 0.7, 0.56, 31.02 }, + /* 10 terms retained, 5 terms dropped, error 0.0091"*T^3 */ + + /* neptune l, T^4 */ + { 114.0, 3.1416, 0 }, + { 0.6, 3.18, 76.27 }, + /* 2 terms retained, 0 terms dropped, error 0.0043"*T^4 */ + + /* neptune l, T^5 */ + { 0.9, 3.14, 0 }, + /* 1 terms retained, 0 terms dropped, error 0.0051"*T^5 */ + /* end neptune l */ + + /* neptune b, T^0 */ + { 3088622.9, 1.44104373, 38.13303564 }, + { 27780.1, 5.912719, 76.266071 }, + { 27623.6, 0, 0 }, + { 15355.5, 2.521238, 36.648563 }, + { 15448.1, 3.508771, 39.617508 }, + { 1999.9, 1.50999, 74.78160 }, + { 1967.5, 4.37778, 1.48447 }, + { 1015.1, 3.21561, 35.16409 }, + { 605.8, 2.8025, 73.2971 }, + { 594.9, 2.1289, 41.1020 }, + { 588.8, 3.1866, 2.9689 }, + { 401.8, 4.1688, 114.3991 }, + { 254.3, 3.2712, 453.4249 }, + { 261.6, 3.7672, 213.2991 }, + { 280.0, 1.6817, 77.7505 }, + { 205.6, 4.2565, 529.6910 }, + { 140.5, 3.5297, 137.0330 }, + { 98.5, 4.168, 33.680 }, + { 51.3, 1.951, 4.453 }, + { 68.0, 4.670, 71.813 }, + { 41.9, 5.418, 111.430 }, + { 41.8, 5.948, 112.915 }, + { 30.6, 0.936, 42.586 }, + /* 23 terms retained, 149 terms dropped, error 0.62" */ + + /* neptune b, T^1 */ + { 227279.2, 3.8079309, 38.1330356 }, + { 1803.1, 1.97576, 76.26607 }, + { 1385.7, 4.82556, 36.64856 }, + { 1433.3, 3.14159, 0 }, + { 1073.3, 6.08054, 39.61751 }, + { 147.9, 3.8577, 74.7816 }, + { 136.4, 0.4776, 1.4845 }, + { 70.3, 6.188, 35.164 }, + { 51.9, 5.052, 73.297 }, + { 37.3, 4.895, 41.102 }, + { 42.6, 0.307, 114.399 }, + { 37.1, 5.760, 2.969 }, + { 26.4, 5.216, 213.299 }, + { 16.9, 4.265, 77.751 }, + { 18.7, 0.904, 453.425 }, + { 13.0, 6.177, 529.691 }, + { 10.5, 1.203, 137.033 }, + /* 17 terms retained, 65 terms dropped, error 0.18"*T */ + + /* neptune b, T^2 */ + { 9690.8, 5.57124, 38.13304 }, + { 78.8, 3.627, 76.266 }, + { 71.5, 0.455, 36.649 }, + { 58.6, 3.142, 0 }, + { 29.9, 1.607, 39.618 }, + { 6.5, 5.61, 74.78 }, + { 5.8, 2.25, 1.48 }, + { 4.3, 1.68, 35.16 }, + { 3.5, 2.39, 114.40 }, + { 2.6, 0.65, 73.30 }, + /* 10 terms retained, 15 terms dropped, error 0.036"*T^2 */ + + /* neptune b, T^3 */ + { 273.4, 1.0169, 38.1330 }, + { 2.3, 2.37, 36.65 }, + { 2.0, 5.33, 76.27 }, + { 2.4, 0, 0 }, + { 0.5, 3.22, 39.62 }, + /* 5 terms retained, 4 terms dropped, error 0.0054"*T^3 */ + + /* neptune b, T^4 */ + { 5.7, 2.67, 38.13 }, + /* 1 terms retained, 0 terms dropped, error 0.033"*T^4 */ + + /* neptune b, T^5 */ + { 0.1, 4.71, 38.13 }, + /* 1 terms retained, 0 terms dropped, error 0.00066"*T^5 */ + /* end neptune b */ + + /* neptune r, T^0 */ + { 3007013206.1, 0, 0 }, + { 27062259.5, 1.329994589, 38.133035638 }, + { 1691764.3, 3.25186139, 36.64856293 }, + { 807830.7, 5.1859284, 1.4844727 }, + { 537760.6, 4.5211390, 35.1640902 }, + { 495725.6, 1.5710565, 491.5579295 }, + { 274572.0, 1.8455226, 175.1660598 }, + { 135134.1, 3.3722061, 39.6175083 }, + { 121801.8, 5.7975444, 76.2660713 }, + { 100895.4, 0.3770275, 73.2971259 }, + { 69791.7, 3.796172, 2.968945 }, + { 46687.8, 5.749378, 33.679618 }, + { 24593.8, 0.508017, 109.945689 }, + { 16939.2, 1.594222, 71.812653 }, + { 14229.7, 1.077861, 74.781599 }, + { 12011.8, 1.920621, 1021.248895 }, + { 8394.7, 0.67817, 146.59425 }, + { 7571.8, 1.07149, 388.46516 }, + { 5720.9, 2.59060, 4.45342 }, + { 4839.7, 1.90686, 41.10198 }, + { 4483.5, 2.90573, 529.69097 }, + { 4270.2, 3.41344, 453.42489 }, + { 4353.8, 0.67986, 32.19514 }, + { 4420.8, 1.74994, 108.46122 }, + { 2881.1, 1.98600, 137.03302 }, + { 2635.5, 3.09756, 213.29910 }, + { 3380.9, 0.84811, 183.24281 }, + { 2878.9, 3.67416, 350.33212 }, + { 2306.3, 2.80963, 70.32818 }, + { 2530.1, 5.79840, 490.07346 }, + { 2523.1, 0.48631, 493.04240 }, + { 2087.3, 0.61858, 33.94025 }, + { 1976.5, 5.11703, 168.05251 }, + { 1905.3, 1.72186, 182.27961 }, + { 1654.0, 1.92783, 145.10978 }, + { 1435.1, 1.70005, 484.44438 }, + { 1403.0, 4.58914, 498.67148 }, + { 1499.2, 1.01623, 219.89138 }, + { 1398.9, 0.76220, 176.65053 }, + { 1403.4, 6.07659, 173.68159 }, + { 1128.6, 5.96661, 9.56123 }, + { 1228.3, 1.59881, 77.75054 }, + { 835.4, 3.9707, 114.3991 }, + { 811.2, 3.0026, 46.2098 }, + { 731.9, 2.1045, 181.7583 }, + { 615.8, 2.9787, 106.9767 }, + { 704.8, 1.1874, 256.5399 }, + { 502.0, 1.3866, 5.9379 }, + { 530.4, 4.2406, 111.4302 }, + { 437.1, 2.2703, 1550.9399 }, + { 400.2, 1.2561, 8.0768 }, + { 421.0, 1.8908, 30.7107 }, + { 382.5, 3.2997, 983.1159 }, + { 422.5, 5.5319, 525.4982 }, + { 355.4, 2.2785, 218.4069 }, + { 280.1, 1.5413, 98.9000 }, + { 314.5, 3.9593, 381.3516 }, + { 280.6, 4.5424, 44.7253 }, + { 267.7, 5.1332, 112.9146 }, + { 333.3, 5.7507, 39.0962 }, + { 291.6, 4.0240, 68.8437 }, + { 321.4, 1.5063, 454.9094 }, + { 309.2, 2.8545, 72.0733 }, + { 345.1, 1.3591, 293.1885 }, + { 307.4, 0.3196, 601.7643 }, + { 251.4, 3.5399, 312.1991 }, + { 248.2, 3.4108, 37.6118 }, + { 306.0, 2.7248, 6244.9428 }, + { 293.5, 4.8908, 528.2065 }, + { 234.5, 0.5923, 42.5865 }, + { 239.6, 3.1644, 143.6253 }, + { 214.5, 3.6248, 278.2588 }, + { 246.2, 1.0151, 141.2258 }, + { 174.1, 5.5501, 567.8240 }, + { 163.9, 2.1017, 2.4477 }, + { 162.9, 2.4895, 4.1928 }, + { 193.5, 1.5843, 138.5175 }, + { 155.3, 3.2843, 31.0195 }, + { 182.5, 2.4524, 255.0555 }, + { 177.8, 4.1477, 10175.1525 }, + { 174.4, 1.5304, 329.8371 }, + { 137.6, 3.3490, 0.9632 }, + { 161.0, 5.1666, 211.8146 }, + { 113.5, 4.9629, 148.0787 }, + { 128.8, 3.2552, 24.1184 }, + { 107.4, 3.2646, 1059.3819 }, + { 122.7, 5.3940, 62.2514 }, + { 120.5, 3.0805, 184.7273 }, + { 99.4, 1.929, 28.572 }, + { 97.7, 2.595, 6.592 }, + { 124.1, 3.1152, 221.3759 }, + { 124.7, 2.9704, 251.4321 }, + { 114.3, 0.2504, 594.6507 }, + { 111.0, 3.3428, 180.2739 }, + { 120.9, 1.9291, 25.6029 }, + { 104.7, 0.9488, 395.5787 }, + { 109.8, 5.4315, 494.5269 }, + { 96.9, 0.862, 1014.135 }, + { 98.7, 0.896, 488.589 }, + { 89.0, 4.781, 144.147 }, + { 107.9, 0.9870, 1124.3417 }, + { 97.1, 2.627, 291.704 }, + { 75.1, 5.889, 43.241 }, + { 93.7, 6.099, 526.722 }, + { 94.8, 0.207, 456.394 }, + { 70.0, 2.397, 426.598 }, + { 77.2, 4.211, 105.492 }, + { 89.9, 3.251, 258.024 }, + { 69.1, 4.930, 1028.362 }, + { 90.7, 1.695, 366.486 }, + { 74.2, 3.145, 82.858 }, + { 58.0, 0.862, 60.767 }, + { 78.7, 1.093, 700.664 }, + { 57.2, 0.813, 2.921 }, + { 63.4, 4.396, 149.563 }, + { 55.7, 3.890, 47.694 }, + { 56.4, 5.150, 0.521 }, + { 56.2, 5.430, 911.043 }, + { 61.7, 6.165, 1019.764 }, + { 70.5, 0.081, 40.581 }, + { 74.7, 4.859, 186.212 }, + { 61.9, 4.787, 11.046 }, + { 61.1, 0.837, 1022.733 }, + { 61.3, 5.702, 178.135 }, + { 52.9, 0.375, 27.087 }, + { 56.7, 3.523, 216.922 }, + { 48.8, 5.108, 64.960 }, + { 63.3, 4.394, 807.950 }, + { 64.1, 6.283, 7.114 }, + { 46.4, 1.347, 451.940 }, + { 60.5, 3.403, 294.673 }, + { 46.9, 0.170, 7.422 }, + { 56.8, 0.450, 140.002 }, + { 55.9, 1.068, 172.197 }, + { 53.8, 2.796, 328.353 }, + { 43.8, 6.047, 135.549 }, + { 49.5, 0.641, 41.054 }, + { 54.0, 2.918, 563.631 }, + { 43.0, 5.402, 487.365 }, + { 51.5, 0.091, 210.330 }, + { 41.9, 3.123, 29.226 }, + { 47.7, 3.907, 63.736 }, + { 41.6, 6.268, 32.716 }, + { 41.4, 4.455, 37.170 }, + { 40.7, 0.160, 79.235 }, + { 48.2, 1.842, 403.134 }, + { 36.9, 0.448, 30.056 }, + { 47.8, 0.881, 3302.479 }, + { 39.5, 3.506, 357.446 }, + { 42.1, 0.634, 343.219 }, + { 41.3, 1.364, 31.232 }, + { 42.6, 3.553, 38.654 }, + { 38.9, 5.267, 415.292 }, + { 39.0, 5.259, 386.981 }, + { 33.7, 5.244, 67.359 }, + { 40.9, 3.553, 331.322 }, + { 38.8, 1.123, 38.181 }, + { 37.5, 6.087, 35.425 }, + { 38.8, 4.679, 38.085 }, + { 38.2, 6.265, 389.950 }, + { 30.0, 4.458, 22.634 }, + { 31.4, 0.077, 12.530 }, + { 26.3, 4.596, 106.014 }, + { 27.5, 5.995, 206.186 }, + { 25.2, 4.499, 34.201 }, + { 29.0, 3.649, 253.571 }, + { 27.2, 4.379, 142.141 }, + { 30.6, 1.593, 348.848 }, + { 31.5, 1.051, 100.384 }, + { 26.3, 3.016, 365.001 }, + { 26.5, 3.614, 367.970 }, + { 25.5, 2.438, 351.817 }, + { 25.7, 2.005, 439.783 }, + { 25.4, 4.740, 1474.674 }, + /* 174 terms retained, 433 terms dropped, error 6.7e-06 a.u. */ + + /* neptune r, T^1 */ + { 236338.5, 0.7049801, 38.1330356 }, + { 13220.3, 3.320155, 1.484473 }, + { 8621.9, 6.21629, 35.16409 }, + { 2701.7, 1.88141, 39.61751 }, + { 2153.2, 5.16874, 76.26607 }, + { 2154.7, 2.09431, 2.96895 }, + { 1463.9, 1.18417, 33.67962 }, + { 1603.2, 0, 0 }, + { 1135.8, 3.91891, 36.64856 }, + { 897.6, 5.2412, 388.4652 }, + { 789.9, 0.5332, 168.0525 }, + { 760.0, 0.0205, 182.2796 }, + { 607.2, 1.0771, 1021.2489 }, + { 571.6, 3.4006, 484.4444 }, + { 560.8, 2.8869, 498.6715 }, + { 490.2, 3.4683, 137.0330 }, + { 264.1, 0.8622, 4.4534 }, + { 270.5, 3.2736, 71.8127 }, + { 203.5, 2.4182, 32.1951 }, + { 155.4, 0.3654, 41.1020 }, + { 132.8, 3.6016, 9.5612 }, + { 93.6, 0.667, 46.210 }, + { 83.3, 3.260, 98.900 }, + { 72.2, 4.477, 601.764 }, + { 69.0, 1.463, 74.782 }, + { 87.0, 5.772, 381.352 }, + { 68.7, 4.526, 70.328 }, + { 64.7, 3.855, 73.297 }, + { 68.4, 3.395, 108.461 }, + { 53.4, 5.437, 395.579 }, + { 44.5, 3.614, 2.448 }, + { 41.2, 4.739, 8.077 }, + { 48.3, 1.986, 175.166 }, + { 41.7, 4.943, 31.019 }, + { 44.1, 1.417, 1550.940 }, + { 41.2, 1.420, 490.073 }, + { 41.1, 4.863, 493.042 }, + { 36.3, 5.308, 312.199 }, + { 36.3, 0.382, 77.751 }, + { 40.6, 2.272, 529.691 }, + { 32.4, 5.911, 5.938 }, + { 31.2, 2.705, 1014.135 }, + { 32.7, 5.221, 41.054 }, + { 36.1, 4.878, 491.558 }, + { 30.2, 3.633, 30.711 }, + { 30.0, 3.308, 1028.362 }, + { 27.0, 1.776, 44.725 }, + { 27.8, 4.556, 7.114 }, + { 27.5, 0.972, 33.940 }, + { 24.9, 3.101, 144.147 }, + { 26.0, 2.997, 60.767 }, + { 21.4, 4.713, 278.259 }, + { 21.3, 0.690, 251.432 }, + { 23.7, 5.120, 176.651 }, + { 21.4, 0.863, 4.193 }, + { 23.4, 1.650, 173.682 }, + { 24.2, 3.566, 145.110 }, + { 20.2, 5.615, 24.118 }, + { 27.0, 4.143, 453.425 }, + { 24.0, 1.007, 213.299 }, + { 18.3, 1.980, 72.073 }, + { 18.3, 6.173, 189.393 }, + { 19.2, 4.652, 106.977 }, + { 17.6, 1.603, 62.251 }, + { 16.5, 1.699, 357.446 }, + { 20.1, 3.295, 114.399 }, + { 15.4, 4.388, 25.603 }, + { 19.2, 2.200, 343.219 }, + { 15.1, 3.668, 0.521 }, + { 14.0, 0.553, 129.919 }, + { 13.4, 5.858, 68.844 }, + { 15.4, 4.207, 567.824 }, + { 12.7, 3.528, 477.331 }, + { 11.7, 5.576, 31.232 }, + { 11.5, 0.891, 594.651 }, + { 10.5, 4.356, 32.716 }, + { 10.8, 5.218, 26.827 }, + { 10.1, 1.981, 40.581 }, + { 10.5, 5.273, 2.921 }, + { 9.2, 0.50, 64.96 }, + { 9.2, 0.68, 160.94 }, + { 8.7, 5.81, 6.59 }, + { 10.1, 4.512, 28.572 }, + { 10.4, 5.189, 42.586 }, + { 9.9, 3.77, 181.76 }, + { 8.3, 2.82, 43.24 }, + { 9.8, 1.49, 47.69 }, + { 7.6, 4.08, 389.95 }, + { 8.0, 2.78, 505.79 }, + { 7.4, 2.36, 11.05 }, + { 7.3, 1.62, 135.55 }, + { 9.5, 0.27, 426.60 }, + { 7.2, 0.83, 911.04 }, + { 7.0, 1.87, 206.19 }, + { 6.9, 0.84, 82.86 }, + { 7.9, 1.87, 38.65 }, + { 6.7, 3.98, 12.53 }, + { 6.4, 0.90, 487.37 }, + { 6.7, 1.34, 220.41 }, + { 7.7, 5.13, 23.91 }, + { 7.1, 6.00, 639.90 }, + { 8.3, 3.86, 37.61 }, + { 6.4, 2.42, 1059.38 }, + { 6.8, 1.97, 45.25 }, + { 6.4, 4.08, 35.69 }, + { 6.4, 0.65, 350.33 }, + /* 106 terms retained, 144 terms dropped, error 1.3e-06 a.u.*T */ + + /* neptune r, T^2 */ + { 4247.4, 5.89911, 38.13304 }, + { 217.6, 0.3458, 1.4845 }, + { 163.0, 2.2387, 168.0525 }, + { 156.3, 4.5941, 182.2796 }, + { 117.9, 5.1030, 484.4444 }, + { 112.4, 1.1900, 498.6715 }, + { 127.1, 2.8479, 35.1641 }, + { 99.5, 3.416, 175.166 }, + { 64.8, 3.462, 388.465 }, + { 77.3, 0.017, 491.558 }, + { 49.5, 4.070, 76.266 }, + { 39.3, 6.095, 1021.249 }, + { 36.5, 5.171, 137.033 }, + { 37.1, 5.973, 2.969 }, + { 30.5, 3.583, 33.680 }, + { 21.1, 0.768, 36.649 }, + { 13.9, 3.592, 395.579 }, + { 13.1, 5.093, 98.900 }, + { 11.4, 1.181, 381.352 }, + { 9.1, 2.35, 601.76 }, + { 8.5, 5.25, 2.45 }, + { 8.1, 4.96, 4.45 }, + { 7.4, 4.47, 189.39 }, + { 7.2, 1.92, 9.56 }, + { 7.3, 1.66, 1028.36 }, + { 8.1, 5.84, 220.41 }, + { 9.7, 0, 0 }, + { 6.6, 0.69, 144.15 }, + { 7.8, 1.14, 1059.38 }, + { 5.7, 6.25, 74.78 }, + { 5.6, 5.23, 46.21 }, + { 5.5, 4.59, 1014.14 }, + { 5.2, 5.23, 477.33 }, + { 5.5, 3.50, 183.76 }, + { 4.9, 3.53, 39.62 }, + { 4.8, 2.08, 41.10 }, + { 5.1, 0.20, 166.57 }, + { 4.8, 1.18, 169.54 }, + { 4.7, 1.51, 73.30 }, + { 6.1, 6.18, 71.81 }, + { 4.6, 3.92, 587.54 }, + { 5.8, 2.24, 176.65 }, + { 4.5, 2.84, 7.11 }, + { 4.3, 0.52, 446.31 }, + { 3.9, 0.26, 1550.94 }, + { 4.5, 3.01, 129.92 }, + { 3.7, 2.38, 160.94 }, + { 3.8, 3.79, 111.43 }, + { 4.1, 1.70, 983.12 }, + { 3.3, 1.08, 505.79 }, + { 4.0, 0.31, 494.74 }, + { 4.0, 5.97, 488.38 }, + { 3.9, 4.86, 60.77 }, + { 3.0, 2.02, 822.18 }, + { 4.0, 1.08, 374.24 }, + { 3.8, 5.23, 350.33 }, + { 2.8, 6.18, 704.86 }, + { 3.5, 0.79, 274.07 }, + { 2.8, 1.32, 386.98 }, + { 2.8, 5.37, 251.43 }, + { 3.1, 5.13, 426.60 }, + { 3.3, 5.61, 1124.34 }, + { 2.6, 0.68, 312.20 }, + { 2.6, 3.56, 567.82 }, + { 2.6, 1.46, 1035.48 }, + { 2.5, 5.19, 1227.43 }, + { 2.5, 4.12, 171.23 }, + { 2.5, 2.72, 179.10 }, + { 2.3, 0.96, 1019.76 }, + { 2.5, 0.70, 707.78 }, + { 2.5, 4.60, 693.55 }, + { 2.3, 0.74, 976.00 }, + /* 72 terms retained, 0 terms dropped, error 3.8e-07 a.u.*T^2 */ + + /* neptune r, T^3 */ + { 166.3, 4.5524, 38.1330 }, + { 22.4, 3.948, 168.053 }, + { 21.3, 2.863, 182.280 }, + { 16.2, 0.542, 484.444 }, + { 15.6, 5.757, 498.671 }, + { 11.9, 4.403, 1.484 }, + { 6.4, 5.19, 31.02 }, + { 3.7, 5.91, 1007.02 }, + { 3.7, 1.63, 388.47 }, + { 3.2, 0.70, 1558.05 }, + { 3.2, 1.88, 522.58 }, + { 3.3, 2.94, 76.27 }, + { 2.7, 1.87, 402.69 }, + { 3.2, 0.79, 536.80 }, + { 2.6, 5.77, 343.22 }, + { 2.6, 4.65, 500.16 }, + { 2.5, 4.79, 482.96 }, + { 2.5, 1.73, 395.58 }, + { 2.7, 2.21, 446.31 }, + { 2.4, 5.77, 485.93 }, + { 2.9, 6.20, 815.06 }, + { 2.3, 3.67, 497.19 }, + /* 22 terms retained, 0 terms dropped, error 2.2e-07 a.u.*T^3 */ + + /* neptune r, T^4 */ + { 4.2, 2.40, 477.33 }, + { 4.3, 0.10, 395.58 }, + { 3.5, 4.78, 1028.36 }, + { 3.2, 3.88, 505.79 }, + { 3.0, 1.04, 189.39 }, + { 2.3, 1.11, 182.28 }, + { 2.3, 5.68, 168.05 }, + /* 7 terms retained, 0 terms dropped, error 1.3e-07 a.u.*T^4 */ + /* end neptune */ +}; + +int vn_neptune[][3] = { + /* addresses for neptune l, b, r */ + /* T^0 */ { 0, 125, 182, }, + /* T^1 */ { 58, 148, 356, }, + /* T^2 */ { 90, 165, 462, }, + /* T^3 */ { 112, 175, 534, }, + /* T^4 */ { 122, 180, 556, }, + /* T^5 */ { 124, 181, 563, }, + /* end */ { 125, 182, 0, }, + /* termination */ { 0, } +}; + +/* version d4 (lbr) + * heliocentric dynamical ecliptic and equinox of the date + */ + +double vx_saturn[][3] = { + /* saturn l, T^0 */ + { 87401354.0, 0, 0 }, + { 11107659.8, 3.962050902, 213.299095438 }, + { 1414151.0, 4.58581516, 7.11354700 }, + { 398379.4, 0.5211203, 206.1855484 }, + { 350769.2, 3.3032990, 426.5981909 }, + { 206816.3, 0.2465837, 103.0927742 }, + { 79271.3, 3.840071, 220.412642 }, + { 23990.3, 4.669769, 110.206321 }, + { 16573.6, 0.437191, 419.484644 }, + { 14907.0, 5.769033, 316.391870 }, + { 15820.3, 0.938090, 632.783739 }, + { 14609.6, 1.565186, 3.932153 }, + { 13160.3, 4.448912, 14.227094 }, + { 15053.5, 2.716700, 639.897286 }, + { 13005.3, 5.981191, 11.045700 }, + { 10725.1, 3.129396, 202.253395 }, + { 5863.2, 0.23657, 529.69097 }, + { 5227.8, 4.20783, 3.18139 }, + { 6126.3, 1.76328, 277.03499 }, + { 5019.7, 3.17788, 433.71174 }, + { 4592.5, 0.61976, 199.07200 }, + { 4005.9, 2.24480, 63.73590 }, + { 2953.8, 0.98280, 95.97923 }, + { 3873.7, 3.22283, 138.51750 }, + { 2461.2, 2.03164, 735.87651 }, + { 3269.5, 0.77492, 949.17561 }, + { 1758.1, 3.26581, 522.57742 }, + { 1640.2, 5.50505, 846.08283 }, + { 1391.3, 4.02332, 323.50542 }, + { 1580.6, 4.37266, 309.27832 }, + { 1123.5, 2.83727, 415.55249 }, + { 1017.3, 3.71698, 227.52619 }, + { 848.6, 3.1915, 209.3669 }, + { 1087.2, 4.18343, 2.44768 }, + { 956.8, 0.5074, 1265.5675 }, + { 789.2, 5.0075, 0.9632 }, + { 687.0, 1.7471, 1052.2684 }, + { 654.5, 1.5989, 0.0482 }, + { 748.8, 2.1440, 853.1964 }, + { 634.0, 2.2989, 412.3711 }, + { 743.6, 5.2528, 224.3448 }, + { 852.7, 3.4214, 175.1661 }, + { 579.9, 3.0926, 74.7816 }, + { 624.9, 0.9705, 210.1177 }, + { 529.9, 4.4494, 117.3199 }, + { 542.6, 1.5182, 9.5612 }, + { 474.3, 5.4753, 742.9901 }, + { 448.5, 1.2899, 127.4718 }, + { 546.4, 2.1268, 350.3321 }, + { 478.1, 2.9649, 137.0330 }, + { 354.9, 3.0129, 838.9693 }, + { 451.8, 1.0444, 490.3341 }, + { 347.4, 1.5393, 340.7709 }, + { 343.5, 0.2460, 0.5213 }, + { 309.0, 3.4949, 216.4805 }, + { 322.2, 0.9614, 203.7379 }, + { 372.3, 2.2782, 217.2312 }, + { 321.5, 2.5718, 647.0108 }, + { 330.2, 0.2472, 1581.9593 }, + { 249.1, 1.4701, 1368.6603 }, + { 286.7, 2.3704, 351.8166 }, + { 220.2, 4.2042, 200.7689 }, + { 277.8, 0.4002, 211.8146 }, + { 204.5, 6.0108, 265.9893 }, + { 207.7, 0.4835, 1162.4747 }, + { 208.7, 1.3452, 625.6702 }, + { 182.5, 5.4912, 2.9208 }, + { 226.6, 4.9100, 12.5302 }, + { 207.7, 1.2830, 39.3569 }, + { 173.9, 1.8631, 0.7508 }, + { 184.7, 3.5034, 149.5632 }, + { 183.5, 0.9725, 4.1928 }, + { 146.1, 6.2310, 195.1398 }, + { 164.5, 0.4401, 5.4166 }, + { 147.5, 1.5353, 5.6291 }, + { 139.7, 4.2945, 21.3406 }, + { 131.3, 4.0683, 10.2949 }, + { 117.3, 2.6792, 1155.3612 }, + { 149.3, 5.7359, 52.6902 }, + { 122.4, 1.9759, 4.6659 }, + { 113.7, 5.5943, 1059.3819 }, + { 102.7, 1.1975, 1685.0521 }, + { 118.2, 5.3407, 554.0700 }, + { 109.3, 3.4381, 536.8045 }, + { 110.4, 0.1660, 1.4845 }, + { 125.0, 6.2774, 1898.3512 }, + { 89.9, 5.804, 114.138 }, + { 104.0, 2.1921, 88.8657 }, + { 112.4, 1.1050, 191.2077 }, + { 106.6, 4.0116, 956.2892 }, + { 91.4, 1.875, 38.133 }, + { 83.8, 5.488, 0.112 }, + { 83.5, 2.290, 628.852 }, + { 97.0, 4.537, 302.165 }, + { 100.6, 4.9651, 269.9214 }, + { 75.5, 2.180, 728.763 }, + { 96.3, 2.833, 275.551 }, + { 82.4, 3.055, 440.825 }, + { 73.9, 5.089, 1375.774 }, + { 71.6, 5.109, 65.220 }, + { 70.4, 4.868, 0.212 }, + { 69.8, 3.710, 14.978 }, + { 88.8, 3.863, 278.519 }, + { 68.1, 0.734, 1478.867 }, + { 66.5, 0.027, 70.849 }, + { 65.7, 2.022, 142.450 }, + { 75.8, 1.614, 284.149 }, + { 63.2, 3.495, 479.288 }, + { 62.5, 2.587, 422.666 }, + { 69.3, 3.440, 515.464 }, + { 79.0, 4.452, 35.425 }, + { 63.7, 3.317, 62.251 }, + { 52.9, 5.514, 0.261 }, + { 53.0, 3.185, 8.077 }, + { 54.5, 2.457, 22.091 }, + { 50.5, 4.267, 99.161 }, + { 55.2, 0.968, 942.062 }, + { 49.3, 2.386, 1471.753 }, + { 47.2, 2.025, 312.199 }, + { 61.1, 1.503, 210.851 }, + { 45.1, 0.931, 2001.444 }, + { 60.6, 2.687, 388.465 }, + { 43.5, 2.526, 288.081 }, + { 42.5, 3.818, 330.619 }, + { 39.9, 5.714, 408.439 }, + { 50.1, 6.032, 2214.743 }, + { 45.9, 0.542, 212.336 }, + { 54.2, 0.782, 191.958 }, + { 47.0, 4.599, 437.644 }, + { 42.4, 1.901, 430.530 }, + { 39.7, 1.633, 1066.495 }, + { 36.3, 0.848, 213.347 }, + { 35.5, 4.186, 215.747 }, + { 36.3, 3.933, 213.251 }, + { 38.0, 0.313, 423.417 }, + { 44.7, 1.125, 6.150 }, + { 37.9, 1.198, 2.708 }, + { 43.4, 1.374, 563.631 }, + { 43.8, 3.930, 525.498 }, + { 34.8, 1.016, 203.004 }, + { 31.8, 1.693, 0.160 }, + { 30.9, 6.135, 417.037 }, + { 36.4, 6.006, 18.159 }, + { 29.0, 1.197, 404.507 }, + { 32.8, 0.536, 107.025 }, + { 30.4, 0.723, 222.860 }, + { 32.6, 0.812, 1795.258 }, + { 37.8, 3.697, 1272.681 }, + { 27.7, 1.457, 7.162 }, + { 27.2, 1.897, 1045.155 }, + { 37.7, 4.520, 24.379 }, + { 34.9, 4.461, 214.262 }, + { 32.6, 0.664, 692.587 }, + { 30.3, 5.304, 33.940 }, + { 27.5, 6.227, 1.272 }, + { 26.7, 4.567, 7.065 }, + { 31.7, 5.498, 56.622 }, + { 28.1, 5.644, 128.956 }, + { 32.0, 5.223, 92.047 }, + { 27.0, 0.067, 205.222 }, + { 31.8, 5.592, 6069.777 }, + { 31.0, 0.372, 703.633 }, + { 29.4, 0.147, 131.404 }, + { 26.2, 5.413, 140.002 }, + { 25.7, 4.360, 32.243 }, + /* 165 terms retained, 987 terms dropped, error 1.4" */ + + /* saturn l, T^1 */ + { 21354295596.0, 0, 0 }, + { 1296855.0, 1.82820545, 213.29909544 }, + { 564347.6, 2.8850014, 7.1135470 }, + { 98323.0, 1.080701, 426.598191 }, + { 107678.8, 2.2776991, 206.1855484 }, + { 40254.6, 2.041283, 220.412642 }, + { 19941.7, 1.279547, 103.092774 }, + { 10511.7, 2.748804, 14.227094 }, + { 6939.2, 0.40493, 639.89729 }, + { 4803.3, 2.44194, 419.48464 }, + { 4056.3, 2.92167, 110.20632 }, + { 3768.6, 3.64966, 3.93215 }, + { 3384.7, 2.41694, 3.18139 }, + { 3302.2, 1.26256, 433.71174 }, + { 3071.4, 2.32739, 199.07200 }, + { 1953.0, 3.56395, 11.04570 }, + { 1249.3, 2.62804, 95.97923 }, + { 921.7, 1.9609, 227.5262 }, + { 705.6, 4.4169, 529.6910 }, + { 649.7, 6.1742, 202.2534 }, + { 627.6, 6.1109, 309.2783 }, + { 486.8, 6.0400, 853.1964 }, + { 468.4, 4.6171, 63.7359 }, + { 478.5, 4.9878, 522.5774 }, + { 417.0, 2.1171, 323.5054 }, + { 407.6, 1.2995, 209.3669 }, + { 343.8, 3.9585, 412.3711 }, + { 339.7, 3.6340, 316.3919 }, + { 335.9, 3.7717, 735.8765 }, + { 331.9, 2.8608, 210.1177 }, + { 352.5, 2.3171, 632.7837 }, + { 289.4, 2.7326, 117.3199 }, + { 265.8, 0.5434, 647.0108 }, + { 230.5, 1.6443, 216.4805 }, + { 280.9, 5.7440, 2.4477 }, + { 191.7, 2.9651, 224.3448 }, + { 172.9, 4.0770, 846.0828 }, + { 167.1, 2.5975, 21.3406 }, + { 136.3, 2.2858, 10.2949 }, + { 131.4, 3.4411, 742.9901 }, + { 127.8, 4.0953, 217.2312 }, + { 108.9, 6.1614, 415.5525 }, + { 93.9, 3.484, 1052.268 }, + { 92.5, 3.948, 88.866 }, + { 97.6, 4.728, 838.969 }, + { 86.6, 1.220, 440.825 }, + { 83.5, 3.113, 625.670 }, + { 77.6, 6.244, 302.165 }, + { 61.6, 1.828, 195.140 }, + { 61.9, 4.293, 127.472 }, + { 67.1, 0.290, 4.666 }, + { 56.9, 5.019, 137.033 }, + { 54.2, 5.126, 490.334 }, + { 54.6, 0.284, 74.782 }, + { 51.4, 1.458, 536.805 }, + { 65.8, 5.648, 9.561 }, + { 57.8, 2.476, 191.958 }, + { 44.4, 2.709, 5.417 }, + { 46.8, 1.177, 149.563 }, + { 40.4, 3.889, 728.763 }, + { 37.8, 2.534, 12.530 }, + { 46.6, 5.148, 515.464 }, + { 45.9, 2.232, 956.289 }, + { 40.4, 0.413, 269.921 }, + { 37.2, 3.782, 2.921 }, + { 33.8, 3.211, 1368.660 }, + { 38.0, 0.647, 422.666 }, + { 32.9, 0.301, 351.817 }, + { 33.0, 5.430, 1066.495 }, + { 30.3, 2.841, 203.004 }, + { 35.1, 6.084, 5.629 }, + { 29.7, 3.391, 1059.382 }, + { 33.2, 4.641, 277.035 }, + { 31.9, 4.386, 1155.361 }, + { 28.9, 2.026, 330.619 }, + { 28.3, 2.742, 265.989 }, + { 30.1, 6.187, 284.149 }, + { 31.3, 2.435, 52.690 }, + { 26.5, 4.512, 340.771 }, + { 22.0, 5.144, 4.193 }, + { 22.2, 1.965, 203.738 }, + { 20.8, 6.160, 860.310 }, + { 21.7, 2.676, 942.062 }, + { 22.6, 5.886, 210.851 }, + { 19.8, 2.313, 437.644 }, + { 19.4, 4.766, 70.849 }, + { 19.3, 4.102, 18.159 }, + { 22.7, 4.137, 191.208 }, + { 18.2, 0.903, 429.780 }, + { 17.7, 1.850, 234.640 }, + { 17.5, 2.447, 423.417 }, + { 15.4, 4.238, 1162.475 }, + { 14.6, 3.597, 1045.155 }, + { 14.1, 2.943, 1685.052 }, + { 16.3, 4.057, 949.176 }, + { 13.3, 6.245, 38.133 }, + { 15.9, 1.064, 56.622 }, + { 14.1, 1.435, 408.439 }, + { 13.1, 5.758, 138.517 }, + { 15.8, 5.594, 6.150 }, + { 15.0, 5.772, 22.091 }, + { 16.0, 1.939, 1272.681 }, + { 16.8, 5.967, 628.852 }, + { 12.8, 4.247, 405.258 }, + { 13.6, 4.099, 1471.753 }, + { 15.1, 0.741, 200.769 }, + { 11.0, 1.550, 223.594 }, + { 11.7, 1.812, 124.433 }, + { 10.3, 3.468, 1375.774 }, + { 12.1, 1.857, 131.404 }, + { 10.1, 2.382, 107.025 }, + { 9.9, 3.95, 430.53 }, + { 9.8, 2.55, 99.91 }, + { 10.6, 5.367, 215.747 }, + { 12.1, 4.845, 831.856 }, + { 10.2, 6.077, 32.243 }, + { 9.2, 3.65, 142.45 }, + { 9.0, 1.24, 106.27 }, + { 9.3, 5.81, 7.16 }, + { 9.7, 1.39, 145.63 }, + { 8.4, 4.42, 703.63 }, + { 8.4, 5.64, 62.25 }, + { 8.2, 2.42, 1258.45 }, + { 7.8, 0.53, 654.12 }, + { 7.6, 3.75, 312.20 }, + { 7.2, 0.28, 0.75 }, + { 8.2, 6.22, 14.98 }, + { 7.1, 0.53, 388.47 }, + { 6.6, 3.49, 35.42 }, + { 9.0, 4.95, 208.63 }, + { 9.0, 0.08, 288.08 }, + { 6.4, 3.33, 1361.55 }, + { 6.5, 2.89, 114.14 }, + { 6.7, 0.24, 8.08 }, + { 7.3, 4.85, 222.86 }, + { 6.3, 3.81, 1788.14 }, + { 6.9, 2.05, 99.16 }, + { 6.6, 5.83, 483.22 }, + /* 138 terms retained, 504 terms dropped, error 0.32"*T */ + + /* saturn l, T^2 */ + { 116441.2, 1.1798785, 7.1135470 }, + { 91920.8, 0.074253, 213.299095 }, + { 90592.3, 0, 0 }, + { 15276.9, 4.064920, 206.185548 }, + { 10631.4, 0.257783, 220.412642 }, + { 10605.0, 5.409636, 426.598191 }, + { 4265.4, 1.04596, 14.22709 }, + { 1215.5, 2.91860, 103.09277 }, + { 1164.7, 4.60942, 639.89729 }, + { 1082.0, 5.69130, 433.71174 }, + { 1020.1, 0.63369, 3.18139 }, + { 1044.8, 4.04206, 199.07200 }, + { 633.6, 4.3883, 419.4846 }, + { 549.3, 5.5730, 3.9322 }, + { 456.9, 1.2684, 110.2063 }, + { 425.1, 0.2094, 227.5262 }, + { 273.7, 4.2884, 95.9792 }, + { 161.6, 1.3814, 11.0457 }, + { 129.5, 1.5659, 309.2783 }, + { 117.0, 3.8812, 853.1964 }, + { 105.4, 4.9000, 647.0108 }, + { 101.0, 0.8927, 21.3406 }, + { 95.2, 5.626, 412.371 }, + { 81.9, 1.025, 117.320 }, + { 74.9, 4.762, 210.118 }, + { 82.7, 6.050, 216.480 }, + { 95.7, 2.911, 316.392 }, + { 63.7, 0.352, 323.505 }, + { 84.9, 5.735, 209.367 }, + { 60.6, 4.875, 632.784 }, + { 66.5, 0.483, 10.295 }, + { 67.2, 0.456, 522.577 }, + { 53.3, 2.747, 529.691 }, + { 45.8, 5.693, 440.825 }, + { 45.3, 1.669, 202.253 }, + { 42.3, 5.708, 88.866 }, + { 32.1, 0.071, 63.736 }, + { 31.6, 1.672, 302.165 }, + { 31.1, 4.164, 191.958 }, + { 24.6, 5.656, 735.877 }, + { 26.6, 0.833, 224.345 }, + { 20.1, 5.944, 217.231 }, + { 17.5, 4.900, 625.670 }, + { 17.1, 1.626, 742.990 }, + { 13.7, 3.765, 195.140 }, + { 12.2, 4.718, 203.004 }, + { 11.9, 0.126, 234.640 }, + { 16.0, 0.579, 515.464 }, + { 11.2, 5.922, 536.805 }, + { 14.1, 0.207, 838.969 }, + { 11.0, 5.602, 728.763 }, + { 11.7, 3.121, 846.083 }, + { 10.0, 4.155, 860.310 }, + { 10.6, 3.203, 1066.495 }, + { 10.1, 0.257, 330.619 }, + { 9.5, 0.46, 956.29 }, + { 10.2, 4.987, 422.666 }, + { 8.3, 2.14, 269.92 }, + { 7.2, 5.40, 1052.27 }, + { 7.7, 5.25, 429.78 }, + { 6.4, 4.46, 284.15 }, + { 5.9, 5.41, 149.56 }, + { 7.5, 4.03, 9.56 }, + { 5.8, 4.29, 415.55 }, + { 6.1, 5.93, 405.26 }, + { 5.7, 0.02, 124.43 }, + { 5.7, 6.02, 223.59 }, + { 4.8, 4.93, 654.12 }, + { 4.7, 2.27, 18.16 }, + { 4.5, 4.41, 942.06 }, + { 5.6, 0.30, 127.47 }, + { 5.5, 5.54, 949.18 }, + { 4.1, 4.69, 74.78 }, + { 4.1, 5.31, 1045.15 }, + { 4.2, 2.89, 56.62 }, + { 4.9, 3.20, 277.03 }, + { 3.9, 3.30, 490.33 }, + { 3.9, 6.10, 81.75 }, + { 3.8, 4.93, 52.69 }, + { 4.6, 6.14, 1155.36 }, + { 3.7, 0.41, 137.03 }, + { 3.4, 4.29, 99.91 }, + { 3.6, 0.20, 1272.68 }, + { 3.9, 0.37, 12.53 }, + { 3.2, 1.57, 1059.38 }, + { 4.1, 0.29, 831.86 }, + { 3.7, 0.15, 437.64 }, + { 2.9, 3.13, 70.85 }, + { 2.8, 0.33, 191.21 }, + { 2.7, 1.88, 295.05 }, + { 3.5, 4.77, 423.42 }, + { 2.6, 5.15, 1368.66 }, + { 2.5, 3.90, 210.85 }, + { 2.5, 1.59, 32.24 }, + { 2.6, 3.59, 131.40 }, + { 2.3, 4.77, 351.82 }, + { 2.4, 5.83, 106.27 }, + { 2.2, 5.98, 6062.66 }, + { 2.2, 2.06, 6076.89 }, + { 2.2, 5.95, 145.63 }, + { 2.7, 3.38, 408.44 }, + { 2.3, 3.14, 22.09 }, + { 2.1, 1.12, 9992.87 }, + { 2.1, 3.48, 10007.10 }, + { 2.6, 5.12, 265.99 }, + { 1.8, 4.15, 1258.45 }, + { 1.8, 5.05, 1361.55 }, + { 1.8, 4.14, 107.02 }, + { 1.9, 4.52, 138.52 }, + { 1.7, 1.36, 231.46 }, + { 2.0, 5.87, 1471.75 }, + { 2.1, 5.23, 1265.57 }, + { 1.6, 5.62, 447.94 }, + { 1.6, 3.75, 628.85 }, + { 1.7, 6.24, 1148.25 }, + /* 115 terms retained, 206 terms dropped, error 0.074"*T^2 */ + + /* saturn l, T^3 */ + { 16038.7, 5.739454, 7.113547 }, + { 4249.8, 4.58540, 213.29910 }, + { 1906.5, 4.76082, 220.41264 }, + { 1465.7, 5.91327, 206.18555 }, + { 1162.0, 5.61973, 14.22709 }, + { 1066.6, 3.60817, 426.59819 }, + { 239.4, 3.8609, 433.7117 }, + { 237.0, 5.7683, 199.0720 }, + { 165.6, 5.1164, 3.1814 }, + { 131.4, 4.7433, 227.5262 }, + { 151.4, 2.7359, 639.8973 }, + { 61.6, 4.743, 103.093 }, + { 63.4, 0.229, 419.485 }, + { 40.4, 5.473, 21.341 }, + { 40.2, 5.964, 95.979 }, + { 38.7, 5.834, 110.206 }, + { 28.0, 3.012, 647.011 }, + { 25.0, 0.988, 3.932 }, + { 18.1, 1.025, 412.371 }, + { 17.9, 3.319, 309.278 }, + { 16.2, 3.898, 440.825 }, + { 15.8, 5.617, 117.320 }, + { 19.0, 1.916, 853.196 }, + { 18.3, 4.967, 10.295 }, + { 12.9, 1.181, 88.866 }, + { 17.9, 4.204, 216.480 }, + { 11.5, 5.575, 11.046 }, + { 10.5, 5.929, 191.958 }, + { 10.4, 3.948, 209.367 }, + { 8.7, 3.39, 302.16 }, + { 7.6, 4.88, 323.51 }, + { 6.7, 0.38, 632.78 }, + { 5.9, 1.06, 210.12 }, + { 5.4, 4.64, 234.64 }, + { 6.3, 2.25, 522.58 }, + { 3.6, 2.31, 515.46 }, + { 3.2, 2.20, 860.31 }, + { 3.7, 3.14, 0 }, + { 2.6, 4.93, 224.34 }, + { 2.5, 0.42, 625.67 }, + { 2.2, 3.20, 202.25 }, + { 2.4, 4.77, 330.62 }, + { 2.9, 0.59, 529.69 }, + { 2.0, 4.40, 124.43 }, + { 2.2, 1.35, 405.26 }, + { 2.3, 3.35, 429.78 }, + { 2.0, 3.07, 654.12 }, + { 2.0, 1.03, 728.76 }, + { 1.9, 3.09, 422.67 }, + { 1.8, 4.15, 536.80 }, + { 2.2, 1.19, 1066.50 }, + { 2.1, 4.16, 223.59 }, + { 1.5, 0.38, 316.39 }, + { 1.7, 5.83, 195.14 }, + { 1.5, 1.58, 81.75 }, + { 1.6, 6.04, 742.99 }, + { 1.3, 1.66, 63.74 }, + { 1.3, 5.02, 956.29 }, + { 1.4, 2.11, 838.97 }, + { 1.2, 3.88, 269.92 }, + { 1.0, 3.73, 295.05 }, + { 1.3, 1.38, 735.88 }, + { 1.3, 2.33, 217.23 }, + { 0.9, 2.76, 284.15 }, + { 0.9, 0.71, 846.08 }, + { 0.9, 3.84, 447.94 }, + { 0.9, 3.31, 18.16 }, + { 0.8, 4.71, 56.62 }, + { 0.9, 2.02, 831.86 }, + { 0.8, 0.80, 1045.15 }, + { 0.7, 4.27, 437.64 }, + { 0.7, 6.18, 942.06 }, + { 0.8, 2.41, 203.00 }, + { 0.7, 1.65, 423.42 }, + { 0.5, 2.86, 184.84 }, + { 0.5, 6.26, 1059.38 }, + { 0.5, 3.43, 149.56 }, + { 0.5, 4.88, 1272.68 }, + { 0.4, 5.40, 408.44 }, + { 0.4, 4.06, 543.92 }, + { 0.4, 1.69, 1155.36 }, + { 0.4, 1.22, 1052.27 }, + /* 82 terms retained, 66 terms dropped, error 0.015"*T^3 */ + + /* saturn l, T^4 */ + { 1661.9, 3.99826, 7.11355 }, + { 257.1, 2.9844, 220.4126 }, + { 236.3, 3.9024, 14.2271 }, + { 149.4, 2.7411, 213.2991 }, + { 109.6, 1.5152, 206.1855 }, + { 114.0, 3.1416, 0 }, + { 68.4, 1.721, 426.598 }, + { 37.7, 1.238, 199.072 }, + { 40.1, 2.046, 433.712 }, + { 31.2, 3.011, 227.526 }, + { 15.1, 0.829, 639.897 }, + { 9.4, 3.71, 21.34 }, + { 5.7, 2.42, 419.48 }, + { 4.5, 1.45, 95.98 }, + { 5.6, 1.16, 647.01 }, + { 4.5, 2.12, 440.83 }, + { 3.2, 4.09, 110.21 }, + { 2.9, 2.77, 412.37 }, + { 2.8, 3.01, 88.87 }, + { 2.6, 0.00, 853.20 }, + { 2.6, 0.39, 103.09 }, + { 1.9, 5.08, 309.28 }, + { 2.2, 3.78, 117.32 }, + { 1.8, 5.19, 302.16 }, + { 1.9, 2.83, 234.64 }, + { 1.8, 2.24, 216.48 }, + { 1.2, 1.55, 191.96 }, + { 0.8, 3.45, 323.51 }, + { 0.8, 4.83, 210.12 }, + { 0.6, 4.19, 515.46 }, + { 0.6, 2.29, 209.37 }, + { 0.6, 4.03, 522.58 }, + { 0.6, 2.38, 632.78 }, + { 0.6, 0.30, 860.31 }, + { 0.6, 2.17, 124.43 }, + { 0.4, 2.24, 447.94 }, + { 0.4, 5.45, 1066.50 }, + { 0.5, 1.27, 654.12 }, + { 0.5, 3.20, 405.26 }, + { 0.4, 3.12, 330.62 }, + { 0.4, 3.39, 81.75 }, + { 0.3, 4.12, 838.97 }, + { 0.3, 3.18, 529.69 }, + { 0.3, 1.41, 429.78 }, + { 0.3, 3.19, 1464.64 }, + { 0.3, 2.94, 728.76 }, + { 0.2, 3.67, 1148.25 }, + { 0.3, 2.58, 1045.15 }, + { 0.2, 3.58, 1155.36 }, + { 0.3, 2.05, 1677.94 }, + { 0.2, 2.62, 536.80 }, + { 0.3, 2.48, 625.67 }, + { 0.2, 4.39, 1574.85 }, + { 0.2, 1.26, 422.67 }, + { 0.2, 2.33, 223.59 }, + { 0.2, 1.09, 742.99 }, + { 0.2, 0.70, 824.74 }, + { 0.2, 5.03, 203.00 }, + { 0.2, 0.40, 867.42 }, + { 0.2, 3.68, 831.86 }, + { 0.2, 5.75, 1073.61 }, + { 0.2, 3.02, 1781.03 }, + { 0.1, 2.28, 295.05 }, + { 0.1, 3.48, 956.29 }, + { 0.2, 1.91, 942.06 }, + { 0.1, 6.17, 316.39 }, + /* 66 terms retained, 2 terms dropped, error 0.0049"*T^4 */ + + /* saturn l, T^5 */ + { 123.6, 2.2592, 7.1135 }, + { 34.2, 2.163, 14.227 }, + { 27.5, 1.199, 220.413 }, + { 5.8, 1.22, 227.53 }, + { 5.3, 0.24, 433.71 }, + { 3.7, 6.23, 426.60 }, + { 3.1, 2.97, 199.07 }, + { 2.9, 4.29, 206.19 }, + { 1.6, 6.25, 213.30 }, + { 1.3, 5.28, 639.90 }, + { 0.9, 5.57, 647.01 }, + { 0.8, 6.18, 191.96 }, + { 0.8, 0.69, 302.16 }, + { 1.0, 0.24, 440.83 }, + { 1.0, 3.14, 0 }, + { 0.5, 4.88, 88.87 }, + { 0.5, 4.78, 419.48 }, + { 0.3, 4.32, 853.20 }, + { 0.4, 5.70, 654.12 }, + { 0.2, 2.05, 323.51 }, + { 0.3, 1.11, 234.64 }, + { 0.2, 0.89, 309.28 }, + { 0.3, 5.10, 95.98 }, + { 0.2, 2.40, 515.46 }, + { 0.2, 4.70, 860.31 }, + { 0.1, 0.49, 117.32 }, + /* 26 terms retained, 1 terms dropped, error 0.0022"*T^5 */ + /* end saturn l */ + + /* saturn b, T^0 */ + { 4330678.0, 3.60284428, 213.29909544 }, + { 240348.3, 2.8523849, 426.5981909 }, + { 84745.9, 0, 0 }, + { 30863.4, 3.484415, 220.412642 }, + { 34116.1, 0.572973, 206.185548 }, + { 14734.1, 2.118466, 639.897286 }, + { 9916.7, 5.79003, 419.48464 }, + { 6993.6, 4.73605, 7.11355 }, + { 4807.6, 5.43305, 316.39187 }, + { 4788.4, 4.96513, 110.20632 }, + { 3432.1, 2.73256, 433.71174 }, + { 1506.1, 6.01305, 103.09277 }, + { 1060.3, 5.63099, 529.69097 }, + { 969.1, 5.2043, 632.7837 }, + { 942.1, 1.3965, 853.1964 }, + { 707.6, 3.8030, 323.5054 }, + { 552.3, 5.1315, 202.2534 }, + { 399.7, 3.3589, 227.5262 }, + { 316.1, 1.9972, 647.0108 }, + { 319.4, 3.6257, 209.3669 }, + { 284.5, 4.8865, 224.3448 }, + { 314.2, 0.4651, 217.2312 }, + { 236.4, 2.1389, 11.0457 }, + { 215.4, 5.9498, 846.0828 }, + { 208.5, 2.1200, 415.5525 }, + { 179.0, 2.9536, 63.7359 }, + { 207.2, 0.7302, 199.0720 }, + { 139.1, 1.9982, 735.8765 }, + { 134.9, 5.2450, 742.9901 }, + { 140.6, 0.6442, 490.3341 }, + { 121.7, 3.1154, 522.5774 }, + { 139.2, 4.5954, 14.2271 }, + { 115.5, 3.1089, 216.4805 }, + { 114.2, 0.9626, 210.1177 }, + { 96.4, 4.482, 117.320 }, + { 80.6, 1.317, 277.035 }, + { 73.0, 3.060, 536.805 }, + { 69.3, 4.924, 309.278 }, + { 74.3, 2.894, 149.563 }, + { 68.0, 2.180, 351.817 }, + { 61.7, 0.677, 1066.495 }, + { 56.6, 2.610, 440.825 }, + { 48.9, 5.787, 95.979 }, + { 48.2, 2.182, 74.782 }, + { 38.3, 5.292, 1059.382 }, + { 36.3, 1.633, 628.852 }, + { 35.1, 1.713, 1052.268 }, + { 34.3, 2.457, 422.666 }, + { 34.3, 5.980, 412.371 }, + { 33.8, 1.141, 949.176 }, + { 31.6, 4.147, 437.644 }, + { 36.8, 6.278, 1162.475 }, + { 27.0, 1.272, 860.310 }, + /* 53 terms retained, 447 terms dropped, error 0.82" */ + + /* saturn b, T^1 */ + { 397555.0, 5.3328999, 213.2990954 }, + { 49478.6, 3.141593, 0 }, + { 18571.6, 6.099192, 426.598191 }, + { 14800.6, 2.305861, 206.185548 }, + { 9644.0, 1.69675, 220.41264 }, + { 3757.2, 1.25430, 419.48464 }, + { 2716.6, 5.91167, 639.89729 }, + { 1455.3, 0.85162, 433.71174 }, + { 1290.6, 2.91771, 7.11355 }, + { 852.6, 0.4357, 316.3919 }, + { 284.4, 1.6188, 227.5262 }, + { 292.2, 5.3157, 853.1964 }, + { 275.1, 3.8886, 103.0928 }, + { 297.7, 0.9191, 632.7837 }, + { 172.4, 0.0522, 647.0108 }, + { 127.7, 1.2071, 529.6910 }, + { 166.2, 2.4435, 199.0720 }, + { 158.2, 5.2085, 110.2063 }, + { 109.8, 2.4570, 217.2312 }, + { 81.8, 2.758, 210.118 }, + { 81.0, 2.860, 14.227 }, + { 68.7, 1.655, 202.253 }, + { 59.3, 1.824, 323.505 }, + { 65.2, 1.255, 216.480 }, + { 61.0, 1.253, 209.367 }, + { 46.4, 0.815, 440.825 }, + { 36.2, 1.819, 224.345 }, + { 34.0, 2.840, 117.320 }, + { 32.2, 1.187, 846.083 }, + { 33.1, 1.306, 412.371 }, + { 27.3, 4.647, 1066.495 }, + { 22.8, 4.129, 415.552 }, + { 27.1, 4.442, 11.046 }, + { 18.1, 5.564, 860.310 }, + { 20.9, 1.410, 309.278 }, + { 14.9, 1.343, 95.979 }, + { 15.3, 1.224, 63.736 }, + { 14.6, 1.008, 536.805 }, + { 12.8, 2.271, 742.990 }, + { 12.8, 4.889, 522.577 }, + { 13.1, 2.460, 490.334 }, + { 11.9, 1.873, 423.417 }, + { 13.0, 3.217, 277.035 }, + { 9.9, 3.12, 625.67 }, + { 12.7, 0.295, 422.666 }, + { 9.6, 1.75, 330.62 }, + { 8.1, 2.42, 430.53 }, + { 8.2, 4.68, 215.75 }, + { 9.0, 0.46, 429.78 }, + { 6.5, 3.01, 949.18 }, + { 7.3, 5.97, 149.56 }, + { 6.6, 3.91, 351.82 }, + { 6.8, 1.52, 437.64 }, + /* 53 terms retained, 207 terms dropped, error 0.21"*T */ + + /* saturn b, T^2 */ + { 20630.0, 0.504824, 213.299095 }, + { 3719.6, 3.99833, 206.18555 }, + { 1627.2, 6.18190, 220.41264 }, + { 1346.1, 0, 0 }, + { 705.8, 3.0391, 419.4846 }, + { 365.0, 5.0993, 426.5982 }, + { 329.6, 5.2790, 433.7117 }, + { 219.3, 3.8284, 639.8973 }, + { 139.4, 1.0427, 7.1135 }, + { 104.0, 6.1573, 227.5262 }, + { 93.0, 1.980, 316.392 }, + { 71.2, 4.148, 199.072 }, + { 51.9, 2.884, 632.784 }, + { 49.0, 4.434, 647.011 }, + { 41.4, 3.159, 853.196 }, + { 28.6, 4.530, 210.118 }, + { 24.0, 1.116, 14.227 }, + { 20.5, 4.351, 217.231 }, + { 19.5, 5.308, 440.825 }, + { 18.3, 0.854, 110.206 }, + { 15.7, 4.258, 103.093 }, + { 16.8, 5.681, 216.480 }, + { 13.6, 2.999, 412.371 }, + { 11.6, 2.527, 529.691 }, + { 8.0, 3.32, 202.25 }, + { 6.6, 0.29, 323.51 }, + { 6.3, 1.16, 117.32 }, + { 5.9, 3.58, 309.28 }, + { 6.6, 5.56, 209.37 }, + { 5.6, 2.48, 1066.50 }, + { 6.2, 3.61, 860.31 }, + { 4.2, 3.02, 846.08 }, + { 3.6, 4.80, 625.67 }, + { 3.4, 3.77, 423.42 }, + { 3.4, 6.04, 234.64 }, + { 2.6, 5.64, 735.88 }, + { 2.8, 4.82, 429.78 }, + { 2.8, 4.48, 654.12 }, + { 2.6, 0.22, 522.58 }, + { 2.6, 3.29, 95.98 }, + { 2.4, 0.03, 415.55 }, + { 2.1, 4.56, 422.67 }, + { 2.3, 6.25, 330.62 }, + { 1.8, 5.53, 536.80 }, + { 1.8, 5.06, 277.03 }, + { 1.6, 5.54, 224.34 }, + /* 46 terms retained, 65 terms dropped, error 0.045"*T^2 */ + + /* saturn b, T^3 */ + { 666.3, 1.9901, 213.2991 }, + { 632.4, 5.6978, 206.1855 }, + { 398.1, 0, 0 }, + { 187.8, 4.3378, 220.4126 }, + { 91.9, 4.841, 419.485 }, + { 42.4, 2.381, 426.598 }, + { 51.5, 3.421, 433.712 }, + { 25.7, 4.402, 227.526 }, + { 20.6, 5.853, 199.072 }, + { 18.1, 1.993, 639.897 }, + { 10.9, 5.373, 7.114 }, + { 9.6, 2.55, 647.01 }, + { 7.1, 3.46, 316.39 }, + { 6.0, 4.80, 632.78 }, + { 5.8, 0.02, 210.12 }, + { 4.9, 5.64, 14.23 }, + { 4.5, 1.22, 853.20 }, + { 5.5, 3.52, 440.83 }, + { 3.5, 4.71, 412.37 }, + { 2.9, 0.63, 103.09 }, + { 2.2, 3.72, 216.48 }, + { 2.0, 6.11, 217.23 }, + { 1.4, 1.69, 860.31 }, + { 1.2, 4.31, 234.64 }, + { 1.2, 5.75, 309.28 }, + { 0.8, 5.69, 117.32 }, + { 0.7, 0.60, 1066.50 }, + { 0.7, 0.22, 625.67 }, + { 0.8, 5.48, 202.25 }, + { 0.9, 2.66, 654.12 }, + { 0.5, 2.86, 429.78 }, + { 0.5, 4.18, 529.69 }, + { 0.5, 4.52, 323.51 }, + /* 33 terms retained, 25 terms dropped, error 0.012"*T^3 */ + + /* saturn b, T^4 */ + { 80.4, 1.119, 206.186 }, + { 31.7, 3.122, 213.299 }, + { 17.1, 2.481, 220.413 }, + { 11.8, 3.142, 0 }, + { 9.0, 0.38, 419.48 }, + { 6.2, 1.56, 433.71 }, + { 4.7, 1.28, 199.07 }, + { 4.8, 2.63, 227.53 }, + { 1.5, 1.43, 426.60 }, + { 1.4, 0.67, 647.01 }, + { 1.1, 6.18, 639.90 }, + { 1.1, 1.72, 440.83 }, + { 0.7, 3.85, 14.23 }, + { 0.7, 3.49, 7.11 }, + { 0.5, 0.47, 632.78 }, + { 0.5, 0.31, 412.37 }, + { 0.3, 5.86, 853.20 }, + { 0.3, 2.50, 234.64 }, + { 0.2, 5.39, 316.39 }, + { 0.2, 2.11, 210.12 }, + { 0.2, 6.10, 860.31 }, + { 0.2, 5.95, 216.48 }, + { 0.1, 1.99, 625.67 }, + { 0.1, 0.86, 654.12 }, + { 0.1, 5.04, 117.32 }, + { 0.1, 0.45, 110.21 }, + /* 26 terms retained, 0 terms dropped, error 0.0025"*T^4 */ + + /* saturn b, T^5 */ + { 7.9, 2.82, 206.19 }, + { 1.0, 0.51, 220.41 }, + { 0.8, 2.99, 199.07 }, + { 1.0, 3.14, 0 }, + { 0.6, 5.96, 433.71 }, + { 0.6, 0.78, 227.53 }, + { 0.4, 2.39, 419.48 }, + { 0.1, 5.11, 647.01 }, + /* 8 terms retained, 3 terms dropped, error 0.0012"*T^5 */ + /* end saturn b */ + + /* saturn r, T^0 */ + { 955758135.8, 0, 0 }, + { 52921382.5, 2.392262197, 213.299095438 }, + { 1873679.9, 5.23549605, 206.18554844 }, + { 1464664.0, 1.64763045, 426.59819088 }, + { 821891.1, 5.9352003, 316.3918697 }, + { 547506.9, 5.0153263, 103.0927742 }, + { 371684.4, 2.2711483, 220.4126424 }, + { 361778.4, 3.1390430, 7.1135470 }, + { 140617.5, 5.7040665, 632.7837393 }, + { 108974.7, 3.2931360, 110.2063212 }, + { 69007.0, 5.940996, 419.484644 }, + { 61053.3, 0.940378, 639.897286 }, + { 48913.0, 1.557334, 202.253395 }, + { 34143.8, 0.195186, 277.034994 }, + { 32401.7, 5.470846, 949.175609 }, + { 20936.6, 0.463492, 735.876514 }, + { 20839.1, 1.521026, 433.711738 }, + { 20746.7, 5.332557, 199.072001 }, + { 15298.5, 3.059437, 529.690965 }, + { 14296.5, 2.604335, 323.505417 }, + { 11993.3, 5.980514, 846.082835 }, + { 11380.3, 1.731057, 522.577418 }, + { 12884.1, 1.648923, 138.517497 }, + { 7752.8, 5.85191, 95.97923 }, + { 9796.1, 5.20476, 1265.56748 }, + { 6466.0, 0.17733, 1052.26838 }, + { 6770.6, 3.00433, 14.22709 }, + { 5850.4, 1.45520, 415.55249 }, + { 5307.5, 0.59738, 63.73590 }, + { 4695.7, 2.14919, 227.52619 }, + { 4044.0, 1.64010, 209.36694 }, + { 3688.1, 0.78016, 412.37110 }, + { 3376.5, 3.69528, 224.34480 }, + { 2885.3, 1.38764, 838.96929 }, + { 2976.0, 5.68468, 210.11770 }, + { 3419.6, 4.94549, 1581.95935 }, + { 3460.9, 1.85089, 175.16606 }, + { 3400.6, 0.55387, 350.33212 }, + { 2507.6, 3.53852, 742.99006 }, + { 2448.3, 6.18412, 1368.66025 }, + { 2406.1, 2.96559, 117.31987 }, + { 2881.2, 0.17961, 853.19638 }, + { 2174.0, 0.01509, 340.77089 }, + { 2024.5, 5.05411, 11.04570 }, + { 1740.3, 2.34657, 309.27832 }, + { 1861.4, 5.93362, 625.67019 }, + { 1888.4, 0.02968, 3.93215 }, + { 1610.9, 1.17302, 74.78160 }, + { 1462.6, 1.92588, 216.48049 }, + { 1474.5, 5.67670, 203.73787 }, + { 1395.1, 5.93669, 127.47180 }, + { 1781.2, 0.76314, 217.23125 }, + { 1817.2, 5.77713, 490.33409 }, + { 1472.4, 1.40065, 137.03302 }, + { 1304.1, 0.77236, 647.01083 }, + { 1149.8, 5.74021, 1162.47470 }, + { 1126.7, 4.46708, 265.98929 }, + { 1277.5, 2.98413, 1059.38193 }, + { 1207.1, 0.75286, 351.81659 }, + { 1071.4, 1.13567, 1155.36116 }, + { 1020.9, 5.91234, 1685.05212 }, + { 1315.0, 5.11203, 211.81462 }, + { 1295.6, 4.69184, 1898.35122 }, + { 1099.0, 1.81765, 149.56320 }, + { 998.5, 2.6313, 200.7689 }, + { 985.9, 2.2599, 956.2892 }, + { 932.4, 3.6698, 554.0700 }, + { 664.5, 0.6030, 728.7630 }, + { 659.8, 4.6664, 195.1398 }, + { 617.7, 5.6209, 942.0621 }, + { 626.4, 5.9421, 1478.8666 }, + { 482.2, 1.8407, 479.2884 }, + { 487.7, 2.7937, 3.1814 }, + { 470.1, 0.8385, 1471.7530 }, + { 451.8, 5.6447, 2001.4440 }, + { 553.1, 3.4109, 269.9214 }, + { 534.4, 1.2644, 275.5505 }, + { 472.6, 1.8820, 515.4639 }, + { 405.4, 1.6400, 536.8045 }, + { 517.2, 4.4431, 2214.7431 }, + { 452.8, 3.0035, 302.1648 }, + { 494.3, 2.2863, 278.5195 }, + { 489.8, 5.8063, 191.2077 }, + { 427.5, 0.0574, 284.1485 }, + { 339.8, 1.4020, 440.8253 }, + { 340.6, 0.8909, 628.8516 }, + { 386.0, 1.9970, 1272.6810 }, + { 288.3, 1.1216, 422.6660 }, + { 294.4, 0.4258, 312.1991 }, + { 262.5, 0.3175, 1045.1548 }, + { 295.3, 0.6714, 88.8657 }, + { 343.0, 5.8560, 1795.2584 }, + { 341.1, 2.3759, 525.4982 }, + { 234.0, 4.2276, 114.1385 }, + { 223.7, 2.2813, 330.6190 }, + { 275.8, 0.4783, 38.1330 }, + { 224.6, 0.5475, 1788.1449 }, + { 303.3, 0.8795, 6069.7768 }, + { 292.1, 6.2142, 210.8514 }, + { 226.1, 0.3750, 142.4497 }, + { 277.3, 5.3192, 692.5875 }, + { 242.9, 5.3719, 1258.4539 }, + { 205.6, 0.9576, 288.0807 }, + { 207.6, 5.3813, 2317.8359 }, + { 186.8, 6.0359, 404.5068 }, + { 218.5, 5.2561, 212.3359 }, + { 222.2, 5.9459, 39.3569 }, + { 179.7, 4.4105, 408.4389 }, + { 241.4, 1.1253, 388.4652 }, + { 197.1, 3.9014, 52.6902 }, + { 236.6, 0.9080, 1375.7738 }, + { 171.9, 5.5632, 213.3473 }, + { 169.9, 2.8567, 99.1606 }, + { 214.4, 4.2025, 2531.1350 }, + { 172.0, 2.3654, 213.2509 }, + { 165.7, 2.6368, 215.7468 }, + { 230.9, 5.4946, 191.9585 }, + { 177.6, 0.3816, 430.5303 }, + { 191.5, 2.9591, 437.6439 }, + { 163.2, 3.4583, 617.8059 }, + { 162.3, 5.7305, 203.0042 }, + { 175.1, 5.7140, 1066.4955 }, + { 183.0, 5.6685, 2111.6503 }, + { 150.1, 4.4066, 417.0370 }, + { 187.9, 6.0792, 563.6312 }, + { 145.1, 5.0818, 423.4168 }, + { 137.5, 5.4391, 222.8603 }, + { 172.8, 1.8492, 1589.0729 }, + { 165.5, 2.8913, 214.2623 }, + { 145.7, 1.5657, 831.8557 }, + { 176.9, 2.3032, 9999.9865 }, + { 128.9, 2.5534, 414.0680 }, + { 120.1, 0.0433, 1361.5467 }, + { 143.4, 0.9982, 76.2661 }, + { 108.7, 2.0928, 207.6700 }, + { 132.1, 2.8590, 312.4597 }, + { 112.2, 0.2622, 2104.5368 }, + { 125.2, 4.7835, 205.2223 }, + { 104.4, 3.6367, 65.2204 }, + { 107.4, 3.6706, 212.7778 }, + { 108.6, 2.8549, 21.3406 }, + { 97.7, 5.122, 2634.228 }, + { 109.1, 1.6323, 208.6332 }, + { 96.9, 4.199, 305.346 }, + { 96.5, 2.560, 1692.166 }, + { 85.8, 4.545, 210.378 }, + { 99.2, 5.138, 1574.846 }, + { 112.5, 5.0311, 703.6332 }, + { 84.0, 1.183, 429.780 }, + { 89.0, 5.388, 107.025 }, + { 110.2, 2.4366, 355.7487 }, + { 90.7, 4.209, 213.820 }, + { 95.9, 5.446, 2428.042 }, + { 94.1, 2.398, 483.221 }, + { 85.6, 0.034, 860.310 }, + { 88.8, 4.058, 128.956 }, + { 82.0, 1.665, 62.251 }, + { 91.2, 3.969, 2847.527 }, + { 84.0, 4.608, 177.874 }, + { 88.4, 3.868, 140.002 }, + { 93.3, 0.738, 831.105 }, + { 91.9, 2.950, 35.425 }, + { 87.1, 1.334, 1905.465 }, + { 96.6, 4.844, 131.404 }, + { 71.0, 0.993, 405.258 }, + { 95.3, 2.515, 2.448 }, + { 72.5, 4.632, 245.542 }, + { 82.6, 1.528, 145.631 }, + { 76.7, 3.152, 767.369 }, + { 70.3, 4.043, 173.942 }, + { 86.0, 2.301, 85.827 }, + { 66.5, 4.751, 70.849 }, + { 65.8, 2.469, 280.967 }, + { 64.8, 0.093, 9.561 }, + { 71.6, 0.012, 565.116 }, + { 66.5, 1.080, 339.286 }, + { 63.5, 2.017, 234.640 }, + { 60.8, 5.120, 756.323 }, + { 58.1, 6.057, 1677.939 }, + { 64.2, 1.286, 1148.248 }, + { 73.1, 4.378, 425.114 }, + { 55.0, 3.859, 342.255 }, + { 57.1, 6.267, 2420.929 }, + { 64.1, 4.099, 327.438 }, + { 55.3, 1.605, 543.024 }, + { 58.0, 5.473, 347.884 }, + { 73.6, 3.723, 92.047 }, + { 73.8, 3.570, 1.484 }, + { 64.9, 2.447, 267.474 }, + { 54.4, 3.715, 344.703 }, + { 49.8, 3.935, 192.692 }, + { 49.5, 3.228, 333.657 }, + { 47.5, 3.929, 199.284 }, + { 49.4, 4.903, 217.492 }, + { 62.7, 4.401, 214.784 }, + { 46.4, 2.094, 212.548 }, + { 46.3, 2.640, 10.295 }, + { 54.3, 1.072, 362.862 }, + { 58.7, 2.623, 225.829 }, + { 48.5, 3.152, 216.220 }, + { 46.3, 4.862, 2950.620 }, + { 46.0, 4.973, 198.321 }, + { 46.7, 2.450, 207.149 }, + { 44.9, 1.776, 223.594 }, + { 44.5, 5.560, 264.505 }, + { 55.9, 4.295, 329.725 }, + { 49.6, 5.208, 2744.434 }, + { 58.8, 4.231, 700.664 }, + { 52.6, 3.792, 343.219 }, + { 41.5, 0.745, 125.987 }, + { 47.8, 2.393, 207.882 }, + { 56.2, 2.072, 124.433 }, + { 43.3, 1.837, 106.274 }, + { 39.8, 4.009, 12.530 }, + { 53.9, 4.979, 134.585 }, + { 50.1, 5.759, 320.324 }, + { 45.0, 5.357, 218.928 }, + { 41.1, 4.923, 1891.238 }, + { 46.5, 2.066, 2008.558 }, + { 42.9, 0.399, 357.446 }, + { 38.0, 2.065, 247.239 }, + { 48.7, 5.328, 3127.313 }, + { 34.6, 5.626, 99.911 }, + { 41.1, 2.473, 237.678 }, + { 40.8, 4.084, 621.738 }, + { 34.2, 0.731, 750.104 }, + { 34.0, 5.313, 206.234 }, + { 36.5, 1.688, 22.091 }, + { 39.4, 3.457, 241.610 }, + { 34.8, 2.248, 487.365 }, + { 33.0, 4.866, 209.106 }, + { 32.6, 2.227, 319.573 }, + { 39.0, 3.739, 3163.919 }, + { 32.7, 1.066, 252.656 }, + { 38.7, 4.396, 18.159 }, + { 34.5, 1.826, 380.128 }, + { 41.5, 0.081, 210.330 }, + { 33.5, 5.805, 251.432 }, + { 31.2, 1.965, 244.319 }, + { 30.5, 2.269, 1169.588 }, + { 34.8, 5.963, 217.965 }, + { 38.5, 4.437, 160.609 }, + { 36.0, 3.833, 56.622 }, + { 31.0, 4.899, 144.147 }, + { 32.3, 3.582, 231.458 }, + { 28.8, 5.801, 1994.330 }, + { 32.2, 2.132, 206.137 }, + { 32.6, 1.931, 98.900 }, + { 34.9, 5.653, 497.448 }, + { 28.9, 2.217, 14.978 }, + { 31.6, 3.818, 73.297 }, + { 32.2, 0.998, 1464.639 }, + { 29.2, 5.984, 2737.321 }, + { 36.7, 4.755, 348.848 }, + { 28.7, 1.687, 78.714 }, + { 27.5, 6.121, 214.050 }, + { 28.8, 0.044, 5.629 }, + { 27.2, 0.246, 313.210 }, + { 32.4, 3.779, 33.940 }, + { 27.1, 5.203, 148.079 }, + { 35.0, 3.439, 273.103 }, + { 33.1, 2.447, 969.622 }, + { 27.7, 1.446, 258.876 }, + { 27.2, 4.259, 179.359 }, + { 27.9, 0.788, 546.956 }, + { 29.1, 4.839, 905.887 }, + { 27.4, 2.449, 254.944 }, + { 34.3, 6.009, 166.829 }, + { 28.9, 6.029, 188.920 }, + { 26.0, 0.650, 654.124 }, + { 33.6, 1.237, 2221.857 }, + { 27.8, 5.178, 5.417 }, + { 25.6, 3.359, 0.963 }, + { 28.8, 0.755, 488.850 }, + { 31.2, 2.053, 282.452 }, + { 25.4, 5.290, 636.716 }, + { 25.3, 4.970, 3060.826 }, + { 29.6, 3.927, 206.707 }, + { 28.3, 2.721, 32.243 }, + { 26.9, 2.863, 24.379 }, + { 28.3, 4.731, 552.586 }, + { 25.3, 5.120, 168.053 }, + { 26.4, 1.593, 491.819 }, + { 27.1, 5.537, 555.554 }, + { 27.3, 3.579, 561.184 }, + { 25.2, 1.781, 182.280 }, + { 25.6, 1.621, 2324.949 }, + { 25.6, 2.099, 248.724 }, + /* 288 terms retained, 917 terms dropped, error 8.7e-06 a.u. */ + + /* saturn r, T^1 */ + { 6182981.3, 0.25843515, 213.29909544 }, + { 506577.6, 0.7111465, 206.1855484 }, + { 341394.1, 5.7963577, 426.5981909 }, + { 188491.4, 0.4721572, 220.4126424 }, + { 186261.5, 3.1415927, 0 }, + { 143891.2, 1.4074486, 7.1135470 }, + { 49621.1, 6.017445, 103.092774 }, + { 20928.2, 5.092457, 639.897286 }, + { 19952.6, 1.175601, 419.484644 }, + { 18839.6, 1.608196, 110.206321 }, + { 12892.8, 5.943303, 433.711738 }, + { 13876.6, 0.758862, 199.072001 }, + { 5396.7, 1.28852, 14.22709 }, + { 4869.3, 0.86794, 323.50542 }, + { 4247.5, 0.39299, 227.52619 }, + { 3252.1, 1.25853, 95.97923 }, + { 2856.0, 2.16731, 735.87651 }, + { 2909.4, 4.60679, 202.25340 }, + { 3081.4, 3.43663, 522.57742 }, + { 1987.7, 2.45054, 412.37110 }, + { 1941.3, 6.02393, 209.36694 }, + { 1581.4, 1.29192, 210.11770 }, + { 1339.5, 4.30802, 853.19638 }, + { 1315.6, 1.25296, 117.31987 }, + { 1203.1, 1.86655, 316.39187 }, + { 1091.1, 0.07527, 216.48049 }, + { 954.4, 5.1517, 647.0108 }, + { 966.0, 0.4799, 632.7837 }, + { 881.8, 1.8847, 1052.2684 }, + { 874.2, 1.4022, 224.3448 }, + { 897.5, 0.9834, 529.6910 }, + { 784.9, 3.0638, 838.9693 }, + { 739.9, 1.3823, 625.6702 }, + { 613.0, 3.0331, 63.7359 }, + { 658.2, 4.1436, 309.2783 }, + { 649.6, 1.7249, 742.9901 }, + { 599.2, 2.5492, 217.2312 }, + { 502.9, 2.1296, 3.9322 }, + { 413.0, 4.5933, 415.5525 }, + { 356.1, 2.3031, 728.7630 }, + { 344.8, 5.8879, 440.8253 }, + { 395.0, 0.5335, 956.2892 }, + { 335.5, 1.6161, 1368.6603 }, + { 362.8, 4.7069, 302.1648 }, + { 321.6, 0.9793, 3.1814 }, + { 277.8, 0.2601, 195.1398 }, + { 291.2, 2.8313, 1155.3612 }, + { 265.0, 2.4267, 88.8657 }, + { 264.9, 5.8286, 149.5632 }, + { 316.8, 3.5840, 515.4639 }, + { 294.3, 2.8163, 11.0457 }, + { 244.9, 1.0449, 942.0621 }, + { 215.4, 3.5654, 490.3341 }, + { 264.0, 1.2855, 1059.3819 }, + { 246.2, 0.9073, 191.9585 }, + { 222.1, 5.1319, 269.9214 }, + { 195.0, 4.5667, 846.0828 }, + { 182.8, 2.6791, 127.4718 }, + { 181.6, 4.9343, 74.7816 }, + { 174.7, 3.4456, 137.0330 }, + { 165.5, 5.9978, 536.8045 }, + { 154.8, 1.1972, 265.9893 }, + { 169.7, 4.6346, 284.1485 }, + { 151.5, 0.5293, 330.6190 }, + { 152.5, 5.4389, 422.6660 }, + { 157.7, 2.9956, 340.7709 }, + { 140.6, 2.0207, 1045.1548 }, + { 139.8, 1.3528, 1685.0521 }, + { 141.0, 1.2710, 203.0042 }, + { 136.0, 5.0168, 351.8166 }, + { 153.4, 0.2697, 1272.6810 }, + { 129.5, 1.1434, 21.3406 }, + { 127.8, 2.5388, 1471.7530 }, + { 126.5, 3.0031, 277.0350 }, + { 100.3, 3.6136, 1066.4955 }, + { 103.2, 0.3818, 203.7379 }, + { 107.5, 4.3187, 210.8514 }, + { 95.9, 0.795, 1258.454 }, + { 82.7, 0.282, 234.640 }, + { 98.0, 2.561, 191.208 }, + { 97.4, 3.262, 831.856 }, + { 72.2, 4.380, 860.310 }, + { 70.6, 0.732, 437.644 }, + { 70.4, 0.877, 423.417 }, + { 72.1, 5.580, 429.780 }, + { 73.3, 0.625, 1375.774 }, + { 66.4, 2.684, 405.258 }, + { 63.8, 1.751, 1361.547 }, + { 61.6, 1.093, 2001.444 }, + { 67.0, 0.069, 408.439 }, + { 68.9, 2.471, 949.176 }, + { 60.5, 2.251, 1788.145 }, + { 67.1, 5.454, 200.769 }, + { 65.6, 0.055, 1589.073 }, + { 49.3, 4.172, 138.517 }, + { 50.6, 6.269, 223.594 }, + { 55.2, 4.595, 628.852 }, + { 47.9, 0.839, 10.295 }, + { 46.7, 2.173, 312.199 }, + { 54.2, 0.284, 124.433 }, + { 49.5, 3.800, 215.747 }, + { 40.1, 5.182, 1478.867 }, + { 39.3, 0.563, 1574.846 }, + { 35.0, 4.685, 38.133 }, + { 42.8, 2.986, 1148.248 }, + { 36.5, 0.635, 52.690 }, + { 39.8, 0.284, 131.404 }, + { 31.8, 5.190, 76.266 }, + { 33.0, 1.980, 142.450 }, + { 42.1, 4.830, 288.081 }, + { 30.8, 1.479, 1677.939 }, + { 42.8, 3.382, 208.633 }, + { 29.2, 5.099, 654.124 }, + { 29.2, 4.957, 1795.258 }, + { 29.1, 2.747, 404.507 }, + { 32.7, 6.121, 145.631 }, + { 28.0, 0.832, 2317.836 }, + { 27.7, 2.244, 430.530 }, + { 29.9, 1.964, 2104.537 }, + { 33.0, 3.282, 222.860 }, + { 31.8, 6.025, 1905.465 }, + { 27.0, 5.243, 388.465 }, + { 26.5, 0.996, 107.025 }, + { 25.4, 2.873, 703.633 }, + { 24.9, 1.077, 99.911 }, + { 25.0, 6.240, 106.274 }, + { 24.9, 0.810, 312.460 }, + { 24.3, 0.549, 214.262 }, + { 28.4, 0.826, 1692.166 }, + { 23.2, 5.080, 479.288 }, + { 24.4, 3.106, 212.336 }, + { 22.0, 6.067, 85.827 }, + { 22.0, 3.899, 563.631 }, + { 22.6, 4.867, 295.051 }, + { 21.3, 5.108, 333.657 }, + { 26.0, 2.208, 1265.567 }, + { 20.9, 3.289, 70.849 }, + { 21.5, 3.795, 347.884 }, + { 22.1, 4.227, 217.965 }, + { 20.6, 1.687, 231.458 }, + { 21.4, 3.089, 554.070 }, + { 21.3, 0.389, 319.573 }, + { 20.5, 2.457, 18.159 }, + { 26.1, 4.276, 483.221 }, + { 20.7, 5.121, 362.862 }, + { 22.0, 5.512, 343.219 }, + { 19.4, 2.024, 313.210 }, + { 20.2, 5.085, 750.104 }, + { 20.1, 3.430, 213.347 }, + { 24.2, 0.648, 207.882 }, + { 22.0, 0.729, 99.161 }, + { 21.1, 2.693, 1464.639 }, + { 17.2, 4.715, 2111.650 }, + { 18.5, 0.048, 245.542 }, + { 17.5, 3.837, 497.448 }, + { 16.1, 4.224, 565.116 }, + { 21.6, 4.166, 2.448 }, + { 16.0, 0.274, 225.829 }, + { 16.8, 1.411, 114.138 }, + { 15.6, 2.828, 81.752 }, + { 15.5, 1.206, 1994.330 }, + { 15.2, 3.846, 1162.475 }, + { 16.4, 3.048, 134.585 }, + { 15.9, 0.330, 1891.238 }, + { 20.4, 0.232, 213.251 }, + { 16.3, 1.706, 2420.929 }, + { 16.3, 4.942, 357.446 }, + { 18.1, 5.695, 56.622 }, + { 13.7, 0.572, 2634.228 }, + { 17.4, 3.553, 218.928 }, + { 13.7, 5.705, 92.047 }, + { 15.3, 1.313, 216.220 }, + { 12.5, 5.192, 635.965 }, + { 12.8, 1.602, 320.324 }, + { 13.0, 0.451, 1169.588 }, + { 12.0, 5.949, 543.918 }, + { 11.8, 2.803, 217.492 }, + { 14.7, 5.565, 344.703 }, + { 12.8, 1.636, 273.103 }, + { 11.9, 2.462, 721.649 }, + { 13.3, 5.756, 2221.857 }, + { 14.5, 0.453, 2008.558 }, + { 11.8, 1.757, 160.609 }, + { 12.4, 1.015, 329.725 }, + { 10.7, 1.581, 212.778 }, + { 12.8, 1.920, 1581.959 }, + { 11.9, 4.447, 32.243 }, + { 11.9, 5.107, 4.666 }, + { 11.9, 4.308, 618.557 }, + { 10.0, 0.487, 305.346 }, + { 12.8, 3.744, 508.350 }, + { 10.7, 0.766, 218.716 }, + { 11.4, 3.000, 198.321 }, + { 10.2, 2.409, 546.956 }, + { 10.0, 2.639, 416.303 }, + { 9.3, 5.46, 414.07 }, + { 9.3, 4.46, 2428.04 }, + { 9.9, 4.05, 62.25 }, + { 12.8, 3.433, 258.876 }, + { 9.7, 1.61, 327.44 }, + { 11.2, 2.407, 1781.031 }, + { 10.6, 2.075, 213.820 }, + { 9.1, 2.92, 1279.79 }, + { 9.5, 1.10, 113.39 }, + { 9.8, 3.28, 275.55 }, + { 11.3, 1.894, 561.184 }, + { 8.6, 2.18, 425.11 }, + { 8.6, 1.95, 35.42 }, + { 10.2, 0.090, 182.280 }, + { 11.8, 3.713, 350.332 }, + { 8.6, 1.83, 629.60 }, + { 8.4, 3.77, 251.43 }, + { 8.5, 0.36, 617.81 }, + { 8.2, 5.31, 65.22 }, + { 8.3, 1.38, 1.48 }, + { 8.0, 5.14, 22.09 }, + { 8.4, 0.92, 1485.98 }, + { 8.0, 0.94, 2310.72 }, + { 8.9, 0.54, 168.05 }, + { 8.2, 3.46, 424.15 }, + { 8.0, 3.38, 144.15 }, + { 7.9, 5.14, 358.93 }, + { 8.9, 6.14, 621.74 }, + { 7.5, 5.75, 447.94 }, + { 7.5, 2.19, 264.50 }, + { 8.1, 1.43, 2737.32 }, + { 8.2, 0.96, 767.37 }, + { 8.2, 0.35, 278.52 }, + { 8.2, 5.44, 254.94 }, + { 6.8, 1.20, 5.42 }, + { 8.9, 4.88, 120.36 }, + { 7.8, 4.56, 280.97 }, + { 6.6, 3.50, 9.56 }, + { 6.4, 0.33, 2950.62 }, + { 6.9, 3.39, 98.90 }, + { 7.4, 4.52, 5.63 }, + { 8.0, 0.94, 636.72 }, + { 7.2, 3.85, 214.05 }, + { 6.4, 2.12, 274.07 }, + { 6.5, 5.31, 6076.89 }, + { 6.4, 0.45, 10007.10 }, + { 6.3, 3.21, 219.45 }, + { 6.7, 1.65, 1898.35 }, + { 7.6, 0.10, 2324.95 }, + { 6.3, 0.76, 210.38 }, + { 6.6, 1.79, 12.53 }, + /* 246 terms retained, 393 terms dropped, error 2.1e-06 a.u.*T */ + + /* saturn r, T^2 */ + { 436902.5, 4.7867167, 213.2990954 }, + { 71922.8, 2.500700, 206.185548 }, + { 49766.8, 4.971682, 220.412642 }, + { 43220.9, 3.869404, 426.598191 }, + { 29645.6, 5.963103, 7.113547 }, + { 4141.6, 4.10671, 433.71174 }, + { 4720.9, 2.47528, 199.07200 }, + { 3789.4, 3.09771, 639.89729 }, + { 2964.0, 1.37206, 103.09277 }, + { 2556.4, 2.85066, 419.48464 }, + { 2208.5, 6.27589, 110.20632 }, + { 2187.6, 5.85546, 14.22709 }, + { 1956.9, 4.92449, 227.52619 }, + { 2326.8, 0, 0 }, + { 923.8, 5.4639, 323.5054 }, + { 705.9, 2.9708, 95.9792 }, + { 546.1, 4.1285, 412.3711 }, + { 373.8, 5.8344, 117.3199 }, + { 360.9, 3.2770, 647.0108 }, + { 356.3, 3.1915, 210.1177 }, + { 390.6, 4.4811, 216.4805 }, + { 431.5, 5.1783, 522.5774 }, + { 325.6, 2.2687, 853.1964 }, + { 405.0, 4.1729, 209.3669 }, + { 204.5, 0.0877, 202.2534 }, + { 206.9, 4.0219, 735.8765 }, + { 178.5, 4.0972, 440.8253 }, + { 180.1, 3.5970, 632.7837 }, + { 153.7, 3.1347, 625.6702 }, + { 147.8, 0.1361, 302.1648 }, + { 123.2, 4.1890, 88.8657 }, + { 133.1, 2.5935, 191.9585 }, + { 100.4, 5.4606, 3.1814 }, + { 132.0, 5.9329, 309.2783 }, + { 97.2, 4.018, 728.763 }, + { 110.7, 4.7785, 838.9693 }, + { 119.1, 5.5539, 224.3448 }, + { 93.9, 4.384, 217.231 }, + { 108.7, 5.2931, 515.4639 }, + { 78.6, 5.725, 21.341 }, + { 81.5, 5.109, 956.289 }, + { 96.4, 6.259, 742.990 }, + { 69.2, 4.049, 3.932 }, + { 65.2, 3.777, 1052.268 }, + { 64.1, 5.812, 529.691 }, + { 62.5, 2.184, 195.140 }, + { 57.0, 3.147, 203.004 }, + { 56.0, 4.841, 234.640 }, + { 52.9, 5.078, 330.619 }, + { 50.6, 2.773, 942.062 }, + { 41.6, 4.790, 63.736 }, + { 44.9, 0.565, 269.921 }, + { 41.4, 3.735, 316.392 }, + { 52.8, 3.926, 949.176 }, + { 38.4, 3.740, 1045.155 }, + { 37.6, 4.189, 536.805 }, + { 35.3, 2.908, 284.149 }, + { 33.6, 3.805, 149.563 }, + { 41.1, 4.579, 1155.361 }, + { 30.4, 2.481, 860.310 }, + { 31.4, 4.841, 1272.681 }, + { 30.2, 4.352, 405.258 }, + { 39.4, 3.509, 422.666 }, + { 29.7, 1.589, 1066.495 }, + { 35.2, 5.945, 1059.382 }, + { 25.8, 3.549, 1368.660 }, + { 26.3, 4.816, 124.433 }, + { 30.0, 3.663, 429.780 }, + { 33.0, 4.969, 831.856 }, + { 24.3, 5.311, 10.295 }, + { 26.3, 4.453, 223.594 }, + { 22.1, 2.761, 415.552 }, + { 27.2, 1.663, 277.035 }, + { 21.6, 1.038, 11.046 }, + { 19.7, 2.522, 1258.454 }, + { 17.1, 3.277, 654.124 }, + { 17.3, 3.494, 1361.547 }, + { 16.1, 1.734, 490.334 }, + { 21.1, 3.621, 1265.567 }, + { 17.7, 4.311, 1471.753 }, + { 13.5, 0.323, 295.051 }, + { 12.6, 3.138, 74.782 }, + { 12.0, 2.329, 210.851 }, + { 15.1, 3.596, 265.989 }, + { 13.0, 4.624, 1589.073 }, + { 15.4, 5.013, 127.472 }, + { 11.2, 4.550, 81.752 }, + { 13.4, 4.887, 437.644 }, + { 10.7, 5.052, 191.208 }, + { 14.0, 3.050, 423.417 }, + { 10.6, 5.028, 137.033 }, + { 14.4, 4.687, 1148.248 }, + { 13.5, 1.903, 408.439 }, + { 10.1, 5.204, 340.771 }, + { 10.3, 3.345, 1685.052 }, + { 9.6, 3.17, 351.82 }, + { 11.3, 5.478, 1375.774 }, + { 8.6, 2.81, 99.91 }, + { 8.5, 3.23, 1677.94 }, + { 7.9, 2.36, 1574.85 }, + { 7.6, 6.08, 231.46 }, + { 9.2, 3.40, 1581.96 }, + { 7.3, 2.00, 131.40 }, + { 8.2, 4.04, 1788.14 }, + { 7.6, 3.68, 846.08 }, + { 6.7, 4.37, 145.63 }, + { 7.5, 3.29, 750.10 }, + { 6.4, 4.00, 447.94 }, + { 6.2, 4.56, 106.27 }, + { 6.5, 1.34, 215.75 }, + { 6.5, 3.78, 313.21 }, + { 6.0, 0.55, 18.16 }, + { 6.2, 2.85, 138.52 }, + { 6.8, 4.83, 319.57 }, + { 6.7, 5.43, 508.35 }, + { 7.2, 4.38, 1464.64 }, + { 5.8, 4.14, 543.92 }, + { 5.7, 4.35, 1905.46 }, + { 5.1, 2.64, 288.08 }, + { 5.3, 3.63, 6076.89 }, + { 5.5, 4.20, 721.65 }, + { 5.1, 5.05, 10007.10 }, + { 5.5, 1.13, 56.62 }, + { 4.8, 3.30, 76.27 }, + { 4.9, 6.18, 483.22 }, + { 5.0, 2.45, 628.85 }, + { 4.5, 1.20, 200.77 }, + { 4.8, 3.12, 2001.44 }, + { 4.7, 1.27, 6062.66 }, + { 4.8, 5.78, 184.84 }, + { 4.8, 0.76, 333.66 }, + { 4.5, 0.95, 343.22 }, + { 4.5, 2.69, 9992.87 }, + { 4.4, 0.80, 222.86 }, + { 4.9, 5.92, 618.56 }, + { 4.1, 1.92, 497.45 }, + { 5.1, 4.50, 416.30 }, + { 4.1, 1.98, 347.88 }, + { 4.0, 2.88, 38.13 }, + { 4.1, 2.90, 107.02 }, + { 4.0, 2.93, 1994.33 }, + { 4.9, 3.12, 1898.35 }, + { 3.7, 3.25, 362.86 }, + { 3.8, 0.88, 703.63 }, + { 3.6, 3.48, 388.47 }, + { 3.6, 4.08, 430.53 }, + { 3.6, 0.05, 32.24 }, + { 3.6, 5.46, 6283.08 }, + { 3.5, 1.82, 70.85 }, + { 3.8, 3.12, 635.97 }, + { 3.4, 0.55, 10213.29 }, + { 3.4, 3.52, 629.60 }, + { 3.4, 3.28, 357.45 }, + { 3.3, 1.98, 203.74 }, + { 3.1, 2.18, 1891.24 }, + { 3.2, 1.26, 134.59 }, + { 4.0, 5.45, 1692.17 }, + { 3.2, 2.46, 867.42 }, + { 3.4, 4.21, 337.73 }, + { 3.0, 2.19, 217.96 }, + { 3.6, 5.55, 113.39 }, + { 3.7, 3.79, 2104.54 }, + { 3.1, 4.09, 1478.87 }, + { 2.9, 3.91, 312.20 }, + { 3.2, 3.92, 1038.04 }, + { 4.0, 5.18, 404.51 }, + { 3.9, 4.12, 1781.03 }, + { 3.1, 1.61, 1073.61 }, + { 3.1, 5.01, 312.46 }, + { 3.0, 5.46, 258.88 }, + { 2.9, 2.38, 181.06 }, + { 3.0, 0.89, 1279.79 }, + { 2.7, 0.01, 195.89 }, + { 3.1, 5.60, 216.22 }, + { 2.6, 6.13, 273.10 }, + { 2.7, 2.32, 565.12 }, + { 3.2, 3.88, 85.83 }, + { 2.7, 5.74, 160.61 }, + { 2.9, 4.75, 213.25 }, + { 2.5, 5.30, 444.76 }, + { 2.8, 5.09, 1169.59 }, + { 2.9, 1.67, 213.35 }, + { 2.9, 4.21, 650.94 }, + { 3.0, 2.55, 6069.78 }, + { 3.1, 2.67, 52.69 }, + { 2.4, 0.90, 121.25 }, + { 3.0, 3.97, 9999.99 }, + { 3.1, 0.41, 561.18 }, + { 2.4, 4.74, 218.72 }, + { 2.6, 1.13, 344.70 }, + { 2.3, 4.08, 131.55 }, + { 2.2, 3.38, 22.09 }, + { 2.1, 3.32, 358.93 }, + { 2.7, 1.69, 208.63 }, + { 2.6, 5.10, 824.74 }, + { 2.2, 2.60, 305.35 }, + { 2.1, 3.37, 320.32 }, + { 2.7, 3.62, 436.89 }, + { 2.5, 2.96, 2214.74 }, + { 2.7, 2.88, 643.08 }, + { 2.1, 1.61, 218.93 }, + { 2.0, 4.63, 188.03 }, + { 2.4, 3.46, 6275.96 }, + { 2.0, 2.29, 2627.11 }, + { 1.9, 5.67, 28.45 }, + { 1.9, 4.26, 546.96 }, + { 2.5, 3.58, 2420.93 }, + { 1.9, 1.31, 212.34 }, + { 1.9, 1.59, 424.15 }, + { 1.9, 3.58, 329.73 }, + { 2.1, 3.95, 1795.26 }, + { 2.2, 4.22, 2221.86 }, + { 1.9, 1.69, 350.33 }, + { 1.8, 2.07, 144.15 }, + { 1.9, 4.61, 182.28 }, + { 2.2, 5.18, 99.16 }, + { 1.8, 2.73, 291.26 }, + { 2.2, 5.43, 207.88 }, + { 1.8, 2.24, 168.05 }, + { 1.7, 1.32, 219.45 }, + { 1.7, 5.56, 92.80 }, + { 1.7, 1.95, 129.92 }, + { 2.1, 4.85, 1141.13 }, + { 1.8, 5.05, 214.26 }, + { 1.8, 2.86, 636.72 }, + { 1.9, 2.90, 2310.72 }, + { 1.8, 5.35, 45.58 }, + { 1.7, 6.14, 554.07 }, + { 1.6, 4.51, 210.38 }, + { 1.7, 3.55, 1354.43 }, + { 1.9, 3.01, 2317.84 }, + { 1.6, 1.16, 235.39 }, + { 1.9, 4.13, 225.83 }, + { 1.6, 3.30, 1670.83 }, + { 1.9, 0.18, 12.53 }, + { 1.6, 5.73, 1485.98 }, + { 1.7, 3.44, 2428.04 }, + { 1.8, 2.70, 12.74 }, + { 1.7, 4.98, 2008.56 }, + /* 239 terms retained, 103 terms dropped, error 5.2e-07 a.u.*T^2 */ + + /* saturn r, T^3 */ + { 20315.0, 3.021866, 213.299095 }, + { 8923.6, 3.19144, 220.41264 }, + { 6908.7, 4.35175, 206.18555 }, + { 4087.1, 4.22407, 7.11355 }, + { 3879.0, 2.01056, 426.59819 }, + { 1070.8, 4.20360, 199.07200 }, + { 907.3, 2.2834, 433.7117 }, + { 606.1, 3.1746, 227.5262 }, + { 596.6, 4.1346, 14.2271 }, + { 483.2, 1.1735, 639.8973 }, + { 393.2, 0, 0 }, + { 229.5, 4.6984, 419.4846 }, + { 188.2, 4.5900, 110.2063 }, + { 149.5, 3.2020, 103.0928 }, + { 121.4, 3.7683, 323.5054 }, + { 101.2, 5.8188, 412.3711 }, + { 102.1, 4.7097, 95.9792 }, + { 93.1, 1.435, 647.011 }, + { 72.6, 4.154, 117.320 }, + { 84.3, 2.635, 216.480 }, + { 62.2, 2.312, 440.825 }, + { 45.1, 4.373, 191.958 }, + { 49.5, 2.389, 209.367 }, + { 54.8, 0.305, 853.196 }, + { 40.5, 1.838, 302.165 }, + { 38.1, 5.945, 88.866 }, + { 32.2, 4.011, 21.341 }, + { 40.7, 0.688, 522.577 }, + { 28.2, 5.772, 210.118 }, + { 25.0, 3.062, 234.640 }, + { 20.8, 4.926, 625.670 }, + { 25.1, 0.731, 515.464 }, + { 17.5, 5.731, 728.763 }, + { 18.0, 1.456, 309.278 }, + { 16.9, 3.528, 3.181 }, + { 13.4, 3.365, 330.619 }, + { 11.1, 3.372, 224.345 }, + { 11.1, 3.417, 956.289 }, + { 10.0, 1.588, 202.253 }, + { 11.6, 5.991, 735.877 }, + { 10.5, 6.069, 405.258 }, + { 9.1, 2.94, 124.43 }, + { 8.7, 4.65, 632.78 }, + { 10.0, 0.582, 860.310 }, + { 7.5, 4.51, 942.06 }, + { 10.1, 0.283, 838.969 }, + { 9.2, 2.57, 223.59 }, + { 8.7, 1.76, 429.78 }, + { 7.6, 1.46, 654.12 }, + { 7.1, 5.47, 1045.15 }, + { 7.0, 1.52, 422.67 }, + { 8.1, 4.48, 742.99 }, + { 6.8, 4.83, 316.39 }, + { 7.7, 0.44, 831.86 }, + { 7.9, 4.20, 195.14 }, + { 6.1, 2.34, 269.92 }, + { 5.6, 1.15, 284.15 }, + { 5.6, 4.18, 529.69 }, + { 5.0, 2.12, 295.05 }, + { 6.6, 3.42, 10.29 }, + { 5.5, 2.47, 536.80 }, + { 6.2, 6.01, 1066.50 }, + { 5.6, 0.83, 217.23 }, + { 4.3, 3.23, 1272.68 }, + { 4.5, 0.92, 203.00 }, + { 3.3, 4.33, 1258.45 }, + { 3.7, 0.06, 81.75 }, + { 4.0, 0.11, 1155.36 }, + { 3.8, 6.01, 1052.27 }, + { 2.9, 5.64, 3.93 }, + { 3.0, 2.19, 447.94 }, + { 3.0, 1.89, 149.56 }, + { 3.1, 0.19, 1148.25 }, + { 2.8, 0.92, 508.35 }, + { 2.8, 4.97, 1677.94 }, + { 2.6, 3.00, 1589.07 }, + { 2.9, 5.41, 1361.55 }, + { 2.3, 1.30, 184.84 }, + { 2.5, 3.71, 408.44 }, + { 2.5, 3.22, 319.57 }, + { 2.6, 2.31, 543.92 }, + { 2.3, 5.88, 721.65 }, + { 2.0, 0.52, 416.30 }, + { 2.5, 4.24, 1059.38 }, + { 1.9, 2.41, 337.73 }, + { 1.9, 0.54, 635.97 }, + { 1.9, 5.62, 11.05 }, + { 2.4, 5.73, 313.21 }, + { 1.9, 2.41, 131.55 }, + { 1.7, 4.58, 1994.33 }, + { 1.9, 5.17, 2854.64 }, + { 1.9, 6.23, 1471.75 }, + { 2.0, 6.18, 1464.64 }, + { 1.8, 5.59, 1038.04 }, + { 1.5, 0.61, 210.85 }, + { 1.6, 1.75, 195.89 }, + { 1.6, 0.56, 2324.95 }, + { 1.5, 0.27, 497.45 }, + { 1.7, 2.58, 2090.31 }, + { 1.8, 1.82, 436.89 }, + { 1.6, 6.15, 490.33 }, + { 1.8, 6.12, 1073.61 }, + { 1.5, 0.85, 415.55 }, + { 1.6, 2.95, 437.64 }, + { 1.4, 4.12, 1574.85 }, + { 1.6, 5.97, 1781.03 }, + { 1.5, 3.85, 1251.34 }, + { 1.4, 5.33, 2538.25 }, + { 1.8, 1.51, 750.10 }, + { 1.5, 3.29, 1884.12 }, + { 1.5, 0.99, 643.08 }, + { 1.3, 3.79, 1567.73 }, + { 1.7, 0.03, 423.42 }, + { 1.5, 5.35, 1354.43 }, + { 1.4, 0.70, 867.42 }, + { 1.1, 1.80, 618.56 }, + { 1.1, 4.70, 113.39 }, + { 1.1, 3.96, 1891.24 }, + { 1.5, 1.50, 430.53 }, + { 1.1, 5.13, 25.27 }, + { 1.2, 2.97, 241.75 }, + { 1.3, 2.29, 2420.93 }, + { 1.1, 0.05, 63.74 }, + { 1.4, 5.58, 1382.89 }, + { 1.1, 3.11, 2200.52 }, + { 1.1, 0.79, 127.47 }, + { 1.0, 5.85, 215.75 }, + { 1.1, 3.73, 131.40 }, + { 1.2, 0.48, 824.74 }, + { 1.1, 3.78, 1375.77 }, + { 1.0, 5.91, 265.99 }, + { 1.2, 1.41, 2634.23 }, + { 1.1, 4.80, 1987.22 }, + { 0.9, 6.26, 2015.67 }, + { 1.0, 1.09, 362.86 }, + { 1.1, 5.42, 1279.79 }, + { 0.9, 1.92, 483.22 }, + { 0.9, 2.97, 934.95 }, + { 0.9, 2.66, 145.63 }, + { 0.9, 6.26, 2.45 }, + { 1.1, 4.48, 2214.74 }, + { 1.0, 0.74, 16.67 }, + { 1.0, 4.06, 231.46 }, + { 0.9, 0.09, 628.85 }, + { 0.9, 5.99, 2524.02 }, + { 0.9, 3.16, 2207.63 }, + { 0.8, 1.24, 74.78 }, + { 0.8, 2.90, 2008.56 }, + { 0.8, 2.28, 1478.87 }, + { 1.0, 5.33, 2428.04 }, + { 0.8, 2.38, 2228.97 }, + { 0.8, 4.70, 1670.83 }, + { 1.0, 4.23, 1802.37 }, + { 0.8, 5.87, 1368.66 }, + { 0.7, 5.92, 1685.05 }, + { 0.8, 1.16, 3053.71 }, + { 0.7, 3.13, 56.62 }, + /* 157 terms retained, 0 terms dropped, error 1.7e-07 a.u.*T^3 */ + + /* saturn r, T^4 */ + { 1202.0, 1.41499, 220.41264 }, + { 707.8, 1.1615, 213.2991 }, + { 516.1, 6.2397, 206.1855 }, + { 426.7, 2.4692, 7.1135 }, + { 267.7, 0.1866, 426.5982 }, + { 170.2, 5.9593, 199.0720 }, + { 145.1, 1.4421, 227.5262 }, + { 150.3, 0.4797, 433.7117 }, + { 121.0, 2.4053, 14.2271 }, + { 47.3, 5.569, 639.897 }, + { 15.7, 2.901, 110.206 }, + { 16.7, 0.529, 440.825 }, + { 19.0, 5.856, 647.011 }, + { 14.1, 1.303, 412.371 }, + { 12.7, 2.093, 323.505 }, + { 14.7, 0.299, 419.485 }, + { 11.1, 2.463, 117.320 }, + { 11.3, 0.218, 95.979 }, + { 9.2, 2.28, 21.34 }, + { 9.2, 1.56, 88.87 }, + { 9.0, 0.68, 216.48 }, + { 7.7, 3.59, 302.16 }, + { 7.8, 4.49, 853.20 }, + { 8.4, 1.27, 234.64 }, + { 9.6, 3.14, 0 }, + { 4.8, 2.59, 515.46 }, + { 6.1, 5.17, 103.09 }, + { 4.4, 0.02, 191.96 }, + { 4.4, 1.60, 330.62 }, + { 3.7, 3.30, 210.12 }, + { 4.4, 5.97, 654.12 }, + { 4.4, 4.97, 860.31 }, + { 3.2, 2.73, 522.58 }, + { 4.0, 1.60, 405.26 }, + { 3.1, 0.75, 209.37 }, + { 2.5, 1.19, 124.43 }, + { 3.1, 1.32, 728.76 }, + { 2.2, 3.28, 203.00 }, + { 2.1, 6.15, 429.78 }, + { 2.1, 0.75, 295.05 }, + { 2.0, 3.89, 1066.50 }, + { 2.2, 0.49, 447.94 }, + { 2.2, 0.73, 625.67 }, + { 1.8, 0.09, 942.06 }, + { 1.7, 1.40, 224.34 }, + { 1.6, 3.02, 184.84 }, + { 1.8, 0.82, 223.59 }, + { 1.9, 2.00, 831.86 }, + { 1.6, 5.41, 824.74 }, + { 1.5, 5.96, 422.67 }, + { 1.1, 1.12, 838.97 }, + { 1.2, 1.90, 956.29 }, + { 1.5, 2.12, 529.69 }, + { 1.4, 0.72, 536.80 }, + { 1.1, 0.89, 721.65 }, + { 1.3, 1.65, 17.41 }, + { 1.2, 5.97, 195.14 }, + { 1.0, 5.36, 316.39 }, + { 1.0, 3.06, 1574.85 }, + { 1.1, 1.59, 735.88 }, + { 0.8, 4.93, 56.62 }, + { 0.8, 2.72, 508.35 }, + { 1.0, 1.01, 1045.15 }, + { 0.7, 1.11, 1169.59 }, + /* 64 terms retained, 0 terms dropped, error 1.2e-07 a.u.*T^4 */ + + /* saturn r, T^5 */ + { 128.6, 5.9128, 220.4126 }, + { 32.3, 0.693, 7.114 }, + { 26.7, 5.914, 227.526 }, + { 19.9, 0.674, 14.227 }, + { 20.2, 4.951, 433.712 }, + { 13.5, 1.457, 199.072 }, + { 14.1, 2.671, 206.186 }, + { 13.4, 4.588, 426.598 }, + { 7.3, 4.63, 213.30 }, + { 4.9, 3.61, 639.90 }, + { 3.1, 4.66, 191.96 }, + { 2.9, 0.49, 323.51 }, + { 3.8, 4.90, 440.83 }, + { 3.3, 4.07, 647.01 }, + { 2.9, 3.18, 419.48 }, + { 2.3, 3.70, 88.87 }, + { 1.9, 5.33, 302.16 }, + { 2.1, 3.32, 95.98 }, + { 1.6, 2.67, 853.20 }, + { 2.0, 0.56, 117.32 }, + { 1.6, 0.86, 515.46 }, + { 1.7, 0, 0 }, + { 1.1, 5.98, 3.18 }, + { 1.3, 5.83, 234.64 }, + { 0.9, 5.23, 216.48 }, + { 1.1, 0.16, 412.37 }, + { 0.8, 0.37, 28.45 }, + { 0.8, 5.05, 124.43 }, + /* 28 terms retained, 0 terms dropped, error 9e-08 a.u.*T^5 */ + /* end saturn */ +}; + +int vn_saturn[][3] = { + /* addresses for saturn l, b, r */ + /* T^0 */ { 0, 592, 811, }, + /* T^1 */ { 165, 645, 1099, }, + /* T^2 */ { 303, 698, 1345, }, + /* T^3 */ { 418, 744, 1584, }, + /* T^4 */ { 500, 777, 1741, }, + /* T^5 */ { 566, 803, 1805, }, + /* end */ { 592, 811, 1833, }, + /* termination */ { 0, } +}; + +/* version d4 (lbr) + * heliocentric dynamical ecliptic and equinox of the date + */ + +double vx_uranus[][3] = { + /* uranus l, T^0 */ + { 548129294.3, 0, 0 }, + { 9260408.3, 0.89106422, 74.78159857 }, + { 1504247.8, 3.62719262, 1.48447271 }, + { 365981.7, 1.8996219, 73.2971259 }, + { 272328.1, 3.3582371, 149.5631971 }, + { 70328.5, 5.392544, 63.735898 }, + { 68892.6, 6.092925, 76.266071 }, + { 61998.6, 2.269520, 2.968945 }, + { 61950.7, 2.850989, 11.045700 }, + { 26468.9, 3.141521, 71.812653 }, + { 25710.5, 6.113798, 454.909367 }, + { 21078.9, 4.360595, 148.078724 }, + { 17818.7, 1.744370, 36.648563 }, + { 14613.5, 4.737320, 3.932153 }, + { 11162.5, 5.826820, 224.344796 }, + { 10997.9, 0.488655, 138.517497 }, + { 9527.5, 2.95517, 35.16409 }, + { 7545.5, 5.23626, 109.94569 }, + { 4220.2, 3.23329, 70.84945 }, + { 4051.9, 2.27754, 151.04767 }, + { 3354.6, 1.06549, 4.45342 }, + { 2926.7, 4.62904, 9.56123 }, + { 3490.4, 5.48306, 146.59425 }, + { 3144.1, 4.75199, 77.75054 }, + { 2922.4, 5.35237, 85.82730 }, + { 2272.8, 4.36601, 70.32818 }, + { 2051.2, 1.51774, 0.11187 }, + { 2148.6, 0.60746, 38.13304 }, + { 1991.7, 4.92437, 277.03499 }, + { 1376.2, 2.04281, 65.22037 }, + { 1666.9, 3.62745, 380.12777 }, + { 1284.2, 3.11346, 202.25340 }, + { 1150.4, 0.93344, 3.18139 }, + { 1533.2, 2.58593, 52.69020 }, + { 1281.6, 0.54270, 222.86032 }, + { 1372.1, 4.19642, 111.43016 }, + { 1221.0, 0.19901, 108.46122 }, + { 946.2, 1.1925, 127.4718 }, + { 1151.0, 4.17898, 33.67962 }, + { 1244.3, 0.91613, 2.44768 }, + { 1072.0, 0.23565, 62.25143 }, + { 1090.5, 1.77502, 12.53017 }, + { 707.9, 5.1829, 213.2991 }, + { 653.4, 0.9659, 78.7138 }, + { 627.6, 0.1821, 984.6003 }, + { 524.5, 2.0128, 299.1264 }, + { 559.4, 3.3578, 0.5213 }, + { 606.8, 5.4321, 529.6910 }, + { 404.9, 5.9869, 8.0768 }, + { 467.2, 0.4148, 145.1098 }, + { 471.3, 1.4066, 184.7273 }, + { 483.2, 2.1055, 0.9632 }, + { 395.6, 5.8704, 351.8166 }, + { 433.5, 5.5214, 183.2428 }, + { 309.9, 5.8330, 145.6310 }, + { 378.6, 2.3498, 56.6224 }, + { 399.0, 0.3381, 415.5525 }, + { 300.4, 5.6435, 22.0914 }, + { 249.2, 4.7462, 225.8293 }, + { 239.3, 2.3505, 137.0330 }, + { 294.2, 5.8392, 39.6175 }, + { 216.5, 4.7785, 340.7709 }, + { 251.8, 1.6370, 221.3759 }, + { 219.6, 1.9221, 67.6681 }, + { 202.0, 1.2969, 0.0482 }, + { 224.1, 0.5157, 84.3428 }, + { 216.5, 6.1421, 5.9379 }, + { 222.6, 2.8431, 0.2606 }, + { 207.8, 5.5802, 68.8437 }, + { 187.5, 1.3192, 0.1601 }, + { 158.0, 0.7381, 54.1747 }, + { 199.1, 0.9563, 152.5321 }, + { 168.6, 5.8787, 18.1592 }, + { 170.3, 3.6772, 5.4166 }, + { 193.7, 1.8880, 456.3938 }, + { 193.0, 0.9162, 453.4249 }, + { 181.9, 3.5362, 79.2350 }, + { 173.1, 1.5386, 160.6089 }, + { 164.6, 1.4238, 106.9767 }, + { 172.0, 5.6795, 219.8914 }, + { 162.8, 3.0503, 112.9146 }, + { 146.7, 1.2630, 59.8037 }, + { 139.5, 5.3860, 32.1951 }, + { 138.6, 4.2599, 909.8187 }, + { 143.1, 1.3000, 35.4247 }, + { 123.8, 1.3736, 7.1135 }, + { 104.4, 5.0282, 0.7508 }, + { 103.3, 0.6810, 14.9779 }, + { 94.7, 0.907, 74.670 }, + { 83.0, 2.928, 265.989 }, + { 110.2, 2.0269, 554.0700 }, + { 94.2, 3.943, 74.893 }, + { 79.9, 1.014, 6.592 }, + { 109.4, 5.7058, 77.9630 }, + { 85.9, 1.706, 82.858 }, + { 103.6, 1.4577, 24.3790 }, + { 74.7, 4.632, 69.365 }, + { 79.9, 3.010, 297.642 }, + { 84.5, 0.369, 186.212 }, + { 88.8, 0.525, 181.758 }, + { 70.3, 1.190, 66.705 }, + { 70.0, 0.875, 305.346 }, + { 69.9, 3.761, 131.404 }, + { 84.6, 5.887, 256.540 }, + { 74.3, 6.243, 447.796 }, + { 62.3, 0.169, 479.288 }, + { 72.7, 2.849, 462.023 }, + { 69.1, 4.439, 39.357 }, + { 76.6, 4.587, 6.220 }, + { 73.4, 4.276, 87.312 }, + { 55.3, 1.496, 71.600 }, + { 57.3, 1.630, 143.625 }, + { 61.7, 3.186, 77.229 }, + { 57.6, 3.672, 51.206 }, + { 50.3, 1.123, 20.607 }, + { 53.7, 5.519, 128.956 }, + { 57.9, 2.669, 381.612 }, + { 58.1, 1.586, 60.767 }, + { 45.4, 0.481, 14.015 }, + { 37.6, 6.068, 211.815 }, + { 38.6, 3.436, 153.495 }, + { 46.1, 4.362, 75.745 }, + { 40.1, 4.573, 46.210 }, + { 34.2, 2.940, 140.002 }, + { 38.7, 5.589, 99.161 }, + { 34.8, 1.028, 203.738 }, + { 40.0, 0.699, 218.407 }, + { 32.5, 4.216, 200.769 }, + { 31.9, 5.510, 72.334 }, + { 41.7, 3.824, 81.001 }, + { 34.8, 0.394, 1.373 }, + { 39.8, 6.056, 293.189 }, + { 27.6, 2.183, 125.987 }, + { 36.3, 1.666, 258.024 }, + { 35.4, 1.967, 835.037 }, + { 35.4, 3.723, 692.587 }, + { 27.3, 2.102, 209.367 }, + { 26.5, 4.483, 373.908 }, + { 34.5, 1.079, 191.208 }, + { 29.9, 3.874, 259.509 }, + { 26.2, 3.632, 490.334 }, + { 25.8, 0.545, 41.644 }, + { 27.0, 6.277, 28.572 }, + { 26.4, 5.811, 75.303 }, + { 34.2, 6.056, 275.551 }, + { 29.9, 1.888, 269.921 }, + { 26.2, 6.201, 134.585 }, + { 25.2, 5.425, 116.426 }, + { 26.5, 4.772, 284.149 }, + { 27.0, 4.753, 41.102 }, + { 28.9, 0.171, 528.206 }, + { 25.8, 0.746, 278.519 }, + /* 152 terms retained, 795 terms dropped, error 1.3" */ + + /* uranus l, T^1 */ + { 7502543121.6, 0, 0 }, + { 154458.2, 5.2420166, 74.7815986 }, + { 24456.4, 1.712557, 1.484473 }, + { 9257.8, 0.42845, 11.04570 }, + { 8266.0, 1.50220, 63.73590 }, + { 7841.7, 1.31984, 149.56320 }, + { 3899.1, 0.46484, 3.93215 }, + { 2283.8, 4.17368, 76.26607 }, + { 1926.6, 0.53013, 2.96895 }, + { 1232.7, 1.58634, 70.84945 }, + { 791.2, 5.4364, 3.1814 }, + { 767.0, 1.9956, 73.2971 }, + { 481.7, 2.9840, 85.8273 }, + { 449.8, 4.1383, 138.5175 }, + { 445.6, 3.7230, 224.3448 }, + { 426.6, 4.7313, 71.8127 }, + { 347.7, 2.4537, 9.5612 }, + { 353.8, 2.5832, 148.0787 }, + { 317.1, 5.5786, 52.6902 }, + { 179.9, 5.6837, 12.5302 }, + { 171.1, 3.0006, 78.7138 }, + { 205.6, 2.3626, 2.4477 }, + { 158.0, 2.9093, 0.9632 }, + { 189.1, 4.2024, 56.6224 }, + { 154.7, 5.5908, 4.4534 }, + { 183.8, 0.2837, 151.0477 }, + { 143.5, 2.5905, 62.2514 }, + { 152.0, 2.9422, 77.7505 }, + { 153.5, 4.6519, 35.1641 }, + { 121.5, 4.1484, 127.4718 }, + { 115.5, 3.7322, 65.2204 }, + { 102.0, 4.1875, 145.6310 }, + { 101.7, 6.0339, 0.1119 }, + { 88.2, 3.990, 18.159 }, + { 87.5, 6.155, 202.253 }, + { 80.5, 2.641, 22.091 }, + { 72.0, 6.045, 70.328 }, + { 68.6, 4.051, 77.963 }, + { 59.2, 3.704, 67.668 }, + { 47.3, 3.543, 351.817 }, + { 42.5, 5.724, 5.417 }, + { 44.3, 5.909, 7.114 }, + { 35.6, 3.292, 8.077 }, + { 35.5, 3.328, 71.600 }, + { 36.1, 5.900, 33.680 }, + { 30.6, 5.464, 160.609 }, + { 31.5, 5.620, 984.600 }, + { 38.5, 4.915, 222.860 }, + { 35.0, 5.080, 38.133 }, + { 30.8, 5.496, 59.804 }, + { 28.9, 4.519, 84.343 }, + { 26.6, 5.541, 131.404 }, + { 29.9, 1.660, 447.796 }, + { 29.2, 1.147, 462.023 }, + { 25.8, 4.994, 137.033 }, + { 25.4, 5.736, 380.128 }, + { 21.7, 2.806, 69.365 }, + { 26.6, 6.146, 299.126 }, + { 23.0, 2.249, 111.430 }, + { 19.2, 3.556, 54.175 }, + { 21.8, 0.933, 213.299 }, + { 19.3, 1.862, 108.461 }, + { 16.2, 3.102, 14.978 }, + { 13.1, 1.954, 87.312 }, + { 13.9, 1.541, 340.771 }, + { 13.5, 4.385, 5.938 }, + { 13.1, 5.883, 6.220 }, + { 11.8, 0.326, 35.425 }, + { 11.0, 1.692, 45.577 }, + { 12.4, 0.328, 51.206 }, + { 10.9, 5.971, 265.989 }, + { 11.4, 3.378, 72.334 }, + { 12.0, 3.604, 269.921 }, + { 11.7, 1.745, 79.235 }, + { 13.8, 2.690, 225.829 }, + { 12.0, 5.344, 152.532 }, + { 9.9, 5.50, 153.50 }, + { 10.4, 4.169, 24.379 }, + { 10.6, 3.069, 284.149 }, + { 9.6, 0.50, 209.37 }, + { 9.3, 3.54, 41.64 }, + { 9.5, 5.60, 82.86 }, + { 9.7, 1.01, 68.84 }, + { 9.2, 4.49, 20.61 }, + { 10.2, 3.518, 529.691 }, + { 8.6, 3.89, 60.77 }, + { 10.0, 4.648, 77.229 }, + { 8.7, 1.97, 195.14 }, + { 8.4, 4.41, 134.59 }, + { 9.3, 3.93, 39.62 }, + { 7.8, 5.36, 75.74 }, + { 7.7, 5.77, 73.82 }, + { 7.7, 4.44, 14.01 }, + { 8.4, 2.44, 146.59 }, + { 8.0, 5.73, 184.73 }, + { 7.5, 2.19, 145.11 }, + { 6.4, 0.85, 32.20 }, + { 6.3, 2.17, 74.89 }, + { 7.9, 0.17, 120.36 }, + { 7.0, 4.12, 191.21 }, + { 6.9, 2.13, 116.43 }, + /* 101 terms retained, 325 terms dropped, error 0.29"*T */ + + /* uranus l, T^2 */ + { 53033.3, 0, 0 }, + { 2357.6, 2.26015, 74.78160 }, + { 769.1, 4.5256, 11.0457 }, + { 551.5, 3.2581, 63.7359 }, + { 541.5, 2.2757, 3.9322 }, + { 529.5, 4.9235, 1.4845 }, + { 257.5, 3.6906, 3.1814 }, + { 238.8, 5.8581, 149.5632 }, + { 181.9, 6.2176, 70.8494 }, + { 49.4, 6.031, 56.622 }, + { 53.5, 1.442, 76.266 }, + { 38.2, 1.785, 52.690 }, + { 44.8, 3.909, 2.448 }, + { 44.5, 0.812, 85.827 }, + { 37.4, 4.462, 2.969 }, + { 33.0, 0.864, 9.561 }, + { 24.3, 2.107, 18.159 }, + { 29.4, 5.098, 73.297 }, + { 22.1, 4.817, 78.714 }, + { 22.5, 5.993, 138.517 }, + { 17.2, 2.535, 145.631 }, + { 21.4, 2.399, 77.963 }, + { 20.6, 2.169, 224.345 }, + { 16.8, 3.466, 12.530 }, + { 12.0, 0.019, 22.091 }, + { 10.5, 4.456, 62.251 }, + { 11.0, 0.085, 127.472 }, + { 8.7, 4.26, 7.11 }, + { 10.5, 5.165, 71.600 }, + { 7.2, 1.25, 5.42 }, + { 8.4, 5.50, 67.67 }, + { 6.1, 5.45, 65.22 }, + { 6.0, 4.52, 151.05 }, + { 5.7, 1.83, 202.25 }, + { 6.1, 3.36, 447.80 }, + { 6.0, 5.73, 462.02 }, + { 5.1, 3.52, 59.80 }, + { 5.2, 1.06, 131.40 }, + { 6.0, 5.61, 148.08 }, + { 5.1, 3.36, 4.45 }, + { 4.8, 1.20, 71.81 }, + { 4.0, 0.68, 77.75 }, + { 3.7, 1.76, 351.82 }, + { 3.1, 3.84, 45.58 }, + { 3.0, 3.32, 160.61 }, + { 3.0, 6.15, 77.23 }, + { 3.6, 4.57, 454.91 }, + { 2.7, 5.36, 269.92 }, + { 2.5, 1.05, 69.36 }, + { 2.3, 2.69, 84.34 }, + { 2.2, 5.08, 14.98 }, + { 2.2, 1.39, 284.15 }, + { 2.1, 4.35, 984.60 }, + { 2.1, 2.32, 120.36 }, + { 1.9, 5.70, 54.17 }, + { 2.0, 3.87, 195.14 }, + { 1.6, 5.08, 209.37 }, + { 1.6, 0.49, 137.03 }, + { 1.6, 2.91, 51.21 }, + { 1.7, 6.26, 41.64 }, + { 2.1, 1.24, 35.16 }, + { 1.7, 6.28, 277.03 }, + /* 62 terms retained, 89 terms dropped, error 0.055"*T^2 */ + + /* uranus l, T^3 */ + { 120.9, 0.0242, 74.7816 }, + { 68.1, 4.121, 3.932 }, + { 52.8, 2.390, 11.046 }, + { 43.8, 2.960, 1.484 }, + { 45.3, 2.044, 3.181 }, + { 45.8, 0, 0 }, + { 25.0, 4.887, 63.736 }, + { 21.1, 4.545, 70.849 }, + { 19.9, 2.313, 149.563 }, + { 8.9, 1.58, 56.62 }, + { 4.3, 0.23, 18.16 }, + { 3.6, 5.39, 76.27 }, + { 3.5, 4.98, 85.83 }, + { 3.5, 4.13, 52.69 }, + { 3.6, 0.95, 77.96 }, + { 2.3, 0.86, 145.63 }, + { 2.7, 0.37, 78.71 }, + { 1.9, 2.68, 7.11 }, + { 2.2, 5.66, 9.56 }, + { 1.4, 4.87, 224.34 }, + { 1.3, 1.25, 12.53 }, + { 1.6, 0.49, 71.60 }, + { 1.5, 5.20, 73.30 }, + { 1.2, 3.93, 22.09 }, + { 0.9, 2.19, 127.47 }, + { 0.8, 3.98, 462.02 }, + { 0.8, 5.06, 447.80 }, + { 0.7, 0.35, 5.63 }, + { 0.7, 1.06, 138.52 }, + { 0.7, 2.94, 131.40 }, + { 0.5, 1.59, 151.05 }, + { 0.4, 4.33, 120.36 }, + /* 32 terms retained, 14 terms dropped, error 0.0098"*T^3 */ + + /* uranus l, T^4 */ + { 113.9, 3.1416, 0 }, + { 5.6, 4.58, 74.78 }, + { 3.2, 0.35, 11.05 }, + { 1.2, 3.42, 56.62 }, + { 0.6, 4.66, 18.16 }, + { 0.2, 3.80, 149.56 }, + { 0.1, 4.36, 63.74 }, + /* 7 terms retained, 0 terms dropped, error 0.0016"*T^4 */ + + /* uranus l, T^5 */ + { 0.9, 3.14, 0 }, + /* 1 terms retained, 0 terms dropped, error 0.0051"*T^5 */ + /* end uranus l */ + + /* uranus b, T^0 */ + { 1346277.6, 2.61877811, 74.78159857 }, + { 62341.4, 5.081112, 149.563197 }, + { 61601.2, 3.141593, 0 }, + { 9963.7, 1.61604, 76.26607 }, + { 9926.2, 0.57630, 73.29713 }, + { 3259.5, 1.26119, 224.34480 }, + { 2972.3, 2.24367, 1.48447 }, + { 2010.3, 6.05550, 148.07872 }, + { 1522.2, 0.27960, 63.73590 }, + { 924.1, 4.0382, 151.0477 }, + { 760.6, 6.1400, 71.8127 }, + { 420.3, 5.2128, 11.0457 }, + { 430.7, 3.5545, 213.2991 }, + { 436.8, 3.3808, 529.6910 }, + { 522.3, 3.3209, 138.5175 }, + { 434.6, 0.3407, 77.7505 }, + { 462.6, 0.7426, 85.8273 }, + { 232.6, 2.2572, 222.8603 }, + { 215.8, 1.5912, 38.1330 }, + { 244.7, 0.7880, 2.9689 }, + { 179.9, 3.7249, 299.1264 }, + { 174.9, 1.2355, 146.5943 }, + { 173.7, 1.9365, 380.1278 }, + { 160.4, 5.3364, 111.4302 }, + { 144.1, 5.9624, 35.1641 }, + { 102.0, 2.6188, 78.7138 }, + { 116.4, 5.7388, 70.8494 }, + { 106.4, 0.9410, 70.3282 }, + { 86.2, 0.703, 39.618 }, + { 72.6, 0.206, 225.829 }, + { 71.2, 0.833, 109.946 }, + { 57.5, 2.670, 108.461 }, + { 54.3, 3.352, 184.727 }, + { 44.5, 2.744, 152.532 }, + { 38.6, 5.174, 202.253 }, + { 39.2, 2.171, 351.817 }, + { 41.3, 3.221, 160.609 }, + { 35.1, 4.001, 112.915 }, + { 33.1, 3.614, 221.376 }, + { 31.3, 2.720, 145.110 }, + { 37.3, 4.021, 52.690 }, + { 32.0, 1.292, 145.631 }, + { 27.6, 3.701, 36.649 }, + /* 43 terms retained, 240 terms dropped, error 0.75" */ + + /* uranus b, T^1 */ + { 206366.2, 4.1239431, 74.7815986 }, + { 8563.2, 0.33820, 149.56320 }, + { 1725.7, 2.12193, 73.29713 }, + { 1368.9, 3.06862, 76.26607 }, + { 1374.4, 0, 0 }, + { 399.8, 2.8477, 224.3448 }, + { 450.6, 3.7766, 1.4845 }, + { 307.2, 1.2546, 148.0787 }, + { 154.3, 3.7858, 63.7359 }, + { 110.9, 5.3289, 138.5175 }, + { 112.4, 5.5730, 151.0477 }, + { 83.5, 3.592, 71.813 }, + { 55.6, 3.401, 85.827 }, + { 41.4, 4.455, 78.714 }, + { 53.7, 1.705, 77.751 }, + { 41.9, 1.215, 11.046 }, + { 32.0, 3.774, 222.860 }, + { 30.3, 2.564, 2.969 }, + { 27.0, 5.337, 213.299 }, + { 26.2, 0.416, 380.128 }, + { 20.1, 5.931, 529.691 }, + { 23.0, 2.489, 146.594 }, + { 19.6, 5.372, 299.126 }, + { 20.4, 3.702, 70.849 }, + { 19.1, 1.092, 111.430 }, + { 19.4, 3.830, 38.133 }, + { 10.8, 2.663, 3.932 }, + { 10.2, 2.313, 109.946 }, + { 9.4, 2.77, 39.62 }, + { 7.7, 1.81, 225.83 }, + { 8.1, 4.69, 184.73 }, + { 6.6, 5.50, 35.16 }, + { 7.4, 1.18, 65.22 }, + { 6.5, 4.98, 71.60 }, + /* 34 terms retained, 120 terms dropped, error 0.16"*T */ + + /* uranus b, T^2 */ + { 9211.7, 5.80044, 74.78160 }, + { 556.9, 0, 0 }, + { 286.3, 2.1773, 149.5632 }, + { 95.0, 3.842, 73.297 }, + { 45.4, 4.878, 76.266 }, + { 20.1, 5.463, 1.484 }, + { 14.8, 0.880, 138.517 }, + { 14.0, 5.072, 63.736 }, + { 14.3, 2.845, 148.079 }, + { 10.1, 5.003, 224.345 }, + { 8.3, 6.27, 78.71 }, + { 4.7, 5.16, 71.81 }, + { 3.8, 6.28, 85.83 }, + { 3.5, 3.53, 11.05 }, + { 2.6, 1.44, 151.05 }, + { 2.4, 4.23, 3.93 }, + { 2.6, 0.41, 71.60 }, + /* 17 terms retained, 43 terms dropped, error 0.045"*T^2 */ + + /* uranus b, T^3 */ + { 267.8, 1.2510, 74.7816 }, + { 11.0, 3.142, 0 }, + { 6.2, 4.01, 149.56 }, + { 3.4, 5.78, 73.30 }, + { 1.6, 1.06, 63.74 }, + { 1.3, 1.67, 78.71 }, + { 1.2, 2.59, 138.52 }, + { 1.1, 0.29, 76.27 }, + { 0.6, 1.87, 71.60 }, + { 0.6, 0.80, 1.48 }, + { 0.5, 4.43, 148.08 }, + /* 11 terms retained, 5 terms dropped, error 0.0067"*T^3 */ + + /* uranus b, T^4 */ + { 5.7, 2.85, 74.78 }, + { 0.3, 3.14, 0 }, + /* 2 terms retained, 0 terms dropped, error 0.0021"*T^4 */ + /* end uranus b */ + + /* uranus r, T^0 */ + { 1921264847.9, 0, 0 }, + { 88784984.1, 5.603775270, 74.781598567 }, + { 3440835.5, 0.32836099, 73.29712586 }, + { 2055653.5, 1.78295170, 149.56319713 }, + { 649321.9, 4.5224730, 76.2660713 }, + { 602248.1, 3.8600382, 63.7358983 }, + { 496404.2, 1.4013993, 454.9093665 }, + { 338525.5, 1.5800268, 138.5174969 }, + { 243508.2, 1.5708660, 71.8126532 }, + { 190521.9, 1.9980936, 1.4844727 }, + { 161858.3, 2.7913786, 148.0787244 }, + { 143705.9, 1.3836857, 11.0457003 }, + { 93192.4, 0.174372, 36.648563 }, + { 71424.3, 4.245093, 224.344796 }, + { 89805.8, 3.661054, 109.945689 }, + { 39009.6, 1.669711, 70.849445 }, + { 46677.3, 1.399766, 35.164090 }, + { 39025.7, 3.362347, 277.034994 }, + { 36755.2, 3.886489, 146.594252 }, + { 30348.9, 0.701004, 151.047670 }, + { 29156.3, 3.180562, 77.750544 }, + { 20471.6, 1.555890, 202.253395 }, + { 25620.4, 5.256563, 380.127768 }, + { 25785.8, 3.785377, 85.827299 }, + { 22637.2, 0.725191, 529.690965 }, + { 20473.2, 2.796398, 70.328180 }, + { 17900.6, 0.554555, 2.968945 }, + { 12328.2, 5.960392, 127.471797 }, + { 14701.6, 4.904344, 108.461216 }, + { 11494.7, 0.437740, 65.220371 }, + { 15502.8, 5.354050, 38.133036 }, + { 10792.7, 1.421049, 213.299095 }, + { 11696.1, 3.298256, 3.932153 }, + { 11959.4, 1.750441, 984.600332 }, + { 12896.5, 2.621540, 111.430161 }, + { 11853.0, 0.993428, 52.690198 }, + { 9111.4, 4.99639, 62.25143 }, + { 8420.6, 5.25351, 222.86032 }, + { 7449.1, 0.79492, 351.81659 }, + { 8402.1, 5.03878, 415.55249 }, + { 6046.4, 5.67961, 78.71375 }, + { 5524.1, 3.11499, 9.56123 }, + { 7329.5, 3.97278, 183.24281 }, + { 5444.9, 5.10576, 145.10978 }, + { 5238.1, 2.62960, 33.67962 }, + { 4079.2, 3.22065, 340.77089 }, + { 3801.6, 6.10986, 184.72729 }, + { 3919.5, 4.25015, 39.61751 }, + { 2940.5, 2.14637, 137.03302 }, + { 3781.2, 3.45840, 456.39384 }, + { 2942.2, 0.42394, 299.12639 }, + { 3686.8, 2.48718, 453.42489 }, + { 3101.7, 4.14031, 219.89138 }, + { 2962.6, 0.82978, 56.62235 }, + { 2937.8, 3.67657, 140.00197 }, + { 2865.1, 0.30997, 12.53017 }, + { 2538.0, 4.85458, 131.40395 }, + { 1962.5, 5.24342, 84.34283 }, + { 2363.6, 0.44253, 554.06999 }, + { 1979.4, 6.12836, 106.97674 }, + { 2182.6, 2.94040, 305.34617 }, + { 1963.0, 0.04115, 221.37585 }, + { 1829.6, 4.01106, 68.84371 }, + { 1642.9, 0.35564, 67.66805 }, + { 1584.8, 3.16267, 225.82927 }, + { 1848.7, 2.91112, 909.81873 }, + { 1632.4, 4.23062, 22.09140 }, + { 1401.4, 1.39084, 265.98929 }, + { 1403.7, 5.63564, 4.45342 }, + { 1655.9, 1.96431, 79.23502 }, + { 1249.0, 5.44027, 54.17467 }, + { 1563.4, 1.47918, 112.91463 }, + { 1248.1, 4.88984, 479.28839 }, + { 1197.4, 2.52186, 145.63104 }, + { 1507.0, 5.24186, 181.75834 }, + { 1481.7, 5.66203, 152.53214 }, + { 1438.8, 1.53046, 447.79582 }, + { 1408.5, 4.41922, 462.02291 }, + { 1477.1, 4.32215, 256.53994 }, + { 1228.3, 5.97703, 59.80375 }, + { 1250.0, 6.24485, 160.60890 }, + { 906.5, 5.6203, 74.6697 }, + { 1090.7, 4.15394, 77.96299 }, + { 844.9, 0.1294, 82.8584 }, + { 900.4, 2.3732, 74.8935 }, + { 1072.0, 1.74287, 528.20649 }, + { 689.7, 3.0810, 69.3650 }, + { 593.8, 4.5007, 8.0768 }, + { 718.6, 4.0005, 128.9563 }, + { 699.6, 0.0399, 143.6253 }, + { 575.7, 5.8955, 66.7048 }, + { 759.0, 2.1370, 692.5875 }, + { 710.4, 5.4161, 218.4069 }, + { 548.7, 5.6281, 3.1814 }, + { 651.6, 4.4234, 18.1592 }, + { 539.8, 6.2079, 71.6002 }, + { 544.5, 5.6938, 203.7379 }, + { 710.3, 4.2197, 381.6122 }, + { 593.8, 3.8381, 32.1951 }, + { 710.1, 4.4897, 293.1885 }, + { 705.5, 0.4552, 835.0371 }, + { 588.0, 5.0825, 186.2118 }, + { 598.2, 0.3582, 269.9214 }, + { 641.9, 2.7113, 87.3118 }, + { 495.6, 2.6509, 200.7689 }, + { 630.3, 4.4615, 275.5505 }, + { 575.2, 5.5786, 2.4477 }, + { 569.9, 1.6393, 77.2293 }, + { 556.7, 1.0723, 1059.3819 }, + { 449.4, 0.2798, 617.8059 }, + { 463.6, 1.4345, 297.6419 }, + { 436.5, 0.5280, 209.3669 }, + { 463.9, 2.3544, 211.8146 }, + { 435.9, 2.1008, 1514.2913 }, + { 515.5, 3.2327, 284.1485 }, + { 454.9, 4.0836, 99.1606 }, + { 477.4, 2.8940, 39.3569 }, + { 542.3, 5.3948, 278.5195 }, + { 410.1, 3.0497, 404.5068 }, + { 367.8, 0.7116, 125.9873 }, + { 503.1, 5.8393, 191.2077 }, + { 487.5, 0.0640, 60.7670 }, + { 455.0, 2.5932, 490.3341 }, + { 436.3, 2.0818, 51.2057 }, + { 435.8, 2.7945, 75.7448 }, + { 323.5, 4.8290, 195.1398 }, + { 359.4, 0.0087, 35.4247 }, + { 429.3, 3.0803, 41.1020 }, + { 320.0, 5.4863, 14.9779 }, + { 414.3, 0.0901, 258.0244 }, + { 379.7, 0.0583, 378.6433 }, + { 420.1, 2.2539, 81.0014 }, + { 357.7, 4.7141, 173.9422 }, + { 358.9, 0.3521, 426.5982 }, + { 405.4, 6.1226, 24.3790 }, + { 365.2, 5.5948, 255.0555 }, + { 308.1, 3.9236, 116.4261 }, + { 325.7, 4.7200, 134.5853 }, + { 292.8, 3.9952, 72.3339 }, + { 386.5, 0.6862, 230.5646 }, + { 305.7, 3.7611, 344.7030 }, + { 287.0, 1.8499, 153.4954 }, + { 353.6, 4.6572, 329.8371 }, + { 302.1, 0.1319, 565.1157 }, + { 241.1, 1.6045, 81.3739 }, + { 249.8, 4.2421, 75.3029 }, + { 245.1, 5.9491, 20.6069 }, + { 248.3, 1.0628, 105.4923 }, + { 305.4, 2.5553, 6208.2943 }, + { 296.3, 4.2110, 1364.7281 }, + { 219.9, 2.9612, 120.3582 }, + { 233.6, 2.9707, 46.2098 }, + { 262.4, 3.8365, 831.1050 }, + { 233.5, 4.4812, 628.8516 }, + { 187.4, 3.0353, 135.5486 }, + { 216.8, 3.4291, 241.6103 }, + { 255.8, 1.1671, 177.8744 }, + { 220.5, 0.1963, 180.2739 }, + { 224.5, 0.4068, 114.3991 }, + { 205.4, 2.3038, 259.5089 }, + { 211.1, 4.9308, 103.0928 }, + { 175.8, 5.5082, 7.1135 }, + { 188.5, 2.2359, 5.4166 }, + { 171.7, 5.2173, 41.6445 }, + { 176.1, 1.9596, 756.3234 }, + { 170.4, 4.9498, 206.1855 }, + { 169.5, 4.0432, 55.6591 }, + { 219.0, 0.2479, 294.6730 }, + { 187.8, 2.0454, 408.4389 }, + { 182.3, 0.7073, 391.1735 }, + { 192.1, 5.7672, 291.7040 }, + { 153.7, 4.7066, 543.0243 }, + { 170.0, 4.5100, 288.0807 }, + { 164.1, 5.2253, 67.3592 }, + { 194.3, 6.1169, 414.0680 }, + { 168.0, 5.2581, 518.6453 }, + { 156.6, 0.6630, 220.4126 }, + { 182.3, 0.7838, 417.0370 }, + { 167.5, 4.9224, 422.6660 }, + { 170.8, 2.3093, 98.9000 }, + { 161.7, 3.2726, 443.8637 }, + { 132.8, 2.8888, 373.9080 }, + { 161.1, 3.8234, 451.9404 }, + { 179.3, 4.8241, 366.4856 }, + { 178.2, 3.9803, 10138.5039 }, + { 141.9, 1.2697, 159.1244 }, + { 153.8, 4.2785, 45.5767 }, + { 161.5, 4.9955, 73.8184 }, + { 146.3, 2.6566, 465.9551 }, + { 124.9, 4.3047, 339.2864 }, + { 154.6, 4.3205, 760.2555 }, + { 142.9, 2.0777, 457.8783 }, + { 152.4, 4.6474, 155.7830 }, + { 116.4, 4.4351, 5.9379 }, + { 113.4, 4.6535, 80.1982 }, + { 107.6, 3.7729, 142.4497 }, + { 133.7, 5.3089, 14.0146 }, + { 116.1, 2.5118, 296.1574 }, + { 129.1, 0.3628, 96.8730 }, + { 122.8, 2.3834, 141.4864 }, + { 101.4, 1.0574, 92.3077 }, + { 114.7, 6.2486, 767.3691 }, + { 113.3, 0.8305, 100.3845 }, + { 107.2, 2.3937, 347.8844 }, + { 95.4, 0.801, 342.255 }, + { 110.8, 0.3865, 216.9224 }, + { 127.0, 0.4236, 331.3215 }, + { 112.6, 0.0811, 558.0021 }, + { 103.2, 0.6979, 358.9301 }, + { 111.5, 0.7502, 80.7195 }, + { 90.9, 5.165, 144.147 }, + { 90.7, 0.220, 333.657 }, + { 98.6, 4.332, 74.521 }, + { 89.3, 2.189, 74.830 }, + { 117.2, 3.9497, 74.2603 }, + { 89.1, 5.878, 74.733 }, + { 97.3, 0.694, 977.487 }, + { 116.6, 1.8368, 1289.9465 }, + { 85.4, 5.803, 6.592 }, + { 86.8, 5.620, 300.611 }, + { 105.2, 5.9451, 328.3526 }, + { 112.1, 1.2117, 329.7252 }, + { 83.0, 2.208, 74.942 }, + { 94.3, 4.539, 28.572 }, + { 106.8, 1.8207, 306.8306 }, + { 103.6, 2.9937, 6.2198 }, + { 106.4, 0.8158, 1087.6931 }, + { 77.7, 2.734, 110.206 }, + { 98.4, 3.735, 75.042 }, + { 86.2, 2.833, 983.116 }, + { 89.0, 4.738, 604.473 }, + { 83.0, 1.883, 387.241 }, + { 90.2, 3.804, 986.085 }, + { 84.6, 1.258, 142.141 }, + { 74.7, 1.351, 350.332 }, + { 95.8, 5.548, 969.622 }, + { 90.3, 0.368, 0.963 }, + { 82.7, 5.856, 74.622 }, + { 75.8, 2.780, 88.115 }, + { 83.8, 1.844, 227.314 }, + { 70.7, 4.656, 44.725 }, + { 71.3, 3.650, 894.841 }, + { 94.1, 4.988, 403.134 }, + { 89.0, 4.439, 154.017 }, + { 79.4, 5.667, 267.474 }, + { 75.6, 5.410, 50.403 }, + { 68.6, 4.767, 991.714 }, + { 65.3, 0.693, 152.745 }, + { 63.0, 2.899, 79.889 }, + { 63.9, 0.098, 681.542 }, + { 80.1, 2.975, 526.722 }, + { 69.7, 3.953, 187.696 }, + { 59.5, 3.596, 58.107 }, + { 59.3, 0.509, 28.311 }, + { 68.6, 2.419, 235.390 }, + { 66.0, 5.046, 30.711 }, + { 70.2, 3.736, 546.956 }, + { 66.8, 0.855, 522.577 }, + { 63.0, 0.293, 119.507 }, + { 62.0, 2.316, 74.031 }, + { 71.4, 3.170, 23.576 }, + { 74.8, 5.368, 373.014 }, + { 64.2, 2.368, 157.640 }, + { 70.7, 0.558, 92.941 }, + { 55.8, 5.270, 874.394 }, + { 75.6, 4.663, 101.869 }, + { 73.7, 6.206, 312.460 }, + { 72.9, 0.584, 367.970 }, + { 53.2, 2.247, 17.526 }, + { 63.1, 4.596, 67.880 }, + { 60.5, 0.576, 253.571 }, + { 52.9, 2.459, 264.505 }, + { 70.2, 1.519, 552.586 }, + { 68.6, 2.445, 555.554 }, + { 62.8, 0.338, 561.184 }, + { 49.0, 1.092, 19.122 }, + { 64.6, 5.275, 68.189 }, + { 63.0, 5.359, 92.047 }, + { 47.7, 3.909, 192.692 }, + { 65.3, 4.236, 771.301 }, + { 65.2, 3.739, 536.805 }, + { 59.5, 6.106, 365.001 }, + { 52.2, 1.717, 905.887 }, + { 46.0, 3.871, 210.330 }, + { 46.4, 5.974, 477.804 }, + { 62.1, 2.675, 130.441 }, + { 46.0, 3.894, 48.758 }, + { 42.7, 3.815, 61.288 }, + { 53.9, 2.865, 353.301 }, + { 46.9, 1.000, 166.829 }, + { 42.2, 2.617, 90.823 }, + { 43.3, 4.158, 173.682 }, + { 41.3, 1.799, 149.451 }, + { 45.0, 1.766, 0.521 }, + { 51.9, 2.978, 383.097 }, + { 42.9, 1.574, 120.991 }, + { 49.6, 4.034, 303.862 }, + { 45.3, 3.584, 97.416 }, + { 38.7, 2.394, 31.493 }, + { 38.1, 5.795, 75.532 }, + { 50.1, 4.764, 911.303 }, + { 50.9, 5.155, 439.783 }, + { 43.1, 0.850, 58.319 }, + { 42.7, 5.173, 162.093 }, + { 50.3, 5.816, 66.917 }, + { 35.6, 1.874, 472.175 }, + { 50.0, 1.889, 42.586 }, + { 40.0, 1.743, 89.759 }, + { 45.3, 1.925, 55.138 }, + { 44.9, 1.484, 450.977 }, + { 34.3, 5.203, 316.392 }, + { 46.4, 0.339, 273.103 }, + { 37.2, 2.038, 117.911 }, + { 46.1, 5.623, 1819.637 }, + { 39.4, 4.194, 486.402 }, + { 41.0, 4.830, 149.675 }, + { 45.0, 0.727, 3265.831 }, + { 43.6, 0.753, 404.619 }, + { 31.8, 3.848, 20.447 }, + { 44.2, 4.368, 418.261 }, + { 37.9, 3.029, 167.089 }, + { 43.7, 1.573, 491.558 }, + { 34.0, 1.263, 260.993 }, + { 31.3, 4.161, 13.333 }, + { 40.0, 2.866, 468.243 }, + { 36.5, 2.588, 68.562 }, + { 32.4, 3.116, 103.353 }, + { 33.9, 0.156, 24.118 }, + { 35.9, 1.368, 59.282 }, + { 33.6, 0.755, 290.220 }, + { 29.8, 5.332, 1033.358 }, + { 32.0, 4.675, 205.222 }, + { 31.0, 4.628, 258.876 }, + { 35.3, 1.007, 1108.140 }, + { 33.4, 3.407, 43.129 }, + { 32.6, 5.255, 114.138 }, + { 29.8, 5.642, 254.944 }, + { 31.6, 3.782, 152.011 }, + { 31.0, 2.267, 104.008 }, + { 34.6, 5.173, 25.603 }, + { 28.4, 1.769, 820.059 }, + { 28.0, 3.925, 199.284 }, + { 29.0, 2.582, 76.479 }, + { 33.8, 5.794, 274.066 }, + { 29.4, 5.936, 280.967 }, + { 31.1, 1.394, 178.789 }, + { 30.1, 0.444, 27.087 }, + { 33.8, 6.262, 401.650 }, + { 27.5, 2.152, 480.773 }, + { 26.9, 2.513, 123.540 }, + { 26.1, 0.220, 286.596 }, + { 26.5, 3.882, 372.424 }, + { 34.0, 1.446, 88.796 }, + { 30.1, 0.827, 100.645 }, + { 27.7, 4.648, 198.321 }, + { 33.7, 1.143, 82.486 }, + { 26.5, 1.979, 95.389 }, + { 26.6, 0.399, 106.014 }, + { 27.0, 2.102, 1057.897 }, + { 31.0, 5.340, 476.431 }, + { 27.0, 0.713, 248.724 }, + { 29.1, 3.992, 908.334 }, + { 28.0, 3.465, 1439.510 }, + { 27.8, 4.124, 694.072 }, + { 25.5, 5.496, 115.884 }, + { 27.2, 5.761, 1215.165 }, + { 26.3, 2.775, 490.073 }, + { 26.4, 3.371, 49.721 }, + { 26.9, 3.260, 691.103 }, + { 25.0, 3.650, 73.409 }, + /* 370 terms retained, 754 terms dropped, error 9.6e-06 a.u. */ + + /* uranus r, T^1 */ + { 1479896.4, 3.67205705, 74.78159857 }, + { 71212.1, 6.226010, 63.735898 }, + { 68627.0, 6.134113, 149.563197 }, + { 20857.3, 5.246255, 11.045700 }, + { 21468.2, 2.601767, 76.266071 }, + { 24059.6, 3.141593, 0 }, + { 11405.3, 0.018485, 70.849445 }, + { 7496.8, 0.42360, 73.29713 }, + { 4243.8, 1.41692, 85.82730 }, + { 3505.9, 2.58354, 138.51750 }, + { 3228.8, 5.25500, 3.93215 }, + { 3926.7, 3.15514, 71.81265 }, + { 3060.0, 0.15322, 1.48447 }, + { 3578.4, 2.31161, 224.34480 }, + { 2564.3, 0.98077, 148.07872 }, + { 2429.4, 3.99440, 52.69020 }, + { 1644.7, 2.65349, 127.47180 }, + { 1583.8, 1.43046, 78.71375 }, + { 1413.1, 4.57462, 202.25340 }, + { 1489.5, 2.67559, 56.62235 }, + { 1403.2, 1.36985, 77.75054 }, + { 1228.2, 1.04704, 62.25143 }, + { 1508.0, 5.05996, 151.04767 }, + { 992.1, 2.1717, 65.2204 }, + { 1032.7, 0.26459, 131.40395 }, + { 861.9, 5.0553, 351.8166 }, + { 744.4, 3.0764, 35.1641 }, + { 604.4, 0.9072, 984.6003 }, + { 646.9, 4.4729, 70.3282 }, + { 574.7, 3.2307, 447.7958 }, + { 687.5, 2.4991, 77.9630 }, + { 623.6, 0.8625, 9.5612 }, + { 527.8, 5.1514, 2.9689 }, + { 561.8, 2.7178, 462.0229 }, + { 530.4, 5.9166, 213.2991 }, + { 460.1, 4.2230, 12.5302 }, + { 494.3, 0.4629, 145.6310 }, + { 487.3, 0.7061, 380.1278 }, + { 380.9, 3.8509, 3.1814 }, + { 444.4, 2.1556, 67.6681 }, + { 338.8, 2.5382, 18.1592 }, + { 372.9, 5.0514, 529.6910 }, + { 348.3, 1.7487, 71.6002 }, + { 405.9, 1.2296, 22.0914 }, + { 268.9, 6.2407, 340.7709 }, + { 255.6, 2.9570, 84.3428 }, + { 259.5, 3.9205, 59.8037 }, + { 224.7, 3.9096, 160.6089 }, + { 221.7, 3.6473, 137.0330 }, + { 254.6, 3.5041, 38.1330 }, + { 238.3, 2.0488, 269.9214 }, + { 272.4, 3.3836, 222.8603 }, + { 200.6, 1.2486, 69.3650 }, + { 234.2, 0.2783, 108.4612 }, + { 188.5, 4.4131, 265.9893 }, + { 211.7, 0.6803, 111.4302 }, + { 205.9, 1.5338, 284.1485 }, + { 196.2, 4.7715, 299.1264 }, + { 153.1, 5.2176, 209.3669 }, + { 162.6, 4.3405, 33.6796 }, + { 150.6, 1.9897, 54.1747 }, + { 137.0, 0.4032, 195.1398 }, + { 117.2, 0.3965, 87.3118 }, + { 127.9, 2.4033, 39.6175 }, + { 104.2, 2.9215, 134.5853 }, + { 103.9, 1.8162, 72.3339 }, + { 105.7, 0.1707, 79.2350 }, + { 106.4, 0.6980, 2.4477 }, + { 95.3, 4.029, 82.858 }, + { 104.8, 4.4362, 305.3462 }, + { 93.8, 5.018, 51.206 }, + { 103.7, 2.5755, 191.2077 }, + { 106.7, 1.2300, 225.8293 }, + { 93.5, 3.093, 77.229 }, + { 97.4, 3.814, 152.532 }, + { 84.6, 5.725, 68.844 }, + { 77.4, 0.083, 45.577 }, + { 76.2, 4.204, 73.818 }, + { 86.2, 0.531, 145.110 }, + { 75.8, 3.786, 75.745 }, + { 77.6, 1.636, 479.288 }, + { 84.6, 0.617, 116.426 }, + { 100.2, 4.9408, 120.3582 }, + { 72.1, 4.305, 565.116 }, + { 70.7, 2.385, 60.767 }, + { 71.6, 3.939, 153.495 }, + { 84.6, 5.560, 344.703 }, + { 63.6, 1.937, 41.644 }, + { 71.6, 3.712, 408.439 }, + { 61.6, 3.900, 4.453 }, + { 65.0, 1.558, 106.977 }, + { 59.9, 0.601, 74.893 }, + { 62.0, 4.394, 453.425 }, + { 63.4, 4.192, 184.727 }, + { 62.3, 3.238, 422.666 }, + { 54.4, 3.725, 7.114 }, + { 52.5, 6.086, 404.507 }, + { 59.1, 1.556, 456.394 }, + { 52.6, 3.505, 125.987 }, + { 52.8, 5.201, 358.930 }, + { 58.1, 5.335, 220.413 }, + { 52.9, 4.448, 426.598 }, + { 50.9, 0.526, 490.334 }, + { 55.0, 1.601, 14.978 }, + { 49.5, 4.255, 5.417 }, + { 51.3, 0.368, 206.186 }, + { 51.8, 1.758, 8.077 }, + { 57.0, 0.841, 146.594 }, + { 49.1, 0.941, 99.161 }, + { 46.4, 5.351, 152.745 }, + { 48.0, 1.972, 288.081 }, + { 43.8, 3.037, 20.607 }, + { 49.5, 5.846, 112.915 }, + { 42.0, 0.046, 128.956 }, + { 48.6, 3.628, 81.001 }, + { 41.5, 2.337, 277.035 }, + { 40.0, 5.095, 35.425 }, + { 41.9, 2.511, 24.379 }, + { 38.3, 3.619, 173.942 }, + { 38.4, 2.060, 333.657 }, + { 42.6, 1.261, 1514.291 }, + { 38.9, 0.742, 347.884 }, + { 38.5, 4.951, 92.941 }, + { 33.2, 1.384, 74.670 }, + { 33.8, 3.684, 66.917 }, + { 39.0, 5.492, 200.769 }, + { 31.9, 0.540, 203.738 }, + { 33.3, 6.260, 1059.382 }, + { 30.8, 2.538, 977.487 }, + { 29.2, 5.431, 58.107 }, + { 30.1, 0.195, 387.241 }, + { 29.0, 3.105, 991.714 }, + { 35.6, 3.729, 96.873 }, + { 27.6, 0.371, 80.198 }, + { 32.5, 4.384, 221.376 }, + { 27.0, 1.356, 0.963 }, + { 31.3, 0.796, 373.014 }, + { 31.1, 2.054, 230.565 }, + { 25.9, 3.468, 144.147 }, + { 30.2, 0.714, 109.946 }, + { 24.7, 3.042, 14.015 }, + { 27.9, 4.766, 415.552 }, + { 25.1, 5.124, 81.374 }, + { 25.6, 2.569, 522.577 }, + { 24.4, 2.203, 628.852 }, + { 25.5, 1.795, 143.625 }, + { 24.2, 5.672, 443.864 }, + { 25.7, 5.432, 546.956 }, + { 24.2, 5.600, 32.195 }, + { 24.4, 3.303, 617.806 }, + { 23.5, 0.658, 46.210 }, + { 22.4, 4.821, 135.549 }, + { 27.2, 2.027, 536.805 }, + { 22.2, 4.617, 391.173 }, + { 22.0, 4.592, 241.610 }, + { 20.8, 0.244, 465.955 }, + { 27.3, 2.152, 140.002 }, + { 21.4, 5.272, 159.124 }, + { 23.6, 4.950, 561.184 }, + { 24.9, 0.546, 181.758 }, + { 23.0, 3.806, 55.138 }, + { 19.8, 1.303, 518.645 }, + { 19.3, 1.314, 543.024 }, + { 19.7, 4.909, 909.819 }, + { 20.8, 0.912, 76.479 }, + { 19.9, 0.665, 66.705 }, + { 19.0, 4.680, 98.900 }, + { 25.9, 4.529, 454.909 }, + { 21.9, 1.234, 41.102 }, + { 18.7, 6.096, 103.093 }, + { 18.2, 0.973, 55.659 }, + { 21.2, 4.194, 329.725 }, + { 19.4, 4.315, 6.220 }, + { 18.5, 5.786, 142.450 }, + { 22.6, 5.846, 297.642 }, + { 16.8, 6.091, 211.815 }, + { 16.4, 2.500, 61.288 }, + { 20.4, 3.161, 186.212 }, + { 16.0, 2.983, 81.895 }, + { 19.0, 6.012, 155.783 }, + { 17.7, 4.826, 273.103 }, + { 15.1, 3.656, 472.175 }, + { 18.4, 3.476, 36.649 }, + { 16.3, 0.131, 554.070 }, + { 18.6, 0.239, 23.576 }, + { 14.4, 2.694, 70.116 }, + { 15.2, 2.438, 486.402 }, + { 14.0, 5.124, 29.205 }, + { 15.8, 4.249, 146.382 }, + { 14.1, 1.557, 110.206 }, + { 17.5, 1.945, 835.037 }, + { 13.7, 1.638, 92.047 }, + { 13.8, 0.137, 235.390 }, + { 13.6, 2.854, 49.509 }, + { 12.6, 3.209, 100.384 }, + { 12.4, 2.886, 60.555 }, + { 15.0, 0.326, 259.509 }, + { 12.9, 2.776, 105.492 }, + { 12.3, 3.364, 440.682 }, + { 15.2, 0.256, 258.876 }, + { 12.1, 0.109, 157.640 }, + { 12.9, 0.307, 124.290 }, + { 10.9, 3.429, 33.137 }, + { 11.2, 4.988, 604.473 }, + { 10.8, 3.863, 767.369 }, + { 11.6, 2.605, 166.829 }, + { 10.2, 5.278, 264.505 }, + { 10.9, 0.641, 558.002 }, + { 12.3, 4.340, 16.675 }, + { 9.9, 0.67, 31.49 }, + { 12.6, 4.832, 114.399 }, + { 10.5, 0.204, 275.551 }, + { 11.3, 0.961, 373.908 }, + { 12.1, 1.917, 378.643 }, + { 12.2, 0.705, 218.407 }, + { 10.8, 5.745, 88.115 }, + { 9.5, 0.66, 353.30 }, + { 11.0, 2.630, 154.017 }, + { 9.1, 2.99, 681.54 }, + { 10.4, 2.331, 132.888 }, + { 9.2, 4.79, 216.48 }, + { 9.3, 0.76, 129.92 }, + { 8.9, 0.78, 67.36 }, + { 8.8, 6.13, 150.53 }, + { 9.6, 2.89, 67.88 }, + { 10.5, 0.369, 699.701 }, + { 9.3, 1.50, 19.64 }, + { 9.4, 5.26, 80.72 }, + { 10.1, 3.565, 278.519 }, + { 9.5, 3.06, 149.68 }, + { 9.2, 3.03, 162.09 }, + { 8.4, 2.18, 342.26 }, + { 9.2, 5.33, 152.01 }, + { 9.8, 2.44, 75.30 }, + { 10.0, 0.819, 339.286 }, + { 9.4, 1.94, 147.12 }, + { 7.9, 4.72, 106.01 }, + { 8.8, 0.02, 42.59 }, + { 7.8, 0.61, 135.34 }, + { 8.2, 2.60, 469.14 }, + { 10.1, 2.586, 50.403 }, + { 8.6, 5.69, 760.26 }, + { 7.5, 2.65, 5.94 }, + { 8.7, 0.54, 66.18 }, + { 8.0, 1.94, 180.27 }, + { 7.5, 5.95, 97.42 }, + { 7.6, 5.80, 450.98 }, + { 8.7, 3.70, 300.61 }, + { 7.7, 1.47, 32.24 }, + { 8.2, 2.31, 254.94 }, + { 8.5, 1.28, 39.36 }, + { 7.0, 0.68, 874.39 }, + { 8.9, 0.16, 43.13 }, + { 7.2, 4.98, 117.91 }, + { 7.4, 4.09, 92.31 }, + { 7.3, 5.04, 756.32 }, + { 8.5, 1.22, 79.45 }, + { 6.9, 6.04, 350.33 }, + { 8.8, 1.33, 48.76 }, + { 7.3, 3.33, 68.19 }, + { 6.8, 4.78, 142.66 }, + { 6.8, 3.90, 480.77 }, + { 7.1, 1.28, 68.56 }, + { 7.9, 4.30, 624.92 }, + { 6.7, 5.43, 610.69 }, + { 6.5, 5.44, 88.80 }, + { 7.6, 4.81, 312.46 }, + { 7.2, 3.18, 268.44 }, + { 8.1, 1.99, 692.59 }, + { 6.5, 1.05, 685.47 }, + { 6.6, 1.38, 291.26 }, + { 6.9, 2.59, 282.66 }, + { 7.1, 5.80, 468.24 }, + { 6.3, 2.58, 458.09 }, + { 7.6, 0.49, 296.16 }, + { 8.5, 0.01, 227.31 }, + { 6.5, 3.99, 42.54 }, + { 6.4, 1.04, 365.90 }, + { 8.2, 1.13, 69.15 }, + { 6.4, 0.16, 228.28 }, + { 8.0, 4.04, 183.24 }, + { 6.3, 3.52, 285.63 }, + { 6.9, 3.32, 306.83 }, + { 6.9, 1.34, 7.86 }, + { 6.5, 0.46, 106.27 }, + { 6.6, 5.25, 58.32 }, + { 6.4, 0.35, 411.62 }, + { 6.4, 5.19, 120.99 }, + { 7.0, 4.86, 419.48 }, + { 6.4, 2.78, 198.32 }, + /* 290 terms retained, 224 terms dropped, error 2.2e-06 a.u.*T */ + + /* uranus r, T^2 */ + { 22439.9, 0.699531, 74.781599 }, + { 4727.0, 1.69902, 63.73590 }, + { 1681.9, 4.64834, 70.84945 }, + { 1433.8, 3.52120, 149.56320 }, + { 1649.6, 3.09660, 11.04570 }, + { 770.2, 0, 0 }, + { 461.0, 0.7668, 3.9322 }, + { 500.4, 6.1723, 76.2661 }, + { 390.4, 4.4961, 56.6224 }, + { 389.9, 5.5267, 85.8273 }, + { 292.1, 0.2039, 52.6902 }, + { 272.9, 3.8471, 138.5175 }, + { 286.6, 3.5336, 73.2971 }, + { 205.4, 3.2476, 78.7138 }, + { 219.7, 1.9642, 131.4039 }, + { 215.8, 0.8481, 77.9630 }, + { 128.8, 2.0815, 3.1814 }, + { 148.6, 4.8984, 127.4718 }, + { 117.5, 4.9341, 447.7958 }, + { 112.7, 1.0136, 462.0229 }, + { 98.9, 6.158, 224.345 }, + { 91.4, 0.680, 18.159 }, + { 89.2, 0.234, 202.253 }, + { 88.2, 2.931, 62.251 }, + { 114.1, 4.7874, 145.6310 }, + { 103.9, 3.5856, 71.6002 }, + { 61.8, 3.300, 351.817 }, + { 57.8, 4.907, 22.091 }, + { 64.4, 3.390, 1.484 }, + { 71.1, 6.105, 454.909 }, + { 51.0, 3.867, 65.220 }, + { 63.5, 3.962, 67.668 }, + { 59.0, 5.555, 9.561 }, + { 48.7, 3.747, 269.921 }, + { 43.6, 1.926, 59.804 }, + { 42.2, 2.617, 151.048 }, + { 42.4, 6.136, 284.149 }, + { 44.3, 5.900, 71.813 }, + { 37.3, 5.913, 984.600 }, + { 36.2, 5.403, 77.751 }, + { 42.0, 2.091, 12.530 }, + { 31.4, 4.592, 148.079 }, + { 31.3, 2.267, 195.140 }, + { 27.2, 3.532, 209.367 }, + { 28.2, 4.578, 77.229 }, + { 26.1, 0.660, 120.358 }, + { 24.4, 5.867, 69.365 }, + { 23.0, 1.038, 84.343 }, + { 22.7, 1.714, 160.609 }, + { 27.7, 4.915, 277.035 }, + { 20.8, 2.196, 45.577 }, + { 20.0, 2.321, 2.448 }, + { 16.6, 4.775, 213.299 }, + { 16.6, 1.856, 340.771 }, + { 17.2, 4.369, 54.175 }, + { 16.1, 3.646, 152.745 }, + { 14.8, 5.438, 408.439 }, + { 13.9, 3.385, 358.930 }, + { 13.3, 5.252, 137.033 }, + { 13.3, 1.263, 134.585 }, + { 12.9, 3.033, 92.941 }, + { 12.5, 1.332, 51.206 }, + { 13.4, 1.532, 422.666 }, + { 16.4, 0.402, 265.989 }, + { 12.0, 5.104, 191.208 }, + { 12.9, 4.432, 87.312 }, + { 11.4, 2.026, 7.114 }, + { 11.8, 4.656, 41.644 }, + { 12.0, 3.239, 116.426 }, + { 11.7, 3.733, 220.413 }, + { 11.6, 4.165, 60.555 }, + { 10.2, 0.329, 70.328 }, + { 11.3, 1.076, 72.334 }, + { 9.7, 3.06, 2.97 }, + { 9.3, 2.44, 565.12 }, + { 9.0, 5.19, 225.83 }, + { 10.3, 1.186, 344.703 }, + { 8.8, 6.01, 5.42 }, + { 8.5, 5.25, 347.88 }, + { 8.3, 3.72, 14.98 }, + { 8.3, 2.27, 299.13 }, + { 8.1, 5.72, 55.14 }, + { 7.8, 0.90, 222.86 }, + { 8.3, 4.49, 70.12 }, + { 8.8, 5.82, 153.50 }, + { 8.5, 3.91, 333.66 }, + { 9.9, 5.97, 35.16 }, + { 9.6, 0.39, 415.55 }, + { 7.1, 1.51, 991.71 }, + { 6.6, 1.18, 96.87 }, + { 8.1, 2.26, 206.19 }, + { 6.5, 2.99, 380.13 }, + { 9.0, 6.05, 146.38 }, + { 6.1, 0.06, 99.16 }, + { 5.8, 0.82, 142.45 }, + { 5.8, 4.63, 49.51 }, + { 5.6, 0.66, 58.11 }, + { 6.0, 2.49, 373.01 }, + { 5.7, 2.24, 80.20 }, + { 5.3, 5.07, 440.68 }, + { 5.2, 4.36, 977.49 }, + { 5.4, 0.85, 546.96 }, + { 5.8, 0.34, 536.80 }, + { 5.9, 5.48, 76.48 }, + { 5.3, 3.73, 23.58 }, + { 5.2, 4.14, 132.89 }, + { 5.3, 6.14, 39.62 }, + { 5.8, 3.40, 458.09 }, + { 5.0, 4.26, 522.58 }, + { 5.0, 4.79, 387.24 }, + { 5.2, 3.26, 561.18 }, + { 4.6, 1.69, 152.53 }, + { 5.3, 1.84, 124.29 }, + { 5.0, 0.37, 60.77 }, + { 4.5, 2.30, 312.46 }, + { 4.5, 0.46, 33.14 }, + { 5.7, 0.90, 81.90 }, + { 5.8, 0.92, 20.61 }, + { 5.7, 0.66, 38.13 }, + { 4.3, 3.55, 479.29 }, + { 4.2, 4.38, 79.24 }, + { 4.2, 1.65, 128.96 }, + { 5.1, 1.41, 144.15 }, + { 4.0, 6.07, 19.64 }, + { 4.0, 5.77, 288.08 }, + { 5.0, 3.00, 29.20 }, + { 3.8, 2.60, 426.60 }, + { 3.9, 3.20, 159.12 }, + { 3.9, 4.44, 141.70 }, + { 5.3, 4.08, 111.43 }, + { 4.6, 0.01, 298.23 }, + { 3.7, 5.28, 353.30 }, + { 3.9, 5.27, 521.09 }, + { 3.7, 5.15, 490.33 }, + { 4.0, 0.61, 152.01 }, + { 3.9, 1.34, 535.32 }, + { 4.4, 0.62, 827.17 }, + { 3.6, 4.72, 6.90 }, + { 3.6, 3.25, 230.56 }, + { 3.5, 0.79, 983.12 }, + { 4.5, 2.87, 129.92 }, + { 3.6, 5.59, 774.48 }, + { 3.5, 4.50, 376.20 }, + { 3.4, 2.56, 258.88 }, + { 4.4, 2.10, 404.51 }, + { 3.3, 0.90, 469.14 }, + { 3.3, 3.86, 42.54 }, + { 3.2, 2.76, 248.72 }, + { 3.2, 0.08, 1514.29 }, + { 3.8, 5.30, 369.08 }, + { 3.3, 2.25, 73.82 }, + { 3.1, 2.60, 433.71 }, + { 3.1, 4.55, 980.67 }, + { 3.1, 1.27, 200.77 }, + { 3.1, 1.71, 639.90 }, + { 3.1, 3.63, 16.67 }, + { 3.5, 4.94, 411.62 }, + { 3.5, 4.49, 881.51 }, + { 3.3, 5.59, 472.17 }, + { 3.0, 6.03, 291.26 }, + { 3.5, 2.17, 554.07 }, + { 3.1, 0.52, 1094.81 }, + { 3.3, 2.49, 451.73 }, + { 2.9, 0.50, 305.35 }, + { 3.1, 4.20, 146.59 }, + { 2.9, 2.45, 135.34 }, + { 3.0, 0.39, 25.27 }, + { 2.8, 2.53, 867.28 }, + { 2.7, 5.29, 125.99 }, + { 2.9, 4.71, 218.93 }, + { 2.8, 4.28, 350.33 }, + { 2.7, 1.99, 82.86 }, + { 2.9, 3.09, 216.48 }, + { 3.4, 3.68, 661.09 }, + { 2.9, 1.44, 381.61 }, + { 2.8, 0.39, 33.68 }, + { 2.8, 4.63, 1357.61 }, + { 3.4, 2.13, 685.47 }, + { 2.6, 5.93, 89.76 }, + { 2.7, 0.76, 486.40 }, + { 2.7, 4.16, 235.39 }, + { 2.6, 3.82, 550.89 }, + { 3.4, 3.17, 108.46 }, + { 2.6, 5.68, 24.38 }, + { 2.7, 1.87, 529.69 }, + { 2.6, 4.37, 1080.58 }, + { 2.4, 3.07, 391.17 }, + { 2.4, 5.74, 535.91 }, + { 2.3, 5.19, 1059.38 }, + { 2.6, 1.10, 913.00 }, + { 2.2, 6.10, 140.00 }, + { 3.1, 5.35, 681.54 }, + /* 192 terms retained, 0 terms dropped, error 8.5e-07 a.u.*T^2 */ + + /* uranus r, T^3 */ + { 1164.4, 4.73453, 74.78160 }, + { 212.4, 3.3426, 63.7359 }, + { 196.4, 2.9800, 70.8494 }, + { 104.5, 0.9581, 11.0457 }, + { 71.7, 0.025, 56.622 }, + { 72.5, 0.997, 149.563 }, + { 54.9, 2.594, 3.932 }, + { 34.0, 3.816, 76.266 }, + { 32.1, 3.598, 131.404 }, + { 29.6, 3.441, 85.827 }, + { 36.4, 5.650, 77.963 }, + { 27.7, 0.428, 3.181 }, + { 27.5, 2.551, 52.690 }, + { 24.6, 5.140, 78.714 }, + { 19.4, 5.135, 18.159 }, + { 15.8, 0.371, 447.796 }, + { 15.4, 5.573, 462.023 }, + { 15.2, 3.860, 73.297 }, + { 15.5, 2.975, 145.631 }, + { 18.0, 0, 0 }, + { 16.0, 5.199, 71.600 }, + { 11.1, 6.032, 138.517 }, + { 10.5, 3.583, 224.345 }, + { 7.6, 1.45, 1.48 }, + { 8.1, 2.62, 22.09 }, + { 7.1, 5.44, 269.92 }, + { 6.5, 4.37, 284.15 }, + { 6.8, 0.01, 151.05 }, + { 8.1, 0.30, 127.47 }, + { 5.8, 4.23, 373.01 }, + { 5.0, 1.84, 202.25 }, + { 4.7, 2.78, 120.36 }, + { 5.1, 0.78, 62.25 }, + { 4.2, 1.84, 72.33 }, + { 3.9, 1.89, 209.37 }, + { 5.2, 4.16, 195.14 }, + { 3.6, 2.00, 65.22 }, + { 3.6, 3.93, 124.29 }, + { 3.8, 1.05, 92.94 }, + { 4.2, 3.96, 9.56 }, + { 3.5, 1.54, 148.08 }, + { 3.2, 2.99, 387.24 }, + { 4.0, 1.86, 152.74 }, + { 3.3, 1.41, 351.82 }, + { 3.6, 1.17, 153.50 }, + { 2.9, 6.04, 12.53 }, + { 2.7, 5.65, 134.59 }, + { 2.8, 0.79, 572.23 }, + { 3.1, 5.84, 160.61 }, + { 2.7, 1.99, 450.98 }, + { 2.7, 2.77, 213.30 }, + { 2.3, 1.68, 358.93 }, + { 2.3, 5.77, 84.34 }, + { 2.3, 4.81, 536.80 }, + { 2.2, 2.20, 465.96 }, + /* 55 terms retained, 0 terms dropped, error 3.3e-07 a.u.*T^3 */ + + /* uranus r, T^4 */ + { 53.0, 3.008, 74.782 }, + { 9.9, 1.91, 56.62 }, + { 7.0, 5.09, 11.05 }, + { 6.7, 5.43, 149.56 }, + { 3.7, 5.23, 131.40 }, + { 3.4, 1.30, 85.83 }, + { 2.7, 0.44, 63.74 }, + { 2.3, 0.92, 145.63 }, + { 2.4, 6.21, 358.93 }, + { 2.3, 2.23, 440.68 }, + { 3.1, 3.14, 0 }, + /* 11 terms retained, 0 terms dropped, error 2.1e-07 a.u.*T^4 */ + /* end uranus */ +}; + +int vn_uranus[][3] = { + /* addresses for uranus l, b, r */ + /* T^0 */ { 0, 355, 462, }, + /* T^1 */ { 152, 398, 832, }, + /* T^2 */ { 253, 432, 1122, }, + /* T^3 */ { 315, 449, 1314, }, + /* T^4 */ { 347, 460, 1369, }, + /* T^5 */ { 354, 462, 1380, }, + /* end */ { 355, 0, 0, }, + /* termination */ { 0, } +}; + +/* version d4 (lbr) + * heliocentric dynamical ecliptic and equinox of the date + */ + +double vx_venus[][3] = { + /* venus l, T^0 */ + { 317614666.8, 0, 0 }, + { 1353968.4, 5.59313320, 10213.28554621 }, + { 89891.6, 5.306500, 20426.571092 }, + { 5477.2, 4.41631, 7860.41939 }, + { 3455.7, 2.69964, 11790.62909 }, + { 2372.1, 2.99378, 3930.20970 }, + { 1317.1, 5.18668, 26.29832 }, + { 1664.1, 4.25019, 1577.34354 }, + { 1438.3, 4.15745, 9683.59458 }, + { 1200.5, 6.15357, 30639.85664 }, + { 761.4, 1.9501, 529.6910 }, + { 707.7, 1.0647, 775.5226 }, + { 584.8, 3.9984, 191.4483 }, + { 769.3, 0.8163, 9437.7629 }, + { 499.9, 4.1234, 15720.8388 }, + { 326.2, 4.5906, 10404.7338 }, + { 429.5, 3.5864, 19367.1892 }, + { 327.0, 5.6774, 5507.5532 }, + { 231.9, 3.1625, 9153.9036 }, + { 179.7, 4.6534, 1109.3786 }, + { 128.3, 4.2260, 20.7754 }, + { 155.5, 5.5704, 19651.0485 }, + { 127.9, 0.9621, 5661.3320 }, + { 105.5, 1.5372, 801.8209 }, + { 85.7, 0.356, 3154.687 }, + { 99.1, 0.833, 213.299 }, + { 98.8, 5.394, 13367.973 }, + { 82.1, 3.216, 18837.498 }, + { 88.0, 3.889, 9999.986 }, + { 71.6, 0.111, 11015.106 }, + { 56.1, 4.240, 7.114 }, + { 70.2, 0.675, 23581.258 }, + { 50.8, 0.245, 11322.664 }, + { 46.1, 5.316, 18073.705 }, + { 44.6, 6.063, 40853.142 }, + { 42.6, 5.329, 2352.866 }, + { 42.6, 1.800, 7084.897 }, + { 41.2, 0.362, 382.897 }, + { 35.7, 2.704, 10206.172 }, + { 33.9, 2.023, 6283.076 }, + { 29.1, 3.592, 22003.915 }, + { 28.5, 2.224, 1059.382 }, + { 29.8, 4.022, 10239.584 }, + { 33.3, 2.100, 27511.468 }, + { 30.2, 4.942, 13745.346 }, + { 29.3, 3.514, 283.859 }, + { 26.3, 0.541, 17298.182 }, + /* 47 terms retained, 320 terms dropped, error 0.75" */ + + /* venus l, T^1 */ + { 1021352943052.9, 0, 0 }, + { 95707.7, 2.464244, 10213.285546 }, + { 14445.0, 0.516246, 20426.571092 }, + { 213.4, 1.7955, 30639.8566 }, + { 151.7, 6.1064, 1577.3435 }, + { 173.9, 2.6554, 26.2983 }, + { 82.2, 5.702, 191.448 }, + { 69.7, 2.681, 9437.763 }, + { 52.4, 3.600, 775.523 }, + { 38.3, 1.034, 529.691 }, + { 29.6, 1.251, 5507.553 }, + { 25.1, 6.107, 10404.734 }, + { 17.8, 6.194, 1109.379 }, + { 16.5, 2.643, 7.114 }, + { 14.2, 5.451, 9153.904 }, + { 12.6, 1.245, 40853.142 }, + { 11.6, 4.976, 213.299 }, + { 12.6, 1.881, 382.897 }, + { 8.9, 0.95, 13367.97 }, + { 7.4, 4.39, 10206.17 }, + { 6.6, 2.28, 2352.87 }, + { 6.3, 4.08, 3154.69 }, + { 6.7, 5.06, 801.82 }, + /* 23 terms retained, 192 terms dropped, error 0.14"*T */ + + /* venus l, T^2 */ + { 54127.1, 0, 0 }, + { 3891.5, 0.34514, 10213.28555 }, + { 1337.9, 2.02011, 20426.57109 }, + { 23.8, 2.046, 26.298 }, + { 19.3, 3.535, 30639.857 }, + { 10.0, 3.971, 775.523 }, + { 7.0, 1.52, 1577.34 }, + { 6.0, 1.00, 191.45 }, + { 3.2, 4.36, 9437.76 }, + { 2.1, 2.66, 40853.14 }, + { 1.9, 3.39, 382.90 }, + /* 11 terms retained, 59 terms dropped, error 0.028"*T^2 */ + + /* venus l, T^3 */ + { 135.7, 4.8039, 10213.2855 }, + { 77.8, 3.669, 20426.571 }, + { 26.0, 0, 0 }, + { 1.2, 5.32, 30639.86 }, + /* 4 terms retained, 5 terms dropped, error 0.011"*T^3 */ + + /* venus l, T^4 */ + { 114.0, 3.1416, 0 }, + { 3.2, 5.21, 20426.57 }, + { 1.7, 2.51, 10213.29 }, + /* 3 terms retained, 2 terms dropped, error 0.014"*T^4 */ + + /* venus l, T^5 */ + { 0.9, 3.14, 0 }, + { 0.1, 0.55, 20426.57 }, + { 0.1, 1.91, 10213.29 }, + /* 3 terms retained, 2 terms dropped, error 0.00097"*T^5 */ + /* end venus l */ + + /* venus b, T^0 */ + { 5923638.5, 0.26702776, 10213.28554621 }, + { 40108.0, 1.147372, 20426.571092 }, + { 32814.9, 3.141593, 0 }, + { 1011.4, 1.08946, 30639.85664 }, + { 149.5, 6.2539, 18073.7049 }, + { 137.8, 0.8602, 1577.3435 }, + { 130.0, 3.6715, 9437.7629 }, + { 119.5, 3.7047, 2352.8662 }, + { 108.0, 4.5390, 22003.9146 }, + { 92.0, 1.540, 9153.904 }, + { 53.0, 2.281, 5507.553 }, + { 45.6, 0.723, 10239.584 }, + { 38.9, 2.934, 10186.987 }, + { 43.5, 6.140, 11790.629 }, + { 41.7, 5.991, 19896.880 }, + { 39.6, 3.868, 8635.942 }, + { 39.2, 3.950, 529.691 }, + { 33.3, 4.832, 14143.495 }, + /* 18 terms retained, 192 terms dropped, error 0.6" */ + + /* venus b, T^1 */ + { 513347.6, 1.8036431, 10213.2855462 }, + { 4380.1, 3.38616, 20426.57109 }, + { 196.6, 2.5300, 30639.8566 }, + { 199.2, 0, 0 }, + { 14.0, 2.271, 9437.763 }, + { 13.0, 1.507, 18073.705 }, + { 11.9, 5.605, 1577.344 }, + { 10.3, 5.242, 2352.866 }, + { 9.3, 6.08, 22003.91 }, + { 7.4, 1.50, 11790.63 }, + { 8.0, 0.29, 9153.90 }, + { 7.5, 5.08, 10186.99 }, + /* 12 terms retained, 121 terms dropped, error 0.11"*T */ + + /* venus b, T^2 */ + { 22377.7, 3.385091, 10213.285546 }, + { 281.7, 0, 0 }, + { 173.2, 5.2556, 20426.5711 }, + { 26.9, 3.870, 30639.857 }, + /* 4 terms retained, 55 terms dropped, error 0.25"*T^2 */ + + /* venus b, T^3 */ + { 646.7, 4.9917, 10213.2855 }, + { 20.0, 3.142, 0 }, + { 5.5, 0.77, 20426.57 }, + { 2.5, 5.44, 30639.86 }, + /* 4 terms retained, 11 terms dropped, error 0.023"*T^3 */ + + /* venus b, T^4 */ + { 14.1, 0.315, 10213.286 }, + { 0.2, 2.35, 20426.57 }, + { 0.2, 0.74, 30639.86 }, + { 0.2, 3.14, 0 }, + /* 4 terms retained, 1 terms dropped, error 0.002"*T^4 */ + + /* venus b, T^5 */ + { 0.2, 2.05, 10213.29 }, + /* 1 terms retained, 3 terms dropped, error 0.0014"*T^5 */ + /* end venus b */ + + /* venus r, T^0 */ + { 72334820.9, 0, 0 }, + { 489824.2, 4.0215183, 10213.2855462 }, + { 1658.1, 4.90207, 20426.57109 }, + { 1632.1, 2.84549, 7860.41939 }, + { 1378.0, 1.12847, 11790.62909 }, + { 498.4, 2.5868, 9683.5946 }, + { 374.0, 1.4231, 3930.2097 }, + { 263.6, 5.5294, 9437.7629 }, + { 237.5, 2.5514, 15720.8388 }, + { 222.0, 2.0135, 19367.1892 }, + { 119.5, 3.0198, 10404.7338 }, + { 125.9, 2.7277, 1577.3435 }, + { 76.2, 1.596, 9153.904 }, + { 85.3, 3.986, 19651.048 }, + { 74.3, 4.120, 5507.553 }, + { 41.9, 1.643, 18837.498 }, + { 42.5, 3.819, 13367.973 }, + { 39.4, 5.390, 23581.258 }, + { 29.0, 5.677, 5661.332 }, + { 27.6, 5.724, 775.523 }, + { 27.3, 4.822, 11015.106 }, + { 31.3, 2.318, 9999.986 }, + /* 22 terms retained, 308 terms dropped, error 3e-06 a.u. */ + + /* venus r, T^1 */ + { 34551.0, 0.891987, 10213.285546 }, + { 234.2, 1.7722, 20426.5711 }, + { 234.0, 3.1416, 0 }, + { 23.9, 1.113, 9437.763 }, + { 10.6, 4.592, 1577.344 }, + { 9.1, 4.54, 10404.73 }, + { 6.6, 5.98, 5507.55 }, + /* 7 terms retained, 173 terms dropped, error 3.7e-07 a.u.*T */ + + /* venus r, T^2 */ + { 1406.6, 5.06366, 10213.28555 }, + { 15.5, 5.473, 20426.571 }, + { 13.1, 0, 0 }, + /* 3 terms retained, 60 terms dropped, error 5.2e-07 a.u.*T^2 */ + + /* venus r, T^3 */ + { 49.6, 3.223, 10213.286 }, + { 0.8, 3.21, 20426.57 }, + /* 2 terms retained, 5 terms dropped, error 2.9e-08 a.u.*T^3 */ + + /* venus r, T^4 */ + { 0.6, 0.92, 10213.29 }, + /* 1 terms retained, 2 terms dropped, error 1.6e-08 a.u.*T^4 */ + + /* venus r, T^5 */ + /* 0 terms retained, 2 terms dropped, error 9e-10 a.u.*T^5 */ + /* end venus */ +}; + +int vn_venus[][3] = { + /* addresses for venus l, b, r */ + /* T^0 */ { 0, 91, 134, }, + /* T^1 */ { 47, 109, 156, }, + /* T^2 */ { 70, 121, 163, }, + /* T^3 */ { 81, 125, 166, }, + /* T^4 */ { 85, 129, 168, }, + /* T^5 */ { 88, 133, 169, }, + /* end */ { 91, 134, 0, }, + /* termination */ { 0, } +}; + + +/* For RCS Only -- Do Not Edit */ +static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: vsop87_data.c,v $ $Date: 1997/05/19 18:21:42 $ $Revision: 1.1 $ $Name: $"}; diff --git a/Common/Servers/AntennaBoss/include/BossCore.h b/Common/Servers/AntennaBoss/include/BossCore.h index c109b4dd2..0c957beaa 100644 --- a/Common/Servers/AntennaBoss/include/BossCore.h +++ b/Common/Servers/AntennaBoss/include/BossCore.h @@ -21,6 +21,7 @@ #include <EphemGeneratorC.h> #include <SkySourceC.h> #include <MoonC.h> +#include <SolarSystemBodyC.h> #include <PointingModelC.h> #include <RefractionC.h> #include <OTFC.h> diff --git a/Common/Servers/AntennaBoss/src/BossCore.cpp b/Common/Servers/AntennaBoss/src/BossCore.cpp index cd3ab88c9..181718076 100644 --- a/Common/Servers/AntennaBoss/src/BossCore.cpp +++ b/Common/Servers/AntennaBoss/src/BossCore.cpp @@ -1551,7 +1551,7 @@ Antenna::EphemGenerator_ptr CBossCore::loadInternalGenerator(const Antenna::TGen ref=Antenna::EphemGenerator::_duplicate(m_satelliteGenerator); break; } - case Antenna::ANT_SOLARSYTEMBODY : { + case Antenna::ANT_SOLARSYSTEMBODY : { if (CORBA::is_nil(m_solarBodyGenerator)) { m_solarBodyGenerator=loadGenerator(type); // could throw exceptions } @@ -1605,7 +1605,7 @@ Antenna::EphemGenerator_ptr CBossCore::loadPrimaryGenerator(const Antenna::TGene ref=Antenna::EphemGenerator::_duplicate(m_primarySatelliteGenerator); break; } - case Antenna::ANT_SOLARSYTEMBODY : { + case Antenna::ANT_SOLARSYSTEMBODY : { if (CORBA::is_nil(m_primarySolarBodyGenerator)) { m_primarySolarBodyGenerator=loadGenerator(type); // could throw exceptions } @@ -1652,7 +1652,7 @@ Antenna::EphemGenerator_ptr CBossCore::loadGenerator(const Antenna::TGeneratorTy cSpec->component_type = CORBA::string_dup((const char*)m_config->getSatelliteInterface()); //IDL interface implemented by the component break; } - case Antenna::ANT_SOLARSYTEMBODY : { + case Antenna::ANT_SOLARSYSTEMBODY : { cSpec->component_type = CORBA::string_dup((const char*)m_config->getSolarSystemBodyInterface()); //IDL interface implemented by the component break; } diff --git a/Common/Servers/AntennaBoss/src/BossCore_prepareScan.i b/Common/Servers/AntennaBoss/src/BossCore_prepareScan.i index afa85a04a..9f6038ba1 100644 --- a/Common/Servers/AntennaBoss/src/BossCore_prepareScan.i +++ b/Common/Servers/AntennaBoss/src/BossCore_prepareScan.i @@ -269,6 +269,7 @@ Antenna::EphemGenerator_ptr CBossCore::prepareScan( } try { currentGenerator->setOffsets(lonOffTmp,latOffTmp,offFrameTmp); //could throw an AntennaErrorsEx exception + ACS_LOG(LM_FULL_INFO,"CBossCore::prepareScan()",(LM_DEBUG,"currentGenerator SET OFFSET")); } catch (CORBA::SystemException& ex) { _EXCPT(ComponentErrors::CORBAProblemExImpl,impl,"CBossCore::prepareScan()"); @@ -383,6 +384,8 @@ Antenna::EphemGenerator_ptr CBossCore::prepareScan( sourceName=IRA::CString(att->sourceID); currentGeneratorFlux=currentGenerator; // the flux computer is the moon generator itself...make a deep copy } + + catch (CORBA::SystemException& ex) { sourceName=IRA::CString("????"); ra=dec=0.0; // in that case I do not want to rise an error @@ -391,11 +394,95 @@ Antenna::EphemGenerator_ptr CBossCore::prepareScan( //velDef=Antenna::ANT_UNDEF_DEF; axis=Management::MNG_NO_AXIS; } + catch(AntennaErrors::AntennaErrorsEx& ex) { + _ADD_BACKTRACE(AntennaErrors::ScanErrorExImpl,impl,ex,"CBossCore::prepareScan()"); + impl.setReason("Unable to load the scan configuration into the generator"); + throw impl; + } + catch (ComponentErrors::ComponentErrorsEx& ex) { + _ADD_BACKTRACE(AntennaErrors::ScanErrorExImpl,impl,ex,"CBossCore::prepareScan()"); + impl.setReason("Unable to load the scan configuration into the generator"); + throw impl; + } + catch (...) { + _THROW_EXCPT(ComponentErrors::UnexpectedExImpl,"CBossCore::prepareScan()"); + } + + vrad=primary.RadialVelocity; velFrame=primary.VradFrame; velDef=primary.VradDefinition; timeToStop=0; } + else if (primary.type==Antenna::ANT_SUN || primary.type==Antenna::ANT_SOLARSYSTEMBODY ) { + // moon has nothing to do...no configuration + Antenna::SolarSystemBody_var tracker; + tracker=Antenna::SolarSystemBody::_narrow(currentGenerator); + try{ + + tracker->setBodyName(primary.targetName); // + + } catch(AntennaErrors::AntennaErrorsEx& ex) { + + _ADD_BACKTRACE(AntennaErrors::ScanErrorExImpl,impl,ex,"CBossCore::prepareScan()"); + impl.setReason("Unable to load the scan configuration into the generator"); + throw impl; + } + + //copy the current track and store it + copyTrack(lastPar,primary); + lastPar.applyOffsets=false; + lastPar.secondary=false; + if (primary.type==Antenna::ANT_SUN ) + { + ACS_LOG(LM_FULL_INFO,"CBossCore::prepareScan()",(LM_DEBUG,"SUN_TRACKING")); + } else + { + ACS_LOG(LM_FULL_INFO,"CBossCore::prepareScan()",(LM_DEBUG,"PLANET_TRACKING")); + + } + + try { + Antenna::SolarSystemBodyAttributes_var att; + tracker->getAttributes(att); + ACS_LOG(LM_FULL_INFO,"CBossCore::prepareScan()",(LM_DEBUG,"GOT ATTRIBUTES")) + ra=att->J2000RightAscension; + + dec=att->J2000Declination; + lon=att->gLongitude; + lat=att->gLatitude; + //vrad=0.0; + //velFrame=Antenna::ANT_UNDEF_FRAME; + //velDef=Antenna::ANT_UNDEF_DEF; + axis=att->axis; + sourceName=IRA::CString(att->sourceID); + currentGeneratorFlux=currentGenerator; // the flux computer is the moon generator itself...make a deep copy + } + catch(AntennaErrors::AntennaErrorsEx& ex) { + _ADD_BACKTRACE(AntennaErrors::ScanErrorExImpl,impl,ex,"CBossCore::prepareScan()"); + impl.setReason("Unable to load the scan configuration into the generator"); + throw impl; + } + catch (...) { + _THROW_EXCPT(ComponentErrors::UnexpectedExImpl,"CBossCore::prepareScan()"); + } + + //catch (CORBA::SystemException& ex) { + // sourceName=IRA::CString("????"); + // ra=dec=0.0; // in that case I do not want to rise an error + // //vrad=0.0; + // //velFrame=Antenna::ANT_UNDEF_FRAME; + // //velDef=Antenna::ANT_UNDEF_DEF; + // axis=Management::MNG_NO_AXIS; + // } + + vrad=primary.RadialVelocity; + velFrame=primary.VradFrame; + velDef=primary.VradDefinition; + timeToStop=0; + } + + else if (primary.type==Antenna::ANT_OTF) { ACS_LOG(LM_FULL_INFO,"CBossCore::prepareScan()",(LM_DEBUG,"OTF_SCANNING")); Antenna::OTF_var tracker; @@ -473,9 +560,15 @@ Antenna::EphemGenerator_ptr CBossCore::prepareScan( } else if (primary.type==Antenna::ANT_SATELLITE) { } - else if (primary.type==Antenna::ANT_SOLARSYTEMBODY) { + + + else if (primary.type==Antenna::ANT_SOLARSYSTEMBODY) { + + } else if (primary.type==Antenna::ANT_SUN) { + + // useless? } // if everything looks ok....return back the offsets..... /* @@ -486,6 +579,8 @@ Antenna::EphemGenerator_ptr CBossCore::prepareScan( return currentGenerator._retn(); } + + Antenna::EphemGenerator_ptr CBossCore::prepareOTFSecondary(const bool& useInternal,const Antenna::TTrackingParameters& sec,IRA::CString& sourceName,double& ra,double& dec,double& lon, double& lat,double& vrad,Antenna::TReferenceFrame& velFrame,Antenna::TVradDefinition& velDef,bool& result) { diff --git a/Common/Servers/AntennaBoss/src/Makefile b/Common/Servers/AntennaBoss/src/Makefile index ba00b1850..8e36f6f4b 100644 --- a/Common/Servers/AntennaBoss/src/Makefile +++ b/Common/Servers/AntennaBoss/src/Makefile @@ -66,7 +66,7 @@ AntennaBossImpl_OBJECTS = AntennaBossImpl BossCore Configuration \ WorkingThread WatchingThread Callback SlewCheck Offset AntennaBossImpl_LIBS = AntennaDefinitionsStubs AntennaBossStubs MountStubs ObservatoryStubs \ EphemGeneratorStubs ManagmentDefinitionsStubs IRALibrary ComponentErrors ManagementErrors \ - AntennaErrors ParserErrors PointingModelStubs RefractionStubs SkySourceStubs OTFStubs MoonStubs acsnc \ + AntennaErrors ParserErrors PointingModelStubs RefractionStubs SkySourceStubs OTFStubs MoonStubs SolarSystemBodyStubs acsnc \ DiscosVersion # diff --git a/Common/Servers/Moon/src/MoonImpl.cpp b/Common/Servers/Moon/src/MoonImpl.cpp index f3408e6ff..0d9c66e72 100644 --- a/Common/Servers/Moon/src/MoonImpl.cpp +++ b/Common/Servers/Moon/src/MoonImpl.cpp @@ -39,7 +39,7 @@ MoonImpl::~MoonImpl() // initialization void MoonImpl::initialize() throw(ACSErr::ACSbaseExImpl) { - AUTO_TRACE("moonImpl::initilize()"); + AUTO_TRACE("moonImpl::initialize()"); ra_off = dec_off = 0.0; az_off = el_off = 0.0; m_offsetFrame=Antenna::ANT_HORIZONTAL; diff --git a/Common/Servers/Scheduler/include/Core_Operations.h b/Common/Servers/Scheduler/include/Core_Operations.h index 65d169927..741433dbb 100644 --- a/Common/Servers/Scheduler/include/Core_Operations.h +++ b/Common/Servers/Scheduler/include/Core_Operations.h @@ -88,6 +88,24 @@ void _track(const char *targetName) throw (ManagementErrors::TelescopeSubScanErr void _moon() throw (ManagementErrors::TelescopeSubScanErrorExImpl,ManagementErrors::TargetOrSubscanNotFeasibleExImpl, ManagementErrors::CloseTelescopeScanErrorExImpl); +/** + * starts the tracking of the sun + */ +void _sun() throw (ManagementErrors::TelescopeSubScanErrorExImpl,ManagementErrors::TargetOrSubscanNotFeasibleExImpl, + ManagementErrors::CloseTelescopeScanErrorExImpl); + + +/** + * Starts a sidereal tracking of a source from equatorial coordinates + * @param planet of the source + * + */ + +void _planet(const char * planetName) throw (ManagementErrors::TelescopeSubScanErrorExImpl,ManagementErrors::TargetOrSubscanNotFeasibleExImpl, + ManagementErrors::CloseTelescopeScanErrorExImpl); + + + /** * Starts a sidereal tracking of a source from equatorial coordinates * @param targetName name of the source diff --git a/Common/Servers/Scheduler/include/Schedule.h b/Common/Servers/Scheduler/include/Schedule.h index aee7ce884..6aba618e9 100644 --- a/Common/Servers/Scheduler/include/Schedule.h +++ b/Common/Servers/Scheduler/include/Schedule.h @@ -64,6 +64,8 @@ public: void track(const char *targetName); void moon(); + void sun(); + void planet(const char * planetName); void sidereal(const char * targetName,const double& ra,const double& dec,const Antenna::TSystemEquinox& eq,const Antenna::TSections& section); void sidereal(const char * targetName,const Antenna::TCoordinateFrame& frame,double *parameters,const long& paramNumber, const Antenna::TSystemEquinox& eq); @@ -543,6 +545,16 @@ private: bool parseSidereal2(const IRA::CString& val,DWORD& id,IRA::CString& errMsg,CSubScanBinder& binder); + /** + * Parse the list of parameters for moon tracking + * @param val line to parse + * @param otf structure containing the ORF parameters + * @param id numeral identifier of the scan + * @param errMsg error specification string in case of unsuccessful operation + * @return the result of the parse + */ + bool parseSun(const IRA::CString& val,Antenna::TTrackingParameters *scan,DWORD& id,IRA::CString& errMsg); + /** * Parse the list of parameters for moon tracking * @param val line to parse @@ -552,6 +564,17 @@ private: * @return the result of the parse */ bool parseMoon(const IRA::CString& val,Antenna::TTrackingParameters *scan,DWORD& id,IRA::CString& errMsg); + + /** + * Parse the list of parameters for moon tracking + * @param val line to parse + * @param otf structure containing the ORF parameters + * @param id numeral identifier of the scan + * @param errMsg error specification string in case of unsuccessful operation + * @return the result of the parse + */ + bool parsePlanet(const IRA::CString& val,Antenna::TTrackingParameters *scan,DWORD& id,IRA::CString& errMsg); + /** * Parse the vRAD switch in order to configure a radial velocity diff --git a/Common/Servers/Scheduler/include/SchedulerImpl.h b/Common/Servers/Scheduler/include/SchedulerImpl.h index d39a3f33e..1fed74cff 100644 --- a/Common/Servers/Scheduler/include/SchedulerImpl.h +++ b/Common/Servers/Scheduler/include/SchedulerImpl.h @@ -398,6 +398,31 @@ public: */ virtual void moon() throw (ComponentErrors::ComponentErrorsEx,ManagementErrors::ManagementErrorsEx,CORBA::SystemException); + /** + * It allows to immediately start a tracking of the sun. + * @throw CORBA::SystemExcpetion + * @throw ComponentErrors::ComponentErrorsEx + * @throw ManagementErrors::ManagementErrorsEx + */ + virtual void sun() throw (ComponentErrors::ComponentErrorsEx,ManagementErrors::ManagementErrorsEx,CORBA::SystemException); + + + /** + * It allows to immediately start a tracking of a sidereal source, given its equatorial coordinates + * @param name or identifier of the planed + * @throw CORBA::SystemExcpetion + * @throw ComponentErrors::ComponentErrorsEx + * @throw ManagementErrors::ManagementErrorsEx + */ + + + + + + + virtual void planet(const char * name) throw (ComponentErrors::ComponentErrorsEx,ManagementErrors::ManagementErrorsEx,CORBA::SystemException); + + /** * It allows to immediately start a tracking of a sidereal source, given its equatorial coordinates * @param targetName name or identifier of the source diff --git a/Common/Servers/Scheduler/src/Core.cpp b/Common/Servers/Scheduler/src/Core.cpp index a92646ba1..6ea312b86 100644 --- a/Common/Servers/Scheduler/src/Core.cpp +++ b/Common/Servers/Scheduler/src/Core.cpp @@ -150,6 +150,8 @@ void CCore::execute() throw(ComponentErrors::TimerErrorExImpl, ComponentErrors:: m_parser->add("latOTF", new function3<CCore, non_constant, void_type, I<enum_type<AntennaFrame2String, Antenna::TCoordinateFrame> >, I<angleOffset_type<rad> >, I<interval_type> >(this, &CCore::_latOTF), 3); m_parser->add("skydipOTF", new function3<CCore, non_constant, void_type, I<elevation_type<rad, false> >, I<elevation_type<rad, false> >, I<interval_type> >(this, &CCore::_skydipOTF), 3); m_parser->add("moon", new function0<CCore, non_constant, void_type>(this, &CCore::_moon), 0); + m_parser->add("sun", new function0<CCore, non_constant, void_type>(this, &CCore::_sun), 0); + m_parser->add("planet", new function1<CCore, non_constant, void_type,I<string_type> > (this, &CCore::_planet), 1); m_parser->add("sidereal", new function5<CCore, non_constant, void_type, I<string_type>, I<rightAscension_type<rad, true> >, I<declination_type<rad, true> >, I<enum_type<AntennaEquinox2String, Antenna::TSystemEquinox> >, I<enum_type<AntennaSection2String, Antenna::TSections> > >(this, &CCore::_sidereal), 5); m_parser->add("track", new function1<CCore, non_constant, void_type, I<string_type> >(this, &CCore::_track), 1); m_parser->add("goTo", new function2<CCore, non_constant, void_type, I<azimuth_type<rad, false> >, I<elevation_type<rad, false> > >(this, &CCore::_goTo), 2); diff --git a/Common/Servers/Scheduler/src/Core_Common.i b/Common/Servers/Scheduler/src/Core_Common.i index 66f3a740e..a69488c9c 100644 --- a/Common/Servers/Scheduler/src/Core_Common.i +++ b/Common/Servers/Scheduler/src/Core_Common.i @@ -36,6 +36,7 @@ bool CCore::checkScan(ACS::Time& ut,const Antenna::TTrackingParameters *const pr try { //antennaUT will stores the estimated start time from the antenna for all kind of subscans antennaAnswer=m_antennaBoss->checkScan(ut,*prim,*sec,minEl,maxEl,m_antennaRTime.out()); + ACS_LOG(LM_FULL_INFO,"CCore::checkScan()",(LM_DEBUG,"MIN EL %f :",(float)minEl)); ACS_LOG(LM_FULL_INFO,"CCore::checkScan()",(LM_DEBUG,"SLEWING_TIME %llu :",(unsigned long long)m_antennaRTime->slewingTime)); } catch (ComponentErrors::ComponentErrorsEx& ex) { diff --git a/Common/Servers/Scheduler/src/Core_Operations.i b/Common/Servers/Scheduler/src/Core_Operations.i index b693b3a1b..0368e1b6b 100644 --- a/Common/Servers/Scheduler/src/Core_Operations.i +++ b/Common/Servers/Scheduler/src/Core_Operations.i @@ -184,6 +184,42 @@ void CCore::_moon() throw (ManagementErrors::TelescopeSubScanErrorExImpl,Managem m_subScanEpoch=startTime; } +void CCore::_sun() throw (ManagementErrors::TelescopeSubScanErrorExImpl,ManagementErrors::TargetOrSubscanNotFeasibleExImpl, + ManagementErrors::CloseTelescopeScanErrorExImpl) +{ + baci::ThreadSyncGuard guard(&m_mutex); + ACS::Time startTime=0; // start asap + Antenna::TTrackingParameters primary,secondary; + MinorServo::MinorServoScan servo; + Receivers::TReceiversParameters receievers; + Management::TSubScanConfiguration subConf; + Schedule::CSubScanBinder binder(&primary,&secondary,&servo,&receievers,&subConf); + binder.sun(); + startTime=0; // it means start as soon as possible + startScan(startTime,&primary,&secondary,&servo,&receievers,subConf); //ManagementErrors::TelescopeSubScanErrorExImpl,ManagementErrors::TargetOrSubscanNotFeasibleExImpl + m_subScanEpoch=startTime; +} +void CCore::_planet(const char * planetName) throw (ManagementErrors::TelescopeSubScanErrorExImpl,ManagementErrors::TargetOrSubscanNotFeasibleExImpl, + ManagementErrors::CloseTelescopeScanErrorExImpl) +{ + baci::ThreadSyncGuard guard(&m_mutex); + ACS::Time startTime=0; // start asap + Antenna::TTrackingParameters primary,secondary; + MinorServo::MinorServoScan servo; + Receivers::TReceiversParameters receievers; + Management::TSubScanConfiguration subConf; + Schedule::CSubScanBinder binder(&primary,&secondary,&servo,&receievers,&subConf); + binder.planet(planetName); + startTime=0; // it means start as soon as possible + # + startScan(startTime,&primary,&secondary,&servo,&receievers,subConf); //ManagementErrors::TelescopeSubScanErrorExImpl,ManagementErrors::TargetOrSubscanNotFeasibleExImpl + + m_subScanEpoch=startTime; +} + + + + void CCore::_sidereal(const char * targetName,const double& ra,const double& dec,const Antenna::TSystemEquinox& eq,const Antenna::TSections& section) throw ( ManagementErrors::TelescopeSubScanErrorExImpl,ManagementErrors::TargetOrSubscanNotFeasibleExImpl,ManagementErrors::CloseTelescopeScanErrorExImpl) { diff --git a/Common/Servers/Scheduler/src/Schedule_ScanList.cpp b/Common/Servers/Scheduler/src/Schedule_ScanList.cpp index e9fe48bc9..c03b2c1b0 100644 --- a/Common/Servers/Scheduler/src/Schedule_ScanList.cpp +++ b/Common/Servers/Scheduler/src/Schedule_ScanList.cpp @@ -13,6 +13,7 @@ #define SUN "SUN" #define MOON "MOON" #define SATELLITE "SATELLITE" +#define PLANET "PLANET" #define SOLARSYTEMBODY "SOLARSYTEMBODY" #define OTF "OTF" #define OTFC "OTFC" @@ -198,6 +199,30 @@ bool CScanList::parseLine(const IRA::CString& line,const DWORD& lnNumber,IRA::CS break; } case Management::MNG_SUN: { + DWORD id; + Antenna::TTrackingParameters *prim=new Antenna::TTrackingParameters; + if (!parseSun(line,prim,id,errMsg)) { + if (prim) delete prim; + return false; // errMsg already set by previous call + } + Antenna::TTrackingParameters *sec=new Antenna::TTrackingParameters; + resetTrackingParameters(sec); + TRecord *rec=new TRecord; + rec->id=id; + rec->type=type; + rec->primaryParameters=(void *)prim; + rec->secondaryParameters=(void *)sec; + // ************************************** + // Da modificare come MNG_PEAKER + CSubScanBinder binder(getConfiguration(),false); + rec->receieversParsmeters=(void *)binder.getReceivers(); + rec->servoParameters=(void *)binder.getServo(); + rec->subScanConfiguration=binder.getSubScanConfiguration(); + // ************************************** + + //rec->target=""; + rec->line=lnNumber; + m_schedule.push_back(rec); break; } case Management::MNG_MOON: { @@ -275,7 +300,34 @@ bool CScanList::parseLine(const IRA::CString& line,const DWORD& lnNumber,IRA::CS case Management::MNG_SATELLITE: { break; } - case Management::MNG_SOLARSYTEMBODY: { + case Management::MNG_PLANET: { + + DWORD id; + Antenna::TTrackingParameters *prim=new Antenna::TTrackingParameters; + if (!parsePlanet(line,prim,id,errMsg)) { + if (prim) delete prim; + return false; // errMsg already set by previous call + } + Antenna::TTrackingParameters *sec=new Antenna::TTrackingParameters; + resetTrackingParameters(sec); + TRecord *rec=new TRecord; + rec->id=id; + rec->type=type; + rec->primaryParameters=(void *)prim; + rec->secondaryParameters=(void *)sec; + // ************************************** + // Da modificare come MNG_PEAKER + CSubScanBinder binder(getConfiguration(),false); + rec->receieversParsmeters=(void *)binder.getReceivers(); + rec->servoParameters=(void *)binder.getServo(); + rec->subScanConfiguration=binder.getSubScanConfiguration(); + // ************************************** + + //rec->target=""; + rec->line=lnNumber; + m_schedule.push_back(rec); + break; + break; } case Management::MNG_OTF: { @@ -379,6 +431,147 @@ bool CScanList::parseMoon(const IRA::CString& val,Antenna::TTrackingParameters * return true; } +bool CScanList::parseSun(const IRA::CString& val,Antenna::TTrackingParameters *scan,DWORD& id,IRA::CString& errMsg) +{ + char type[32],offFrame[32],lonOff[32],latOff[32]; + long out; + //double lonOff,latOff; + out=sscanf((const char *)val,"%u\t%s\t%s\t%s\t%s",&id,type,offFrame,lonOff,latOff); + if ((out!=2) && (out!=5)) { + errMsg="invalid sun scan definition"; + return false; + } + scan->targetName=CORBA::string_dup("Sun"); + scan->type=Antenna::ANT_SUN; + scan->paramNumber=0; + scan->secondary=false; + scan->VradFrame=Antenna::ANT_UNDEF_FRAME; + scan->VradDefinition=Antenna::ANT_UNDEF_DEF; + scan->RadialVelocity=0.0; + scan->section=Antenna::ACU_NEUTRAL; // no support for section selection in schedule right now + scan->enableCorrection=true; + if (out==5) { + if (strcmp(offFrame,OFFFRAMEEQ)==0) { + scan->offsetFrame=Antenna::ANT_EQUATORIAL; + if (!IRA::CIRATools::offsetToRad(lonOff,scan->longitudeOffset)) { + errMsg="invalid equatorial longitude offset"; + return false; //ra + } + if (!IRA::CIRATools::offsetToRad(latOff,scan->latitudeOffset)) { + errMsg="invalid equatorial latitude offset"; + return false; //dec + } + } + else if (strcmp(offFrame,OFFFRAMEHOR)==0) { + scan->offsetFrame=Antenna::ANT_HORIZONTAL; + if (!IRA::CIRATools::offsetToRad(lonOff,scan->longitudeOffset)) { + errMsg="invalid horizontal longitude offset"; + return false; //azimuth...since they are offsets negative values are valid + } + if (!IRA::CIRATools::offsetToRad(latOff,scan->latitudeOffset)) { + errMsg="invalid horizontal latitude offset"; + return false; //elevation + } + } + else if (strcmp(offFrame,OFFFRAMEGAL)==0) { + scan->offsetFrame=Antenna::ANT_GALACTIC; + if (!IRA::CIRATools::offsetToRad(lonOff,scan->longitudeOffset)) { + errMsg="invalid galactic longitude offset"; + return false; //longitude + } + if (!IRA::CIRATools::offsetToRad(latOff,scan->latitudeOffset)) { + errMsg="invalid galactic latitude offset"; + return false; //latitude + } + } + else { + return false; + } + scan->applyOffsets=true; + } + else { + scan->latitudeOffset=0.0; + scan->longitudeOffset=0.0; + scan->applyOffsets=false; + } + return true; +} + +bool CScanList::parsePlanet(const IRA::CString& val,Antenna::TTrackingParameters *scan,DWORD& id,IRA::CString& errMsg) +{ + char type[32],offFrame[32],lonOff[32],latOff[32],planetName[32]; + long out; + //double lonOff,latOff; + out=sscanf((const char *)val,"%u\t%s\t%s\t%s\t%s\t%s",&id,type,planetName,offFrame,lonOff,latOff); + if ((out!=3) && (out!=6)) { + errMsg="invalid planet scan definition"; + return false; + } + scan->targetName=CORBA::string_dup(planetName); + scan->type=Antenna::ANT_SOLARSYSTEMBODY; + scan->paramNumber=0; + scan->secondary=false; + scan->VradFrame=Antenna::ANT_UNDEF_FRAME; + scan->VradDefinition=Antenna::ANT_UNDEF_DEF; + scan->RadialVelocity=0.0; + scan->section=Antenna::ACU_NEUTRAL; // no support for section selection in schedule right now + scan->enableCorrection=true; + if (out==6) { + + if (strcmp(offFrame,OFFFRAMEEQ)==0) { + scan->offsetFrame=Antenna::ANT_EQUATORIAL; + if (!IRA::CIRATools::offsetToRad(lonOff,scan->longitudeOffset)) { + errMsg="invalid equatorial longitude offset"; + return false; //ra + } + if (!IRA::CIRATools::offsetToRad(latOff,scan->latitudeOffset)) { + errMsg="invalid equatorial latitude offset"; + return false; //dec + } + } + else if (strcmp(offFrame,OFFFRAMEHOR)==0) { + scan->offsetFrame=Antenna::ANT_HORIZONTAL; + if (!IRA::CIRATools::offsetToRad(lonOff,scan->longitudeOffset)) { + errMsg="invalid horizontal longitude offset"; + return false; //azimuth...since they are offsets negative values are valid + } + if (!IRA::CIRATools::offsetToRad(latOff,scan->latitudeOffset)) { + errMsg="invalid horizontal latitude offset"; + return false; //elevation + } + } + else if (strcmp(offFrame,OFFFRAMEGAL)==0) { + scan->offsetFrame=Antenna::ANT_GALACTIC; + if (!IRA::CIRATools::offsetToRad(lonOff,scan->longitudeOffset)) { + errMsg="invalid galactic longitude offset"; + return false; //longitude + } + if (!IRA::CIRATools::offsetToRad(latOff,scan->latitudeOffset)) { + errMsg="invalid galactic latitude offset"; + return false; //latitude + } + } + else { + return false; + } + scan->applyOffsets=true; + } + else { + scan->latitudeOffset=0.0; + scan->longitudeOffset=0.0; + scan->applyOffsets=false; + } + return true; +} + + + + + + + + + // void CSubScanBinder::sidereal(const char * targetName,const double& ra,const double& dec,const Antenna::TSystemEquinox& eq,const Antenna::TSections& section) bool CScanList::parseSidereal2(const IRA::CString& val,DWORD& id,IRA::CString& errMsg,CSubScanBinder& binder) diff --git a/Common/Servers/Scheduler/src/SchedulerImpl.cpp b/Common/Servers/Scheduler/src/SchedulerImpl.cpp index 510057e46..ef6ba3cd6 100644 --- a/Common/Servers/Scheduler/src/SchedulerImpl.cpp +++ b/Common/Servers/Scheduler/src/SchedulerImpl.cpp @@ -476,6 +476,41 @@ void SchedulerImpl::moon() throw (ComponentErrors::ComponentErrorsEx,ManagementE } } +void SchedulerImpl::sun() throw (ComponentErrors::ComponentErrorsEx,ManagementErrors::ManagementErrorsEx,CORBA::SystemException) +{ + try { + m_core->_sun(); + } + catch (ComponentErrors::ComponentErrorsExImpl& ex) { + ex.log(LM_DEBUG); + throw ex.getComponentErrorsEx(); + } + catch (ManagementErrors::ManagementErrorsExImpl& ex) { + ex.log(LM_DEBUG); + throw ex.getManagementErrorsEx(); + } +} + +void SchedulerImpl::planet(const char * name) throw ( + ComponentErrors::ComponentErrorsEx,ManagementErrors::ManagementErrorsEx,CORBA::SystemException) +{ + + try { + m_core->_planet(name); + } + catch (ComponentErrors::ComponentErrorsExImpl& ex) { + ex.log(LM_DEBUG); + throw ex.getComponentErrorsEx(); + } + catch (ManagementErrors::ManagementErrorsExImpl& ex) { + ex.log(LM_DEBUG); + throw ex.getManagementErrorsEx(); + } + + +} + + void SchedulerImpl::sidereal(const char * targetName,CORBA::Double ra,CORBA::Double dec,Antenna::TSystemEquinox eq,Antenna::TSections section) throw ( ComponentErrors::ComponentErrorsEx,ManagementErrors::ManagementErrorsEx,CORBA::SystemException) { diff --git a/Common/Servers/Scheduler/src/SubScanBinder.cpp b/Common/Servers/Scheduler/src/SubScanBinder.cpp index 0e9e7c1a2..c5bab1e27 100644 --- a/Common/Servers/Scheduler/src/SubScanBinder.cpp +++ b/Common/Servers/Scheduler/src/SubScanBinder.cpp @@ -326,6 +326,48 @@ void CSubScanBinder::moon() // The other subsystems can stay with defaults } +void CSubScanBinder::sun() +{ + m_secondary->type=Antenna::ANT_NONE; + m_secondary->secondary=false; + m_secondary->applyOffsets=false; + m_secondary->paramNumber=0; + m_secondary->enableCorrection=true; + m_primary->type=Antenna::ANT_SUN; + m_primary->secondary=false; + m_primary->targetName=CORBA::string_dup("Sun"); + m_primary->applyOffsets=false; + m_primary->section=Antenna::ACU_NEUTRAL; + m_primary->enableCorrection=true; + m_servo->is_empty_scan=true; + m_servo->axis_code=CORBA::string_dup(""); + m_servo->range=0; + m_servo->total_time=0; + m_subScanConf->signal=Management::MNG_SIGNAL_SIGNAL; + // The other subsystems can stay with defaults +} + +void CSubScanBinder::planet(const char * planetName) +{ + m_secondary->type=Antenna::ANT_NONE; + m_secondary->secondary=false; + m_secondary->applyOffsets=false; + m_secondary->paramNumber=0; + m_secondary->enableCorrection=true; + m_primary->type=Antenna::ANT_SOLARSYSTEMBODY; + m_primary->secondary=false; + m_primary->targetName=CORBA::string_dup(planetName); + m_primary->applyOffsets=false; + m_primary->section=Antenna::ACU_NEUTRAL; + m_primary->enableCorrection=true; + m_servo->is_empty_scan=true; + m_servo->axis_code=CORBA::string_dup(""); + m_servo->range=0; + m_servo->total_time=0; + m_subScanConf->signal=Management::MNG_SIGNAL_SIGNAL; + // The other subsystems can stay with defaults +} + void CSubScanBinder::track(const char *targetName) { m_secondary->type=Antenna::ANT_NONE; diff --git a/Common/Servers/Scheduler/templates/MapJupiter1x1.bck b/Common/Servers/Scheduler/templates/MapJupiter1x1.bck new file mode 100644 index 000000000..bda5d9ea0 --- /dev/null +++ b/Common/Servers/Scheduler/templates/MapJupiter1x1.bck @@ -0,0 +1,2 @@ +STD:BACKENDS/TotalPower { +} diff --git a/Common/Servers/Scheduler/templates/MapJupiter1x1.cfg b/Common/Servers/Scheduler/templates/MapJupiter1x1.cfg new file mode 100644 index 000000000..9b46e6dbf --- /dev/null +++ b/Common/Servers/Scheduler/templates/MapJupiter1x1.cfg @@ -0,0 +1,13 @@ +INIT { + nop +} + +PRE { + waitOnsource + tsys + wait=5.000 +} + +POST { + wait=2.000 +} diff --git a/Common/Servers/Scheduler/templates/MapJupiter1x1.lis b/Common/Servers/Scheduler/templates/MapJupiter1x1.lis new file mode 100644 index 000000000..8b5309358 --- /dev/null +++ b/Common/Servers/Scheduler/templates/MapJupiter1x1.lis @@ -0,0 +1,208 @@ +#OTF columns labels +#ID type label Lon1 Lat1 Lon2 Lat2 frame sFrame geometry descr direction duration offsetFrame LonOffset LatOffset +1 PLANET JUPITER +2 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.493056d +3 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.479167d +4 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.465278d +5 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.451389d +6 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.437500d +7 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.423611d +8 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.409722d +9 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.395833d +10 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.381944d +11 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.368056d +12 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.354167d +13 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.340278d +14 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.326389d +15 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.312500d +16 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.298611d +17 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.284722d +18 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.270833d +19 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.256944d +20 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.243056d +21 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.229167d +22 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.215278d +23 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.201389d +24 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.187500d +25 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.173611d +26 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.159722d +27 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.145833d +28 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.131944d +29 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.118056d +30 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.104167d +31 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.0902778d +32 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.0763889d +33 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.0625000d +34 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.0486111d +35 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.0347222d +36 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d -0.0208333d +37 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d -0.00694444 +38 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.00694444d +39 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.0208333d +40 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.0347222d +41 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.0486111d +42 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.0625000d +43 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.0763889d +44 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.0902778d +45 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.104167d +46 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.118056d +47 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.131944d +48 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.145833d +49 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.159722d +50 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.173611d +51 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.187500d +52 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.201389d +53 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.215278d +54 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.229167d +55 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.243056d +56 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.256944d +57 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.270833d +58 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.284722d +59 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.298611d +60 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.312500d +61 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.326389d +62 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.340278d +63 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.354167d +64 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.368056d +65 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.381944d +66 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.395833d +67 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.409722d +68 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.423611d +69 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.437500d +70 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.451389d +71 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.465278d +72 OTFC 1 1.0d EQ EQ LAT INC 20.0 -EQOFFS 0.00000d 0.479167d +73 OTFC 1 1.0d EQ EQ LAT DEC 20.0 -EQOFFS 0.00000d 0.493056d + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Common/Servers/Scheduler/templates/MapJupiter1x1.scd b/Common/Servers/Scheduler/templates/MapJupiter1x1.scd new file mode 100644 index 000000000..6a4fe0133 --- /dev/null +++ b/Common/Servers/Scheduler/templates/MapJupiter1x1.scd @@ -0,0 +1,85 @@ +PROJECT: S0000 +OBSERVER: ssss +SCANLIST: MapJupiter1x1.lis +PROCEDURELIST: MapJupiter1x1.cfg +BACKENDLIST: MapJupiter1x1.bck +MODE: SEQ +SCANTAG: 1 +INITPROC: INIT +#1x1 map done in equatorial frame over JUPITER. +#scan scanTag label backend scanLayout +#subScanTag duration IDSubScan preSubScan postSubScan +SC: 1 VirA7GHz_Map_bis STD:MANAGEMENT/FitsZilla +1_1 20.000000 2 NULL POST +1_2 20.000000 3 NULL POST +1_3 20.000000 4 NULL POST +1_4 20.000000 5 NULL POST +1_5 20.000000 6 NULL POST +1_6 20.000000 7 NULL POST +1_7 20.000000 8 NULL POST +1_8 20.000000 9 NULL POST +1_9 20.000000 10 NULL POST +1_10 20.000000 11 NULL POST +1_11 20.000000 12 NULL POST +1_12 20.000000 13 NULL POST +1_13 20.000000 14 NULL POST +1_14 20.000000 15 NULL POST +1_15 20.000000 16 NULL POST +1_16 20.000000 17 NULL POST +1_17 20.000000 18 NULL POST +1_18 20.000000 19 NULL POST +1_19 20.000000 20 NULL POST +1_20 20.000000 21 NULL POST +1_21 20.000000 22 NULL POST +1_22 20.000000 23 NULL POST +1_23 20.000000 24 NULL POST +1_24 20.000000 25 NULL POST +1_25 20.000000 26 NULL POST +1_26 20.000000 27 NULL POST +1_27 20.000000 28 NULL POST +1_28 20.000000 29 NULL POST +1_29 20.000000 30 NULL POST +1_30 20.000000 31 NULL POST +1_31 20.000000 32 NULL POST +1_32 20.000000 33 NULL POST +1_33 20.000000 34 NULL POST +1_34 20.000000 35 NULL POST +1_35 20.000000 36 NULL POST +1_36 20.000000 37 NULL POST +1_37 20.000000 38 NULL POST +1_38 20.000000 39 NULL POST +1_39 20.000000 40 NULL POST +1_40 20.000000 41 NULL POST +1_41 20.000000 42 NULL POST +1_42 20.000000 43 NULL POST +1_43 20.000000 44 NULL POST +1_44 20.000000 45 NULL POST +1_45 20.000000 46 NULL POST +1_46 20.000000 47 NULL POST +1_47 20.000000 48 NULL POST +1_48 20.000000 49 NULL POST +1_49 20.000000 50 NULL POST +1_50 20.000000 51 NULL POST +1_51 20.000000 52 NULL POST +1_52 20.000000 53 NULL POST +1_53 20.000000 54 NULL POST +1_54 20.000000 55 NULL POST +1_55 20.000000 56 NULL POST +1_56 20.000000 57 NULL POST +1_57 20.000000 58 NULL POST +1_58 20.000000 59 NULL POST +1_59 20.000000 60 NULL POST +1_60 20.000000 61 NULL POST +1_61 20.000000 62 NULL POST +1_62 20.000000 63 NULL POST +1_63 20.000000 64 NULL POST +1_64 20.000000 65 NULL POST +1_65 20.000000 66 NULL POST +1_66 20.000000 67 NULL POST +1_67 20.000000 68 NULL POST +1_68 20.000000 69 NULL POST +1_69 20.000000 70 NULL POST +1_70 20.000000 71 NULL POST +1_71 20.000000 72 NULL POST +1_72 20.000000 73 NULL POST + diff --git a/Common/Servers/Scheduler/templates/calib.lis b/Common/Servers/Scheduler/templates/calib.lis index 1fd87c845..e280a61e1 100644 --- a/Common/Servers/Scheduler/templates/calib.lis +++ b/Common/Servers/Scheduler/templates/calib.lis @@ -1,4 +1,4 @@ -10 SIDEREAL 3c123 +10 PLNET JUPIrER 11 SIDEREAL 3c123 -HOROFFS 1.0d 0.0d 20 SIDEREAL 3c286 21 SIDEREAL 3c286 -HOROFFS 1.0d 0.0d diff --git a/Common/Servers/SolarSystem/ChangeLog b/Common/Servers/SolarSystem/ChangeLog new file mode 100644 index 000000000..a6bf091b5 --- /dev/null +++ b/Common/Servers/SolarSystem/ChangeLog @@ -0,0 +1 @@ +"@(#) $Id$" diff --git a/Common/Servers/SolarSystem/include/SolarSystemBodyImpl.h b/Common/Servers/SolarSystem/include/SolarSystemBodyImpl.h new file mode 100644 index 000000000..60187d4bd --- /dev/null +++ b/Common/Servers/SolarSystem/include/SolarSystemBodyImpl.h @@ -0,0 +1,222 @@ +#ifndef SOLSYSBODYIMPL_H_ +#define SOLSYSBODYIMPL_H_ +/** +* This code is under GNU General Public Licence (GPL) +* +* Sergio Poppi 09/05/2017 creation +* +* +*/ + +/** + * @mainpage Solar System bodies tracking component implementation documentation + * @date 09/05/2017 + * @version 1.02.0 + * @author <a. href=mailto:sergio.poppi@inaf.it>Sergio Poppi </a> + * @remarks + + */ + +#ifndef __cplusplus +#error This is a C++ include file and cannot be used from plain C +#endif + + +#include <baci.h> +#include "SolarSystemBodyS.h" +#include <String.h> +#include <Site.h> +#include <SkySource.h> + +#include <IRA> +#include <ComponentErrors.h> +#include <AntennaErrors.h> +#include <acscomponentImpl.h> + +#include <EphemGeneratorS.h> +#include <AntennaDefinitionsS.h> +#include <map> +#include <cctype> + +// If THROUGH_GET is true get the exception by an exImpl method +#define THROW_EX(TYPE, NAME, MESSAGE, THROUGH_GET) \ +{ \ + string msg(MESSAGE); \ + ACS_SHORT_LOG((LM_ERROR, msg.c_str())); \ + TYPE::NAME##Impl exImpl(__FILE__, __LINE__, msg.c_str()); \ + if(THROUGH_GET) \ + throw exImpl.get##NAME(); \ + else \ + throw exImpl; \ +} + +#include "libastrowrapper.h" + + +class SolarSystemBodyImpl: public virtual acscomponent::ACSComponentImpl,public virtual POA_Antenna::SolarSystemBody + +{ +public: + + SolarSystemBodyImpl(const ACE_CString &CompName,maci::ContainerServices *containerServices); + + virtual ~SolarSystemBodyImpl(); + /** + * Called to give the component time to initialize itself. The component reads into + configuration files/parameters, builds up connection. + * Called before execute. It is implimented as a synchronous (blocking) call. + */ + + virtual void initialize() throw (ACSErr::ACSbaseExImpl); + /* + * Called after <i>initialize()</i> to tell the component that it has to be ready to + accept incoming function calls at any time. + * Must be implemented as a synchronous (blocking) call. + * In this class the default implementation only logs the COMPSTATE_OPERTIONAL + */ + virtual void execute() throw (ACSErr::ACSbaseExImpl); + + + /** + * Called by the container before destroying the server in a normal situation. This function takes charge of releasing all resources. + */ + virtual void cleanUp(); + + + /* + * Called by the container in the case of error or emergency situation. This function tries to free all the resources even though + * there is no warrenty that the function is completly executed before the component is destroyed + * */ + virtual void aboutToAbort(); + /* + * This method is used to retrive all the attribute of the component in one shot. + * @throw CORBA::SystemException + * @param att that's the pointer to the structure containing all the data. + */ + void getAttributes(Antenna::SolarSystemBodyAttributes_out att) throw (CORBA::SystemException); + + + void setBodyName(const char* bodyName) throw (CORBA::SystemException,AntennaErrors::AntennaErrorsEx) ; + + /* + * This method is used to apply new offsets to a givrn frame. Longitude is corrected for latitude cosine before use. + * @throw CORBA::SystemException + * @throw AntennaErrors::AntennaErrorsEx + * @param longitude new offset for the longitude in radians. + * @param latitude new offset for the latitude in radians. + * @param frame frame the offstes refer to, galactic frame not supported and an error is thrown. + */ + void setOffsets(CORBA::Double lon,CORBA::Double lat,Antenna::TCoordinateFrame frame) throw (CORBA::SystemException,AntennaErrors::AntennaErrorsEx); + + /* + * It used, given a timestamp, to retrive the apparent topocentric coordinates in one shot. + * @throw CORBA::SystemException + * @param time this parameter is used to pass the exact time the caller wants to know the topocentric coordinates. + * @param az that's the returned value in radians of the azimuth for the requested time. + * @param az that's the returned value in radians of the elevation for the requested time. + */ + void getHorizontalCoordinate(ACS::Time time, CORBA::Double_out az, CORBA::Double_out el) throw (CORBA::SystemException); + + /** + * This method is only for control software internal use. It used, given a timestamp, to retrive the apparent + * J2000 Equatorial coordiantes coordinates in one shot. + * @throw CORBA::SystemException + * @param timestamp this parameter is used to pass the exact time the caller wants to know the topocentric coordinates. + * @param ra that's the returned value in radians of the right ascension for the requested time. + * @param re that's the returned value in radians of the declination for the requested time. + */ + void getJ2000EquatorialCoordinate(ACS::Time time, CORBA::Double_out ra, CORBA::Double_out dec) throw (CORBA::SystemException); + + + + /** + * It used, given a timestamp, to retrieve the all apparent coordinates in all frames in one shot. + * @throw CORBA::SystemException + * @param time this parameter is used to pass the exact time the caller wants to know the horizontal coordinates. + * @param az that's the returned value in radians of the azimuth for the requested time. + * @param el that's the returned value in radians of the elevation for the requested time. + * @param ra that's the returned value in radians of the elevation for the requested time. + * @param dec that's the returned value in radians of the right ascension for the requested time. + * @param jepoch julian epoch the returned equatorial point refers to + * @param lon that's the returned value in radians of the galactic longitude for the requested time. + * @param lat that's the returned value in radians of the galactic latitude for the requested time. + */ + void getAllCoordinates(ACS::Time time,CORBA::Double_out az,CORBA::Double_out el,CORBA::Double_out ra,CORBA::Double_out dec,CORBA::Double_out jepoch, + CORBA::Double_out lon,CORBA::Double_out lat) throw (CORBA::SystemException); + + /* + * This method is used to check if the given coordinate at the given time belongs to the trajectory generated by this component with + * the tollerance of a tens of HPBW. If the given coordinate is the telescope coordinate we can say that the antenna is tracking. + * @throw CORBA::SystemException + * @param time that the time mark the given coordinate refers to. + * @param az that's the azimuth of the given coordinate (in radians) + * @param el that's the elevation of the given coordinate (in radians) + * @param HPBW that's the beam width at half power for the telescope. This parameter, given in radians, changes with + the frequency so it must be provided by the caller. + * @return true if the given point is in the generated trajectory. + */ + bool checkTracking(ACS::Time time,CORBA::Double az,CORBA::Double el,CORBA::Double HPBW) throw (CORBA::SystemException); + + /** + * This method is supposed to compute the flux of the moon. At present a 0.0 Jy is always returned. + * @throw CORBA::SystemException + * @param freq frequency observed + * @param fwhm fwhm + * @param flux computed flux (Jy) + */ + void computeFlux(CORBA::Double freq, CORBA::Double fwhm, CORBA::Double_out flux) throw (CORBA::SystemException); + /** + * This method is only for control software internal use. It used, given a timestamp, to body distance in AY. + * @throw CORBA::SystemException + * @param timestamp this parameter is used to pass the exact time the caller wants to know the topocentric coordinates. + * @param distance that's the returned distance at given time in AU + */ + + + + void getDistance(ACS::Time time,CORBA::Double_out distance) throw (CORBA::SystemException); + +private: + + IRA::CString m_bodyName; + int m_bodycode; + BACIMutex m_mutex; + + IRA::CSite m_site; + IRA::CSkySource m_source; + xephemlib::Site* m_sitex; // site class for libastro + xephemlib::SolarSystemBody* m_body_xephem; + // dummy CSkySource onj for coordinate conversion + double m_longitude; + double m_latitude; + double m_height; + + /* + * right ascension, declination, right ascension and declination offset + * azimuth, elevation, azimuth and elevation offset + */ + double m_ra, m_dec,m_ra_off, m_dec_off; + double m_az, m_el,m_az_off, m_el_off; + double m_glon, m_glat; + double m_ra2000,m_dec2000; + double m_dut1; + + double m_distance; + /* + * Currently used frame for the offsets + */ + Antenna::TCoordinateFrame m_offsetFrame; + double m_parallacticAngle; + /* + * This will contain the name of the component...... + */ + IRA::CString m_componentName; + + void BodyPosition(TIMEVALUE &time); + +}; + + + + +#endif /*SOLSYSBODYIMPL_H_*/ diff --git a/Common/Servers/SolarSystem/include/libastrowrapper.h b/Common/Servers/SolarSystem/include/libastrowrapper.h new file mode 100644 index 000000000..90da0dea6 --- /dev/null +++ b/Common/Servers/SolarSystem/include/libastrowrapper.h @@ -0,0 +1,104 @@ +/* + + C++ Wrapper for Xephem libastro. + + + +*/ + + + + +#ifndef _LIBRWAPPER +#define _LIBRWAPPER + +#include <iostream> +#include <cstring> +#include "astro.h" +#include "preferences.h" +#include <string> +#include <map> +#include <cctype> +#include <algorithm> +#include <locale> + +namespace xephemlib +{ + + +class Site: public Now { + +public: + + Site(double mj, double lon, double lt, double height); + Site(); + + void setCoordinate(double lon, double lt, double height); + void setTime(double mj); + + void stampa(void); + double getMjd(); + + +private: + double m_lon,m_lat,m_height; + std::string name; + +}; + +class SolarSystemBody { + +public: + + + SolarSystemBody(PLCode code); + ~SolarSystemBody(){ delete obj;} + + static std::string getPlanetNameFromCode(PLCode code); + static PLCode getPlanetCodeFromName(std::string name); + void compute (Site* site); + SolarSystemBody(); + void setObject(PLCode code); + + + Obj* getObject(); + void report(); + static std::map<std::string,PLCode> planet; + void getCoordinates(double& ra, double& dec,double& az,double& el, double& range); + private: + + double _ra,_dec,_range,_az,_el; + PLCode _code; + + + +protected: + + Obj* obj; + + + +}; + +class Jupiter : public SolarSystemBody { + +public: + + Jupiter() ; + + + +}; + +} + + + + + + + + + + +#endif /*_LIBRWAPPER*/ diff --git a/Common/Servers/SolarSystem/src/Makefile b/Common/Servers/SolarSystem/src/Makefile new file mode 100644 index 000000000..b0c7cafc0 --- /dev/null +++ b/Common/Servers/SolarSystem/src/Makefile @@ -0,0 +1,113 @@ +#******************************************************************************* +# PPPPPPPP +# +# "@(#) $Id$" +# +# Makefile of ........ +# +# who when what +# -------- -------- ---------------------------------------------- +# spoppi 03/05/17 created +# + +#******************************************************************************* +# This Makefile follows VLT Standards (see Makefile(5) for more). +#******************************************************************************* +# REMARKS +# None +#------------------------------------------------------------------------ + +# +# user definable C-compilation flags +#USER_CFLAGS = + +# +# additional include and library search paths +#USER_INC = +#USER_LIB = + +# +# MODULE CODE DESCRIPTION: +# ------------------------ +# As a general rule: public file are "cleaned" and "installed" +# local (_L) are not "installed". + +# +# C programs (public and local) +# ----------------------------- + EXECUTABLES = testastrolib +# EXECUTABLES_L = + + + +# +# special compilation flags for single c sources +#yyyyy_CFLAGS = + +# +# Includes (.h) files (public only) +# --------------------------------- +# INCLUDES = + +# +# Libraries (public and local) +# ---------------------------- +LIBRARIES = SolarSystemBodyImpl +LIBRARIES_L = + +# +# <brief description of lllll library> + +SolarSystemBodyImpl_OBJECTS = SolarSystemBodyImpl libastrowrapper +SolarSystemBodyImpl_LIBS = EphemGeneratorStubs SolarSystemBodyStubs baci maci IRALibrary \ + SlaLibrary ObservatoryStubs \ + ComponentErrors AntennaErrors \ + AntennaDefinitionsStubs ManagmentDefinitionsStubs \ + ManagementErrors astro + +testastrolib_OBJECTS = libastrowrapper mainastro +testastrolib_LIBS = astro +# +# Scripts (public and local) +# ---------------------------- +# +# list of all possible C-sources (used to create automatic dependencies) +# ------------------------------ +CSOURCENAMES = \ + $(foreach exe, $(EXECUTABLES) $(EXECUTABLES_L), $($(exe)_OBJECTS)) \ + $(foreach rtos, $(RTAI_MODULES) , $($(rtos)_OBJECTS)) \ + $(foreach lib, $(LIBRARIES) $(LIBRARIES_L), $($(lib)_OBJECTS)) + +# +#>>>>> END OF standard rules + +# +# INCLUDE STANDARDS +# ----------------- + +MAKEDIRTMP := $(shell searchFile include/acsMakefile) +ifneq ($(MAKEDIRTMP),\#error\#) + MAKEDIR := $(MAKEDIRTMP)/include + include $(MAKEDIR)/acsMakefile +endif + +# +# TARGETS +# ------- +all: do_all + @echo " . . . 'all' done" + +clean : clean_all + @echo " . . . clean done" + +clean_dist : clean_all clean_dist_all + @echo " . . . clean_dist done" + +man : do_man + @echo " . . . man page(s) done" + +install : install_all + @echo " . . . installation done" + + +#___oOo___ diff --git a/Common/Servers/SolarSystem/src/MyMake b/Common/Servers/SolarSystem/src/MyMake new file mode 100644 index 000000000..825063c56 --- /dev/null +++ b/Common/Servers/SolarSystem/src/MyMake @@ -0,0 +1,22 @@ + +CC = c++ +CFLAGS= -O2 -Wall -lm +CFLAGS_TEST= -L/opt/gtest/lib -lgtest -lgtest_main -lpthread +DEPS= +INCLUDE= -I../libastro/ +HS = + +%.o: %.cpp $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) $(INCLUDE) + +myephem: testlibastro.o + $(CC) -o testlibastro testlibastro.o ../libastro/libastro.a + +debug: testlibastro.o + $(CC) -g -o testlibastro testlibastro.o ../libastro/libastro.a + +astrotest: mainastro.o libastrowrapper.o + $(CC) -g -o mainastro libastrowrapper.o mainastro.o ../libastro/libastro.a + +test: libastrowrapper.o test.o + $(CC) -o test -I$(INTROOT)/include libastrowrapper.o test.o ../libastro/libastro.a $(CFLAGS_TEST) diff --git a/Common/Servers/SolarSystem/src/SolarSystemBodyImpl.cpp b/Common/Servers/SolarSystem/src/SolarSystemBodyImpl.cpp new file mode 100644 index 000000000..f9ba45baf --- /dev/null +++ b/Common/Servers/SolarSystem/src/SolarSystemBodyImpl.cpp @@ -0,0 +1,424 @@ +#include "SolarSystemBodyImpl.h" +//#include <IRA> +#include <Definitions.h> +#include <ObservatoryS.h> +#include <slamac.h> +#include <slalib.h> +#include <LogFilter.h> +//#include <baci.h> +//#include <acstimeEpochHelper.h> +//#include <Site.h> +//#include <DateTime.h> +//#include <SkySource.h> +#include <iostream> +//#include <Site.h> +#include <exception> +#define R2D 57.29577951308232 + +using namespace ComponentErrors; +// using namespace baci; +using namespace IRA; + +using namespace baci; + + +SolarSystemBodyImpl::SolarSystemBodyImpl(const ACE_CString &CompName,maci::ContainerServices *containerServices) : + acscomponent::ACSComponentImpl(CompName, containerServices) +{ + AUTO_TRACE("SolarSystemBodyImpl::SolarSystemBodyImpl()"); + m_componentName=CString(CompName); + m_bodyName="Unset"; +} + +SolarSystemBodyImpl::~SolarSystemBodyImpl() +{ + AUTO_TRACE("SolarSystemBodyImpl::~SolarSystemBodyImpl()"); + +} + +void SolarSystemBodyImpl::initialize() throw(ACSErr::ACSbaseExImpl) +{ + AUTO_TRACE("SolarSystemBodyImpl::initialize()"); + + m_ra_off = m_dec_off = 0.0; + m_az_off = m_el_off = 0.0; + m_offsetFrame=Antenna::ANT_HORIZONTAL; + + + ACS_LOG(LM_FULL_INFO, "SolarSystemBodyImpl::initialize()", (LM_INFO,"COMPSTATE_INITIALIZING")); +} + +void SolarSystemBodyImpl::cleanUp() +{ + AUTO_TRACE("SolarSystemBodyImpl::cleanUp()"); + delete m_sitex; + delete m_body_xephem; + ACSComponentImpl::cleanUp(); +} + +void SolarSystemBodyImpl::aboutToAbort() +{ + AUTO_TRACE("SolarSystemBodyImpl::aboutToAbort()"); +} + +void SolarSystemBodyImpl::execute() throw (ACSErr::ACSbaseExImpl) +{ + AUTO_TRACE("SolarSystemBodyImpl::execute()"); + CError error; + Antenna::TSiteInformation_var site; + + + Antenna::Observatory_var observatory=Antenna::Observatory::_nil(); + try { + observatory=getContainerServices()->getComponent<Antenna::Observatory>("ANTENNA/Observatory"); + } + catch (maciErrType::CannotGetComponentExImpl & ex){ + _ADD_BACKTRACE(ComponentErrors::CouldntGetComponentExImpl,Impl,ex,"SolarSystemBodyImpl::execute()"); + Impl.setComponentName("ANTENNA/Observatory"); + throw Impl; + } + + ACS_LOG(LM_FULL_INFO,"SolarSystemBodyImpl::execute()", (LM_INFO, (const char *)CString(m_componentName+"::OBSERVATORY_LOCATED"))); + try { + site=observatory->getSiteSummary(); + } + catch (CORBA::SystemException& ex) { + _EXCPT(ComponentErrors::CORBAProblemExImpl,_dummy, "SolarSystemBodyImpl::execute()"); + _dummy.setName(ex._name()); + _dummy.setMinor(ex.minor()); + throw _dummy; + } + m_site=CSite(site.out()); + m_source=IRA::CSkySource(); // dummy obj for coordinate conversion + + m_dut1=site->DUT1; + m_longitude=site->longitude; + m_latitude=site->latitude; + m_height=site->height; + // std::cout << "Site:" << site->longitude *R2D << " " << m_latitude ; + m_sitex= new xephemlib::Site(); + m_sitex-> setCoordinate(site->longitude,site->latitude,site->height); //coordinates in degrees. + m_body_xephem = new xephemlib::SolarSystemBody(); + + + try { + getContainerServices()->releaseComponent((const char*)observatory->name()); + } + catch (maciErrType::CannotReleaseComponentExImpl& ex) { + _ADD_BACKTRACE(ComponentErrors::CouldntReleaseComponentExImpl,Impl,ex,"SolarSystemBodyImpl::initialize()"); + Impl.setComponentName("ANTENNA/Observatory"); + throw Impl; + } + ACS_LOG(LM_FULL_INFO,"SolarSystemBodyImpl::execute()", (LM_INFO,"SITE_INITIALIZED")); +} + + + +void SolarSystemBodyImpl::getAttributes(Antenna::SolarSystemBodyAttributes_out att) throw (CORBA::SystemException) +{ + + AUTO_TRACE("SolarSystemBodyImpl::getAttributes()"); + + + baci::ThreadSyncGuard guard(&m_mutex); +TIMEVALUE now; + + IRA::CIRATools::getTime(now); + + BodyPosition(now); + + /* Returns the julian epoch of the date. + * @return the epoch which is the year with the fracional part of the year. + */ + double JulianEpoch; + + BodyPosition(now); + IRA::CDateTime currentTime(now,m_dut1); + JulianEpoch = currentTime.getJulianEpoch(); + + /* Getting the output field + */ + + att=new Antenna::SolarSystemBodyAttributes; + + att->sourceID=CORBA::string_dup(m_bodyName); + att->J2000RightAscension=slaDranrm(m_ra2000); + att->J2000Declination=IRA::CIRATools::latRangeRad(m_dec2000); + att-> rightAscension = slaDranrm(m_ra); + att-> declination = IRA::CIRATools::latRangeRad(m_dec) ; + att-> azimuth = slaDranrm(m_az); + att-> elevation = IRA::CIRATools::latRangeRad(m_el); + att-> julianEpoch = JulianEpoch; + att-> parallacticAngle = m_parallacticAngle; + att-> userAzimuthOffset = m_az_off; + att-> userElevationOffset = m_el_off; + att-> userRightAscensionOffset = m_ra_off; + att-> userDeclinationOffset = m_dec_off; + att->gLongitude=slaDranrm(m_glon); + att->gLatitude=IRA::CIRATools::latRangeRad(m_glat); + att->userLatitudeOffset=att->userLongitudeOffset=0.0; + att->axis=Management::MNG_TRACK; + att->distance=m_distance; + att->angularSize= att->radialVelocity=0; + att->vradFrame= Antenna::ANT_TOPOCEN ; + att->vradDefinition=Antenna::ANT_RADIO; + +} + +void SolarSystemBodyImpl::setOffsets(CORBA::Double lon,CORBA::Double lat,Antenna::TCoordinateFrame frame) throw (CORBA::SystemException,AntennaErrors::AntennaErrorsEx) +{ + AUTO_TRACE("SolarSystemBodyImpl::setOffsets()"); + if (frame==Antenna::ANT_HORIZONTAL) { + m_source.setHorizontalOffsets(lon,lat); + m_az_off=lon; + m_el_off=lat; + m_ra_off=0.0; + m_dec_off=0.0; + } + else if (frame==Antenna::ANT_EQUATORIAL) { + m_az_off=0.0; + m_el_off=0.0; + m_ra_off=lon; + m_dec_off=lat; + m_source.setEquatorialOffsets(lon,lat); + + } + else { + _EXCPT(AntennaErrors::OffsetFrameNotSupportedExImpl,impl,"SolarSystemBodyImpl::setOffsets()"); + throw impl.getAntennaErrorsEx(); + } + +} + +void SolarSystemBodyImpl::getJ2000EquatorialCoordinate(ACS::Time time, CORBA::Double_out ra2000, CORBA::Double_out dec2000) throw (CORBA::SystemException) + +{ + AUTO_TRACE("SolarSystemBodyImpl::getJ2000EquatorialCoordinate()"); + double _ra,_dec; + TIMEVALUE val(time); + BodyPosition(val); + + IRA::CDateTime ctime(val,m_dut1); + _ra =slaDranrm(m_ra2000); + _dec =IRA::CIRATools::latRangeRad(m_dec2000); + ra2000=_ra; + dec2000=_dec; + + +} + + +void SolarSystemBodyImpl::getHorizontalCoordinate(ACS::Time time, CORBA::Double_out az, CORBA::Double_out el) throw (CORBA::SystemException) + +{ + AUTO_TRACE("SolarSystemBodyImpl::getHorizontalCoordinate()"); + double azi,ele; + TIMEVALUE val(time); + IRA::CDateTime ctime(val,m_dut1); + baci::ThreadSyncGuard guard(&m_mutex); + BodyPosition(val); + m_source.process(ctime,m_site); + m_source.getApparentHorizontal(azi,ele); + az=azi; el=ele; + + + +} + +void SolarSystemBodyImpl::getAllCoordinates(ACS::Time time,CORBA::Double_out az,CORBA::Double_out el,CORBA::Double_out ra,CORBA::Double_out dec,CORBA::Double_out jepoch,CORBA::Double_out lon, + CORBA::Double_out lat) throw (CORBA::SystemException) +{ + + AUTO_TRACE("SolarSystemBodyImpl::getAllCoordinates()") + + TIMEVALUE val(time); + double azi,ele,rae,dece,lone,late,jepoche; + IRA::CDateTime ctime(val,m_dut1); + baci::ThreadSyncGuard guard(&m_mutex); + BodyPosition(val); + m_source.process(ctime,m_site); + m_source.getApparentHorizontal(azi,ele); + m_source.getApparentEquatorial(rae,dece,jepoche); + m_source.getApparentGalactic(lone,late); + az=azi; el=ele; + ra=rae; dec=dece; jepoch=jepoche; + lon=lone; lat=late; +} + + +bool SolarSystemBodyImpl::checkTracking(ACS::Time time,CORBA::Double az,CORBA::Double el,CORBA::Double HPBW) throw (CORBA::SystemException) +{ + AUTO_TRACE("SolarSystemBodyImpl::checkTracking()") + double computedAz,computedEl,azErr,elErr,skyErr; + TIMEVALUE val(time); + IRA::CDateTime refTime(val,m_dut1); + baci::ThreadSyncGuard guard(&m_mutex); // obtain access + m_source.process(refTime,m_site); + m_source.getApparentHorizontal(computedAz,computedEl); + elErr=computedEl-el; + azErr=(computedAz-az)*cos(el); + skyErr=sqrt(elErr*elErr+azErr*azErr); //total skyError + return skyErr<=HPBW*0.1; + +} + + +void SolarSystemBodyImpl::setBodyName(const char* bodyName) throw (CORBA::SystemException,AntennaErrors::AntennaErrorsEx) +{ + +/* +typedef enum { + MERCURY, + VENUS, + MARS, + JUPITER, + SATURN, + URANUS, + NEPTUNE, + PLUTO, + SUN, + MOON, + NOBJ // total number of basic objects +} PLCode; +*/ + + + AUTO_TRACE("SolarSystemBodyImpl::setBodyName()"); + m_bodyName=CString(bodyName); + m_bodyName.MakeUpper(); +// std::map<CString,int> plan; + + PLCode code; + + code=xephemlib::SolarSystemBody::getPlanetCodeFromName(bodyName); + CUSTOM_LOG(LM_FULL_INFO,"SolarSystemBodyImpl::setBodyName()", + (LM_INFO,"Solar System body name:%s",(const char *)m_bodyName)); + + + if (code!=NOBJ){ +// m_body_xephem = new xephemlib::SolarSystemBody(code); + try{ + m_body_xephem ->setObject(code); + } + + + catch (std::exception& e) + { + std::cout << e.what() << '\n'; + } + catch (...) + {std::cout << "except" << std::endl;} + + + + // std::cout << "Body name:" << bodyName <<std::endl; + // std::cout << "code:" << code <<std::endl; + + } else + { + // THROW_EX(AntennaErrors, SourceNotFoundExImpl, "SolarSystemBodyImpl::setBodyName", false); + + _EXCPT(AntennaErrors::SourceNotFoundExImpl, __dummy,"SkySourceImpl::loadSourceFromCatalog()"); + __dummy.setSourceName(bodyName); + CUSTOM_EXCPT_LOG(__dummy,LM_DEBUG); + + throw __dummy.getAntennaErrorsEx(); + + + + } + + +//_EXCPT(AntennaErrors::SourceNotFoundExImpl, __dummy,"SkySourceImpl::loadSourceFromCatalog()"); + //__dummy.setSourceName(bodyName); + // CUSTOM_EXCPT_LOG(__dummy,LM_DEBUG); + + // throw __dummy.getAntennaErrorsEx(); + + +} + +void SolarSystemBodyImpl::computeFlux(CORBA::Double freq, CORBA::Double fwhm, CORBA::Double_out flux) throw (CORBA::SystemException) +{ + flux=0.0; + AUTO_TRACE("SolarSystemBodyImpl::computeFlux()"); + +} + +void SolarSystemBodyImpl::getDistance(ACS::Time time,CORBA::Double_out distance) throw (CORBA::SystemException) +{ + AUTO_TRACE("SolarSystemBodyImpl::getDistance()"); + double azi,ele; + TIMEVALUE val(time); + IRA::CDateTime ctime(val,m_dut1); + baci::ThreadSyncGuard guard(&m_mutex); + BodyPosition(val); + distance=m_distance; + +} + + + +void SolarSystemBodyImpl::BodyPosition(TIMEVALUE &time) +{ + + AUTO_TRACE("SolarSystemBodyImpl::BodyPosition()"); + double TDB,time_utc,TT; +#ifdef DEBUG +// std::cout <<time.year() << " " << time.month() << " " <<time.day() ; +// std::cout <<time.hour() << " " << time.minute() << " " <<time.second() << std::endl ; +#endif + + baci::ThreadSyncGuard guard(&m_mutex); + + + IRA::CDateTime date(time,m_dut1); + TDB=date.getTDB(m_site); + TT=date.getTT() ; + + + /* + * TDB as a Modified Julian Date (JD - 2400000.5 + * )*/ + TDB = TDB - 2400000.5; + TT = TT - 2400000.5; + + time_utc= CDateTime::julianEpoch2JulianDay (date.getJulianEpoch()); + time_utc = time_utc - 2400000.5; + //std::cout << time_utc-(int)time_utc << " " <<TDB << std::endl; + + + + double ra,dec,eph,az,el,range,lone,late; + +// Site *site = new Site(59319.5,degrad(9.5),degrad(39.5),600); + + m_sitex -> setTime(time_utc) ; + m_body_xephem->compute( m_sitex ); + // m_body_xephem->report(); + m_body_xephem->getCoordinates(ra,dec,az,el,range); + m_ra2000 = ra; + m_dec2000= dec; + m_distance=range; + m_source.setInputEquatorial(m_ra2000, m_dec2000, IRA::CSkySource::SS_J2000); + // IRA::CSkySource m_source; // dummy CSkySource onj for coordinate conversion + m_source.process(date,m_site); + m_source.getApparentEquatorial (ra,dec,eph); + m_source.getApparentHorizontal(az,el); + m_source.getApparentGalactic(lone,late); + m_source.apparentToHorizontal(date,m_site); + m_ra=ra; + m_dec=dec; + m_az=az; + m_el=el; + m_glon=lone; + m_glat=late; + + m_parallacticAngle=m_source.getParallacticAngle(); +} + +#include <maciACSComponentDefines.h> +MACI_DLL_SUPPORT_FUNCTIONS(SolarSystemBodyImpl) + + + diff --git a/Common/Servers/SolarSystem/src/libastrowrapper.cpp b/Common/Servers/SolarSystem/src/libastrowrapper.cpp new file mode 100644 index 000000000..e8f90406e --- /dev/null +++ b/Common/Servers/SolarSystem/src/libastrowrapper.cpp @@ -0,0 +1,281 @@ +#include "libastrowrapper.h" + +namespace xephemlib { + + + +const char *planetnames[]={"Mercury","Venus","Mars","Jupiter","Saturn", + "Uranus","Neptune","Pluto","Sun","Moon","NOBJ"}; + + + + +Site::Site(double mj, double lon, double lt, double height) +{ + this->n_mjd=mj-15019.5; // xephem uses mjd 0 as 1899 12 31 at 12:00 + this->n_lat=lt; + this->n_lng=lon; + this->n_epoch=J2000; + // this->n_height=height; + +} + +Site::Site() + +{ + this->n_epoch=J2000; +} + +void Site::setCoordinate(double lon, double lt,double height) +{ + + this->n_lat=lt; + this->n_lng=lon; + // this->n_heigt=height; + +} + +void Site::setTime(double mj) +{ + + this->n_mjd=mj-15019.5; // xephem uses mjd 0 as 1899 12 31 at 12:00 + + + +} + + + + +void Site::stampa(void){ + + std::cout<< "mjd:"<< this->n_mjd <<std::endl; + std::cout << "lon:"<< raddeg(this->n_lng) << std::endl; + std::cout << "lat:"<< raddeg(this->n_lat) << std::endl; + + +} + +double Site::getMjd() +{ + + return this->n_mjd+15019.5; + +} + +SolarSystemBody::SolarSystemBody() +{ + obj=new Obj(); + + +}; + +void SolarSystemBody::setObject(PLCode code){ + + + +// obj=new Obj(); + _code=code; + + + // obj->any.co_type=PLANET; + strncpy(obj->any.co_name,planetnames[_code],10); +// obj-> + // pl.plo_code=code; +#ifdef DEBUG +// std::cout << "Code: " << code << std::endl; +// std::cout << "Name: " << planetnames[code] << std::endl; + // std::cout << "Name: " << obj->any.co_name << std::endl; +#endif + +// pref_set(PREF_EQUATORIAL,PREF_TOPO); + + // std::cout << "exit after pref_set: " << obj->any.co_name << std::endl; + +}; + +SolarSystemBody::SolarSystemBody(PLCode code) +{ + //obj=new Obj(); + + _code=code; + +// obj->any.co_type=PLANET; + // strncpy(obj->any.co_name,planetnames[_code],10); + // obj->pl.plo_code=code; +#ifdef DEBUG +// std::cout << "Code: " << code << std::endl; +// std::cout << "Name: " << planetnames[code] << std::endl; +// std::cout << "Name: " << obj->any.co_name << std::endl; +#endif + + // pref_set(PREF_EQUATORIAL,PREF_TOPO); + + + +} + +PLCode SolarSystemBody::getPlanetCodeFromName(std::string str) +{ + std::locale loc; + for (std::string::size_type i=0; i<str.length(); ++i){ + str[i]=std::toupper(str[i],loc); + } + if (planet.find(str) != planet.end()) + { + // std::cout <<str << " is in the map." << std::endl; + return SolarSystemBody::planet[str]; + } + else + { + + //std::cout << str << " is not in the map." << std::endl; + return NOBJ; + } + + + + + + + +} + + + + +std::string SolarSystemBody::getPlanetNameFromCode(PLCode code ){ + + + + + std::string name; + for (std::map<std::string,PLCode>::iterator it=SolarSystemBody::planet.begin(); it!=SolarSystemBody::planet.end(); ++it) + { +#ifdef DEBUG + // std::cout << it->first << " => " << it->second << '\n'; +#endif + if (it->second == code) + name=it->first; + + } + + + + return name; + + + + +} + + +void SolarSystemBody::getCoordinates(double& ra, double& dec,double& az,double& el, double& range) +{ + ra=_ra; + dec=_dec; + az=_az; + el=_el; + range=_range; + + +}; + + +void SolarSystemBody::compute(Site* site){ + + Obj* obj=new Obj(); + + + + obj->any.co_type=PLANET; + strncpy(obj->any.co_name,planetnames[_code],10); + obj-> + pl.plo_code=_code; +#ifdef DEBUG +// std::cout << "Code: " << _code << std::endl; +// std::cout << "Name: " << planetnames[_code] << std::endl; +// std::cout << "Name: " << obj->any.co_name << std::endl; +#endif + pref_set(PREF_EQUATORIAL,PREF_TOPO); + + +// std::cout << "Compute " <<std::endl; + obj_cir (site, obj); + + _ra=obj->any.co_ra; + _dec=obj->any.co_dec; + _az=obj->any.co_az; + _el=obj->any.co_alt; + _range=obj->anyss.so_edist; + delete obj; + +} + + +Obj* SolarSystemBody::getObject() +{ + return obj; + + +} + +void SolarSystemBody::report() +{ +/* Astrometric right ascension and declination of the target center with +respect to the observing site (coordinate origin) in the reference frame of +the planetary ephemeris (ICRF). Compensated for down-leg light-time delay +aberration.*/ + + + + std::cout << "Ra : " << _ra << std::endl; + std::cout << "Dec: " << _dec << std::endl; + std::cout << "Az : " << _az << std::endl; + std::cout << "El : " << _el << std::endl; + std::cout << "Range : " << _range << std::endl; + + + + +} + +std::map<std::string,PLCode>SolarSystemBody::planet; //definition of static variable + + + bool createMap() // function to initialize static map +{ /* +typedef enum { + MERCURY, + VENUS, + MARS, + JUPITER, + SATURN, + URANUS, + NEPTUNE, + PLUTO, + SUN, + MOON, + NOBJ // total number of basic objects +} PLCode; +*/ + + SolarSystemBody::planet["MERCURY"]=MERCURY; + SolarSystemBody::planet["VENUS"]=VENUS ; + SolarSystemBody::planet["MARS"]=MARS ; + SolarSystemBody::planet["JUPITER"]=JUPITER; + SolarSystemBody::planet["SATURN"]=SATURN ; + SolarSystemBody::planet["URANUS"]=URANUS ; + SolarSystemBody::planet["NEPTUNE"]=NEPTUNE ; + SolarSystemBody::planet["PLUTO"]=PLUTO ; + SolarSystemBody::planet["SUN"]=SUN ; + SolarSystemBody::planet["MOON"]=MOON ; + SolarSystemBody::planet["NOBJ"]=NOBJ ; + return 0; +} + + +static bool _tmp=createMap(); // call to the function + +} + diff --git a/Common/Servers/SolarSystem/src/mainastro.cpp b/Common/Servers/SolarSystem/src/mainastro.cpp new file mode 100644 index 000000000..c25fbaa73 --- /dev/null +++ b/Common/Servers/SolarSystem/src/mainastro.cpp @@ -0,0 +1,22 @@ +#include "libastrowrapper.h" +#include <iostream> +int main(int argc, char** argv) + +{ + + xephemlib::SolarSystemBody p = xephemlib::SolarSystemBody(MERCURY); + std::cout << "New SolarSystemBody done" << std::endl; + xephemlib::Site *site = new xephemlib::Site(); + site -> setCoordinate(degrad(9.5),degrad(39.5),600); + site -> setTime(59319.5) ; +// Site *site = new Site(59319.5,degrad(9.5),degrad(39.5),600); + + + p.compute(site); + p.report(); + std::cout <<xephemlib::SolarSystemBody::getPlanetNameFromCode(JUPITER)<<std::endl; + std::cout << xephemlib::SolarSystemBody::getPlanetCodeFromName("MERCURY")<<std::endl; + std::cout << xephemlib::SolarSystemBody::getPlanetCodeFromName("Mddd")<<std::endl; + return 0; + +} diff --git a/Common/Servers/SolarSystem/src/test.cpp b/Common/Servers/SolarSystem/src/test.cpp new file mode 100644 index 000000000..76ad10a4b --- /dev/null +++ b/Common/Servers/SolarSystem/src/test.cpp @@ -0,0 +1,86 @@ +#include "libastrowrapper.h" +#include <gtest/gtest.h> +#include <iostream> + +class SolarSystemBodyTest : public ::testing::Test { + + + protected: + + + Site* site; + + SolarSystemBodyTest() + { + + } + + virtual void SetUp() { + + site = new Site(59393.5,degrad(9.5),degrad(39.5),600); + + } + + virtual void TearDown() { + } +}; + + + + + +// TEST_F(EphemTest,versionTest){ +// std::string toolkit_version; +// EXPECT_STREQ("CSPICE_N0065",solsys.spiceToolkitVersion().c_str()); +// +// } + + + +TEST_F(SolarSystemBodyTest,JupiterPosition){ + +// Site *site = new Site(59393.5,degrad(9.5),degrad(39.5),700); + + SolarSystemBody* p = new SolarSystemBody(JUPITER); + p->compute(this->site); + + EXPECT_NEAR( 334.167106906 ,raddeg(p->ra),2.7e-4); + EXPECT_NEAR( -11.764766054 ,raddeg(p->dec),2.7e-4); + EXPECT_NEAR( 4.39448666972074 ,p->range,2.7e-5); + + //334.16711 -11.76477 + + +} + +TEST_F(SolarSystemBodyTest,Sun){ + + Site *site = new Site(); + site -> setCoordinate(degrad(9.5),degrad(39.5),700); + site -> setTime(59393.5) + + + SolarSystemBody* p = new SolarSystemBody(SUN); + p->compute(site); + + EXPECT_NEAR( 96.800863628 ,raddeg(p->ra),2.7e-4); + EXPECT_NEAR( 23.287056282 ,raddeg(p->dec),2.7e-4); + EXPECT_NEAR( 1.01658809887528 ,p->range,2.7e-6); + + + + +} + + + +// Google Test can be run manually from the main() function +// or, it can be linked to the gtest_main library for an already +// set-up main() function primed to accept Google Test test cases. +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} + +// Build command: g++ main.cpp -lgtest diff --git a/Common/Servers/SolarSystem/src/test_SolarSystemBody.py b/Common/Servers/SolarSystem/src/test_SolarSystemBody.py new file mode 100644 index 000000000..4f5ef77a0 --- /dev/null +++ b/Common/Servers/SolarSystem/src/test_SolarSystemBody.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +#******************************************************************************* +# ALMA - Atacama Large Millimiter Array +# (c) Associated Universities Inc., 2002 +# (c) European Southern Observatory, 2002 +# Copyright by ESO (in the framework of the ALMA collaboration) +# and Cosylab 2002, All rights reserved +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# @(#) $Id: acspyexmplDynamicHelloWorld.py,v 1.10 2006/03/30 16:58:36 dfugate Exp $ + + +''' +DESCRIPTION +This client consists of an example which asks manager to create a dynamic +<a href="../../idl/html/interfaceHelloWorld_1_1HelloWorld.html">Hello World</a> +component for it. This is done by changing some of the default parameters to the +getComponent method of the ContainerServices class. Once the reference to the newly +created component has been retrieved, a method is invoked to show that the +everything is working. + +WHAT CAN I GAIN FROM THIS EXAMPLE? +- PySimpleClient usage. +- Accessing (remote) components. +- Using PySimpleClient to create and reference dynamic components. +- Manipulating default parameters of ContainerServices methods. + +LINKS +- <a href="../../idl/html/interfaceHelloWorld_1_1HelloWorld.html">HelloWorld IDL Documentation</a> +''' + +# Import command-line arguments +from sys import argv + +# Import the SimpleClient class +from Acspy.Clients.SimpleClient import PySimpleClient +import AntennaErrorsImpl +import AntennaErrors +import sys +import Antenna +from math import radians,degrees +from IRAPy import logger +import Acspy.Common.TimeHelper +import time +''' +Date__(UT)__HR:MN R.A.___(ICRF)___DEC R.A._(a-appar)_DEC. Azi____(a-app)___Elev +************************************************************************************** +2022-Jan-21 00:00:00.000 m 336.65825 -10.79656 336.94218 -10.68735 312.371754 -52.320793 + 2021-Apr-15 00:00 2459319.500000000 328.035447923 -13.662097629 327.791152902 -13.167532812 84.489404675 -27.482527702 5.49776328729022 -23.8801089 + 328.03548968344006, -13.662066250524141 + + 328.03548968344006, -13.66206625052414 +''' + + + +epoch = Acspy.Common.TimeHelper.TimeUtil() + +struct_time = time.strptime("2021-Apr-15 00:00", "%Y-%b-%d %H:%M") + +tm=time.mktime(struct_time) + + + +acstime=epoch.py2epoch(tm) + +print (acstime.value) +# Make an instance of the PySimpleClient +simpleClient = PySimpleClient() + +# Obtain a reference to a dynamic component using the ContainerServices +# getComponent method. +hwRef = simpleClient.getDynamicComponent(None, + "IDL:alma/Antenna/SolarSystemBody:1.0", + "SolarSystemBodyImpl",None) + +if hwRef != None: + simpleClient.getLogger().logInfo("Retrieved valid reference from manager.") + #Do something useful with the reference. + + try: + name='Neptuune' + hwRef.setBodyName(name) + except AntennaErrors.SourceNotFoundEx, ex: + newex=AntennaErrorsImpl.SourceNotFoundExImpl(ex) + logger.logError('source %s not found' % ex) + logger.logError(newex.log()) + simpleClient.disconnect() + sys.exit(-1) + except ValueError: + print('zzz') + sys.exit(-1) + sourceID = J2000RightAscension= J2000Declination= rightAscension= declination= julianEpoch= gLongitude= gLatitude= azimuth= elevation= parallacticAngle=0. + userAzimuthOffset=userElevationOffset= userRightAscensionOffset= userDeclinationOffset= userLongitudeOffset= userLatitudeOffset=axis=angularSize=0. + distance= radialVelocity= vradFrame= vradDefinition=0. +# hwRef.getAttributes(sourceID, J2000RightAscension, J2000Declination, rightAscension, declination, julianEpoch, gLongitude, gLatitude, azimuth, elevation, parallacticAngle, userAzimuthOffset, userElevationOffset, userRightAscensionOffset, +# userDeclinationOffset, userLongitudeOffset, userLatitudeOffset, axis, angularSize, distance, radialVelocity, vradFrame, vradDefinition) +#print(att) + +# az,el,ra,dec,l,lon,lat = hwRef.getAllCoordinates(acstime.value) + + ra,dec=hwRef.getJ2000EquatorialCoordinate(acstime.value) + +# print ("az,el",degrees(az),degrees(el)) + print ("ra,dec",degrees(ra),degrees(dec)) + att=hwRef.getAttributes() + dec2000=att.J2000Declination + ra2000=att.J2000RightAscension + print(degrees(ra2000),degrees(dec2000)) + simpleClient.getLogger().logInfo("Method of dynamic component successfully invoked. Have a nice day!") +else: + simpleClient.getLogger().logAlert("Bad reference retrieved from manager") + +simpleClient.disconnect() +print "The end __oOo__" + diff --git a/Common/Servers/SolarSystem/test/Makefile b/Common/Servers/SolarSystem/test/Makefile new file mode 100644 index 000000000..0e616982f --- /dev/null +++ b/Common/Servers/SolarSystem/test/Makefile @@ -0,0 +1,3 @@ +test: + python -m unittest discover -v + diff --git a/Common/Servers/SolarSystem/test/__init__.py b/Common/Servers/SolarSystem/test/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Common/Servers/SolarSystem/test/test_jupiter.py b/Common/Servers/SolarSystem/test/test_jupiter.py new file mode 100644 index 000000000..1d6af1823 --- /dev/null +++ b/Common/Servers/SolarSystem/test/test_jupiter.py @@ -0,0 +1,54 @@ +import unittest +# Import command-line arguments +from sys import argv + +# Import the SimpleClient class +from Acspy.Clients.SimpleClient import PySimpleClient + +import Antenna +from math import radians,degrees + +import Acspy.Common.TimeHelper +import time + + +class JupiterPositionTest(unittest.TestCase): + def setUp(self): + epoch = Acspy.Common.TimeHelper.TimeUtil() + struct_time = time.strptime("2021-Apr-15 00:00", "%Y-%b-%d %H:%M") + tm=time.mktime(struct_time) + self.acstime=epoch.py2epoch(tm) + print(tm) + self.simpleClient = PySimpleClient() + self.hwRef = self.simpleClient.getDynamicComponent(None,"IDL:alma/Antenna/SolarSystemBody:1.0","SolarSystemBodyImpl",None) + self.hwRef.setBodyName('Jupiter') + + + + def test_equatorialJ2000(self): + ra,dec=self.hwRef.getJ2000EquatorialCoordinate(self.acstime.value) + time.sleep(1) + print(ra,dec) + + + self.assertAlmostEqual(degrees(ra), 328.035447280, places=4) + self.assertAlmostEqual(degrees(dec), -13.662097261, places=4) + + def test_equatorialApparent(self): + + az,el,ra,dec,l,lon,lat =self.hwRef.getAllCoordinates(self.acstime.value) + self.assertAlmostEqual(degrees(ra), 328.315829715 , delta=1e-4) + self.assertAlmostEqual(degrees(dec), -13.564437853 , delta=1e-4) +# def test_horizontalApparent(self): +# az,el,ra,dec,l,lon,lat =self.hwRef.getAllCoordinates(self.acstime.value) + self.assertAlmostEqual(degrees(az), 84.320777342 , delta=5e-4) + self.assertAlmostEqual(degrees(el), -28.325680692 , delta=5e-4) + + def tearDown(self): + print('closing') + self.simpleClient.disconnect() + +if __name__ == '__main__': + + unittest.main() + diff --git a/Common/Servers/SolarSystem/test/test_jupiter_distance.py b/Common/Servers/SolarSystem/test/test_jupiter_distance.py new file mode 100644 index 000000000..25d7d943b --- /dev/null +++ b/Common/Servers/SolarSystem/test/test_jupiter_distance.py @@ -0,0 +1,44 @@ +import unittest +# Import command-line arguments +from sys import argv + +# Import the SimpleClient class +from Acspy.Clients.SimpleClient import PySimpleClient + +import Antenna +from math import radians,degrees + +import Acspy.Common.TimeHelper +import time + + +class JupiterDistanceTest(unittest.TestCase): + def setUp(self): + epoch = Acspy.Common.TimeHelper.TimeUtil() + struct_time = time.strptime("2021-Apr-15 00:00", "%Y-%b-%d %H:%M") + tm=time.mktime(struct_time) + self.acstime=epoch.py2epoch(tm) + print(tm) + simpleClient = PySimpleClient() + self.hwRef = simpleClient.getDynamicComponent(None,"IDL:alma/Antenna/SolarSystemBody:1.0","SolarSystemBodyImpl",None) + self.hwRef.setBodyName('Jupiter') + + + + def test_jupiter_distance(self): + distance=self.hwRef.getDistance(self.acstime.value) + time.sleep(1) + + print('distance',distance) + + + self.assertAlmostEqual(distance, 5.49776341649024, delta=5e-5) + + + + + +if __name__ == '__main__': + + unittest.main() + diff --git a/Common/Servers/SolarSystem/test/test_offset.py b/Common/Servers/SolarSystem/test/test_offset.py new file mode 100644 index 000000000..2815471c9 --- /dev/null +++ b/Common/Servers/SolarSystem/test/test_offset.py @@ -0,0 +1,54 @@ +import unittest +# Import command-line arguments +from sys import argv + +# Import the SimpleClient class +from Acspy.Clients.SimpleClient import PySimpleClient + +import Antenna +from math import radians,degrees,cos + +import Acspy.Common.TimeHelper +import time + + +class SetOffsetTest(unittest.TestCase): + def setUp(self): + epoch = Acspy.Common.TimeHelper.TimeUtil() + struct_time = time.strptime("2021-Apr-15 00:00", "%Y-%b-%d %H:%M") + tm=time.mktime(struct_time) + self.acstime=epoch.py2epoch(tm) + print(tm) + simpleClient = PySimpleClient() + self.hwRef = simpleClient.getDynamicComponent(None,"IDL:alma/Antenna/SolarSystemBody:1.0","SolarSystemBodyImpl",None) + self.hwRef.setBodyName('Jupiter') + + + + + def test_equatorialOffset(self): + ra_ref=radians(328.315829715) + dec_ref=radians(-13.564437853) + ra_offs=radians(1) + dec_offs=radians(1) + + self.hwRef.setOffsets(ra_offs,dec_offs,Antenna.ANT_EQUATORIAL) + _,_,ra,dec,l,lon,lat =self.hwRef.getAllCoordinates(self.acstime.value) + self.assertAlmostEqual(degrees(ra), degrees(ra_ref+ra_offs/cos(dec_ref+dec_offs)) , delta=1e-4) + self.assertAlmostEqual(degrees(dec), degrees(dec_ref+dec_offs) , delta=1e-4) + def test_horizontalOffset(self): + az_ref=radians(84.320777342) + el_ref=radians(-28.325680692 ) + az_offs=radians(1) + el_offs=radians(1) + self.hwRef.setOffsets(az_offs,el_offs,Antenna.ANT_HORIZONTAL) + az,el,_,_,l,lon,lat =self.hwRef.getAllCoordinates(self.acstime.value) + self.assertAlmostEqual(degrees(az),degrees( az_ref+az_offs/cos(el_ref+el_offs)) , delta=5e-4) + self.assertAlmostEqual(degrees(el), degrees( el_ref+el_offs) , delta=5e-4) + + + +if __name__ == '__main__': + + unittest.main() + diff --git a/Common/Servers/SolarSystem/test/test_sun.py b/Common/Servers/SolarSystem/test/test_sun.py new file mode 100644 index 000000000..abb7c833f --- /dev/null +++ b/Common/Servers/SolarSystem/test/test_sun.py @@ -0,0 +1,55 @@ +import unittest +# Import command-line arguments +from sys import argv + +# Import the SimpleClient class +from Acspy.Clients.SimpleClient import PySimpleClient + +import Antenna +from math import radians,degrees + +import Acspy.Common.TimeHelper +import time + + + +class SunPositionTest(unittest.TestCase): + def setUp(self): + epoch = Acspy.Common.TimeHelper.TimeUtil() + struct_time = time.strptime("2022-Jan-27 13:30", "%Y-%b-%d %H:%M") + tm=time.mktime(struct_time) + self.acstime=epoch.py2epoch(tm) + print(tm) + simpleClient = PySimpleClient() + self.hwRef = simpleClient.getDynamicComponent(None,"IDL:alma/Antenna/SolarSystemBody:1.0","SolarSystemBodyImpl",None) + self.hwRef.setBodyName('Sun') + + + + def test_equatorialJ2000(self): + ra,dec=self.hwRef.getJ2000EquatorialCoordinate(self.acstime.value) + time.sleep(1) + print(ra,dec) + + + self.assertAlmostEqual(degrees(ra), 309.681353589, delta=1e-4) + self.assertAlmostEqual(degrees(dec), -18.451737235, delta=1e-4) + + def test_equatorialApparent(self): + + az,el,ra,dec,l,lon,lat =self.hwRef.getAllCoordinates(self.acstime.value) + print('type az',type(az)) + self.assertAlmostEqual(degrees(ra),309.986231168 , delta=1e-4) + self.assertAlmostEqual(degrees(dec),-18.376456126 , delta=1e-4) +# def test_horizontalApparent(self): +# az,el,ra,dec,l,lon,lat =self.hwRef.getAllCoordinates(self.acstime.value) + print ('az,el=',degrees(az),degrees(el)) + self.assertAlmostEqual(degrees(az), 210.403368369 , delta=5e-4) + self.assertAlmostEqual(degrees(el), 26.276295555 , delta=5e-4) + + + +if __name__ == '__main__': + + unittest.main() + diff --git a/SRT/CDB/MACI/Components/ANTENNA/IncludeDynamic.xml b/SRT/CDB/MACI/Components/ANTENNA/IncludeDynamic.xml index ea6e644ba..1ff19de19 100644 --- a/SRT/CDB/MACI/Components/ANTENNA/IncludeDynamic.xml +++ b/SRT/CDB/MACI/Components/ANTENNA/IncludeDynamic.xml @@ -18,4 +18,9 @@ Type="IDL:alma/Antenna/Moon:1.0" Container="AntennaContainer" ImplLang="cpp"/> + <e Name="*" + Code="SolarSystemBodyImpl" + Type="IDL:alma/Antenna/SolarSystemBody:1.0" + Container="AntennaContainer" + ImplLang="cpp"/> </Components> diff --git a/SRT/CDB/MACI/Containers/AntennaBossContainer/AntennaBossContainer.xml b/SRT/CDB/MACI/Containers/AntennaBossContainer/AntennaBossContainer.xml index b6cba5510..d1c9a8313 100644 --- a/SRT/CDB/MACI/Containers/AntennaBossContainer/AntennaBossContainer.xml +++ b/SRT/CDB/MACI/Containers/AntennaBossContainer/AntennaBossContainer.xml @@ -10,7 +10,7 @@ UseIFR="true" ManagerRetry="10" ImplLang="cpp" - Recovery="false"> + Recovery="true"> <Autoload> <cdb:e string="baci" /> @@ -18,8 +18,8 @@ <LoggingConfig centralizedLogger="Log" - minLogLevel="5" - minLogLevelLocal="5" + minLogLevel="2" + minLogLevelLocal="2" dispatchPacketSize="0" immediateDispatchLevel="8" flushPeriodSeconds="1" diff --git a/SRT/CDB/MACI/Containers/AntennaContainer/AntennaContainer.xml b/SRT/CDB/MACI/Containers/AntennaContainer/AntennaContainer.xml index b6cba5510..13451d222 100644 --- a/SRT/CDB/MACI/Containers/AntennaContainer/AntennaContainer.xml +++ b/SRT/CDB/MACI/Containers/AntennaContainer/AntennaContainer.xml @@ -18,8 +18,8 @@ <LoggingConfig centralizedLogger="Log" - minLogLevel="5" - minLogLevelLocal="5" + minLogLevel="2" + minLogLevelLocal="2" dispatchPacketSize="0" immediateDispatchLevel="8" flushPeriodSeconds="1" diff --git a/SRT/CDB/MACI/Containers/ManagementContainer/ManagementContainer.xml b/SRT/CDB/MACI/Containers/ManagementContainer/ManagementContainer.xml index efe679bf6..b6d00b54f 100644 --- a/SRT/CDB/MACI/Containers/ManagementContainer/ManagementContainer.xml +++ b/SRT/CDB/MACI/Containers/ManagementContainer/ManagementContainer.xml @@ -18,8 +18,8 @@ <LoggingConfig centralizedLogger="Log" - minLogLevel="5" - minLogLevelLocal="5" + minLogLevel="2" + minLogLevelLocal="2" dispatchPacketSize="0" immediateDispatchLevel="8" flushPeriodSeconds="1" diff --git a/SRT/CDB/alma/ANTENNA/Boss/Boss.xml b/SRT/CDB/alma/ANTENNA/Boss/Boss.xml index a15766a83..78970db70 100644 --- a/SRT/CDB/alma/ANTENNA/Boss/Boss.xml +++ b/SRT/CDB/alma/ANTENNA/Boss/Boss.xml @@ -14,19 +14,19 @@ MinPointNumber="25" MaxPointNumber="250" GapTime="200000" - CoordinateIntegration="1000000" - CutOffElevation="70.0" - SkydipElevationRange="15.0 90.0" + CoordinateIntegration="1000000" + CutOffElevation="70.0" + SkydipElevationRange="15.0-90.0" MountInstance="ANTENNA/Mount" ObservatoryInterface="IDL:alma/Antenna/Observatory:1.0" PointingModelInstance="ANTENNA/PointingModel" RefractionInstance="ANTENNA/Refraction" - Sidereal="IDL:alma/Antenna/SkySource:1.0" - Sun="" - Moon="IDL:alma/Antenna/Moon:1.0" - Satellite="" - SolarSystemBody="" - Otf="IDL:alma/Antenna/OTF:1.0"> + Sidereal="IDL:alma/Antenna/SkySource:1.0" + Sun="IDL:alma/Antenna/SolarSystemBody:1.0" + Moon="IDL:alma/Antenna/Moon:1.0" + Satellite="" + SolarSystemBody="IDL:alma/Antenna/SolarSystemBody:1.0" + Otf="IDL:alma/Antenna/OTF:1.0"> <target/> <targetRightAscension/> diff --git a/SRT/Configuration/CDB/MACI/Components/ANTENNA/IncludeDynamic.xml b/SRT/Configuration/CDB/MACI/Components/ANTENNA/IncludeDynamic.xml index ea6e644ba..1ff19de19 100644 --- a/SRT/Configuration/CDB/MACI/Components/ANTENNA/IncludeDynamic.xml +++ b/SRT/Configuration/CDB/MACI/Components/ANTENNA/IncludeDynamic.xml @@ -18,4 +18,9 @@ Type="IDL:alma/Antenna/Moon:1.0" Container="AntennaContainer" ImplLang="cpp"/> + <e Name="*" + Code="SolarSystemBodyImpl" + Type="IDL:alma/Antenna/SolarSystemBody:1.0" + Container="AntennaContainer" + ImplLang="cpp"/> </Components> diff --git a/SRT/Configuration/CDB/alma/ANTENNA/Boss/Boss.xml b/SRT/Configuration/CDB/alma/ANTENNA/Boss/Boss.xml index 918f7dde4..44487b11d 100644 --- a/SRT/Configuration/CDB/alma/ANTENNA/Boss/Boss.xml +++ b/SRT/Configuration/CDB/alma/ANTENNA/Boss/Boss.xml @@ -22,10 +22,10 @@ PointingModelInstance="ANTENNA/PointingModel" RefractionInstance="ANTENNA/Refraction" Sidereal="IDL:alma/Antenna/SkySource:1.0" - Sun="" - Moon="IDL:alma/Antenna/Moon:1.0" - Satellite="" - SolarSystemBody="" + Sun="IDL:alma/Antenna/SolarSystemBody:1.0" + Moon="IDL:alma/Antenna/Moon:1.0" + Satellite="" + SolarSystemBody="IDL:alma/Antenna/SolarSystemBody:1.0" Otf="IDL:alma/Antenna/OTF:1.0"> <target/> diff --git a/SystemMake/Makefile b/SystemMake/Makefile index bede02f70..af500c4ad 100644 --- a/SystemMake/Makefile +++ b/SystemMake/Makefile @@ -30,9 +30,9 @@ COMMON_INTERFACES:=CommonInterface ManagmentInterface AntennaInterface Receivers WeatherStationInterface ActiveSurfaceInterface \ XBackendInterface COMMON_LIBRARIES:=SlaLibrary IRALibrary DiscosVersion TextWindowLibrary ParserLibrary \ - XarcosLibrary ModbusChannel ComponentProxy DiscosLocals \ + XarcosLibrary ModbusChannel ComponentProxy DiscosLocals XEphemAstroLib \ DiscosBackendProtocol PyTestingLibrary \ -COMMON_SERVERS:=AntennaBoss Observatory OTF PointingModel Refraction SkySource \ +COMMON_SERVERS:=AntennaBoss Observatory OTF PointingModel Refraction SkySource SolarSystem \ Moon FitsWriter Scheduler ReceiversBoss ExternalClients \ CalibrationTool TotalPower CustomLogger \ PyDewarPositioner Sardara Skarab PyLocalOscillator MFKBandBaseReceiver PyCalmux \ -- GitLab