EOPStore.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 
44 //------------------------------------------------------------------------------------
45 #include "EOPStore.hpp"
46 //#include "logstream.hpp"
47 
48 //------------------------------------------------------------------------------------
49 using namespace std;
50 
51 namespace gnsstk
52 {
53  // Add to the store directly
54  void EOPStore::addEOP(int mjd, EarthOrientation& eop)
55  {
56  mapMJD_EOP[mjd] = eop;
57 
58  if (begMJD == -1 || endMJD == -1)
59  {
60  begMJD = endMJD = mjd;
61  }
62  else if (mjd < begMJD)
63  {
64  begMJD = mjd;
65  }
66  else if (mjd > endMJD)
67  {
68  endMJD = mjd;
69  }
70  }
71 
72  //---------------------------------------------------------------------------------
73  /* Add to the store by computing using an EOPPrediction file.
74  @param MJD integer MJD(UTC) at which to add EOPs
75  @return non-0 if MJD is outside range */
76  int EOPStore::addEOP(int mjd, EOPPrediction& eopp)
77  {
79  try
80  {
81  eo = eopp.computeEOP(mjd);
82  }
83  catch (Exception& e)
84  {
85  GNSSTK_RETHROW(e);
86  }
87 
88  addEOP(mjd, eo);
89 
90  return 0;
91  }
92 
93  /* Add EOPs to the store via an inpu file: either an EOPP file
94  or a flat file produced by USNO (see http: maia.usno.navy.mil/
95  and get either file 'finals.data' or finals2000A.data').
96  @param filename Name of file to read, including path.
97  @throw if the file is not found */
98  void EOPStore::addFile(const string& filename)
99  {
100  try
101  {
102  addEOPPFile(filename);
103  }
104  catch (FileMissingException& fme)
105  {
106  if (StringUtils::matches(fme.getText(), string("wrong format")).empty())
107  {
108  GNSSTK_RETHROW(fme);
109  }
110 
111  // try other format
112  try
113  {
114  addIERSFile(filename);
115  }
116  catch (FileMissingException& fme)
117  {
118  GNSSTK_RETHROW(fme);
119  }
120  }
121  }
122 
123  //---------------------------------------------------------------------------------
124  /* Add EOPs to the store via an EOPP file: read the EOPPrediction from the
125  file and then compute EOPs for all days within the valid range.
126  @param filename Name of file to read, including path.
127  @throw if the file is not found */
128  void EOPStore::addEOPPFile(const string& filename)
129  {
130  // read the file into an EOPPrediction
131  EOPPrediction eopp;
132  try
133  {
134  eopp.loadFile(filename);
135  }
136  catch (FileMissingException& fme)
137  {
138  GNSSTK_RETHROW(fme);
139  }
140 
141  // pull out the beginning of the valid time range
142  int mjd;
143  mjd = eopp.getValidTime();
144  // add all 7 days
145  for (int i = 0; i < 7; i++)
146  {
147  EarthOrientation eo;
148  eo = eopp.computeEOP(mjd);
149  addEOP(mjd, eo);
150  mjd++;
151  }
152  }
153 
154  //---------------------------------------------------------------------------------
155  // see http://maia.usno.navy.mil/readme.finals
156  void EOPStore::addIERSFile(const string& filename)
157  {
158  bool ok;
159  int n, mjd;
160  double fracmjd;
161  string line, word;
162 
163  ifstream inpf(filename.c_str());
164  if (!inpf)
165  {
166  FileMissingException fme("Could not open IERS file " + filename);
167  GNSSTK_THROW(fme);
168  }
169 
170  ok = true;
171  while (!inpf.eof() && inpf.good())
172  {
173  getline(inpf, line);
174  StringUtils::stripTrailing(line, '\r');
175  if (inpf.eof())
176  {
177  break;
178  }
179  // line length is actually 187
180  if (inpf.bad() || line.size() < 70)
181  {
182  ok = false;
183  break;
184  }
185  EarthOrientation eo;
186  mjd = StringUtils::asInt(line.substr(7, 5));
187  // Bulletin A
188  eo.xp = StringUtils::asDouble(line.substr(18, 9)); // arcseconds
189  eo.yp = StringUtils::asDouble(line.substr(37, 9)); // arcseconds
190  eo.UT1mUTC = StringUtils::asDouble(line.substr(58, 10)); // seconds
191  /* Bulletin B
192  eo.xp = StringUtils::asDouble(line.substr(134,10));
193  arcseconds eo.yp = StringUtils::asDouble(line.substr(144,10));
194  arcseconds eo.UT1mUTC = StringUtils::asDouble(line.substr(154,11));
195  // seconds */
196 
197  addEOP(mjd, eo);
198  };
199  inpf.close();
200 
201  if (!ok)
202  {
203  FileMissingException fme("IERS File " + filename +
204  " is corrupted or wrong format");
205  GNSSTK_THROW(fme);
206  }
207  }
208 
209  //---------------------------------------------------------------------------------
210  /* Edit the store by deleting all entries before(after) the given min(max)
211  MJDs. If mjdmin is later than mjdmax, the two times are switched.
212  @param mjdmin integer MJD desired earliest store time.
213  @param mjdmax integer MJD desired latest store time. */
214  void EOPStore::edit(int mjdmin, int mjdmax)
215  {
216  if (mjdmin > mjdmax)
217  {
218  int m = mjdmin;
219  mjdmin = mjdmax;
220  mjdmax = m;
221  }
222 
223  if (mjdmin > endMJD)
224  {
225  return;
226  }
227  if (mjdmax < begMJD)
228  {
229  return;
230  }
231 
232  map<int, EarthOrientation>::iterator it;
233  it = mapMJD_EOP.lower_bound(mjdmin);
234  if (it != mapMJD_EOP.begin())
235  {
236  mapMJD_EOP.erase(mapMJD_EOP.begin(), it);
237  }
238 
239  it = mapMJD_EOP.upper_bound(mjdmax);
240  if (it != mapMJD_EOP.end())
241  {
242  mapMJD_EOP.erase(it, mapMJD_EOP.end());
243  }
244 
245  it = mapMJD_EOP.begin();
246  if (it == mapMJD_EOP.end())
247  {
248  begMJD = -1;
249  }
250  else
251  {
252  begMJD = it->first;
253  }
254 
255  it = mapMJD_EOP.end();
256  if (--it == mapMJD_EOP.end())
257  {
258  endMJD = -1;
259  }
260  else
261  {
262  endMJD = it->first;
263  }
264  }
265 
266  //---------------------------------------------------------------------------------
267  /* Dump the store to cout.
268  @param detail determines how much detail to include in the output
269  0 start and stop times (MJD), and number of EOPs.
270  1 list of all times and EOPs. */
271  void EOPStore::dump(short detail, ostream& os) const
272  {
273  os << "EOPStore dump (" << mapMJD_EOP.size() << " entries):\n";
274  os << " Time limits: [MJD " << begMJD << " - " << endMJD << "]";
275 
276  int yy, mm, dd;
277  convertJDtoCalendar(static_cast<long>(begMJD + MJD_TO_JD), yy, mm, dd);
278  os << " = [m/d/y " << mm << "/" << dd << "/" << yy;
279  convertJDtoCalendar(static_cast<long>(endMJD + MJD_TO_JD), yy, mm, dd);
280  os << " - " << mm << "/" << dd << "/" << yy << "]" << endl;
281 
282  if (detail > 0)
283  {
284  os << " MJD xp yp UT1-UTC IERS\n";
285  int lastmjd = -1;
286  map<int, EarthOrientation>::const_iterator it;
287  for (it = mapMJD_EOP.begin(); it != mapMJD_EOP.end(); it++)
288  {
289  if (lastmjd != -1 && it->first - lastmjd > 1)
290  {
291  os << " ....." << endl;
292  }
293  os << " " << it->first << " " << it->second << " ("
294  << setfill('0') << setw(3)
295  << EOPPrediction::getSerialNumber(it->first) << setfill(' ')
296  << ")" << endl;
297  lastmjd = it->first;
298  }
299  }
300  }
301 
302  //---------------------------------------------------------------------------------
303  /* Get the EOP at the given epoch. This involves interpolation and
304  corrections as prescribed by the appropriate IERS convention, using code
305  in class EarthOrientation. This routine pulls data from the map for 4
306  entries surrounding the input time; this array of data is passed to class
307  EarthOrientation to perform the interpolation and corrections.
308  @param mjd MJD(UTC) time of interest
309  @param conv IERSConvention to be used.
310  @throw InvalidRequest if the integer MJD falls outside the store,
311  or if the store contains fewer than 4 entries
312  @return EarthOrientation EOPs at mjd. */
313  EarthOrientation EOPStore::getEOP(double mjd,
314  const IERSConvention& conv)
315  {
316  if (mapMJD_EOP.size() < 4)
317  {
318  InvalidRequest ir("Store is too small for interpolation");
319  GNSSTK_THROW(ir);
320  }
321 
322  /* Stored data uses UTC times
323  if(t.getTimeSystem() == TimeSystem::Unknown) {
324  InvalidRequest ir("Time system is unknown");
325  GNSSTK_THROW(ir);
326  } */
327 
328  // get MJD(UTC)
329  double mjdUTC(mjd);
330 
331  // find 4 points surrounding the time of interest ----------------
332  map<int, EarthOrientation>::iterator lowit, hiit, it;
333  it = lowit = mapMJD_EOP.find(int(mjdUTC));
334  (hiit = it)++;
335  if (lowit == mapMJD_EOP.end() || hiit == mapMJD_EOP.end())
336  {
337  InvalidRequest ir("Requested time lies outside the store");
338  GNSSTK_THROW(ir);
339  }
340  if (mapMJD_EOP.size() < 4)
341  {
342  InvalidRequest ir("Store contains less than 4 entries");
343  GNSSTK_THROW(ir);
344  }
345 
346  // low and hi must span 4 entries and bracket t
347  (it = lowit)--;
348  if (it == mapMJD_EOP.end())
349  {
350  hiit++;
351  hiit++; // L t . . H
352  }
353  else
354  {
355  lowit = it;
356  (it = hiit)++;
357  if (it == mapMJD_EOP.end())
358  {
359  lowit--; // L . . t H
360  }
361  else
362  {
363  hiit = it; // L . t . H
364  }
365  }
366 
367  /* fill arrays for Lagrange interpolation -----------------------
368  LOG(INFO) << " LAGINT at " << fixed << setprecision(9) << mjdUTC <<
369  "(UTC)"; */
370  vector<double> vtime, vX, vY, vdT;
371  for (it = lowit; it != mapMJD_EOP.end(); ++it)
372  {
373  vtime.push_back(double(it->first));
374  vX.push_back(it->second.xp);
375  vY.push_back(it->second.yp);
376  /* LOG(INFO) << " xy " << fixed << setprecision(10) <<
377  double(it->first)
378  << " " << it->second.xp << " " << it->second.yp; */
379  vdT.push_back(it->second.UT1mUTC);
380  if (it == hiit)
381  {
382  break;
383  }
384  }
385 
386  // let EarthOrientation do the interpolation and correction -----
387  EarthOrientation eo;
388  EphTime ttag;
389  ttag.setMJD(mjdUTC);
390  ttag.setTimeSystem(TimeSystem::UTC);
391  eo.interpolateEOP(ttag, vtime, vX, vY, vdT, conv);
392 
393  return eo;
394  }
395 
396 } // end namespace gnsstk
gnsstk::dump
void dump(vector< SatPass > &SatPassList, ostream &os, bool rev, bool dbug)
Definition: SatPassUtilities.cpp:59
gnsstk::StringUtils::asInt
long asInt(const std::string &s)
Definition: StringUtils.hpp:713
example6.mjd
mjd
Definition: example6.py:102
gnsstk::StringUtils::word
std::string word(const std::string &s, const std::string::size_type wordNum=0, const char delimiter=' ')
Definition: StringUtils.hpp:1112
gnsstk::EphTime::setTimeSystem
void setTimeSystem(TimeSystem sys)
Definition: EphTime.hpp:141
gnsstk::EOPPrediction::loadFile
int loadFile(const std::string &filename)
Definition: EOPPrediction.cpp:56
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::EOPPrediction::computeEOP
EarthOrientation computeEOP(int &imjd) const
Definition: EOPPrediction.hpp:138
gnsstk::EarthOrientation::yp
double yp
Polar motion angle yp, in arcseconds.
Definition: EarthOrientation.hpp:100
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::EarthOrientation::interpolateEOP
void interpolateEOP(const EphTime &ttag, const std::vector< double > &time, const std::vector< double > &X, const std::vector< double > &Y, std::vector< double > &dT, const IERSConvention &conv)
Definition: EarthOrientation.cpp:158
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
gnsstk::convertJDtoCalendar
void convertJDtoCalendar(long jd, int &iyear, int &imonth, int &iday)
Definition: TimeConverters.cpp:52
gnsstk::EOPPrediction::getValidTime
int getValidTime() const
Definition: EOPPrediction.hpp:112
gnsstk::EphTime
Definition: EphTime.hpp:67
EOPStore.hpp
gnsstk::StringUtils::asDouble
double asDouble(const std::string &s)
Definition: StringUtils.hpp:705
gnsstk::IERSConvention
IERSConvention
Definition: IERSConvention.hpp:69
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
std
Definition: Angle.hpp:142
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::StringUtils::matches
std::string matches(const std::string &s, const std::string &aPattern, const char zeroOrMore=' *', const char oneOrMore='+', const char anyChar='.')
Definition: StringUtils.hpp:1934
gnsstk::EarthOrientation
Definition: EarthOrientation.hpp:93
gnsstk::EphTime::setMJD
void setMJD(long double mjd)
Definition: EphTime.hpp:155
gnsstk::EarthOrientation::xp
double xp
Polar motion angle xp, in arcseconds.
Definition: EarthOrientation.hpp:97
gnsstk::EOPPrediction
Definition: EOPPrediction.hpp:81
gnsstk::EarthOrientation::UT1mUTC
double UT1mUTC
Time offset UT1 minus UTC, in seconds.
Definition: EarthOrientation.hpp:103


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