SinexData.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 #include "StringUtils.hpp"
45 #include "SinexStream.hpp"
46 #include "SinexData.hpp"
47 #include "SinexTypes.hpp"
48 
49 using namespace gnsstk::StringUtils;
50 using namespace std;
51 
52 namespace gnsstk
53 {
54 namespace Sinex
55 {
56 
58  BlockFactory Data::blockFactory;
59 
60 
61  void
62  Data::initBlockFactory()
63  {
64  if (blockFactory.size() > 0) return;
65 
66  blockFactory["FILE/REFERENCE"] = Block<FileReference>::create;
67  blockFactory["FILE/COMMENT"] = Block<FileComment>::create;
68  blockFactory["INPUT/HISTORY"] = Block<InputHistory>::create;
69  blockFactory["INPUT/FILES"] = Block<InputFile>::create;
70  blockFactory["INPUT/ACKNOWLEDGMENTS"] = Block<InputAck>::create;
71  blockFactory["INPUT/ACKNOWLEDGEMENTS"] = Block<InputAck>::create;
72  blockFactory["NUTATION/DATA"] = Block<NutationData>::create;
73  blockFactory["PRECESSION/DATA"] = Block<PrecessionData>::create;
74  blockFactory["SOURCE/ID"] = Block<SourceId>::create;
75  blockFactory["SITE/ID"] = Block<SiteId>::create;
76  blockFactory["SITE/DATA"] = Block<SiteData>::create;
77  blockFactory["SITE/RECEIVER"] = Block<SiteReceiver>::create;
78  blockFactory["SITE/ANTENNA"] = Block<SiteAntenna>::create;
79  blockFactory["SITE/GPS_PHASE_CENTER"] = Block<SiteGpsPhaseCenter>::create;
80  blockFactory["SITE/GAL_PHASE_CENTER"] = Block<SiteGalPhaseCenter>::create;
81  blockFactory["SITE/ECCENTRICITY"] = Block<SiteEccentricity>::create;
82  blockFactory["SATELLITE/ID"] = Block<SatelliteId>::create;
83  blockFactory["SATELLITE/PHASE_CENTER"] = Block<SatellitePhaseCenter>::create;
84  blockFactory["BIAS/EPOCHS"] = Block<BiasEpoch>::create;
85  blockFactory["SOLUTION/EPOCHS"] = Block<SolutionEpoch>::create;
86  blockFactory["SOLUTION/STATISTICS"] = Block<SolutionStatistics>::create;
87  blockFactory["SOLUTION/ESTIMATE"] = Block<SolutionEstimate>::create;
88  blockFactory["SOLUTION/APRIORI"] = Block<SolutionApriori>::create;
89  blockFactory["SOLUTION/MATRIX_ESTIMATE L CORR"] = Block<SolutionMatrixEstimateLCorr>::create;
90  blockFactory["SOLUTION/MATRIX_ESTIMATE L COVA"] = Block<SolutionMatrixEstimateLCova>::create;
91  blockFactory["SOLUTION/MATRIX_ESTIMATE L INFO"] = Block<SolutionMatrixEstimateLInfo>::create;
92  blockFactory["SOLUTION/MATRIX_ESTIMATE U CORR"] = Block<SolutionMatrixEstimateUCorr>::create;
93  blockFactory["SOLUTION/MATRIX_ESTIMATE U COVA"] = Block<SolutionMatrixEstimateUCova>::create;
94  blockFactory["SOLUTION/MATRIX_ESTIMATE U INFO"] = Block<SolutionMatrixEstimateUInfo>::create;
95  blockFactory["SOLUTION/MATRIX_APRIORI L CORR"] = Block<SolutionMatrixAprioriLCorr>::create;
96  blockFactory["SOLUTION/MATRIX_APRIORI L COVA"] = Block<SolutionMatrixAprioriLCova>::create;
97  blockFactory["SOLUTION/MATRIX_APRIORI L INFO"] = Block<SolutionMatrixAprioriLInfo>::create;
98  blockFactory["SOLUTION/MATRIX_APRIORI U CORR"] = Block<SolutionMatrixAprioriUCorr>::create;
99  blockFactory["SOLUTION/MATRIX_APRIORI U COVA"] = Block<SolutionMatrixAprioriUCova>::create;
100  blockFactory["SOLUTION/MATRIX_APRIORI U INFO"] = Block<SolutionMatrixAprioriUInfo>::create;
101  blockFactory["SOLUTION/NORMAL_EQUATION_VECTOR"] = Block<SolutionNormalEquationVector>::create;
102  blockFactory["SOLUTION/NORMAL_EQUATION_MATRIX L"] = Block<SolutionNormalEquationMatrixL>::create;
103  blockFactory["SOLUTION/NORMAL_EQUATION_MATRIX U"] = Block<SolutionNormalEquationMatrixU>::create;
104 
105  } // Data::initBlockFactory()
106 
107 
108  Data::~Data()
109  {
110  BlockIter i = blocks.begin();
111  for ( ; i != blocks.end(); ++i)
112  {
113  delete (*i);
114  *i = NULL;
115  }
116  } // Data::~Data()
117 
118 
119  void
120  Data::reallyPutRecord(FFStream& s) const
121  {
122  Sinex::Stream& strm = dynamic_cast<Sinex::Stream&>(s);
123  try
124  {
125  strm << (std::string)header << endl;
126  }
127  catch (Exception& exc)
128  {
129  FFStreamError err;
130  GNSSTK_THROW(err);
131  }
132  Blocks::const_iterator i = blocks.begin();
133  for ( ; i != blocks.end(); ++i)
134  {
135  const BlockBase *block = *i;
136  if (block)
137  {
139  try
140  {
141  strm << BLOCK_START << block->getTitle() << endl;
142  block->putBlock(strm);
143  strm << BLOCK_END << block->getTitle() << endl;
144  }
145  catch (Exception& exc)
146  {
147  FFStreamError err(exc);
148  GNSSTK_THROW(err);
149  }
150  }
151  }
152  strm << FILE_END << endl;
153 
154  } // Data::reallyPutRecord()
155 
156 
157  void
158  Data::reallyGetRecord(FFStream& s)
159  {
160  Sinex::Stream& strm = dynamic_cast<Sinex::Stream&>(s);
161  bool terminated = false;
162  string currentBlock;
163  string line;
164  blocks.clear();
165  strm.formattedGetLine(line, true);
166  try
167  {
168  header = line;
169  }
170  catch (Exception& exc)
171  {
172  FFStreamError err(exc);
173  GNSSTK_THROW(err);
174  }
175  while (strm.good() )
176  {
177  try
178  {
179  strm.formattedGetLine(line, true);
180  }
181  catch (EndOfFile& e)
182  {
183  break;
184  }
185  if (line.size() < 1)
186  {
187  FFStreamError err("Invalid empty line.");
188  GNSSTK_THROW(err);
189  }
190  switch (line[0])
191  {
192  case BLOCK_START:
193  {
194  if (currentBlock.size() > 0)
195  {
196  FFStreamError err("Unexpected start of block.");
197  GNSSTK_THROW(err);
198  }
199  currentBlock = line.substr(1);
200  BlockFactory::iterator i = blockFactory.find(currentBlock);
201  if (i == blockFactory.end() )
202  {
203  string errMsg("Invalid block title: ");
204  FFStreamError err(errMsg + currentBlock);
205  GNSSTK_THROW(err);
206  }
207  BlockCreateFunc createFunc = i->second;
208  BlockBase *block = createFunc();
209  if (block)
210  {
211  try
212  {
213  block->getBlock(strm);
214  blocks.push_back(block);
215  }
216  catch (Exception& exc)
217  {
218  FFStreamError err(exc);
219  GNSSTK_THROW(err);
220  }
221  }
222  else
223  {
224  string errMsg("Error creating block: ");
225  FFStreamError err(errMsg + currentBlock);
226  GNSSTK_THROW(err);
227  }
228  break;
229  }
230  case BLOCK_END:
231  {
232  if (currentBlock.size() == 0)
233  {
234  FFStreamError err("Unexpected end of block.");
235  GNSSTK_THROW(err);
236  }
237  if (currentBlock.compare(line.substr(1) ) != 0)
238  {
239  FFStreamError err("Block start and end do not match.");
240  GNSSTK_THROW(err);
241  }
242  currentBlock.clear();
243  break;
244  }
245  case DATA_START:
246  {
247  FFStreamError err("Missing start of block.");
248  GNSSTK_THROW(err);
249  break;
250  }
251  case HEAD_TAIL_START:
252  {
253  if (line.compare("%ENDSNX") == 0)
254  {
255  terminated = true;
256  }
257  else
258  {
259  string errMsg("Invalid line: ");
260  FFStreamError err(errMsg + line);
261  GNSSTK_THROW(err);
262  }
263  break;
264  }
265  case COMMENT_START:
266  {
268  break;
269  }
270  default:
271  {
272  string errMsg("Invalid line start character: ");
273  FFStreamError err(errMsg + line[0]);
274  GNSSTK_THROW(err);
275  break;
276  }
277 
278  } // switch
279  }
280  if (currentBlock.size() > 0)
281  {
282  string errMsg("Block not properly terminated: ");
283  FFStreamError err(errMsg + currentBlock);
284  GNSSTK_THROW(err);
285  }
286  if (!terminated)
287  {
288  FFStreamError err("File not properly terminated (missing "
289  + FILE_END + " )");
290  GNSSTK_THROW(err);
291  }
292  } // Data::reallyGetRecord()
293 
294 
295  bool Data::isValidBlockTitle(const std::string& title)
296  {
297  initBlockFactory();
298  BlockFactory::iterator i = blockFactory.find(title);
299  return (i == blockFactory.end() ) ? false: true;
300 
301  } // Data::isValidBlockTitle()
302 
303 
304  void
305  Data::dump(std::ostream& s) const
306  {
307  Blocks::const_iterator i = blocks.begin();
308  for ( ; i != blocks.end(); ++i)
309  {
310  const BlockBase *block = *i;
311  if (block)
312  {
313  s << setw(6) << block->getSize() << " "
314  << block->getTitle() << endl;
315  }
316  }
317  } // Data::dump()
318 
319 } // namespace Sinex
320 
321 } // namespace gnsstk
gnsstk::Sinex::BLOCK_END
const char BLOCK_END
Definition: SinexBase.hpp:62
gnsstk::Sinex::BlockFactory
std::map< std::string, BlockCreateFunc > BlockFactory
Mapping from block titles to block create functions.
Definition: SinexBlock.hpp:221
gnsstk::dump
void dump(vector< SatPass > &SatPassList, ostream &os, bool rev, bool dbug)
Definition: SatPassUtilities.cpp:59
SinexStream.hpp
example3.header
header
Definition: example3.py:22
gnsstk::Sinex::Stream
Definition: SinexStream.hpp:62
gnsstk::FFStream
Definition: FFStream.hpp:119
StringUtils.hpp
gnsstk::FFTextStream::formattedGetLine
void formattedGetLine(std::string &line, const bool expectEOF=false)
Definition: FFTextStream.cpp:149
gnsstk::Sinex::Block
Definition: SinexBlock.hpp:117
NULL
#define NULL
Definition: getopt1.c:64
gnsstk::Sinex::BlockBase::getBlock
virtual size_t getBlock(Sinex::Stream &s)=0
SinexTypes.hpp
gnsstk::Sinex::BlockIter
Blocks::iterator BlockIter
Block iterator.
Definition: SinexBlock.hpp:215
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
SinexData.hpp
gnsstk::Exception
Definition: Exception.hpp:151
gnsstk::Sinex::HEAD_TAIL_START
const char HEAD_TAIL_START
Definition: SinexBase.hpp:60
example4.err
err
Definition: example4.py:126
gnsstk::Sinex::FILE_END
const std::string FILE_END("%ENDSNX")
gnsstk::Sinex::BLOCK_START
const char BLOCK_START
Definition: SinexBase.hpp:61
gnsstk::Sinex::BlockBase::getSize
virtual size_t getSize() const =0
gnsstk::StringUtils
Definition: IonexStoreStrategy.cpp:44
std
Definition: Angle.hpp:142
gnsstk::Sinex::BlockBase::putBlock
virtual size_t putBlock(Sinex::Stream &s) const =0
gnsstk::Sinex::BlockBase::getTitle
virtual std::string getTitle() const =0
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
gnsstk::Sinex::COMMENT_START
const char COMMENT_START
Definition: SinexBase.hpp:63
gnsstk::Sinex::BlockCreateFunc
BlockBase *(* BlockCreateFunc)()
Function pointer for invoking create methods for blocks.
Definition: SinexBlock.hpp:218
gnsstk::Sinex::BlockBase
Definition: SinexBlock.hpp:63
gnsstk::Sinex::DATA_START
const char DATA_START
Definition: SinexBase.hpp:64


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