testSSEph.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
49 // system includes
50 #include <iostream>
51 #include <iomanip>
52 #include <fstream>
53 #include <string>
54 #include <time.h>
55 #include <cmath>
56 
57 // GNSSTk
58 #include "TimeString.hpp"
59 #include "Exception.hpp"
60 #include "StringUtils.hpp"
61 #include "CommonTime.hpp"
62 #include "SystemTime.hpp"
63 #include "SolarSystemEphemeris.hpp"
64 #include "logstream.hpp"
65 #include "FormattedDouble.hpp"
66 
67 
68 
69 using namespace std;
70 using namespace gnsstk;
71 using namespace gnsstk::StringUtils;
72 
73 
74 
75 string Version("1.0 9/10/07");
76 // 1.0
77 
78 
79 
80 // TD
81 
82 
83 
84 // global data
85 string PrgmName; // name of this program - must match Jamfile
86 string Title; // name, version and runtime
87 ofstream logstrm;
88 
89 
90 
91 // prototypes -- this module only
92 
93 
94 
95 int main(int argc, char **argv)
96 {
97  try
98  {
99  clock_t totaltime; // for timing
100  totaltime = clock();
101 
102  // locals
103  int i,iret=0;
104  CommonTime CurrEpoch = SystemTime();
105  SolarSystemEphemeris SSEphemeris;
106 
107  // program name, title and version
108  PrgmName = string("testSSEph");
109  Title = PrgmName + ", test program for JPL ephemeris, version "
110  + Version + ", "
111  + printTime(CurrEpoch,"Run %04Y/%02m/%02d at %02H:%02M:%02S");
112 
113  // default command line input
114  bool verbose=false,debug=false;
115  string inputFilename,testFilename,logFilename;
116 
117  // parse the command line input
118  for (i=0; i<argc; i++)
119  {
120  string word = string(argv[i]);
121  if (argc == 1 || word == "-h" || word == "--help")
122  {
123  cout << "Program " << PrgmName
124  << " reads a binary JPL planetary ephemeris file, created by "
125  << "convertSSEph,\n and a test file, downloaded from the JPL ftp site, "
126  << "containing times and planets\n with JPL-generated ephemeris "
127  << "coordinate values. The coordinates are computed using\n the binary "
128  << "file and the SolarSystemEphemeris class, and compared with the JPL"
129  << " values;\n "
130  << "any difference larger than 10^-13 is noted with the word 'Warning' "
131  << "at EOL.\n Note that some large coordinate values may differ at the "
132  << "level of 10^-13 because the\n size of double precision is barely "
133  << "able to hold that much precision; compare the\n computed value "
134  << "with the JPL value (copied as a string) in the output file.\n "
135  << "Differences larger than 10^-12 are atypical and are noted with "
136  << "the word 'Failure'\n at EOL.\n"
137  << "\n Usage: " << PrgmName << " [options]\n Options are:\n"
138  << " --log <file> name of optional log file (otherwise stderr)\n"
139  << " --file <file> name of binary SS ephemeris file\n"
140  << " --test <file> name of JPL test file (e.g. testpo.403)\n"
141  << " --verbose print info to the log file.\n"
142  << " --debug print debugging info to the log file.\n"
143  << " --help print this and quit.\n"
144  ;
145  return 0;
146  }
147  else if (i == 0)
148  {
149  continue;
150  }
151  else if (word == "-d" || word == "--debug")
152  {
153  debug = true;
154  }
155  else if (word == "-v" || word == "--verbose")
156  {
157  verbose = true;
158  }
159  else if (word == "--log")
160  {
161  logFilename = string(argv[++i]);
162  }
163  else if (word == "--file")
164  {
165  inputFilename = string(argv[++i]);
166  }
167  else if (word == "--test")
168  {
169  testFilename = string(argv[++i]);
170  }
171  }
172 
173  // test input
174  if (inputFilename.empty())
175  {
176  LOG(ERROR) << "Must specify an input binary file name";
177  return -1;
178  }
179  if (testFilename.empty())
180  {
181  LOG(ERROR) << "Must specify an input test file name";
182  return -1;
183  }
184 
185  if (!logFilename.empty())
186  {
187  // choose the log file
188  logstrm.open(logFilename.c_str(),ios_base::out);
189  ConfigureLOG::Stream() = &logstrm;
190  // if not the above, output is to stderr
191 
192  cout << Title << endl;
193  cout << "Output is logged to file " << logFilename << endl;
194  }
195 
196  // set the maximum level to be logged
197  ConfigureLOG::ReportLevels() = ConfigureLOG::ReportTimeTags() = false;
198  if (debug)
199  {
200  ConfigureLOG::ReportingLevel() = ConfigureLOG::FromString("DEBUG");
201  }
202  else if (verbose)
203  {
204  ConfigureLOG::ReportingLevel() = ConfigureLOG::FromString("VERBOSE");
205  }
206  else
207  {
208  ConfigureLOG::ReportingLevel() = ConfigureLOG::FromString("INFO");
209  }
210  // = any of ERROR,WARNING,INFO,VERBOSE,DEBUG,DEBUGn (n=1,2,3,4,5,6,7)
211  //cout << "Reporting in main is "
212  // << ConfigureLOG::ToString(ConfigureLOG::ReportingLevel()) << endl;
213 
214  // display title in the log file
215  LOG(INFO) << Title;
216 
217  // now read the binary file, and read selected records
218  // use the binary to test using the JPL file testpo.<EPH#>
219  LOG(VERBOSE) << "Initialize with file " << inputFilename;
220  SSEphemeris.initializeWithBinaryFile(inputFilename);
221  LOG(VERBOSE) << "End Initialize";
222  LOG(INFO) << "Ephemeris number is " << SSEphemeris.EphNumber();
223 
224  bool foundEOT=false;
225  int target,center,coord;
226  double JD,PV[6],value,diff;
227  SolarSystemEphemeris::Planet Target,Center;
228  ifstream istrm;
229 
230  istrm.open(testFilename.c_str(),ios::in);
231  if (!istrm.is_open())
232  {
233  LOG(ERROR) << "Could not open test file " << testFilename;
234  }
235  else while (1)
236  {
237  string line,word;
238  getline(istrm,line);
239  stripTrailing(line,'\r');
240  strip(line);
241  if (line.empty())
242  {
243  }
244  else if (line == string("EOT"))
245  {
246  foundEOT = true;
247  }
248  else if (!foundEOT)
249  {
250  }
251  else
252  {
253  word = stripFirstWord(line); // DEPHEM
254  word = stripFirstWord(line); // date in YYYY.MM.DD form
255  JD = FormattedDouble(stripFirstWord(line),26,'D');
256  target = asInt(stripFirstWord(line));
257  center = asInt(stripFirstWord(line));
258  coord = asInt(stripFirstWord(line)) - 1; // my coords are 0-5, theirs 1-6
259  word = stripFirstWord(line);
260  value = FormattedDouble(word,26,'D');
261  word = rightJustify(word,25);
262 
263  Target = SolarSystemEphemeris::Planet(target);
265  try
266  {
268  JD-MJD_TO_JD, Target, Center, PV, false);
269  }
270  catch(Exception& e)
271  {
272  string what=e.getText(0);
273  if (isLike(what,string("Requested time is before .*")))
274  {
275  iret=1;
276  }
277  else if (isLike(what,string("Requested time is after .*")))
278  {
279  iret=2;
280  }
281  else if (isLike(what,string("Stream error .*")))
282  {
283  iret=3;
284  }
285  else if (isLike(what,string("Ephemeris not initialized .*")))
286  {
287  iret=4;
288  }
289  else
290  {
291  iret = 5;
292  }
293  if (iret==1)
294  {
295  continue;
296  }
297  if (iret==2)
298  {
299  iret = 0;
300  }
301  break;
302  }
303 
304  diff = ::fabs(PV[coord]-value);
305  // NB The original JPL code (testeph.f) prints
306  // "Warning" when the difference is > 1.e-13
307  LOG(INFO) << fixed << setprecision(1) << setw(9) << JD
308  << " " << setw(2) << target
309  //<< " " << setw(2) << Target
310  << " " << setw(2) << center
311  //<< " " << setw(2) << Center
312  << " " << setw(1) << coord+1
313  << " " << scientific << setprecision(5) << setw(13)
314  << diff
315  << " " << word
316  << " " << fixed << setprecision(20) << setw(25)
317  << PV[coord]
318  << " " << iret
319  << (diff > 1.e-12 ? (diff > 1.e-11 ? " Failure"
320  : " Warning") : "");
321 
322  if (diff > 1.e-11)
323  {
324  iret = 6;
325  break;
326  }
327  }
328 
329  if (istrm.eof() || !istrm.good())
330  {
331  break;
332  }
333  }
334 
335  if (iret)
336  {
337  LOG(ERROR) << " Error - " << PrgmName
338  << " terminating with error code " << iret << ": " <<
339  (iret == 1 ? "time is before first time in ephemeris" :
340  (iret == 2 ? "time is beyond end time of ephemeris" :
341  (iret == 3 ? "file reading failed" :
342  (iret == 4 ? "ephemeris file not initialized" :
343  (iret == 5 ? "unknown error" : "accuracy failure")))));
344  }
345 
346  // compute run time
347  totaltime = clock()-totaltime;
348  LOG(INFO) << PrgmName << " iret " << iret
349  << " timing: " << fixed << setprecision(9)
350  << double(totaltime)/double(CLOCKS_PER_SEC) << " seconds.";
351 
352  return iret;
353  }
354  catch(Exception& e)
355  {
356  LOG(ERROR) << "GNSSTk Exception : " << e.what();
357  }
358  catch (...)
359  {
360  LOG(ERROR) << "Unknown error in " << PrgmName << ". Abort." << endl;
361  }
362  return -1;
363 } // end main()
364 
gnsstk::StringUtils::asInt
long asInt(const std::string &s)
Definition: StringUtils.hpp:713
logstrm
ofstream logstrm
Definition: testSSEph.cpp:87
gnsstk::SolarSystemEphemeris::initializeWithBinaryFile
int initializeWithBinaryFile(const std::string &filename)
Definition: SolarSystemEphemeris.cpp:874
PrgmName
string PrgmName
Definition: testSSEph.cpp:85
gnsstk::StringUtils::word
std::string word(const std::string &s, const std::string::size_type wordNum=0, const char delimiter=' ')
Definition: StringUtils.hpp:1112
Version
string Version("1.0 9/10/07")
StringUtils.hpp
gnsstk::StringUtils::center
std::string & center(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1607
gnsstk::Exception::what
std::string what() const
Dump to a string.
Definition: Exception.cpp:193
logstream.hpp
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::SolarSystemEphemeris::EphNumber
int EphNumber() const
Definition: SolarSystemEphemeris.hpp:303
gnsstk::MJD_TO_JD
const double MJD_TO_JD
Add this offset to convert Modified Julian Date to Julian Date.
Definition: TimeConstants.hpp:51
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::StringUtils::stripTrailing
std::string & stripTrailing(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1453
Title
string Title
Definition: testSSEph.cpp:86
gnsstk::Exception::getText
std::string getText(const size_t &index=0) const
Definition: Exception.cpp:139
gnsstk::FormattedDouble
Definition: FormattedDouble.hpp:70
SolarSystemEphemeris.hpp
gnsstk::SolarSystemEphemeris::Planet
Planet
These are indexes used by the caller of inertialPositionVelocity().
Definition: SolarSystemEphemeris.hpp:110
debug
#define debug
Definition: Rinex3ClockHeader.cpp:51
SystemTime.hpp
gnsstk::ERROR
@ ERROR
Definition: logstream.hpp:57
gnsstk::SystemTime
Definition: SystemTime.hpp:54
gnsstk::CommonTime
Definition: CommonTime.hpp:84
gnsstk::SolarSystemEphemeris
Definition: SolarSystemEphemeris.hpp:96
gnsstk::StringUtils::stripFirstWord
std::string stripFirstWord(std::string &s, const char delimiter=' ')
Definition: StringUtils.hpp:2253
main
int main(int argc, char **argv)
Definition: testSSEph.cpp:95
gnsstk::VERBOSE
@ VERBOSE
Definition: logstream.hpp:57
FormattedDouble.hpp
gnsstk::SolarSystemEphemeris::relativeInertialPositionVelocity
void relativeInertialPositionVelocity(double MJD, Planet target, Planet center, double PV[6], bool kilometers=true)
Definition: SolarSystemEphemeris.cpp:916
gnsstk::StringUtils
Definition: IonexStoreStrategy.cpp:44
gnsstk::StringUtils::isLike
bool isLike(const std::string &s, const std::string &aPattern, const char zeroOrMore=' *', const char oneOrMore='+', const char anyChar='.')
Definition: StringUtils.hpp:948
gnsstk::StringUtils::rightJustify
std::string & rightJustify(std::string &s, const std::string::size_type length, const char pad=' ')
Definition: StringUtils.hpp:1557
LOG
#define LOG(level)
define the macro that is used to write to the log stream
Definition: logstream.hpp:315
gnsstk::printTime
std::string printTime(const CommonTime &t, const std::string &fmt)
Definition: TimeString.cpp:64
Exception.hpp
CommonTime.hpp
std
Definition: Angle.hpp:142
gnsstk::INFO
@ INFO
Definition: logstream.hpp:57
gnsstk::StringUtils::strip
std::string & strip(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1482
TimeString.hpp


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:42