General Purpose Geodetic Library
SgExternalErpFile.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is a part of Space Geodetic Library. The library is used by
4  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
5  * geodetic VLBI observations.
6  * Copyright (C) 2010-2020 Sergei Bolotin.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 
24 #include <math.h>
25 
26 
27 #include <QtCore/QFile>
28 #include <QtCore/QStringList>
29 #include <QtCore/QTextStream>
30 
31 #include <SgExternalErpFile.h>
32 #include <SgLogger.h>
33 #include <SgMatrix.h>
34 #include <SgVector.h>
35 
36 
37 
38 
39 /*=======================================================================================================
40 *
41 * SgExternalEopFile's METHODS:
42 *
43 *======================================================================================================*/
44 //
45 // static first:
47 {
48  return "SgExternalEopFile";
49 };
50 
51 
52 
53 // A destructor:
55 {
56  if (argument_)
57  {
58  delete argument_;
59  argument_ = NULL;
60  };
61  if (eopTable_)
62  {
63  delete eopTable_;
64  eopTable_ = NULL;
65  };
66 };
67 
68 
69 
70 //
71 bool SgExternalEopFile::readFile(const QString& fileName, const SgMJD& tMean, int numOfPoints)
72 {
73  int num;
74  num = 5;
75  isOk_ = false;
76 
77  //
78  if (fileName.right(4) == ".erp")
79  {
81  }
82  else if (fileName.right(5) == ".data")
83  {
85  }
86  else if (fileName.right(4) == ".txt")
87  {
89  }
90  else
92 
94  {
96  ": readFile(): uknown file type of the file \"" + fileName + "\"; import is not possible");
97  return isOk_;
98  };
99 
100  if (argument_)
101  delete argument_;
102  argument_ = new SgVector(numOfPoints);
103  if (eopTable_)
104  delete eopTable_;
105  eopTable_ = new SgMatrix(numOfPoints, num);
106 
107  if (inputEopType_ == IET_ERP)
108  isOk_ = readErpFile(fileName, tMean, numOfPoints);
109  else if (inputEopType_ == IET_FINALS)
110  isOk_ = readFinalsFile(fileName, tMean, numOfPoints);
111  else if (inputEopType_ == IET_C04)
112  isOk_ = readC04File(fileName, tMean, numOfPoints);
113 
114 
115  if (!isOk_)
116  {
117  delete argument_;
118  argument_ = NULL;
119  delete eopTable_;
120  eopTable_ = NULL;
121  };
122  return isOk_;
123 };
124 
125 
126 
127 //
128 bool SgExternalEopFile::readErpFile(const QString& fileName, const SgMJD& tMean, int numOfPoints)
129 {
130  bool isOk(false);
131  QFile f(fileName);
132  if (!f.exists())
133  {
135  ": readErpFile(): the ERP file [" + fileName +
136  "] does not exist; import of external ERP is not possible");
137  return false;
138  };
139  QString str;
140 
141  if (f.open(QFile::ReadOnly))
142  {
143  QTextStream s(&f);
144  str = s.readLine();
145  // parse first record:
146  // 1 2 3 4 5 6 7 8
147  //012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
148  //EOP-MOD Ver 2.0 2444074.5 1.0 12122 UT1-TAI UNDEF
149  if (str.mid(0, 15) != "EOP-MOD Ver 2.0" || str.length()<57)
150  {
151  f.close();
152  s.setDevice(NULL);
154  ": readErpFile(): the ERP file [" + fileName +
155  "] is not real ERP file or its version is unknown; import is not possible");
156  return false;
157  };
158  SgMJD t0(tZero);
159  double d, step(0.0);
160  int numOfRecords(0);
161  d = str.mid(17, 9).toDouble(&isOk);
162  if (!isOk)
163  {
164  f.close();
165  s.setDevice(NULL);
167  ": readErpFile(): problems with the ERP file [" + fileName +
168  "]: cannot determine declared first epoch (orig='" + str.mid(17, 9) +
169  "'); import is not possible");
170  return false;
171  };
172  d -= 2400000.5;
173  t0 = d;
174  step = str.mid(28, 4).toDouble(&isOk);
175  if (!isOk)
176  {
177  f.close();
178  s.setDevice(NULL);
180  ": readErpFile(): problems with the ERP file [" + fileName +
181  "]: cannot determine declared spacing (orig='" + str.mid(28, 4) +
182  "'); import is not possible");
183  return false;
184  };
185  numOfRecords = str.mid(34, 5).toInt(&isOk);
186  if (!isOk)
187  {
188  f.close();
189  s.setDevice(NULL);
191  ": readErpFile(): problems with the ERP file [" + fileName +
192  "]: cannot determine declared number of records (orig='" + str.mid(34, 6) +
193  "'); import is not possible");
194  return false;
195  };
196  if (str.mid(41, 4) == "UT1 " || str.mid(41, 4) == "UT1-")
198  else if (str.mid(41, 4) == "UT1S")
200  else if (str.mid(41, 4) == "UT1R")
202  else
204 // ut1Type_ = SgTidalUt1::CT_SHORT_TERMS_REMOVED;
205 
206  // std::cout << qPrintable(fileName) << ": t0=" << qPrintable(t0.toString()) << ", dt = " << step
207  // << ", numOfRecords = " << numOfRecords << ", type: " << ut1Type_
208  // << "\n";
209 
210  // skip comments:
211  str = "##";
212  while (!s.atEnd() && str.at(0)=='#')
213  str = s.readLine();
214 
215  if (s.atEnd())
216  {
217  f.close();
218  s.setDevice(NULL);
220  ": readErpFile(): problems with the ERP file [" + fileName +
221  "]: the file consists from comments; import is not possible");
222  return false;
223  };
224 
225  // determine how many strings have to skip:
226  int num2skip;
227  num2skip = (tMean - t0 + 0.1)/step - (numOfPoints + 1)/2 - 1;
228  if (num2skip < 0)
229  {
230  f.close();
231  s.setDevice(NULL);
233  ": readErpFile(): problems with the ERP file [" + fileName +
234  "]: the file does not contain necessary points; nothing to import");
235  return false;
236  };
237  if (numOfRecords < num2skip + numOfPoints)
238  {
239  f.close();
240  s.setDevice(NULL);
242  ": readErpFile(): problems with the ERP file [" + fileName +
243  "]: the file is too old; nothing to import");
244  return false;
245  };
246  //
247  // skip the lines
248  for (int i=0; i<num2skip; i++)
249  str = s.readLine();
250  // read the data:
251  for (int i=0; i<numOfPoints; i++)
252  {
253  // 1 2 3 4 5 6 7
254  //0123456789012345678901234567890123456789012345678901234567890123456789012345
255  //2444074.5 -0.4840 3.8424 -17986194 -.0681 -.0403 -26. 0.000 0.000 0.000
256  //2444075.5 -0.4840 3.8424 -17985965 -.0681 -.0403 -26. 0.000 0.000 0.000
257  //...
258  //2456195.5 1.7226 3.4290 -34616396 -.0752 -.0751 -1974. 0.001 0.000 0.000
259  //2456196.5 1.7190 3.4183 -34617166 -.0829 -.0828 -2178. 0.001 0.000 0.000
260  //
261  // there is no specified format here, just "read is list-directed"
262  str = s.readLine();
263  double pmX, pmY, pmUT1;
264  QStringList strList=str.simplified().split(' ', QString::SkipEmptyParts);
265  if (strList.size() < 4)
266  {
268  "readErpFile(): does not look like a proper string: [" + str +
269  "]; import has been interrupted");
270  f.close();
271  s.setDevice(NULL);
272  return false;
273  };
274  d = strList.at(0).toDouble(&isOk);
275  if (!isOk)
276  {
277  f.close();
278  s.setDevice(NULL);
280  "readErpFile(): cannot convert epoch string to double: [" + strList.at(0) +
281  "]; import has been interrupted");
282  return false;
283  };
284  if (d > 2390000.0)
285  d -= 2400000.5;
286  pmX = strList.at(1).toDouble(&isOk);
287  if (!isOk)
288  {
289  f.close();
290  s.setDevice(NULL);
292  "readErpFile(): cannot convert PM_X string to double: [" + strList.at(1) +
293  "]; import has been interrupted");
294  return false;
295  };
296  pmX *= 100.0;
297  pmY = strList.at(2).toDouble(&isOk);
298  if (!isOk)
299  {
300  f.close();
301  s.setDevice(NULL);
303  "readErpFile(): cannot convert PM_Y string to double: [" + strList.at(2) +
304  "]; import has been interrupted");
305  return false;
306  };
307  pmY *= 100.0;
308  pmUT1 = strList.at(3).toDouble(&isOk);
309  if (!isOk)
310  {
311  f.close();
312  s.setDevice(NULL);
314  "readErpFile(): cannot convert PM_UT1 string to double: [" + strList.at(3) +
315  "]; import has been interrupted");
316  return false;
317  };
318  pmUT1 /= 1.0E6;
319 
320  argument_->setElement(i, d);
321  eopTable_->setElement(i, PMX_IDX, pmX);
322  eopTable_->setElement(i, PMY_IDX, pmY);
323  eopTable_->setElement(i, UT1_IDX, pmUT1);
324  eopTable_->setElement(i, CIX_IDX, 0.0);
325  eopTable_->setElement(i, CIY_IDX, 0.0);
326  };
327  f.close();
328  s.setDevice(NULL);
329  fileName_ = fileName;
330  }
331  else
332  {
333  f.close();
335  ": readErpFile(): unable to open the ERP file [" + fileName +
336  "]; import is not possible");
337  return false;
338  };
339  //
340  return true;
341 };
342 
343 
344 
345 //
346 bool SgExternalEopFile::readFinalsFile(const QString& fileName, const SgMJD& tMean, int numOfPoints)
347 {
348  bool isOk;
349  QFile f(fileName);
350  if (!f.exists())
351  {
353  ": readFinalsFile(): the finals EOP file \"" + fileName +
354  "\" does not exist; import of external EOP is not possible");
355  return false;
356  };
357  QString str(""), ss("");
358 
359  if (f.open(QFile::ReadOnly))
360  {
361  QTextStream s(&f);
362  double d, dFirst;
363  double pmX, pmY, pmUT1, cipX, cipY;
364  int numOfReadRecs, l;
365 
366  dFirst = tMean.toDouble() - (numOfPoints + 1)/2;
367 
368 //------- ------ -------------------------------------------------------------
369 //19-27 F9.6 Bull. A PM-x (sec. of arc)
370 //28-36 F9.6 error in PM-x (sec. of arc)
371 //37 X [blank]
372 //38-46 F9.6 Bull. A PM-y (sec. of arc)
373 //47-55 F9.6 error in PM-y (sec. of arc)
374 //56-57 2X [blanks]
375 //58 A1 IERS (I) or Prediction (P) flag for Bull. A UT1-UTC values
376 //59-68 F10.7 Bull. A UT1-UTC (sec. of time)
377 //69-78 F10.7 error in UT1-UTC (sec. of time)
378 //79 X [blank]
379 //80-86 F7.4 Bull. A LOD (msec. of time) -- NOT ALWAYS FILLED
380 //87-93 F7.4 error in LOD (msec. of time) -- NOT ALWAYS FILLED
381 //94-95 2X [blanks]
382 //96 A1 IERS (I) or Prediction (P) flag for Bull. A nutation values
383 //97 X [blank]
384 //98-106 F9.3 Bull. A dX wrt IAU2000A Nutation (msec. of arc), Free Core Nutation NOT Removed
385 //107-115 F9.3 error in dX (msec. of arc)
386 //116 X [blank]
387 //117-125 F9.3 Bull. A dY wrt IAU2000A Nutation (msec. of arc), Free Core Nutation NOT Removed
388 //126-134 F9.3 error in dY (msec. of arc)
389 //135-144 F10.6 Bull. B PM-x (sec. of arc)
390 //145-154 F10.6 Bull. B PM-y (sec. of arc)
391 //155-165 F11.7 Bull. B UT1-UTC (sec. of time)
392 //166-175 F10.3 Bull. B dX wrt IAU2000A Nutation (msec. of arc)
393 //176-185 F10.3 Bull. B dY wrt IAU2000A Nutation (msec. of arc)
394 //
395 
396 
397 // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
398 //01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
399 //21 325 59298.00 I 0.072757 0.000016 0.407851 0.000024 I-0.1705248 0.0000033 -0.0594 0.0024 I 0.246 0.246 0.051 0.066 0.072812 0.407873 -0.1705313 0.224 0.065 PM-x sigma PM-y sigma dUT1 sigma LOD sig dX sig dY sig Bull. B values
400 //
401 
402 
403  numOfReadRecs = 0;
404  isOk = true;
405 
406  while (!s.atEnd() && numOfReadRecs<numOfPoints)
407  {
408  pmX = pmY = pmUT1 = cipX = cipY = 0.0;
409  str = s.readLine();
410  l = str.size();
411  if (77 < l)
412  {
413  d = str.mid(7, 8).toDouble(&isOk);
414  if (isOk && dFirst <= d)
415  {
416  pmX = str.mid( 18, 9).toDouble(&isOk);
417  if (isOk)
418  {
419  pmY = str.mid( 37, 9).toDouble(&isOk);
420  if (isOk)
421  {
422  pmUT1 = str.mid( 58, 10).toDouble(&isOk);
423  if (isOk)
424  {
425  cipX = str.mid( 97, 9).toDouble(&isOk);
426  if (isOk)
427  {
428  cipY = str.mid(116, 9).toDouble(&isOk);
429  if (isOk)
430  {
431  argument_->setElement(numOfReadRecs, d);
432  eopTable_->setElement(numOfReadRecs, PMX_IDX, pmX*1000.0); // arcsec -> mas
433  eopTable_->setElement(numOfReadRecs, PMY_IDX, pmY*1000.0); // arcsec -> mas
434  eopTable_->setElement(numOfReadRecs, UT1_IDX, pmUT1); // sec
435  eopTable_->setElement(numOfReadRecs, CIX_IDX, cipX); // mas
436  eopTable_->setElement(numOfReadRecs, CIY_IDX, cipY); // mas
437  numOfReadRecs++;
438  };
439  };
440  };
441  };
442  };
443  };
444  };
445  };
446  f.close();
447  s.setDevice(NULL);
448  fileName_ = fileName;
450  }
451  else
452  {
453  f.close();
455  ": readFinalsFile(): unable to open the EOP file \"" + fileName +
456  "\"; import is not possible");
457  return false;
458  };
459  //
460  return true;
461 };
462 
463 
464 
465 //
466 bool SgExternalEopFile::readC04File(const QString& fileName, const SgMJD& tMean, int numOfPoints)
467 {
468  bool isOk;
469  QFile f(fileName);
470  if (!f.exists())
471  {
473  ": readC04File(): the finals EOP file \"" + fileName +
474  "\" does not exist; import of external EOP is not possible");
475  return false;
476  };
477  QString str(""), ss("");
478 
479  if (f.open(QFile::ReadOnly))
480  {
481  QTextStream s(&f);
482  double d, dFirst;
483  double pmX, pmY, pmUT1, cipX, cipY;
484  int numOfReadRecs, l;
485 
486  dFirst = tMean.toDouble() - (numOfPoints + 1)/2;
487 
488 // FORMAT(3(I4),I7,2(F11.6),2(F12.7),2(F11.6),2(F11.6),2(F11.7),2(F12.6))
489 //##################################################################################
490 //
491 // Date MJD x y UT1-UTC LOD dX dY x Err y Err UT1-UTC Err LOD Err dX Err dY Err
492 // " " s s " " " " s s " "
493 // (0h UTC)
494 //
495 // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
496 //0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
497 //1962 1 1 37665 -0.012700 0.213000 0.0326338 0.0017230 0.000000 0.000000 0.030000 0.030000 0.0020000 0.0014000 0.004774 0.002000
498 
499 
500 
501  numOfReadRecs = 0;
502  isOk = true;
503 
504  while (!s.atEnd() && numOfReadRecs<numOfPoints)
505  {
506  pmX = pmY = pmUT1 = cipX = cipY = 0.0;
507  str = s.readLine();
508  l = str.size();
509  if (90 < l)
510  {
511  d = str.mid(12, 7).toDouble(&isOk);
512  if (isOk && dFirst <= d)
513  {
514  pmX = str.mid(19, 11).toDouble(&isOk);
515  if (isOk)
516  {
517  pmY = str.mid(30, 11).toDouble(&isOk);
518  if (isOk)
519  {
520  pmUT1 = str.mid(41, 12).toDouble(&isOk);
521  if (isOk)
522  {
523  cipX = str.mid(65, 11).toDouble(&isOk);
524  if (isOk)
525  {
526  cipY = str.mid(76, 11).toDouble(&isOk);
527  if (isOk)
528  {
529  argument_->setElement(numOfReadRecs, d);
530  eopTable_->setElement(numOfReadRecs, PMX_IDX, pmX*1000.0); // arcsec -> mas
531  eopTable_->setElement(numOfReadRecs, PMY_IDX, pmY*1000.0); // arcsec -> mas
532  eopTable_->setElement(numOfReadRecs, UT1_IDX, pmUT1); // sec
533  eopTable_->setElement(numOfReadRecs, CIX_IDX, cipX*1000.0);// arcsec -> mas
534  eopTable_->setElement(numOfReadRecs, CIY_IDX, cipY*1000.0);// arcsec -> mas
535  numOfReadRecs++;
536  };
537  };
538  };
539  };
540  };
541  };
542  };
543  };
544  f.close();
545  s.setDevice(NULL);
546  fileName_ = fileName;
548  }
549  else
550  {
551  f.close();
553  ": readC04File(): unable to open the EOP file \"" + fileName +
554  "\"; import is not possible");
555  return false;
556  };
557  //
558  return true;
559 };
560 
561 
562 /*=====================================================================================================*/
563 
564 
565 
566 
567 
568 
569 /*=======================================================================================================
570 *
571 * FRIENDS:
572 *
573 *======================================================================================================*/
574 //
575 
576 
577 
578 /*=====================================================================================================*/
579 //
580 // aux functions:
581 //
582 
583 
584 // i/o:
585 
586 
587 /*=====================================================================================================*/
588 //
589 // constants:
590 //
591 /*=====================================================================================================*/
592 
593 
594 
595 
596 /*=====================================================================================================*/
SgLogger * logger
Definition: SgLogger.cpp:231
const SgMJD tZero(1957, 10, 4)
InputEopType inputEopType_
static const QString className()
SgTidalUt1::UT1TideContentType ut1Type_
bool readErpFile(const QString &fileName, const SgMJD &tMean, int numOfPoints)
bool readFinalsFile(const QString &fileName, const SgMJD &tMean, int numOfPoints)
bool readC04File(const QString &fileName, const SgMJD &tMean, int numOfPoints)
bool readFile(const QString &, const SgMJD &, int numOfPoints)
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ IO_TXT
Definition: SgLogger.h:65
Definition: SgMJD.h:59
double toDouble() const
Definition: SgMJD.h:533
void setElement(unsigned int i, unsigned int j, double d)
Definition: SgMatrix.h:402
@ CT_ALL_TERMS_REMOVED
Definition: SgTidalUt1.h:53
@ CT_SHORT_TERMS_REMOVED
Definition: SgTidalUt1.h:52
void setElement(unsigned int i, double d)
Definition: SgVector.h:348