AtmLoadTides.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 
40 
41 // system includes
42 #include <algorithm>
43 #include <fstream>
44 #include <iostream>
45 // GNSSTk
46 #include "GNSSconstants.hpp"
47 #include "MiscMath.hpp"
48 #include "StringUtils.hpp"
49 // geomatics
50 #include "AtmLoadTides.hpp"
51 //#include "logstream.hpp" // TEMP
52 
53 using namespace std;
54 
55 namespace gnsstk
56 {
57 
58  using namespace StringUtils;
59 
60  //---------------------------------------------------------------------------------
61  /* Open and read the given file, containing atmospheric loading coefficients,
62  and initialize this object for the sites names in the input list that
63  match a name in the file (case sensitive). Return the number of
64  successfully initialized site names, and remove those sites from the input
65  list. Atmospheric loading files can be obtained by running the program
66  grdinterp.f
67  param sites vector<string> On input contains site labels
68  found in the file, on output contains only sites
69  that were NOT found.
70  If sites is empty, all sites are loaded.
71  param filename string Input atmospheric loading file name.
72  return the number of sites successfully initialized.
73  throw if the file could not be opened.
74  */
75  int AtmLoadTides::initializeSites(vector<string>& sites, string filename)
76  {
77  try
78  {
79  bool allsites = false;
80  if (sites.size() == 0)
81  {
82  allsites = true;
83  }
84  int i, nwant, nfound;
85 
86  ifstream infile(filename.c_str());
87  if (!infile || !infile.is_open())
88  {
89  Exception e("File " + filename + " could not be opened.");
90  GNSSTK_THROW(e);
91  }
92 
93  nwant = sites.size();
94  nfound = 0; // number of successes
95  bool looking = true; // true if looking for a site name
96  double lat, lon;
97  vector<double> coeff;
98  string site;
99  while (1)
100  { // read the file
101  int count;
102  string line, word;
103 
104  // get the next line
105  getline(infile, line);
106  stripTrailing(line, '\r');
107  stripLeading(line);
108 
109  // process line
110  if (!line.empty())
111  {
112  word = firstWord(line);
113  // LOG(INFO) << "Word is " << word << " and line is " << line;
114 
115  if (word == "$$")
116  { // NB ignore header - assume column order, etc.
117  // pick out the lat/lon
118  while (!line.empty())
119  {
120  word = stripFirstWord(line);
121  if (word == string("station"))
122  {
123  site = stripFirstWord(line);
124  stripTrailing(site, ';');
125  }
126  if (word == string("coord.(long,lat)"))
127  {
128  lon = asDouble(stripFirstWord(line));
129  lat = asDouble(stripFirstWord(line));
130  // LOG(INFO) << "Found coords for site " << site << " "
131  // << fixed << setprecision(6) << lon << " " <<
132  // lat;
133  break;
134  }
135  }
136  }
137  else if (looking && line.length() <= 40)
138  { // site
139  // site name
140  site = line;
141  // LOG(INFO) << "Found site " << site;
142  if (allsites)
143  {
144  // LOG(INFO) << "Push back " << site;
145  looking = false;
146  sites.push_back(site);
147  }
148  else
149  {
150  for (i = 0; i < sites.size(); i++)
151  {
152  // LOG(INFO) << "Compare " << sites[i];
153  if (site == sites[i])
154  {
155  looking = false;
156  break;
157  }
158  }
159  }
160  if (!looking)
161  { // found a site
162  count = 0;
163  coeff.clear();
164  }
165  }
166  else if (!looking)
167  { // not comment and not looking - must be data
168  if (numWords(line) != 4)
169  {
170  Exception e("File " + filename +
171  " is corrupted for site " + site +
172  " - offending line follows\n" + line);
173  GNSSTK_THROW(e);
174  }
175  // LOG(INFO) << "Push back line " << line;
176  for (i = 0; i < 4; i++)
177  coeff.push_back(asDouble(stripFirstWord(line)));
178  count++;
179  if (count == 3)
180  { // success
181  ostringstream oss;
182  oss << fixed;
183  for (i = 0; i < coeff.size(); i++)
184  {
185  oss << " " << setprecision(4) << setw(7) << coeff[i];
186  if ((i + 1) % 4 == 0)
187  {
188  oss << "\n";
189  }
190  }
191  // LOG(INFO) << " Found site " << site << " with
192  // coefficients:"; LOG(INFO) << oss.str();
193 
194  // update coeff map
195  coefficientMap[site] = coeff;
196  nfound++;
197  // update position map
198  coeff.clear();
199  coeff.push_back(lat);
200  coeff.push_back(lon);
201  positionMap[site] = coeff;
202  // LOG(INFO) << "pushback coords for site " << site << " "
203  // << fixed << setprecision(6) << lon << " " <<
204  // lat;
205 
206  // erase a vector element
207  if (!allsites)
208  {
209  vector<string>::iterator pos;
210  pos = find(sites.begin(), sites.end(), site);
211  if (pos != sites.end())
212  {
213  sites.erase(pos);
214  }
215  }
216  looking = true;
217  }
218  }
219 
220  } // end if line not empty
221 
222  if (!allsites && nfound >= nwant)
223  {
224  break;
225  }
226 
227  if (infile.eof() || !infile.good())
228  {
229  break;
230  }
231 
232  } // end loop over lines in the file
233 
234  return nfound;
235  }
236  catch (Exception& e)
237  {
238  GNSSTK_RETHROW(e);
239  }
240  catch (exception& e)
241  {
242  Exception E("std except: " + string(e.what()));
243  GNSSTK_THROW(E);
244  }
245  catch (...)
246  {
247  Exception e("Unknown exception");
248  GNSSTK_THROW(e);
249  }
250  }
251 
252  //---------------------------------------------------------------------------------
253  /* Compute the site displacement vector at the given time for the given site.
254  The site must have been successfully initialized; if not an exception is
255  thrown.
256  param site string Input name of the site; must be the same as previously
257  successfully passed to initializeSites().
258  param t EphTime Input time of interest.
259  param UT1mUTC Difference of UT1 and UTC, a very small correction to t.
260  return Triple containing the North, East and Up components of the site
261  displacement in meters.
262  throw if the site has not been initialized, if the time system is unknown,
263  if there is corruption in the static arrays.
264  */
265  Triple AtmLoadTides::computeDisplacement(string site, EphTime time,
266  double UT1mUTC)
267  {
268  try
269  {
270 
271  // get the coefficients for this site
272  if (coefficientMap.find(site) == coefficientMap.end())
273  {
274  GNSSTK_THROW(
275  Exception("Site not found in atmospheric loading store"));
276  }
277  vector<double> coeff = coefficientMap[site];
278 
279  // compute time argument
280  EphTime ttag(time);
281  ttag.convertSystemTo(TimeSystem::UTC);
282  // ignoring UT1-UTC is probably fine, since this is extremely small
283  ttag += UT1mUTC;
284  double dayfr(ttag.secOfDay() / 86400.0); // fraction of day
285  static const double w1(2 * PI), w2(4 * PI);
286  const double cos1(::cos(w1 * dayfr));
287  const double sin1(::sin(w1 * dayfr));
288  const double cos2(::cos(w2 * dayfr));
289  const double sin2(::sin(w2 * dayfr));
290 
291  /* NB Displacement is defined positive up, north
292  and east directions, and is in millimeters
293 
294  total d(t) = d(1)*cos(t*w1) + d(2)*sin(t*w1)
295  + d(3)*cos(t*w2) + d(4)*sin(t*w2)
296  If t is fractions of a UT1 day,
297  then w1=2pi radians/day and w2=4pi radians/day.
298 
299  Column order coss1 sins1 coss2 sins2
300  Row (coeff) order: RADIAL NS EW
301  */
302 
303  Triple dc; // dc is NEU, so must RAD,N,E -> NEU
304  dc[2] = coeff[0] * cos1 + coeff[1] * sin1 + coeff[2] * cos2 +
305  coeff[3] * sin2;
306  dc[0] = coeff[4] * cos1 + coeff[5] * sin1 + coeff[6] * cos2 +
307  coeff[7] * sin2;
308  dc[1] = coeff[8] * cos1 + coeff[9] * sin1 + coeff[10] * cos2 +
309  coeff[11] * sin2;
310  // convert to meters
311  dc[0] /= 1000.0;
312  dc[1] /= 1000.0;
313  dc[2] /= 1000.0;
314 
315  return dc;
316  }
317  catch (Exception& e)
318  {
319  GNSSTK_RETHROW(e);
320  }
321  catch (exception& e)
322  {
323  Exception E("std except: " + string(e.what()));
324  GNSSTK_THROW(E);
325  }
326  catch (...)
327  {
328  Exception e("Unknown exception");
329  GNSSTK_THROW(e);
330  }
331 
332  } // end Triple AtmLoadTides::computeDisplacement
333 
334 } // end namespace gnsstk
gnsstk::EphTime::convertSystemTo
void convertSystemTo(const TimeSystem &ts)
Definition: EphTime.hpp:96
AtmLoadTides.hpp
coeff
static const struct @1 coeff[]
Constants used in the nutation models, adapted from SOFA nut80.c.
gnsstk::StringUtils::word
std::string word(const std::string &s, const std::string::size_type wordNum=0, const char delimiter=' ')
Definition: StringUtils.hpp:1112
StringUtils.hpp
gnsstk::PI
const double PI
GPS value of PI; also specified by GAL.
Definition: GNSSconstants.hpp:62
GNSSconstants.hpp
gnsstk::Triple
Definition: Triple.hpp:68
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::StringUtils::stripLeading
std::string & stripLeading(std::string &s, const std::string &aString, std::string::size_type num=std::string::npos)
Definition: StringUtils.hpp:1426
std::sin
double sin(gnsstk::Angle x)
Definition: Angle.hpp:144
MiscMath.hpp
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::StringUtils::numWords
int numWords(const std::string &s, const char delimiter=' ')
Definition: StringUtils.hpp:2171
example4.time
time
Definition: example4.py:103
gnsstk::EphTime
Definition: EphTime.hpp:67
gnsstk::StringUtils::stripFirstWord
std::string stripFirstWord(std::string &s, const char delimiter=' ')
Definition: StringUtils.hpp:2253
std::cos
double cos(gnsstk::Angle x)
Definition: Angle.hpp:146
gnsstk::StringUtils::asDouble
double asDouble(const std::string &s)
Definition: StringUtils.hpp:705
GNSSTK_RETHROW
#define GNSSTK_RETHROW(exc)
Definition: Exception.hpp:369
example4.pos
pos
Definition: example4.py:125
std
Definition: Angle.hpp:142
gnsstk::EphTime::secOfDay
double secOfDay() const
Definition: EphTime.hpp:177
gnsstk::StringUtils::firstWord
std::string firstWord(const std::string &s, const char delimiter=' ')
Definition: StringUtils.hpp:2138
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366


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