General Purpose Geodetic Library
SgStnLogCollector.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) 2016-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 #include <iostream>
24 #include <stdlib.h>
25 #include <math.h>
26 
27 
28 #include <QtCore/QDataStream>
29 #include <QtCore/QDir>
30 #include <QtCore/QFile>
31 #include <QtCore/QRegExp>
32 #include <QtCore/QRegularExpression>
33 #include <QtCore/QStringList>
34 #include <QtCore/QTextStream>
35 
36 
37 #include <SgIoExternalFilter.h>
38 #include <SgStnLogCollector.h>
39 #include <SgVersion.h>
40 #include <SgVlbiAuxObservation.h>
41 #include <SgVlbiObservation.h>
42 #include <SgVlbiStationInfo.h>
43 #include <SgVlbiSourceInfo.h>
44 
45 
46 
47 
48 QString asciifyString(const QString& str);
49 
50 
51 
52 
53 /*=======================================================================================================
54 *
55 * SgCableCalReading's METHODS:
56 *
57 *======================================================================================================*/
58 //
59 // static first:
61 {
62  return "SgCableCalReading";
63 };
64 /*=====================================================================================================*/
65 
66 
67 
68 
69 
70 
71 /*=======================================================================================================
72 *
73 * SgMeteoReading's METHODS:
74 *
75 *======================================================================================================*/
76 //
77 // static first:
79 {
80  return "SgMeteoReading";
81 };
82 /*=====================================================================================================*/
83 
84 
85 
86 
87 
88 
89 /*=======================================================================================================
90 *
91 * SgPointingReading's METHODS:
92 *
93 *======================================================================================================*/
94 //
95 // static first:
97 {
98  return "SgTraklReading";
99 };
100 /*=====================================================================================================*/
101 
102 
103 
104 
105 
106 
107 
108 /*=======================================================================================================
109 *
110 * SgTsysReading's METHODS:
111 *
112 *======================================================================================================*/
113 //
114 // static first:
116 {
117  return "SgTsysReading";
118 };
119 
120 
121 
122 //
123 void SgTsysReading::addTsyses(const QMap<QString, float>& tsys)
124 {
125  for (QMap<QString, float>::const_iterator it=tsys.begin(); it!=tsys.end(); ++it)
126  tsys_.insert(it.key(), it.value());
127 };
128 
129 
130 
131 //
132 void SgTsysReading::addTpconts(const QMap<QString, QVector<int> >& tpcont)
133 {
134  for (QMap<QString, QVector<int> >::const_iterator it=tpcont.begin(); it!=tpcont.end(); ++it)
135  tpcont_.insert(it.key(), it.value());
136 };
137 /*=====================================================================================================*/
138 
139 
140 
141 
142 
143 
144 /*=======================================================================================================
145 *
146 * SgPcalReading's METHODS:
147 *
148 *======================================================================================================*/
149 //
150 // static first:
152 {
153  return "SgPcalReading";
154 };
155 /*=====================================================================================================*/
156 
157 
158 
159 
160 
161 
162 /*=======================================================================================================
163 *
164 * SgSefdReading's METHODS:
165 *
166 *======================================================================================================*/
167 //
168 // static first:
170 {
171  return "SgSefdReading";
172 };
173 
174 
175 
176 //
177 bool SgSefdReading::addValByChanKey(const SgMJD& t, const QString& srcName, double az, double el,
178  const QString& chanKey, const QVector<double>& val)
179 {
180  bool isOk=true;
181  if (t_!=tZero && 0.3/DAY2SEC < fabs(t-t_))
182  {
183  isOk = false;
185  "::addValByChanKey(): unexpected epoch: old: \"" + t_.toString(SgMJD::F_YYYYMMDDHHMMSSSS) +
186  "\", new: \"" + t.toString(SgMJD::F_YYYYMMDDHHMMSSSS));
187  };
188  if (srcName_.size() && srcName != srcName_)
189  {
190  isOk = false;
192  "::addValByChanKey(): source name has changed: old: \"" + srcName_ + "\", new: \"" +
193  srcName + "\"; record of " + t.toString(SgMJD::F_YYYYMMDDHHMMSSSS));
194  };
195  if (-1000<az_ && az != az_)
196  {
197  isOk = false;
199  "::addValByChanKey(): azimuth has changed: old: \"" + QString("").setNum(az_) + ", new: " +
200  QString("").setNum(az) + "; record of " + t.toString(SgMJD::F_YYYYMMDDHHMMSSSS));
201  };
202  if (-1000<el_ && el != el_)
203  {
204  isOk = false;
206  "::addValByChanKey(): elevation has changed: old: \"" + QString("").setNum(el_) + ", new: " +
207  QString("").setNum(el) + "; record of " + t.toString(SgMJD::F_YYYYMMDDHHMMSSSS));
208  };
209  QVector<double> *v =new QVector<double>(val);
210  if (valByChanKey_.contains(chanKey))
211  {
212  isOk = false;
213  valByChanKey_.remove(chanKey);
215  "::addValByChanKey(): the channel key \"" + chanKey + "\" is already in the map");
216  };
217  t_ = t;
218  srcName_ = srcName;
219  az_ = az;
220  el_ = el;
221  valByChanKey_.insert(chanKey, v);
222  return isOk;
223 };
224 
225 
226 /*=====================================================================================================*/
227 
228 
229 
230 
231 
232 
233 /*=======================================================================================================
234 *
235 * SgOnSourceRecord's METHODS:
236 *
237 *======================================================================================================*/
238 //
239 // static first:
241 {
242  return "SgOnSourceRecord";
243 };
244 /*=====================================================================================================*/
245 
246 
247 
248 
249 
250 
251 
252 /*=======================================================================================================
253 *
254 * SgChannelSetup's METHODS:
255 *
256 *======================================================================================================*/
257 //
258 // static first:
260 {
261  return "SgChannelSetup";
262 };
263 
264 
265 
266 //
267 double SgChannelSetup::calcSkyFreq(double loFreq, double bbcFreq, double width,
268  SgChannelSideBand loSideBand, SgChannelSideBand ifSideBand)
269 {
270  double skyFrq;
271 /*
272  if a sideband of the IF is LSB and a sideband of LO is USB, then
273  frq_if = frq_lo + frq_bbc - bandwidth
274 
275  if a sideband of the IF is LSB and a sideband of LO is LSB, then
276  frq_if = frq_lo - frq_bbc - bandwidth
277 
278  if a sideband of the IF is USB and a sideband of LO is USB, then
279  frq_if = frq_lo + frq_bbc
280 
281  and if a sideband of the IF is USB and a sideband of LO is LSB, then
282  frq_if = frq_lo - frq_bbc
283 
284 */
285  //
286  if (ifSideBand==CSB_LSB && loSideBand==CSB_USB)
287  skyFrq = loFreq + bbcFreq - width;
288  else if (ifSideBand==CSB_LSB && loSideBand==CSB_LSB)
289  skyFrq = loFreq - bbcFreq - width;
290  else if (ifSideBand==CSB_USB && loSideBand==CSB_USB)
291  skyFrq = loFreq + bbcFreq;
292  else if (ifSideBand==CSB_USB && loSideBand==CSB_LSB)
293  skyFrq = loFreq - bbcFreq;
294  else
295  return -99.9;
296 
297  return skyFrq + width/2.0;
298 };
299 
300 
301 
302 
303 
304 
305 //
306 bool SgChannelSetup::selfCheck(const QString& stnKey)
307 {
308  isOk_ = true;
309 
310  if (hwType_ == HT_VGOS &&
311  backEndType_ != BET_DBBC3 ) // dbbc3 setup can be figured out from a log file
312  {
313 /*
314  const double frqsStd[64] = {
315  3480.40, 3448.40, 3384.40, 3320.40, 3224.40, 3096.40, 3064.40, 3032.40,
316  3480.40, 3448.40, 3384.40, 3320.40, 3224.40, 3096.40, 3064.40, 3032.40,
317 
318  5720.40, 5688.40, 5624.40, 5560.40, 5464.40, 5336.40, 5304.40, 5272.40,
319  5720.40, 5688.40, 5624.40, 5560.40, 5464.40, 5336.40, 5304.40, 5272.40,
320 
321  6840.40, 6808.40, 6744.40, 6680.40, 6584.40, 6456.40, 6424.40, 6392.40,
322  6840.40, 6808.40, 6744.40, 6680.40, 6584.40, 6456.40, 6424.40, 6392.40,
323 
324  10680.40,10648.40,10584.40,10520.40,10424.40,10296.40,10264.40,10232.40,
325  10680.40,10648.40,10584.40,10520.40,10424.40,10296.40,10264.40,10232.40};
326 
327  const double frqsIsh[64] = {
328  3032.40, 3064.40, 3096.40, 3224.40, 3320.40, 3384.40, 3448.40, 3480.40,
329  3032.40, 3064.40, 3096.40, 3224.40, 3320.40, 3384.40, 3448.40, 3480.40,
330 
331  5272.40, 5304.40, 5336.40, 5464.40, 5560.40, 5624.40, 5688.40, 5720.40,
332  5272.40, 5304.40, 5336.40, 5464.40, 5560.40, 5624.40, 5688.40, 5720.40,
333 
334  6392.40, 6424.40, 6456.40, 6584.40, 6680.40, 6744.40, 6808.40, 6840.40,
335  6392.40, 6424.40, 6456.40, 6584.40, 6680.40, 6744.40, 6808.40, 6840.40,
336 
337  10232.40,10264.40,10296.40,10424.40,10520.40,10584.40,10648.40,10680.40,
338  10232.40,10264.40,10296.40,10424.40,10520.40,10584.40,10648.40,10680.40};
339 */
340 /*
341  QList<QString> chanIds;
342  for (int i=0; i<16; i++)
343  for (int j=0; j<2; j++)
344  chanIds << QString("").sprintf(" %02da%01d", i, j) << QString("").sprintf(" %02db%01d", i, j)
345  << QString("").sprintf(" %02dc%01d", i, j) << QString("").sprintf(" %02dd%01d", i, j);
346 */
347 
348  // std. setup:
349  if (!loFreqById_.size())
350  {
351  loFreqById_.insert("a0", 2472.4);
352  loFreqById_.insert("a1", 2472.4);
353 
354  loFreqById_.insert("b0", 4712.4);
355  loFreqById_.insert("b1", 4712.4);
356 
357  loFreqById_.insert("c0", 5832.4);
358  loFreqById_.insert("c1", 5832.4);
359 
360  loFreqById_.insert("d0", 9672.4);
361  loFreqById_.insert("d1", 9672.4);
362  };
363 
364  for (QMap<QString, double>::iterator it=loFreqBySensorKey_.begin(); it!=loFreqBySensorKey_.end();
365  ++it)
366  {
367  QString sensorKey=it.key();
368  QString sensorId("");
369  //
370  if (ifIdBySensorKey_.contains(sensorKey))
371  sensorId = ifIdBySensorKey_.value(sensorKey);
372  else
374  "::selfCheck(): VGOS setup: cannot find sensor ID for key \"" +
375  sensorKey + "\" for station \"" + stnKey + "\"");
376  //
377  };
378  }
379  else
380  {
381  if (bbcFreqByIdx_.size() == 0)
382  {
383  isOk_ = false;
385  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
386  "the map bbcFreqByIdx is empty");
387  };
388  if (bbcBandwidthByIdx_.size() == 0)
389  {
390  isOk_ = false;
392  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
393  "the map bbcBandwidthByIdx is empty");
394  };
395  if (loIdByIdx_.size()==0 && loIdByCid_.size()==0)
396  {
397  isOk_ = false;
399  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
400  "the maps loIdByIdx/loIdByCid are empty");
401  };
402  if (loFreqById_.size() == 0)
403  {
404  isOk_ = false;
406  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
407  "the map loFreqById is empty");
408  };
409  if (loSideBandById_.size() == 0)
410  {
411  isOk_ = false;
413  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
414  "the map loSideBandById is empty");
415  };
416  if (loPolarizationById_.size() == 0)
417  {
418  isOk_ = false;
420  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
421  "the map loPolarizationById is empty");
422  };
423  if (ifIdxById_.size() == 0)
424  {
425  isOk_ = false;
427  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
428  "the map ifIdxById is empty");
429  };
430  if (ifSideBandById_.size() == 0)
431  {
432  isOk_ = false;
434  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
435  "the map ifSideBandById is empty");
436  };
437  for (QMap<QString, int>::const_iterator it=ifIdxById_.begin(); it!=ifIdxById_.end(); ++it)
438  {
439  int cIdx=it.value();
440  QString ifId(it.key());
441  QString loId("");
442 
443  if (loIdByIdx_.contains(cIdx))
444  loId = loIdByIdx_.value(cIdx);
445  else if (loIdByCid_.contains(ifId))
446  loId = loIdByCid_.value(ifId);
447 
448  if (loId.size())
449  {
450  // LO side band:
451  if (!loSideBandById_.contains(loId))
452  {
453  isOk_ = false;
455  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
456  "cannot find side band for LO \"" + loId + "\"");
457  };
458  // channel side band:
459  if (!ifSideBandById_.contains(ifId))
460  {
461  isOk_ = false;
463  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
464  "cannot find side band for channel #" + QString("").setNum(cIdx) + ", ID: \"" + ifId + "\"");
465  };
466 
467  // polarization:
468  if (!loPolarizationById_.contains(loId))
469  {
470  isOk_ = false;
472  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
473  "cannot find polarization for LO \"" + loId + "\"");
474  };
475 
476  // bandwidth:
477  if (!bbcBandwidthByIdx_.contains(cIdx))
478  {
479  isOk_ = false;
481  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
482  "cannot find bandwidth for channel #" + QString("").setNum(cIdx) + ", ID=" + ifId);
483  };
484 
485  if (!bbcFreqByIdx_.contains(cIdx))
486  {
487  isOk_ = false;
489  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
490  "cannot find BBC_FRQ for channel #" + QString("").setNum(cIdx));
491  };
492  if (!loFreqById_.contains(loId))
493  {
494  isOk_ = false;
496  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
497  "cannot find LO frq for channel #" + QString("").setNum(cIdx) + ", loID=" + loId);
498  };
499  }
500  else
501  {
502  isOk_ = false;
504  "::selfCheck(): the channel setup for station \"" + stnKey + "\" is not usable: "
505  "cannot find LO ID for channel #" + QString("").setNum(cIdx) + " with id \"" + ifId + "\"");
506  };
507  };
508  };
509 
510  return isOk_;
511 };
512 /*=====================================================================================================*/
513 
514 
515 
516 
517 
518 
519 
520 
521 
522 /*=======================================================================================================
523 *
524 * SgChannelSkeded's METHODS:
525 *
526 *======================================================================================================*/
527 //
528 // static first:
530 {
531  return "SgChannelSkeded";
532 };
533 
534 
535 
536 //
537 bool SgChannelSkeded::parseSkdFile(const QString& fileName)
538 {
539  QString str("");
540  QFile f(fileName);
542  "::parseSkdFile(): going to parse \"" + f.fileName() + "\" sked file");
543 
544  if (!f.exists())
545  {
547  "::parseSkdFile(): the file " + f.fileName() + " does not exists");
548  return (isOk_=false);
549  };
550 
551  if (f.open(QFile::ReadOnly))
552  {
553  QTextStream s(&f);
554  bool haveDone=false;
555  int numOfReadStrs=0;
556  QRegExp reCodes("^\\$CODES", Qt::CaseInsensitive);
557  QRegExp reFrec("^F\\s+(\\S+)\\s+(\\S+)\\s+(.+)$", Qt::CaseInsensitive);
558  //C SX X 8445.75 10000.0 2 Mk341:1 8.00 1(1,,2) 4
559  QRegExp reCrec("^C\\s+(\\w+)\\s+(\\w+)\\s+(.+)$", Qt::CaseInsensitive);
560  QRegExp reSb("\\w*\\s*\\(([-+0-9,]+)\\).*", Qt::CaseInsensitive);
561  bool getCodesRec=false;
562  QList<QString> lst;
563  QList<QString> stations;
564  double frq, width;
565  int cIdx;
566  bool isOk;
567  bool hasUsb, hasLsb, hasBothBands;
568  QString bandKey("");
569 
570  while (!s.atEnd() && !haveDone)
571  {
572  str = s.readLine();
573  numOfReadStrs++;
574 
575  if (str.size() && str.at(0)== "*")
576  {
577  }
578  else if (reCodes.indexIn(str) != -1)
579  getCodesRec = true;
580  else if (getCodesRec)
581  {
582  if (reFrec.indexIn(str) != -1)
583  {
584  stations.clear();
585  lst = reFrec.cap(3).split(" ", QString::SkipEmptyParts);
586  for (int i=0; i<lst.size(); i++)
587  stations << lst.at(i).leftJustified(8, ' ');
588  if (!stations.size())
590  "::parseSkdFile(): got \"F\" record without stations: \"" + str + "\"");
591  else
592  {
593  for (int i=0; i<stations.size(); i++)
594  {
595  const QString& key=stations.at(i);
596  stnCfgByKey_[key] = StnCfg(key);
597  };
599  "::parseSkdFile(): got " + QString("").setNum(stations.size()) + " stations from F record");
600  };
601  }
602  else if (reCrec.indexIn(str) != -1)
603  {
604  // parse C rec:
605  lst = reCrec.cap(0).split(" ", QString::SkipEmptyParts);
606 
607 // for (int i=0; i<lst.size(); i++)
608 
609  bandKey = lst.at(2);
610  // Sky frequency:
611  frq = lst.at(3).toDouble(&isOk);
612  if (!isOk)
613  {
614  frq = -1.0;
616  "::parseSkdFile(): cannot get sky frequency from C record \"" + str + "\"");
617  };
618  // channel index:
619  cIdx = lst.at(5).toDouble(&isOk);
620  if (!isOk)
621  {
622  cIdx = -1;
624  "::parseSkdFile(): cannot get channel index from C record \"" + str + "\"");
625  };
626  // channel width:
627  width = lst.at(7).toDouble(&isOk);
628  if (!isOk)
629  {
630  width = -1.0;
632  "::parseSkdFile(): cannot get channel width from C record \"" + str + "\"");
633  };
634  // upper/lower side band:
635  hasUsb = hasLsb = hasBothBands = false;
636  QList<SgChannelSideBand>sideBands;
637  if (reSb.indexIn(lst.at(8)) != -1)
638  {
639  lst = reSb.cap(1).split(",", QString::KeepEmptyParts);
640  if (!lst.size())
642  "::parseSkdFile(): nothing to parse side band set up: \"" + str + "\"");
643  else
644  {
645  if (lst.at(0).size())
646  {
647  sideBands << CSB_USB;
648  hasUsb = true;
649  };
650  if (1 < lst.size() && lst.at(1).size())
651  {
652  sideBands << CSB_LSB;
653  hasLsb = true;
654  };
655  if (2 < lst.size() && lst.at(2).size())
656  {
657  sideBands << CSB_USB;
658  hasUsb = true;
659  };
660  if (3 < lst.size() && lst.at(3).size())
661  {
662  sideBands << CSB_LSB;
663  hasLsb = true;
664  };
665  hasBothBands = hasUsb && hasLsb;
666  };
667  }
668  else
670  "::parseSkdFile(): cannot get parse side band set up: \"" + str + "\"");
671  //
672  // crutches:
673  if (hasBothBands)
674  {
675  ChanCfg cc(bandKey, cIdx, frq - width, width, sideBands);
676  for (int i=0; i<stations.size(); i++)
677  stnCfgByKey_[stations.at(i)].channelCfgs().append(ChanCfg(cc));
678  };
679  ChanCfg cc(bandKey, cIdx, frq, width, sideBands);
680  for (int i=0; i<stations.size(); i++)
681  stnCfgByKey_[stations.at(i)].channelCfgs().append(ChanCfg(cc));
682  }
683  else
684  haveDone = true;
685  };
686  };
687  };
688  f.close();
689  //
690  // check:
691  if (!stnCfgByKey_.size())
692  {
693  isOk_ = false;
695  "::parseSkdFile(): nothing has found in the sked file \"" + f.fileName() + "\"");
696  return isOk_;
697  };
698  //
699  //
700  isOk_ = true;
701  for (QMap<QString, StnCfg>::iterator it=stnCfgByKey_.begin(); it!=stnCfgByKey_.end(); ++it)
702  {
703  const StnCfg& cfg=it.value();
704  if (isOk_ && cfg.getStnKey().size() == 0)
705  {
706  isOk_ = false;
708  "::parseSkdFile(): the sked file \"" + f.fileName() +
709  "\" is not usable: station name is missing");
710  }
711  if (isOk_ && cfg.getChannelCfgs().size() == 0)
712  {
713  isOk_ = false;
715  "::parseSkdFile(): the sked file \"" + f.fileName() + "\" is not usable for " + it.key() +
716  ": no channels setup");
717  }
718  else
719  {
720  for (int i=0; i<cfg.getChannelCfgs().size(); i++)
721  {
722  const ChanCfg& cc=cfg.getChannelCfgs().at(i);
723  if (isOk_ && cc.getChanIdx() < 0)
724  {
725  isOk_ = false;
727  "::parseSkdFile(): the sked file \"" + f.fileName() + "\" is not usable for " + it.key() +
728  ": bad channel index for chan#" + QString("").setNum(i));
729  }
730  if (isOk_ && cc.getBandKey().size() < 0)
731  {
732  isOk_ = false;
734  "::parseSkdFile(): the sked file \"" + f.fileName() + "\" is not usable for " + it.key() +
735  ": bad band key for chan#" + QString("").setNum(i));
736  }
737  if (isOk_ && cc.getSkyFrq() < 0.0)
738  {
739  isOk_ = false;
741  "::parseSkdFile(): the sked file \"" + f.fileName() + "\" is not usable for " + it.key() +
742  ": bad sky frequency for chan#" + QString("").setNum(i));
743  }
744  if (isOk_ && cc.getBandWidth() < 0.0)
745  {
746  isOk_ = false;
748  "::parseSkdFile(): the sked file \"" + f.fileName() + "\" is not usable for " + it.key() +
749  ": bad bandwidth for chan#" + QString("").setNum(i));
750  }
751  if (isOk_ && cc.getSideBands().size() < 0)
752  {
753  isOk_ = false;
755  "::parseSkdFile(): the sked file \"" + f.fileName() + "\" is not usable for " + it.key() +
756  ": no sideband setup for chan#" + QString("").setNum(i));
757  };
758  };
759  };
760  };
761  return isOk_;
762 };
763 /*=====================================================================================================*/
764 
765 
766 
767 
768 
769 
770 
771 
772 
773 
774 /*=======================================================================================================
775 *
776 * SgStnLogReadings's METHODS:
777 *
778 *======================================================================================================*/
779 //
780 // static first:
782 {
783  return "SgStnLogReadings";
784 };
785 
786 
787 
788 //
790  stationName_(""),
791  experimentName_(""),
792  fsVersionLabel_(""),
793  backEndInfo_(""),
794  recorderInfo_(""),
795  onSourceRecords_(),
796  cableCals_(),
797  cableLongs_(),
798  meteoPars_(),
799  tSyses_(),
800  dbbc3Tps_(),
801  trakls_(),
802  pcals_(),
803  dot2xpses_(),
804  recordByScan_(),
805  channelSetup_()
806 {
807  itType_= IT_UNDEF;
809  tSensorsPrinted2AntCal_ = false;
810  cableCalAmbig_ = 100.0e-9;
811  cableSign_ = 0;
812 };
813 
814 
815 
816 //
817 SgStnLogReadings::SgStnLogReadings(const QString& stationName) :
818  stationName_(stationName),
819  experimentName_(""),
820  fsVersionLabel_(""),
821  backEndInfo_(""),
822  recorderInfo_(""),
823  onSourceRecords_(),
824  cableCals_(),
825  cableLongs_(),
826  meteoPars_(),
827  tSyses_(),
828  dbbc3Tps_(),
829  trakls_(),
830  pcals_(),
831  dot2xpses_(),
832  recordByScan_()
833 {
835  tSensorsPrinted2AntCal_ = false;
836  cableCalAmbig_ = 100.0e-9;
837  cableSign_ = 0;
838 };
839 
840 
841 
842 //
844 {
845  // free the used memory:
846  onSourceRecords_.clear();
847  //
848  for (int i=0; i<cableCals_.size(); i++)
849  delete cableCals_[i];
850  for (int i=0; i<cableLongs_.size(); i++)
851  delete cableLongs_[i];
852  for (int i=0; i<meteoPars_.size(); i++)
853  delete meteoPars_[i];
854  for (int i=0; i<tSyses_.size(); i++)
855  delete tSyses_[i];
856  for (int i=0; i<dbbc3Tps_.size(); i++)
857  delete dbbc3Tps_[i];
858  for (int i=0; i<trakls_.size(); i++)
859  delete trakls_[i];
860  for (int i=0; i<pcals_.size(); i++)
861  delete pcals_[i];
862 // for (int i=0; i<sefds_.size(); i++)
863 // delete sefds_[i];
864  for (int i=0; i<dot2xpses_.size(); i++)
865  delete dot2xpses_[i];
866 
867  cableCals_.clear();
868  cableLongs_.clear();
869  meteoPars_.clear();
870  tSyses_.clear();
871  dbbc3Tps_.clear();
872  trakls_.clear();
873  pcals_.clear();
874  sefds_.clear();
875  dot2xpses_.clear();
876  recordByScan_.clear();
877 };
878 
879 
880 
881 //
883 {
884  for (int i=0; i<onSourceRecords_.size(); i++)
885  {
886  if (onSourceRecords_.at(i)->cableCals().size())
887  onSourceRecords_.at(i)->cableCals().clear();
888  };
889  for (int i=0; i<cableCals_.size(); i++)
890  delete cableCals_[i];
891  cableCals_.clear();
892  areCableCalsPresent_ = false;
893 };
894 
895 
896 
897 //
899 {
900  for (int i=0; i<onSourceRecords_.size(); i++)
901  if (onSourceRecords_.at(i)->meteoPars().size())
902  onSourceRecords_.at(i)->meteoPars().clear();
903  for (int i=0; i<meteoPars_.size(); i++)
904  delete meteoPars_[i];
905  meteoPars_.clear();
906  areMeteosPresent_ = false;
907 };
908 
909 
910 
911 //
913 {
914  for (int i=0; i<tSyses_.size(); i++)
915  delete tSyses_[i];
916  tSyses_.clear();
917  areTsysesPresent_ = false;
918 };
919 
920 
921 
922 //
924  const QMap<QString, int> *defaultCableSignByStn)
925 {
926  bool hasCableSign;
927  SgMJD tFirst, tLast;
928  SgMJD tLeftMarging, tRightMarging;
929 
930  if (!stationName_.size())
931  stationName_ = stn->name(); // simplified name, no spaces
932 
933  //
934  if (!stn->auxObservationByScanId()->size()) // nothing to worry about
935  {
937  "::verifyReadings(): the station " + stationName_ + " has no any observations; skipped");
938  return;
939  };
940  //
941  tFirst = *stn->auxObservationByScanId()->begin().value();
942  tLast = *(--stn->auxObservationByScanId()->end()).value();
943 
944  tLeftMarging = tFirst - 1.0/24.0; // one hr earlier
945  tRightMarging = tLast + 1.0/24.0; // one hr later
946 
947  hasCableSign = cableSign_ != 0;
948 
949  if (stationName_ == "KOKEE")
950  cableCalAmbig_ = 1.0e-9;
951 
952  for (int i=0; i<onSourceRecords_.size(); i++)
953  {
954  SgOnSourceRecord *osRec=onSourceRecords_.at(i);
955  // if the scan name is missed, try to pick it up:
956  if (!osRec->getScanName().size())
957  lookupScanName(osRec, *stn->auxObservationByScanId());
958  // if the scan name is ok (it is from the log file or picked up):
959  if (osRec->getScanName().size() &&
960  tLeftMarging <= osRec->getTstart() && osRec->getTfinis() <= tRightMarging)
961  {
962  SgOnSourceRecord *r=NULL;
963  if (!recordByScan_.contains(osRec->getScanName()))
964  recordByScan_.insert(osRec->getScanName(), osRec);
965  else
966  {
967  r = recordByScan_.value(osRec->getScanName());
968  /*
969  if (r->cableCals().size()==0 && r->meteoPars().size()==0 && // an empty record, replace it
970  (osRec->cableCals().size()!=0 || osRec->meteoPars().size()!=0) )
971  {
972  recordByScan_.remove(r->getScanName());
973  recordByScan_.insert(osRec->getScanName(), osRec);
974  logger->write(SgLogger::INF, SgLogger::IO, className() +
975  "::verifyReadings(): station " + stationName_ + ": the empty record for the scan " +
976  r->getScanName() + " [" + r->getTstart().toString() + " -- " + r->getTfinis().toString() +
977  "] @ " + r->getSourceName() + " has been replaced by the new one");
978  logger->write(SgLogger::INF, SgLogger::IO, className() +
979  "::verifyReadings(): station " + stationName_ + ": the new record is: [" +
980  osRec->getTstart().toString() + " -- " + osRec->getTfinis().toString() + "] @ " +
981  osRec->getSourceName() + " numRecs(c/m)=" +
982  QString("").setNum(osRec->cableCals().size()) + "/" +
983  QString("").setNum(osRec->meteoPars().size()));
984  //delete r;
985  }
986  else */
987  if (*r == *osRec)
988  {
990  "::verifyReadings(): station " + stationName_ + ": got the duplicate scan \"" +
991  osRec->getScanName() + "\" [" + osRec->getTstart().toString() + " -- " +
992  osRec->getTfinis().toString() + "] @ " + osRec->getSourceName());
993  }
994  else
995  {
997  "::verifyReadings(): station " + stationName_ +
998  ": cannot insert osRec [" + osRec->getTstart().toString(SgMJD::F_Simple) +
999  " -- " + osRec->getTfinis().toString(SgMJD::F_Simple) + "] @ " + osRec->getSourceName() +
1000  " scan " + osRec->getScanName() + ", it's already in the map, nr(c/m)=" +
1001  QString("").setNum(osRec->cableCals().size()) + "/" +
1002  QString("").setNum(osRec->meteoPars().size()));
1003 
1005  "::verifyReadings(): station " + stationName_ +
1006  ": content of the map [" + r->getTstart().toString(SgMJD::F_Simple) +
1007  " -- " + r->getTfinis().toString(SgMJD::F_Simple) + "] @ " + r->getSourceName() +
1008  ", nr(c/m)=" +
1009  QString("").setNum(osRec->cableCals().size()) + "/" +
1010  QString("").setNum(osRec->meteoPars().size()));
1011  };
1012  };
1013  };
1014  };
1015  //
1016  int inRangePts;
1017  inRangePts = 0;
1018  for (int i=0; i<meteoPars_.size(); i++)
1019  if (tFirst<=meteoPars_.at(i)->getT() && meteoPars_.at(i)->getT()<=tLast)
1020  {
1021  areMeteosPresent_ = true;
1022  inRangePts++;
1023  };
1024  // check for number acquired of data:
1025  if (inRangePts<4)
1026  {
1028  "::verifyReadings(): station " + stationName_ + ": insufficient number (" +
1029  QString("").setNum(inRangePts) + ") of meteo parameters; skipped");
1031  areMeteosPresent_ = false;
1032  };
1033  //
1034  // cable cals:
1035  inRangePts = 0;
1036  for (int i=0; i<cableCals_.size(); i++)
1037  if (tFirst<=cableCals_.at(i)->getT() && cableCals_.at(i)->getT()<=tLast)
1038  {
1039  areCableCalsPresent_ = true;
1040  inRangePts++;
1041  };
1042  // check for number acquired of data:
1043  if (inRangePts<4)
1044  {
1046  "::verifyReadings(): station " + stationName_ + ": insufficient number (" +
1047  QString("").setNum(inRangePts) + ") of cable calibrations; skipped");
1049  areCableCalsPresent_ = false;
1050  };
1051  //
1052  // tsyses:
1053  inRangePts = 0;
1054  for (int i=0; i<tSyses_.size(); i++)
1055  if (tFirst<=tSyses_.at(i)->getT() && tSyses_.at(i)->getT()<=tLast)
1056  {
1057  areTsysesPresent_ = true;
1058  inRangePts++;
1059  };
1060  // check for number acquired of data:
1061  if (inRangePts<4)
1062  {
1064  "::verifyReadings(): station " + stationName_ + ": insufficient number (" +
1065  QString("").setNum(inRangePts) + ") of tsys readings; skipped");
1067  areTsysesPresent_ = false;
1068  };
1069  //
1071  {
1072  if (cableLongs_.size()) // try to figure out the cable sign:
1073  {
1074  int signCableLong;
1075  if ((signCableLong=determineCableSignFromLong()) == 0)
1077  "::verifyReadings(): station " + stationName_ +
1078  ": cannot determine the cable sign from cablelong measurements");
1079  else if (!hasCableSign)
1080  {
1081  cableSign_ = signCableLong;
1083  "::verifyReadings(): station " + stationName_ + ": the cable sign has been set to \"" +
1084  (cableSign_>0?"+":"-") + "\" according to cablelong measurements");
1085  hasCableSign = true;
1086  }
1087  else if (signCableLong != cableSign_)
1088  {
1090  "::verifyReadings(): station " + stationName_ +
1091  ": the found cable sign is different from the cablelong measurements: \"" +
1092  (cableSign_>0?"+":"-") + "\" vs \"" + (signCableLong>0?"+":"-") +
1093  "\"; the sign has been reverted");
1094  cableSign_ = signCableLong;
1095  }
1096  else
1098  "::verifyReadings(): station " + stationName_ +
1099  ": the cable sign has been confirmed by cablelong measurements");
1100  }
1101  else
1103  "::verifyReadings(): station " + stationName_ +
1104  ": cannot find any usable cablelong measurements");
1105  };
1106  //
1107  // complain:
1110  "::verifyReadings(): station " + stationName_ + ": cannot find any usable meteo readings");
1113  "::verifyReadings(): station " + stationName_ + ": cannot find any usable cable calibrations");
1114 
1115  if (areCableCalsPresent_ && !hasCableSign)
1116  {
1118  "::verifyReadings(): station " + stationName_ + ": cannot determine the cable calibration sign");
1119  //
1120  // predefined station names:
1121  //
1122  if (defaultCableSignByStn)
1123  {
1124  if (defaultCableSignByStn->contains(stationName_))
1125  {
1126  cableSign_ = defaultCableSignByStn->value(stationName_);
1128  "::verifyReadings(): station " + stationName_ +
1129  ": the cable sign was set to \"" + QString(cableSign_==1?"+":"-") +
1130  "\" according to the list of default cable signs");
1131  };
1132 
1133  }
1134  else
1136  "::verifyReadings(): no default cable cal list were provided");
1137  };
1138  //
1139  // check ambigs, remove outliers and, then, the average:
1142  if (areMeteosPresent_)
1144 };
1145 
1146 
1147 
1148 //
1150  const QMap<QString, SgVlbiAuxObservation*> &auxObservationByScan)
1151 {
1152  if (!osRec->getSourceName().size())
1153  {
1155  "::lookupScanName(): station " + stationName_ +
1156  ": unable to lookup the scan name: no source name provided,");
1158  "::lookupScanName(): station " + stationName_ + ": the on_data record is: " +
1159  osRec->getScanName() + " [" + osRec->getTstart().toString(SgMJD::F_Simple) + " -- " +
1160  osRec->getTfinis().toString(SgMJD::F_Simple) + "] @ \"" + osRec->getSourceName() + "\"");
1161  return;
1162  };
1163 
1164  double tLimit=15.0/60.0/24.0; // 15min window where the scan can be
1165  double dT;
1166  const SgMJD &t=osRec->getTstart() + (osRec->getTfinis() - osRec->getTstart())/2.0;
1167  SgVlbiAuxObservation *auxClosest=auxObservationByScan.begin().value();
1168  SgMJD tClosest=*auxClosest;
1169  //
1170  dT = fabs(tClosest - t);
1171  for (QMap<QString, SgVlbiAuxObservation*>::const_iterator it=auxObservationByScan.begin();
1172  it!=auxObservationByScan.end(); ++it)
1173  {
1174  SgMJD &ti=*it.value();
1175  if ( (fabs(ti-t)<dT) && it.value()->getOwner()->src()->getKey().contains(osRec->getSourceName()))
1176  {
1177  tClosest = ti;
1178  dT = fabs(ti - t);
1179  auxClosest = it.value();
1180  };
1181  };
1182 
1183  if (auxClosest && dT<=tLimit) // found something:
1184  {
1185  osRec->setScanName(auxClosest->getOwner()->getScanName().simplified().toLower());
1186 /*
1187  logger->write(SgLogger::DBG, SgLogger::IO_TXT, className() +
1188  "::lookupScanName(): the scan name " + osRec->getScanName() +
1189  " has been assigned to the on_data record; source: " + osRec->getSourceName() +
1190  ", interval: [" + osRec->getTstart().toString(SgMJD::F_Simple) +
1191  " -- " + osRec->getTfinis().toString(SgMJD::F_Simple) + "]");
1192 */
1193  }
1194  else
1196  "::lookupScanName(): station " + stationName_ +
1197  ": no scan name was assigned to the on_data record: [" +
1198  osRec->getTstart().toString(SgMJD::F_Simple) + " -- " +
1199  osRec->getTfinis().toString(SgMJD::F_Simple) + "] @ " +
1200  osRec->getSourceName());
1201 };
1202 
1203 
1204 
1205 //
1207 {
1208  int cableSign=0;
1209  double window=10.0/60.0/24.0; // 10 mins, is it ok?
1210  QList<int> signByCablelong;
1211  QList<SgCableCalReading*> selectedReadings;
1212  for (int i=0; i<cableLongs_.size(); i++)
1213  {
1214  const SgMJD &tL=cableLongs_.at(i)->getT();
1215  double clV=cableLongs_.at(i)->getV();
1216  for (int j=0; j<cableCals_.size(); j++)
1217  if (fabs(cableCals_.at(j)->getT() - tL) < window)
1218  selectedReadings << cableCals_.at(j);
1219  //
1220  if (selectedReadings.size())
1221  {
1222  double vAverage, ratio;
1224  "::determineCableSignFromLong(): collected " + QString("").setNum(selectedReadings.size()) +
1225  " close cable readings for cablelong measurement on " + tL.toString());
1226  // find average cable measurement:
1227  vAverage = 0.0;
1228  for (int j=0; j<selectedReadings.size(); j++)
1229  vAverage += selectedReadings.at(j)->getV();
1230  vAverage /= selectedReadings.size();
1231  //
1232  ratio = (clV - vAverage)/vAverage;
1233  if (1.0e-3 < ratio)
1234  cableSign = 1;
1235  else if (ratio < -1.0e-3 )
1236  cableSign = -1;
1237  else
1238  cableSign = 0;
1239  signByCablelong << cableSign;
1241  "::determineCableSignFromLong(): average cable cal: " + QString("").setNum(vAverage*1.0e9) +
1242  "ns, cablelong: " + QString("").setNum(clV*1.0e9) +
1243  "ns; the sign is \"" + QString(cableSign==0?"?":(cableSign<0?"-":"+")) + "\"");
1244  selectedReadings.clear();
1245  }
1246  else
1248  "::determineCableSignFromLong(): no close cable readings found for cablelong measurement on " +
1249  tL.toString());
1250  };
1251 
1252  if (signByCablelong.size() == 0)
1253  cableSign = 0;
1254  else if (signByCablelong.size() == 1)
1255  cableSign = signByCablelong.at(0);
1256  else
1257  {
1258  QMap<int, int> signByNum;
1259  for (int i=0; i<signByCablelong.size(); i++)
1260  {
1261  if (signByNum.contains(signByCablelong.at(i)))
1262  signByNum[signByCablelong.at(i)]++;
1263  else
1264  signByNum[signByCablelong.at(i)] = 1;
1265  };
1266  if (signByNum.size() == 1)
1267  {
1268  cableSign = signByNum.begin().key();
1270  "::determineCableSignFromLong(): according to all " +
1271  QString("").setNum(signByCablelong.size()) + " cablelong measurements, the sign is \"" +
1272  QString(cableSign==0?"?":(cableSign<0?"-":"+")) + "\"");
1273  }
1274  else
1275  {
1276  cableSign = 0;
1278  "::determineCableSignFromLong(): cannot determine the proper sign, the "
1279  "numbers of measuremnts are:");
1280  for (QMap<int, int>::iterator it=signByNum.begin(); it!=signByNum.end(); ++it)
1282  "::determineCableSignFromLong(): " +
1283  QString("").sprintf("sign \"%s\": %2d count(s)", it.key()==0?"?":(it.key()<0?"-":"+"),
1284  it.value()));
1285  };
1286  };
1287  signByCablelong.clear();
1288  return cableSign;
1289 };
1290 
1291 
1292 
1293 //
1295 {
1296  double vAverage;
1297  double vDispersion;
1298  double vTmp;
1299  SgCableCalReading *rec=NULL;
1300  int numOfResolvedAmbigs=0;
1301  int numOfOutliers=0;
1302  bool allReadingsRsame;
1303  //
1304  // first, resolve ambiguities:
1305  vAverage = 0.0;
1306  for (int i=0; i<cableCals_.size(); i++)
1307  {
1308  rec = cableCals_.at(i);
1309  if (fabs((rec->getV()-vAverage)/cableCalAmbig_) > 0.75)
1310  {
1311  rec->setV(rec->getV() - round((rec->getV()-vAverage)/cableCalAmbig_)*cableCalAmbig_);
1312  numOfResolvedAmbigs++;
1313  };
1314  vAverage = vAverage*i/(i + 1) + rec->getV()/(i+1);
1315  };
1316  if (numOfResolvedAmbigs)
1318  "::cleanCableCalibrations() station " + stationName_ + ": " +
1319  QString("").setNum(numOfResolvedAmbigs) + " ambiguit" + (numOfResolvedAmbigs==1?"y":"ies") +
1320  " resolved in the cable cal readings");
1321 
1322  //
1323  // check for outliers:
1324  vAverage = 0.0;
1325  vDispersion = 0.0;
1326  vTmp = 0.0;
1327  if (cableCals_.size() > 0)
1328  vTmp = cableCals_.at(0)->getV();
1329  allReadingsRsame = true;
1330  for (int i=0; i<cableCals_.size(); i++)
1331  {
1332  vAverage += cableCals_.at(i)->getV();
1333  vDispersion += cableCals_.at(i)->getV()*cableCals_.at(i)->getV();
1334  if (allReadingsRsame && cableCals_.at(i)->getV()!=vTmp)
1335  allReadingsRsame = false;
1336  };
1337  if (!allReadingsRsame)
1338  {
1339  vAverage /= cableCals_.size();
1340  vDispersion /= cableCals_.size();
1341  vDispersion -= vAverage*vAverage;
1342  if (vDispersion < 0.0)
1343  {
1345  "::cleanCableCalibrations(): station " + stationName_ + ": dispersion^2<0.0 (" +
1346  QString("").sprintf("%.16g", vDispersion) + ")");
1347  vDispersion = -vDispersion;
1348  };
1349  if (vDispersion > 0.0)
1350  {
1351  vDispersion = sqrt(vDispersion);
1352  for (int i=0; i<cableCals_.size(); i++)
1353  if (fabs(cableCals_.at(i)->getV()-vAverage) > 5.0*vDispersion)
1354  {
1355  cableCals_[i]->setIsOk(false);
1356  numOfOutliers++;
1357  };
1358  };
1359  // and adjust the data structures:
1360  if (numOfOutliers)
1361  {
1362  int j;
1363  for (int i=0; i<onSourceRecords_.size(); i++)
1364  {
1367  j = 0;
1368  while (j < cl.size())
1369  if (!cl.at(j)->getIsOk())
1370  cl.removeAt(j);
1371  else
1372  j++;
1373  };
1374  j = 0;
1375  while (j < cableCals_.size())
1376  if (!cableCals_.at(j)->getIsOk())
1377  {
1378  delete cableCals_[j];
1379  cableCals_[j] = NULL;
1380  cableCals_.removeAt(j);
1381  }
1382  else
1383  j++;
1385  "::cleanCableCalibrations(): station " + stationName_ + ": " +
1386  QString("").setNum(numOfOutliers) + " outlier" +
1387  QString(numOfOutliers==1?" has ":"s have ") + "been removed", true);
1388  };
1389  };
1390  //
1391  // remove average:
1392  vAverage = 0.0;
1393  for (int i=0; i<cableCals_.size(); i++)
1394  vAverage += cableCals_.at(i)->getV();
1395  vAverage /= cableCals_.size();
1396  for (int i=0; i<cableCals_.size(); i++)
1397  cableCals_.at(i)->setV(cableCals_.at(i)->getV() - vAverage);
1399  "::cleanCableCalibrations(): station " + stationName_ + ": subtracted the average value of " +
1400  QString("").setNum(vAverage*1.0e9) + "ns from the cable cal readings");
1401 };
1402 
1403 
1404 
1405 //
1407 {
1408  // first, make sure the parameters are in time order:
1409  QMap<QString, SgMeteoReading*>
1410  mpByEpoch;
1411  QString str("");
1412  double d, dt, extrRmin=0.0, extrRmax=1.0;
1413  int nExtr4Rmin=0, nExtr4Rmax=0, numOfDuples=0, numOfSameEpochs=0;
1414  SgMJD t;
1415 
1416  // first, check meteo parameters:
1417  for (int i=0; i<meteoPars_.size(); i++)
1418  {
1419  t = meteoPars_.at(i)->getT();
1420  str = t.toString(SgMJD::F_INTERNAL);
1421  //
1422  // check for duplicates:
1423  if (mpByEpoch.contains(str))
1424  {
1425  if (*mpByEpoch[str] == *meteoPars_.at(i))
1426  {
1428  "::cleanMeteoParameters(): station " + stationName_ + ": got duplicate weather record at " +
1430  numOfDuples++;
1431  }
1432  else
1433  {
1434  logger->write(SgLogger::ERR, SgLogger::IO, className() + "::cleanMeteoParameters(): station " +
1435  stationName_ + ": got two different records at the same epoch " +
1437  numOfSameEpochs++;
1438  };
1439  delete meteoPars_.at(i);
1440  }
1441  else
1442  mpByEpoch.insert(str, meteoPars_.at(i));
1443  };
1444  //
1445  if (numOfDuples)
1447  "::cleanMeteoParameters(): station " + stationName_ + ": " + QString("").setNum(numOfDuples) +
1448  " duplicate meteo records found");
1449  if (numOfSameEpochs)
1451  "::cleanMeteoParameters(): station " + stationName_ + ": " + QString("").setNum(numOfSameEpochs) +
1452  " records with the same epoch and different values found");
1453  //
1454  //
1455 // for (int i=0; i<meteoPars_.size(); i++)
1456 // delete meteoPars_.at(i);
1457  meteoPars_.clear();
1458  meteoPars_ = mpByEpoch.values();
1459  mpByEpoch.clear();
1460  //
1461  if (meteoPars_.size() <= 2)
1462  {
1464  "::cleanMeteoParameters(): station " + stationName_ + ": too small number of meteo records (" +
1465  QString("").setNum(meteoPars_.size()) + "), nothing to do");
1466  return;
1467  };
1468  //
1469  //
1470  int nPars(meteoPars_.size());
1471  SgVector dP(nPars), dT(nPars), dR(nPars);
1472  t = meteoPars_.at(0)->getT();
1473  for (int i=1; i<nPars; i++)
1474  {
1475  t = meteoPars_.at(i)->getT();
1476  //
1477  // calculate reates:
1478  dt = t - meteoPars_.at(i-1)->getT();
1479  d = meteoPars_.at(i)->getM().getPressure() - meteoPars_.at(i-1)->getM().getPressure();
1480  if (0.15 < fabs(d)) // current format has one digit after dot:
1481  dP.setElement(i, d/dt);
1482 
1483  d = meteoPars_.at(i)->getM().getTemperature() - meteoPars_.at(i-1)->getM().getTemperature();
1484  if (0.15 < fabs(d)) // current format has one digit after dot:
1485  dT.setElement(i, d/dt);
1486 
1487  d = meteoPars_.at(i)->getM().getRelativeHumidity() - meteoPars_.at(i-1)->getM().getRelativeHumidity();
1488  if (0.15 < fabs(d)) // current format has one digit after dot:
1489  dR.setElement(i, d/dt);
1490  //
1491  // check for extremums:
1492  if (fabs(meteoPars_.at(i)->getM().getRelativeHumidity() - extrRmin) < 1.0e-6)
1493  nExtr4Rmin++;
1494  if (fabs(meteoPars_.at(i)->getM().getRelativeHumidity() - extrRmax) < 1.0e-6)
1495  nExtr4Rmax++;
1496  //
1497  };
1498 
1499  //
1500  double mrP, mrT, mrR;
1501  int n4P=0, n4T=0, n4R=0;
1502  bool isOkP=true, isOkT=true, isOkR=true, hasSuspiciousExtrems4R=false;
1503  // max allowable rates:
1504  mrP =100.0*24.0; // 100 mbar per hour
1505  mrT =200.0*24.0; // 200 degree per hour
1506  mrR = 10.0*24.0; // 1000% per hour
1507  for (int i=1; i<nPars; i++)
1508  {
1509  if (mrP < fabs(dP.getElement(i)))
1510  {
1512  "::cleanMeteoParameters(): station " + stationName_ +
1513  " has too big pressure rate, " + QString("").setNum(dP.getElement(i)/24.0) +
1514  "(mbar/hr) at the idx " + QString("").setNum(i));
1515  n4P++;
1516  };
1517  if (mrT < fabs(dT.getElement(i)))
1518  {
1520  "::cleanMeteoParameters(): station " + stationName_ +
1521  " has too big atm.temperature rate, " + QString("").setNum(dT.getElement(i)/24.0) +
1522  "(C/hr) at the idx " + QString("").setNum(i));
1523  n4T++;
1524  };
1525  if (mrR < fabs(dR.getElement(i)))
1526  {
1528  "::cleanMeteoParameters(): station " + stationName_ +
1529  " has too big rel.humidity rate, " + QString("").setNum(100.0*dR.getElement(i)/24.0) +
1530  "(%/hr) at the idx " + QString("").setNum(i));
1532  "::cleanMeteoParameters(): station " + stationName_ + ": i-1: " +
1533  meteoPars_.at(i-1)->getT().toString(SgMJD::F_Simple) + " " +
1534  QString("").sprintf("%.4f", meteoPars_.at(i-1)->getM().getRelativeHumidity()) +
1535  "; i: " + meteoPars_.at(i)->getT().toString(SgMJD::F_Simple) + " " +
1536  QString("").sprintf("%.4f", meteoPars_.at(i)->getM().getRelativeHumidity()));
1537 
1538  n4R++;
1539  };
1540  };
1541  if (n4P>10)
1542  {
1543  isOkP = false;
1545  "::cleanMeteoParameters(): station " + stationName_ + " has more than 10 (" +
1546  QString("").setNum(n4P) + ") suspicious big pressure rates, use standard pressure instead");
1547  };
1548  if (n4T>10)
1549  {
1550  isOkT = false;
1552  "::cleanMeteoParameters(): station " + stationName_ + " has more than 10 (" +
1553  QString("").setNum(n4T) +
1554  ") suspicious big atm.temperature rates, use default temperature instead");
1555  };
1556  if (n4R>10)
1557  {
1558  isOkR = false;
1560  "::cleanMeteoParameters(): station " + stationName_ + " has more than 10 (" +
1561  QString("").setNum(n4R) +
1562  ") suspicious big rel.humidity rates, use default humidity instead");
1563  };
1564  if (8 < nExtr4Rmin && 8 < nExtr4Rmax)
1565  {
1567  "::cleanMeteoParameters(): station " + stationName_ + " has too much extremal values (" +
1568  QString("").setNum(nExtr4Rmin) + "/" + QString("").setNum(nExtr4Rmax) +
1569  ") for rel.humidity, use default humidity instead");
1570  hasSuspiciousExtrems4R = true;
1571  };
1572  //
1573  //
1574  // if one of readings is wrong, set it to constant:
1575  if (!isOkP || !isOkT || !isOkR || hasSuspiciousExtrems4R)
1576  {
1577  SgMeteoData m;
1578  for (int i=0; i<meteoPars_.size(); i++)
1579  {
1580  m = meteoPars_.at(i)->getM();
1581  if (!isOkP)
1582  m.setPressure(1013.25);
1583  if (!isOkT)
1584  m.setTemperature(10.0);
1585  if (!isOkR || hasSuspiciousExtrems4R)
1586  m.setRelativeHumidity(0.5);
1587  meteoPars_.at(i)->setM(m);
1588  };
1589  };
1590  //
1592  "::cleanMeteoParameters(): station " + stationName_ + ": the meteoparameters have been ordered");
1593 };
1594 
1595 
1596 
1597 //
1599 {
1600  SgMJD &t=*aux;
1601  int idx_r=0;
1602  int idx_l=meteoPars_.size() - 1;
1603  //
1604  // limit the extrapolation:
1605  if (600.0/DAY2SEC < meteoPars_.at(idx_r)->getT() - t) // 10 mins
1606  {
1607  aux->setMeteoData(meteoPars_.at(idx_r)->getM());
1609  "::interpolateMeteoParameters(): station " + stationName_ + ": epoch " + t.toString() +
1610  " is too far from the first available meteo reading (" + meteoPars_.at(idx_r)->getT().toString() +
1611  "), no extrapolation");
1612  return;
1613  };
1614  if (600.0/DAY2SEC < t - meteoPars_.at(idx_l)->getT()) // 10 mins
1615  {
1616  aux->setMeteoData(meteoPars_.at(idx_l)->getM());
1618  "::interpolateMeteoParameters(): station " + stationName_ + ": epoch " + t.toString() +
1619  " is too far from the last available meteo reading (" + meteoPars_.at(idx_l)->getT().toString() +
1620  "), no extrapolation");
1621  return;
1622  };
1623  //
1624  // assume that first and last measurements are ok
1625  if (t < meteoPars_.at(idx_r)->getT())
1626  idx_l = idx_r++;
1627  else if (meteoPars_.at(idx_l)->getT() < t)
1628  idx_r = idx_l--;
1629  else
1630  {
1631  while (meteoPars_.at(idx_r)->getT()<t && idx_r<meteoPars_.size()-1)
1632  idx_r++;
1633  while (t<meteoPars_.at(idx_l)->getT() && 0<idx_l)
1634  idx_l--;
1635  };
1636  //
1637  //
1638  if (idx_l == idx_r)
1639  aux->setMeteoData(meteoPars_.at(idx_r)->getM());
1640  else
1641  {
1642  double dt, dPr, dTp, dRh, x;
1643  dt = meteoPars_.at(idx_r)->getT() - meteoPars_.at(idx_l)->getT();
1644  x = t - meteoPars_.at(idx_l)->getT();
1645  dPr = meteoPars_.at(idx_r)->getM().getPressure() -
1646  meteoPars_.at(idx_l)->getM().getPressure();
1647  dTp = meteoPars_.at(idx_r)->getM().getTemperature() -
1648  meteoPars_.at(idx_l)->getM().getTemperature();
1649  dRh = meteoPars_.at(idx_r)->getM().getRelativeHumidity() -
1650  meteoPars_.at(idx_l)->getM().getRelativeHumidity();
1651  aux->meteoData().setPressure(meteoPars_.at(idx_l)->getM().getPressure() + dPr/dt*x);
1652  aux->meteoData().setTemperature(meteoPars_.at(idx_l)->getM().getTemperature() + dTp/dt*x);
1653  aux->meteoData().setRelativeHumidity(meteoPars_.at(idx_l)->getM().getRelativeHumidity() + dRh/dt*x);
1654  };
1655 };
1656 
1657 
1658 
1659 //
1661 {
1662  QRegExp reBrokenScanName("([a-zA-Z0-9+-]+)_.+", Qt::CaseInsensitive);
1663  bool isScanNameSuspicious;
1664  //
1665  int numOfExactMatches, numOfMultExactMatches, numOfClosestMatches, cSign;
1666  int numOfChannels, chanIdx;
1667  bool hasMeteoOk, hasCableOk, hasTsysOk;
1668  SgMJD t(tZero);
1669  SgVector *tS;
1670  numOfExactMatches = numOfMultExactMatches = numOfClosestMatches = 0;
1671  hasMeteoOk = hasCableOk = hasTsysOk = false;
1672  static const QString sideBand2str[] = {"UNDEF", "LSB", "USB", "DUAL"};
1673  static const QString polarization2str[] = {"UNDEF", "RCP", "LCP", "HLP", "VLP"};
1674 
1675  cSign = cableSign_;
1676  if (cSign==0)
1677  cSign = 1; // no cable sign found
1678 
1679  numOfChannels = channelSetup_.ifIdBySensorKey().size();
1680  tS = new SgVector(numOfChannels);
1681  //
1683  for (QMap<QString, SgVlbiAuxObservation*>::iterator it=stn->auxObservationByScanId()->begin();
1684  it!=stn->auxObservationByScanId()->end(); ++it)
1685  {
1686  SgVlbiAuxObservation *aux=it.value();
1687  QString scanName=aux->getOwner()->getScanName().simplified().toLower();
1688  QString scanNameAux("");
1689  QString sourceName=aux->getOwner()->src()->getKey();
1690  QString surrogateScanName("");
1691  int idx4Cable=-1;
1693  double dt, f;
1694 
1695  //
1696  // set up scan start time:
1697  if (itType_==IT_CDMS || itType_==IT_PCMT)
1698  {
1699  if (aux->getOwner()->observableByKey().size())
1700  t = aux->getOwner()->observableByKey().begin().value()->getTstart();
1701  else
1702  t = tZero;
1703  }
1704  else
1705  t = *aux;
1706  //
1707  for (int i=0; i<numOfChannels; i++)
1708  tS->setElement(i, -4.0);
1709  //
1710  // workaround a database bug:
1711  isScanNameSuspicious = reBrokenScanName.indexIn(scanName) != -1;
1712  if (isScanNameSuspicious)
1713  scanNameAux = reBrokenScanName.cap(1).toLower();
1714  if (scanName.size()==9 && scanName.at(8).isLetter())
1715  surrogateScanName = scanName.left(8);
1716  //
1717  // here is a missed scan, e.g. the FS has been restarted:
1718  if (!recordByScan_.contains(scanName) && !isScanNameSuspicious)
1719  {
1720  if (itType_==IT_FSLG)
1722  "::propagateData(): station " + stationName_ + ": cannot find the scan \"" + scanName +
1723  "\" in the log file");
1724  }
1725  else if (isScanNameSuspicious && !recordByScan_.contains(scanNameAux))
1726  {
1727  if (itType_==IT_FSLG)
1729  "::propagateData(): station " + stationName_ + ": cannot find the suspicious scan \"" +
1730  scanNameAux + "\"' in the log file");
1731  }
1732  else if (surrogateScanName.size() &&
1733  !recordByScan_.contains(surrogateScanName) &&
1734  !recordByScan_.contains(scanName))
1735  {
1736  if (itType_==IT_CDMS)
1738  "::propagateData(): station " + stationName_ + ": cannot find the surrogate scan \"" +
1739  scanNameAux + "\"' in the CDMS file");
1740  }
1741  else
1742  {
1743  SgOnSourceRecord *osRec=recordByScan_.value(scanName);
1744  if (!osRec && isScanNameSuspicious)
1745  osRec = recordByScan_.value(scanNameAux);
1746  else if (!osRec && surrogateScanName.size())
1747  osRec = recordByScan_.value(surrogateScanName);
1748  //
1749  if (osRec) // just in case
1750  {
1751  //
1752  // cable calibration:
1754  {
1755  if (osRec->cableCals().size())
1756  {
1757  cables = &osRec->cableCals();
1758  numOfExactMatches++;
1759  }
1760  else
1761  {
1763  "::propagateData(): station " + stationName_ +
1764  ": no cable cal record found for the scan \"" + scanName + "\" in the log file");
1765  numOfClosestMatches++;
1766  };
1767  //
1768  if (osRec->cableCals().size() == 1) // only one record with cable cals:
1769  idx4Cable = 0;
1770  else if (osRec->cableCals().size() > 1)
1771  {
1772  /*
1773  logger->write(SgLogger::DBG, SgLogger::IO, className() +
1774  "::propagateData(): station " + stationName_ + ": found more than one (" +
1775  QString("").setNum(osRec->cableCals().size()) + ") cable cal records for the scan [" +
1776  scanName + "] in the log file");
1777  */
1778  numOfMultExactMatches++;
1779  };
1780  // check source name:
1781  if (osRec->getSourceName().leftJustified(8, ' ') != sourceName)
1783  "::propagateData(): source name mismatch: from the log: \"" + osRec->getSourceName() +
1784  "\", from the obs: \"" + sourceName + "\"");
1785  };
1786  //
1787  if (areTsysesPresent_ && osRec->tSyses().size())
1788  {
1789  SgTsysReading *tsr=NULL;
1790  if (osRec->tSyses().size() == 1)
1791  tsr = osRec->tSyses().last();
1792  else
1793  {
1794  int idx=0;
1795  dt = fabs(osRec->tSyses().at(0)->getT() - t);
1796  for (int i=1; i<osRec->tSyses().size(); i++)
1797  if ((f=fabs(osRec->tSyses().at(i)->getT() - t)) < dt)
1798  {
1799  idx = i;
1800  dt = f;
1801  };
1802  tsr = osRec->tSyses().at(idx);
1803  };
1804  //
1805  chanIdx = 0;
1806  if (tsr)
1807  for (QMap<QString, QString>::const_iterator jt=channelSetup_.ifIdBySensorKey().begin();
1808  jt!=channelSetup_.ifIdBySensorKey().end(); ++jt, chanIdx++)
1809  if (tsr->getTsys().contains(jt.value()))
1810  tS->setElement(chanIdx, tsr->getTsys().value(jt.value()));
1811  //
1813  1 < osRec->tSyses().size())
1815  "::propagateData(): station " + stationName_ +
1816  ": the OnSource record has more than one (" +
1817  QString("").setNum(osRec->tSyses().size()) + ") TSYS record for the scan \"" +
1818  scanName + "\"");
1819  };
1820  }
1821  else
1823  "::propagateData(): the OnSource record is NULL: the station= " + stationName_ +
1824  ", the scan= \"" + scanName + "\"");
1825  };
1826  // set up:
1827  // meteo:
1829  {
1831  hasMeteoOk = true;
1832  };
1833  // cable calibration:
1835  {
1836  if (idx4Cable == -1)
1837  {
1838  dt = fabs(cables->at((idx4Cable=0))->getT() - t);
1839  for (int i=1; i<cables->size(); i++)
1840  if ((f=fabs(cables->at(i)->getT() - t)) < dt)
1841  {
1842  idx4Cable = i;
1843  dt = f;
1844  };
1845  };
1846  aux->setCableCalibration(cables->at(idx4Cable)->getV()*cSign);
1847  hasCableOk = true;
1848  };
1849  // tsys:
1851  {
1852  aux->setTsyses(*tS);
1853  hasTsysOk = true;
1854  };
1855  };
1856  //
1857  //
1858  if (hasCableOk)
1859  {
1862  stn->setCableCalMultiplierDBCal(cSign);
1864  "::propagateData(): station " + stationName_ + ": " + QString("").setNum(numOfExactMatches) +
1865  " exact " + (numOfMultExactMatches?("(" + QString("").setNum(numOfMultExactMatches) +
1866  (numOfMultExactMatches==1?" is ":" are ") + "multiple) "):"") +
1867  (numOfClosestMatches?"and " + QString("").setNum(numOfClosestMatches) + " closest ":"") +
1868  "matches of cable calibrations were found");
1869  };
1870  if (hasMeteoOk)
1871  {
1875  "::propagateData(): station " + stationName_ + ": meteo parameters were found");
1876  };
1877  if (hasTsysOk)
1878  {
1881  //set up channel info:
1882  stn->tsysIfFreqs().resize(numOfChannels);
1883  stn->tsysIfIds().resize(numOfChannels);
1884  stn->tsysIfSideBands().resize(numOfChannels);
1885  stn->tsysIfPolarizations().resize(numOfChannels);
1886  chanIdx = 0;
1887  for (QMap<QString, QString>::const_iterator jt=channelSetup_.ifIdBySensorKey().begin();
1888  jt!=channelSetup_.ifIdBySensorKey().end(); ++jt, chanIdx++)
1889  {
1890  const QString &id=jt.value();
1891  const QString &sensorKey=jt.key();
1892  //
1893  stn->tsysIfIds()[chanIdx] = id;
1894  stn->tsysIfFreqs()[chanIdx] = channelSetup_.ifFreqBySensorKey()[sensorKey];
1895  //
1897  stn->tsysIfSideBands()[chanIdx] = sideBand2str[sb];
1898  //
1900  stn->tsysIfPolarizations()[chanIdx] = polarization2str[pz];
1901  };
1902 
1904  "::propagateData(): station " + stationName_ + ": tsys data were found");
1905  };
1906 
1907  //
1908  delete tS;
1909  //
1910  return hasMeteoOk || hasCableOk || hasTsysOk;
1911 };
1912 
1913 
1914 
1915 //
1917 {
1918  int allocatedNum=0;
1919  for (int i=0; i<cableCals_.size(); i++)
1920  {
1921  SgCableCalReading *cbl=cableCals_.at(i);
1922  for (int j=0; j<onSourceRecords_.size(); j++)
1923  {
1924  SgOnSourceRecord *osRec=onSourceRecords_.at(j);
1925  if (osRec->getTstart() <= cbl->getT() && cbl->getT() <= osRec->getTfinis())
1926  {
1927  osRec->cableCals() << cbl;
1928  allocatedNum++;
1929  };
1930  };
1931  };
1933  "::allocateCableReadings(): station " + stationName_ + ": " + QString("").setNum(allocatedNum) +
1934  " cable cal readings were linked to on data records");
1935 };
1936 
1937 
1938 
1939 //
1941 {
1942  QString str("");
1943  int idx;
1944 
1945 //s << "#\nNUMB_FRQ: " << channelSetup_.ifIdxById().size() << "\n#\n";
1946  s << "#\nNUMB_FRQ: " << channelSetup_.ifIdBySensorKey().size() << "\n#\n";
1947  s << "# Sensor# IF_Freq LO_Freq Sky_freq Pol SensorId Channel# SideBand\n#\n";
1948 
1949  idx = 1;
1950 //for (QMap<QString, int>::const_iterator it=channelSetup_.ifIdxById().begin();
1951 // it!=channelSetup_.ifIdxById().end(); ++it)
1952  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
1953  it!=channelSetup_.ifIdBySensorKey().end(); ++it)
1954  {
1955  QString ifKey(it.key());
1956  QString ifId(it.value());
1957 
1958  int cIdx=-1;
1959  if (!channelSetup_.ifIdxById().contains(ifId))
1960  {
1962  "::export2antabFrqs_nativeSetup(): station " + stationName_ +
1963  ": cannot find IF index for if with the id \"" + ifId + "\"");
1964  continue;
1965  }
1966  else
1967  cIdx = channelSetup_.ifIdxById().value(ifId);
1968 
1969 // int cIdx=it.value();
1970 // QString ifId(it.key());
1971  QString loId("");
1974  SgChannelPolarization polarization=CP_UNDEF;
1975  double ifFrq, loFrq, skyFrq, bw;
1976  ifFrq = loFrq = skyFrq = bw = 0.0;
1977 
1978  if (channelSetup_.loIdByIdx().contains(cIdx))
1979  loId = channelSetup_.loIdByIdx().value(cIdx);
1980  else if (channelSetup_.loIdByCid().contains(ifId))
1981  loId = channelSetup_.loIdByCid().value(ifId);
1982  if (loId.size())
1983  {
1984  // LO side band:
1985  if (channelSetup_.loSideBandById().contains(loId))
1986  loSb = channelSetup_.loSideBandById().value(loId);
1987  else
1989  "::export2antabFrqs_nativeSetup(): station " + stationName_ + ": cannot find side band for LO \"" +
1990  loId + "\"");
1991 
1992  // channel side band:
1993  if (channelSetup_.ifSideBandById().contains(ifId))
1994  ifSb = channelSetup_.ifSideBandById().value(ifId);
1995  else
1997  "::export2antabFrqs_nativeSetup(): station " + stationName_ + ": cannot find side band for channel #" +
1998  QString("").setNum(cIdx) + ", ID: \"" + ifId + "\"");
1999 
2000  // polarization:
2001  if (channelSetup_.loPolarizationById().contains(loId))
2002  polarization = channelSetup_.loPolarizationById().value(loId);
2003  else
2005  "::export2antabFrqs_nativeSetup(): station " + stationName_ + ": cannot find polarization for LO \"" +
2006  loId + "\"");
2007 
2008  // bandwidth:
2009  if (channelSetup_.bbcBandwidthByIdx().contains(cIdx))
2010  bw = channelSetup_.bbcBandwidthByIdx().value(cIdx);
2011  else
2013  "::export2antabFrqs_nativeSetup(): station " + stationName_ + ": cannot find bandwidth for channel #" +
2014  QString("").setNum(cIdx) + ", ID=" + ifId);
2015 
2016  if (channelSetup_.bbcFreqByIdx().contains(cIdx))
2017  {
2018  ifFrq = channelSetup_.bbcFreqByIdx().value(cIdx);
2019  //
2020  if (loSb == CSB_USB && ifSb == CSB_USB)
2021  ifFrq = channelSetup_.bbcFreqByIdx().value(cIdx);
2022  else if (loSb == CSB_USB && ifSb == CSB_LSB)
2023  ifFrq = channelSetup_.bbcFreqByIdx().value(cIdx) - bw;
2024  else if (loSb == CSB_LSB && ifSb == CSB_LSB)
2025  ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx) - bw;
2026 // ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx);
2027  else if (loSb == CSB_LSB && ifSb == CSB_USB)
2028  ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx);
2029 // ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx) - bw;
2030  }
2031  else
2033  "::export2antabFrqs_nativeSetup(): station " + stationName_ + ": cannot find BBC_FRQ for channel #" +
2034  QString("").setNum(cIdx));
2035 
2036  if (channelSetup_.loFreqById().contains(loId))
2037  loFrq = channelSetup_.loFreqById().value(loId);
2038  else
2040  "::export2antabFrqs_nativeSetup(): station " + stationName_ + ": cannot find LO frq for channel #" +
2041  QString("").setNum(cIdx) + ", loID=" + loId);
2042 
2043  skyFrq = loFrq + ifFrq;
2044  }
2045  else
2047  "::export2antabFrqs_nativeSetup(): station " + stationName_ + ": cannot find LO ID for channel #" +
2048  QString("").setNum(cIdx));
2049 
2050  channelSetup_.ifFreqByIdx()[cIdx] = skyFrq;
2051  channelSetup_.ifPolarizationById()[ifId] = polarization;
2052 
2053  str.sprintf("FRQ: %7d %11.2f %11.2f %11.2f",
2054  idx, ifFrq, loFrq, skyFrq);
2055  s << str << " ";
2056  if (polarization == CP_RightCP)
2057  s << " R";
2058  else if (polarization == CP_LeftCP)
2059  s << " L";
2060  else
2061  s << " ?";
2062 
2063  str.sprintf(" %6s ", qPrintable(ifId));
2064  s << str;
2065  str.sprintf("%6d", cIdx);
2066  s << str << " ";
2067 
2068  if (ifSb == CSB_USB)
2069  s << "USB";
2070  else if (ifSb == CSB_LSB)
2071  s << "LSB";
2072  else if (ifSb == CSB_DUAL)
2073  s << "USB/LSB";
2074  else
2075  s << "UNK";
2076  s << "\n";
2077  idx++;
2078  };
2079  s << "#\n";
2080 };
2081 
2082 
2083 
2084 //
2086 {
2087  QString str("");
2088  int idx;
2089 
2090  s << "#\nNUMB_FRQ: " << channelSetup_.ifIdBySensorKey().size() << "\n#\n";
2091  s << "# Sensor# IF_Freq LO_Freq Sky_freq Pol SensorId Channel# SideBand\n#\n";
2092 
2093  idx = 1;
2094  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
2095  it!=channelSetup_.ifIdBySensorKey().end(); ++it)
2096  {
2097  QString ifKey(it.key());
2098  QString ifId(it.value());
2099  QString loId("");
2100 
2101  int cIdx=-1;
2102  if (!channelSetup_.ifIdxById().contains(ifId))
2103  {
2105  "::export2antabFrqs_vgosSetup(): station " + stationName_ +
2106  ": cannot find IF index for if with the id \"" + ifId + "\"");
2107  continue;
2108  }
2109  else
2110  cIdx = channelSetup_.ifIdxById().value(ifId);
2111 
2113  SgChannelPolarization polarization=CP_UNDEF;
2114  double skyFrq, loFrq=-1.0;
2115  skyFrq = -1.0;
2116 
2117  // channel side band:
2118  if (channelSetup_.ifSideBandById().contains(ifId))
2119  ifSb = channelSetup_.ifSideBandById().value(ifId);
2120  else
2122  "::export2antabFrqs_vgosSetup(): station " + stationName_ +
2123  ": cannot find side band for channel #" + QString("").setNum(cIdx) + ", ID: \"" + ifId + "\"");
2124 
2125  // bandwidth:
2126  skyFrq = channelSetup_.ifFreqByIdx()[cIdx];
2127 
2128  if (channelSetup_.loIdByIdx().contains(cIdx))
2129  loId = channelSetup_.loIdByIdx().value(cIdx);
2130  else if (channelSetup_.loIdByCid().contains(ifId))
2131  loId = channelSetup_.loIdByCid().value(ifId);
2132 
2133 
2134  if (loId.size() && channelSetup_.loFreqById().contains(loId))
2135  loFrq = channelSetup_.loFreqById().value(loId);
2136  else
2138  "::export2antabFrqs_vgosSetup(): station " + stationName_ +
2139  ": cannot find LO frq for channel #" + QString("").setNum(cIdx) + ", loID=\"" + loId + "\"");
2140 
2141 
2142  // polarization:
2143  if (channelSetup_.loPolarizationById().contains(ifId))
2144  polarization = channelSetup_.loPolarizationById().value(ifId);
2145  else
2147  "::export2antabFrqs_vgosSetup(): station " + stationName_ +
2148  ": cannot find polarization for LO \"" + ifId + "\"");
2149 
2150  channelSetup_.ifPolarizationById()[ifId] = polarization;
2151 
2152  str.sprintf("FRQ: %7d %11.2f %11.2f %11.2f ",
2153  idx, -1.0, loFrq, skyFrq);
2154  s << str;
2155 
2156  if (polarization == CP_RightCP)
2157  s << " R";
2158  else if (polarization == CP_LeftCP)
2159  s << " L";
2160  else if (polarization == CP_HorizontalLP)
2161  s << " H";
2162  else if (polarization == CP_VerticalLP)
2163  s << " V";
2164  else
2165  s << " ?";
2166 
2167  str.sprintf(" %6s %6d ", qPrintable(ifId), cIdx);
2168  s << str;
2169 
2170  if (ifSb == CSB_USB)
2171  s << "USB";
2172  else if (ifSb == CSB_LSB)
2173  s << "LSB";
2174  else
2175  s << "UNK";
2176  s << "\n";
2177  idx++;
2178  };
2179  s << "#\n";
2180 };
2181 
2182 
2183 
2184 //
2186 {
2187  QString str("");
2188  int idx;
2189 
2190  if (channelSetup_.ifIdxById().size() != sCfg.getChannelCfgs().size())
2191  {
2193  "::export2antabFrqs_skededSetup(): station " + stationName_ +
2194  ": number of channels are different");
2195  return;
2196  };
2197 //std::cout << " -- 1: sCfg.getChannelCfgs().size()=" << sCfg.getChannelCfgs().size() << "\n";
2198  s << "#\nNUMB_FRQ: " << channelSetup_.ifIdxById().size() << "\n#\n";
2199  s << "# Sensor# IF_Freq LO_Freq Sky_freq Pol SensorId Channel# SideBand\n#\n";
2200 
2201  idx = 1;
2202 
2203  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
2204  it!=channelSetup_.ifIdBySensorKey().end(); ++it)
2205  {
2206  QString ifKey(it.key());
2207  QString ifId(it.value());
2208 
2209  int cIdx=-1;
2210  if (!channelSetup_.ifIdxById().contains(ifId))
2211  {
2213  "::export2antabFrqs_nativeSetup(): station " + stationName_ +
2214  ": cannot find IF index for if with the id \"" + ifId + "\"");
2215  continue;
2216  }
2217  else
2218  cIdx = channelSetup_.ifIdxById().value(ifId);
2219 
2221  double skyFrq, bw;
2222  skyFrq = bw = 0.0;
2223  // channel side band:
2224  if (channelSetup_.ifSideBandById().contains(ifId))
2225  ifSb = channelSetup_.ifSideBandById().value(ifId);
2226  else
2228  "::export2antabFrqs_skededSetup(): station " + stationName_ + ": cannot find side band for channel #" +
2229  QString("").setNum(cIdx) + ", ID: \"" + ifId + "\"");
2230  // bandwidth:
2231  bw = sCfg.getChannelCfgs().at(idx - 1).getBandWidth();
2232  skyFrq = sCfg.getChannelCfgs().at(idx - 1).getSkyFrq();
2233  channelSetup_.ifFreqByIdx()[cIdx] = skyFrq;
2235 
2236  str.sprintf("FRQ: %7d %11.2f %11.2f %11.2f",
2237  idx, -1.0, -1.0, skyFrq);
2238  s << str << " ";
2239  s << " ?";
2240 
2241  str.sprintf(" %6s ", qPrintable(ifId));
2242  s << str;
2243  str.sprintf("%6d", cIdx);
2244  s << str << " ";
2245 
2246  if (ifSb == CSB_USB)
2247  s << "USB";
2248  else if (ifSb == CSB_LSB)
2249  s << "LSB";
2250  else
2251  s << "UNK";
2252  s << "\n";
2253  idx++;
2254  };
2255  s << "#\n";
2256 //std::cout << " -- 10\n";
2257 };
2258 
2259 
2260 
2261 //
2263 {
2264  QString str("");
2265  int idx;
2266 
2267  s << "#\nNUMB_FRQ: " << channelSetup_.ifIdxById().size() << "\n#\n";
2268  s << "# Sensor# IF_Freq LO_Freq Sky_freq Pol SensorId Channel# SideBand\n#\n";
2269 
2270  idx = 1;
2271 
2272  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
2273  it!=channelSetup_.ifIdBySensorKey().end(); ++it, idx++)
2274  {
2275  QString ifKey(it.key());
2276  QString ifId(it.value());
2277 
2278  int cIdx=-1;
2279  if (!channelSetup_.ifIdxById().contains(ifId))
2280  {
2282  "::export2antabFrqs_missedSetup(): station " + stationName_ +
2283  ": cannot find IF index for if with the id \"" + ifId + "\"");
2284  continue;
2285  }
2286  else
2287  cIdx = channelSetup_.ifIdxById().value(ifId);
2288 
2290 
2291  // channel side band:
2292  if (channelSetup_.ifSideBandById().contains(ifId))
2293  ifSb = channelSetup_.ifSideBandById().value(ifId);
2294  else
2296  "::export2antabFrqs_missedSetup(): station " + stationName_ +
2297  ": cannot find side band for channel #" + QString("").setNum(cIdx) +
2298  ", ID: \"" + ifId + "\"");
2299 
2300  channelSetup_.ifFreqByIdx()[cIdx] = -1.0;
2302  channelSetup_.ifSideBandById()[ifId] = ifSb;
2303 
2304  str.sprintf("FRQ: %7d %11.2f %11.2f %11.2f",
2305  idx, -1.0, -1.0, -1.0);
2306  s << str << " ?";
2307 
2308  str.sprintf(" %6s ", qPrintable(ifId));
2309  s << str;
2310  str.sprintf("%6d", cIdx);
2311  s << str << " ";
2312 
2313  if (ifSb == CSB_USB)
2314  s << "USB";
2315  else if (ifSb == CSB_LSB)
2316  s << "LSB";
2317  else
2318  s << "UNK";
2319  s << "\n";
2320  };
2321 
2322  s << "#\n";
2323 };
2324 
2325 
2326 
2327 //
2329 {
2330  bool isOk;
2331  double skyFrq, bw;
2332  int idx;
2333  QMap<int, double> frqByIdx_Fsl, frqByIdx_Skd;
2334  QMap<int, double> bwByIdx_Fsl, bwByIdx_Skd;
2335  int numOfChansAtSked, numOfChansAtLog;
2336 
2337  numOfChansAtSked = numOfChansAtLog = 0;
2338  isOk = true;
2339  //
2340  // sked's:
2341  for (int i=0; i<sCfg.getChannelCfgs().size(); i++)
2342  {
2343  bw = sCfg.getChannelCfgs().at(i).getBandWidth();
2344  skyFrq = sCfg.getChannelCfgs().at(i).getSkyFrq();
2345  frqByIdx_Skd[i] = skyFrq;
2346  bwByIdx_Skd[i] = bw;
2347  numOfChansAtSked++;
2348  };
2349 
2350  // FS log:
2351  idx = 0;
2352  for (QMap<QString, int>::const_iterator it=channelSetup_.ifIdxById().begin();
2353  it!=channelSetup_.ifIdxById().end(); ++it, idx++)
2354  {
2355  int cIdx=it.value();
2356  QString ifId(it.key());
2357  QString loId("");
2360  double ifFrq, loFrq, skyFrq, bw;
2361  ifFrq = loFrq = skyFrq = bw = 0.0;
2362 
2363  if (channelSetup_.loIdByIdx().contains(cIdx))
2364  loId = channelSetup_.loIdByIdx().value(cIdx);
2365  else if (channelSetup_.loIdByCid().contains(ifId))
2366  loId = channelSetup_.loIdByCid().value(ifId);
2367 
2368  if (loId.size())
2369  {
2370 // loId = channelSetup_.loIdByIdx().value(cIdx);
2371 
2372  // LO side band:
2373  if (channelSetup_.loSideBandById().contains(loId))
2374  loSb = channelSetup_.loSideBandById().value(loId);
2375  else
2377  "::compareChannelSetups(): station " + stationName_ + ": cannot find side band for LO \"" +
2378  loId + "\"");
2379 
2380  // channel side band:
2381  if (channelSetup_.ifSideBandById().contains(ifId))
2382  ifSb = channelSetup_.ifSideBandById().value(ifId);
2383  else
2385  "::compareChannelSetups(): station " + stationName_ + ": cannot find side band for channel #" +
2386  QString("").setNum(cIdx) + ", ID: \"" + ifId + "\"");
2387 
2388  // bandwidth:
2389  if (channelSetup_.bbcBandwidthByIdx().contains(cIdx))
2390  bw = channelSetup_.bbcBandwidthByIdx().value(cIdx);
2391  else
2393  "::compareChannelSetups(): station " + stationName_ + ": cannot find bandwidth for channel #" +
2394  QString("").setNum(cIdx) + ", ID=" + ifId);
2395 
2396  if (channelSetup_.bbcFreqByIdx().contains(cIdx))
2397  {
2398  ifFrq = channelSetup_.bbcFreqByIdx().value(cIdx);
2399  //
2400  if (loSb == CSB_USB && ifSb == CSB_USB)
2401  ifFrq = channelSetup_.bbcFreqByIdx().value(cIdx);
2402  else if (loSb == CSB_USB && ifSb == CSB_LSB)
2403  ifFrq = channelSetup_.bbcFreqByIdx().value(cIdx) - bw;
2404 // here is freq calculation is perverted -- at the time of reading sked file we do not know about
2405 // LO's sidebanad:
2406  else if (loSb == CSB_LSB && ifSb == CSB_LSB)
2407 // ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx) - bw;
2408  ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx);
2409  else if (loSb == CSB_LSB && ifSb == CSB_USB)
2410 // ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx);
2411  ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx) - bw;
2412  }
2413  else
2415  "::compareChannelSetups(): station " + stationName_ + ": cannot find BBC_FRQ for channel #" +
2416  QString("").setNum(cIdx));
2417 
2418  if (channelSetup_.loFreqById().contains(loId))
2419  loFrq = channelSetup_.loFreqById().value(loId);
2420  else
2422  "::compareChannelSetups(): station " + stationName_ + ": cannot find LO frq for channel #" +
2423  QString("").setNum(cIdx) + ", loID=" + loId);
2424 
2425  skyFrq = loFrq + ifFrq;
2426  }
2427  else
2429  "::compareChannelSetups(): station " + stationName_ + ": cannot find LO ID for channel #" +
2430  QString("").setNum(cIdx));
2431 
2432  // special case:
2433  if (ifSb == CSB_DUAL)
2434  {
2435  frqByIdx_Fsl[idx] = skyFrq - bw;
2436  bwByIdx_Fsl[idx] = bw;
2437  idx++;
2438  numOfChansAtLog++;
2439  };
2440  frqByIdx_Fsl[idx] = skyFrq;
2441  bwByIdx_Fsl[idx] = bw;
2442  numOfChansAtLog++;
2443  };
2444 
2445  // check:
2446  if (frqByIdx_Fsl.size() != frqByIdx_Skd.size())
2447  {
2448  isOk = false;
2450  "::compareChannelSetups(): station " + stationName_ + ": the number of channels are different, " +
2451  QString("").sprintf("%d (log) vs %d (sked)", frqByIdx_Fsl.size(), frqByIdx_Skd.size()));
2452  }
2453  else
2454  {
2455  // Grrr!
2456  // freqs:
2457  QMap<double, int> idxByFrq_Fsl, idxByFrq_Skd;
2458  for (QMap<int, double>::iterator it=frqByIdx_Fsl.begin(); it!=frqByIdx_Fsl.end(); ++it, idx++)
2459  idxByFrq_Fsl[it.value()] = it.key();
2460  for (QMap<int, double>::iterator it=frqByIdx_Skd.begin(); it!=frqByIdx_Skd.end(); ++it, idx++)
2461  idxByFrq_Skd[it.value()] = it.key();
2462  //
2463  QList<double> d_Fsl=idxByFrq_Fsl.keys();
2464  QList<double> d_Skd=idxByFrq_Skd.keys();
2465 
2466  for (int i=0; i<d_Fsl.size(); i++)
2467  {
2468  double frqFsl=d_Fsl.at(i), frqSkd=d_Skd.at(i);
2469  if (1.0e-4 < fabs(frqSkd - frqFsl))
2470  {
2471  isOk = false;
2473  "::compareChannelSetups(): station " + stationName_ +
2474  ": the sky frequency for the channel #" +
2475  QString("").setNum(i) + " is different: " +
2476  QString("").sprintf("%.4f (log) vs %.4f (sked)", frqFsl, frqSkd));
2477  };
2478  };
2479  // bandwidth:
2480  d_Fsl = bwByIdx_Fsl.values();
2481  d_Skd = bwByIdx_Skd.values();
2482  for (int i=0; i<d_Fsl.size(); i++)
2483  {
2484  double bwFsl=d_Fsl.at(i), bwSkd=d_Skd.at(i);
2485  if (1.0e-2 < fabs(bwSkd - bwFsl))
2486  {
2487  isOk = false;
2489  "::compareChannelSetups(): station " + stationName_ +
2490  ": the width for the channel #" +
2491  QString("").setNum(i) + " is different: " +
2492  QString("").sprintf("%.2f (log) vs %.2f (sked)", bwFsl, bwSkd));
2493  };
2494  };
2495  /*
2496  for (QMap<int, double>::iterator it=frqByIdx_Fsl.begin(); it!=frqByIdx_Fsl.end(); ++it, idx++)
2497  {
2498  int cIdx=it.key();
2499  double frqFsl=it.value(), frqSkd;
2500  if (frqByIdx_Skd.contains(cIdx))
2501  {
2502  frqSkd = frqByIdx_Skd.value(cIdx);
2503  if (1.0e-4 < fabs(frqSkd - frqFsl))
2504  {
2505  isOk = false;
2506  logger->write(SgLogger::WRN, SgLogger::IO, className() +
2507  "::compareChannelSetups(): station " + stationName_ +
2508  ": the sky frequency for the channel #" +
2509  QString("").setNum(cIdx) + " is different: " +
2510  QString("").sprintf("%.4f (log) vs %.4f (sked)", frqFsl, frqSkd));
2511  }
2512  }
2513  else
2514  {
2515  isOk = false;
2516  logger->write(SgLogger::WRN, SgLogger::IO, className() +
2517  "::compareChannelSetups(): station " + stationName_ + ": canot find channel index #" +
2518  QString("").setNum(cIdx) + " in the list of sked's channels (frq)");
2519  };
2520  double bwFsl, bwSkd;
2521  bwFsl = bwByIdx_Fsl.value(cIdx);
2522  if (bwByIdx_Skd.contains(cIdx))
2523  {
2524  bwSkd = bwByIdx_Skd.value(cIdx);
2525  if (1.0e-2 < fabs(bwSkd - bwFsl))
2526  {
2527  isOk = false;
2528  logger->write(SgLogger::WRN, SgLogger::IO, className() +
2529  "::compareChannelSetups(): station " + stationName_ +
2530  ": the width for the channel #" +
2531  QString("").setNum(cIdx) + " is different: " +
2532  QString("").sprintf("%.2f (log) vs %.2f (sked)", bwFsl, bwSkd));
2533  };
2534  }
2535  else
2536  {
2537  isOk = false;
2538  logger->write(SgLogger::WRN, SgLogger::IO, className() +
2539  "::compareChannelSetups(): station " + stationName_ + ": canot find channel index #" +
2540  QString("").setNum(cIdx) + " in the list of sked's channels (bw)");
2541  };
2542  };
2543  */
2544  };
2545  return isOk;
2546 };
2547 
2548 
2549 
2550 //
2552 {
2553  bool isOk;
2554  int numOfChansAtSked, numOfChansAtLog;
2555 
2556  numOfChansAtSked = numOfChansAtLog = 0;
2557  isOk = true;
2558  //
2559  // sked's:
2560  numOfChansAtSked = sCfg.getChannelCfgs().size();
2561 
2562  // FS log:
2563  for (QMap<QString, int>::const_iterator it=channelSetup_.ifIdxById().begin();
2564  it!=channelSetup_.ifIdxById().end(); ++it)
2565  {
2566  QString ifId(it.key());
2568  // channel side band:
2569  if (channelSetup_.ifSideBandById().contains(ifId))
2570  ifSb = channelSetup_.ifSideBandById().value(ifId);
2571  else
2573  "::compareChannelNumbers(): station " + stationName_ + ": cannot find side band for channel #" +
2574  QString("").setNum(it.value()) + ", ID: \"" + ifId + "\"");
2575 
2576  // special case:
2577  if (ifSb == CSB_DUAL)
2578  numOfChansAtLog++;
2579  numOfChansAtLog++;
2580  };
2581 
2582  // check:
2583  if (numOfChansAtLog != numOfChansAtSked)
2584  {
2585  isOk = false;
2587  "::compareChannelNumbers(): station " + stationName_ + ": the number of channels are different, " +
2588  QString("").sprintf("%d (log) vs %d (sked)", numOfChansAtLog, numOfChansAtSked));
2589  };
2590  return isOk;
2591 };
2592 
2593 
2594 
2595 //
2596 bool SgStnLogReadings::createAntabFile(const QString& inputLogFileName, const QString& outputFileName,
2597  const QString& stnKey, const SgChannelSkeded *channelSkeded, bool useSkededChannelSetup,
2598  bool have2overwrite, bool reportAllTsysData)
2599 {
2600  enum ChannelSetup2Use {CSU_NONE, CSU_NATIVE, CSU_SKED, CSU_VEX, CSU_VGOS};
2601  bool haveSkeded;
2602  bool haveTsys;
2603  ChannelSetup2Use setup2use;
2604  setup2use = CSU_NONE;
2605  haveSkeded = false;
2606  haveTsys = 0 < tSyses_.size();
2607 
2608  QString str("");
2609 
2610  if (!outputFileName.size())
2611  {
2612  // set up outut file name:
2613  if (5 < inputLogFileName.size() && inputLogFileName.right(4) == QString(".log"))
2614  {
2615  str = inputLogFileName.left(inputLogFileName.size() - 4) + ".ant";
2616  }
2617  else
2618  str = inputLogFileName + ".ant";
2619  }
2620  else
2621  str = outputFileName;
2622  QFile f(str);
2624  "::createAntabFile(): station " + stnKey + ": " +
2625  " going to create " + f.fileName() + " LOG-ANTAB file");
2626 
2627  if (haveTsys)
2628  {
2629  // check channel set up:
2630  if (!channelSkeded)
2632  "::createAntabFile(): station " + stnKey +
2633  ": the sked's channel setup is missing");
2634  else if (!channelSkeded->isOk())
2636  "::createAntabFile(): station " + stnKey +
2637  ": the sked's channel setup is not good, skipping it");
2638  else if (!channelSkeded->stnCfgByKey_.contains(stnKey))
2640  "::createAntabFile(): station " + stnKey +
2641  ": the sked's channel setup does not contain this station, skipping it");
2643  !compareChannelNumbers(channelSkeded->stnCfgByKey_.value(stnKey)))
2645  "::createAntabFile(): station " + stnKey +
2646  ": the number of collected channels and number of channels in the sked are different, skipping it");
2647  else
2648  {
2649  haveSkeded = true;
2651  "::createAntabFile(): station " + stnKey +
2652  ": looks like we have channel setup from sked");
2653  };
2654  //
2655  //
2656  if (channelSetup_.selfCheck(stnKey))
2657  {
2658  setup2use = CSU_NATIVE;
2660  setup2use = CSU_VGOS;
2662  "::createAntabFile(): station " + stnKey +
2663  ": channel setup from the log file looks ok");
2664  if (haveSkeded && channelSetup_.getHwType() != SgChannelSetup::HT_VGOS)
2665  {
2667  "::createAntabFile(): station " + stnKey +
2668  ": comparing sked's and FS log channel setups");
2669  compareChannelSetups(channelSkeded->stnCfgByKey_.value(stnKey));
2670  };
2671  }
2672  else if (haveSkeded)
2673  {
2674  setup2use = CSU_SKED;
2676  "::createAntabFile(): station " + stnKey + ": cannot figure out channel setup from the log "
2677  "file, falling back to the set up from sked file");
2678  }
2679  else
2680  {
2681  setup2use = CSU_NONE;
2683  "::createAntabFile(): station " + stnKey + ": cannot figure out the channel setup");
2684  };
2685 
2686  if (setup2use == CSU_NATIVE && useSkededChannelSetup)
2687  {
2688  setup2use = CSU_SKED;
2690  "::createAntabFile(): station " + stnKey + ": forced to use the set up from sked file");
2691  };
2692  }
2693  else
2695  "::createAntabFile(): station " + stnKey + ": no TSYS data have found in the log file");
2696 
2697  //
2698  //
2699  if (f.exists())
2700  {
2701  if (have2overwrite)
2703  "::createAntabFile(): the file " + f.fileName() + " already exists; it will be overwritten");
2704  else
2705  {
2707  "::createAntabFile(): the file " + f.fileName() + " already exists, skipping");
2708  return false;
2709  };
2710  };
2711  // find associated OnSource records for tsyses:
2712  // ...
2713  // ...
2714 
2715 
2716  if (f.open(QFile::WriteOnly))
2717  {
2718  QTextStream s(&f);
2719 
2720  s << "# LOG-ANTAB Format Version of 2009.08.07\n";
2721  s << "#\n";
2722  s << "# Generator: " << qPrintable(libraryVersion.name()) << "\n";
2723  s << "#\n";
2724  s << "# Generated from log file " << qPrintable(inputLogFileName) << " on "
2725  << qPrintable(SgMJD().currentMJD().toString(SgMJD::F_SOLVE_SPLFL))<<"\n";
2726  s << "#\n";
2727  s << "STATION: " << qPrintable(stnKey) << "\n";
2728  s << "#\n";
2729 
2730  // Data On/Off:
2731  s << "NUMB_DATA_ON: " << onSourceRecords_.size() << "\n";
2732  s << "#\n";
2733  s << "# Data_on start Data_on end Source Scan\n";
2734  s << "#\n";
2735  for (int i=0; i<onSourceRecords_.size(); i++)
2736  {
2738  s << "DATA_ON: "
2739  << qPrintable(rec->getTstart().toString(SgMJD::F_SOLVE_SPLFL_V3)) << " "
2740  << qPrintable(rec->getTfinis().toString(SgMJD::F_SOLVE_SPLFL_V3)) << " "
2741  << qPrintable(rec->getSourceName().leftJustified(8, ' ')) << " "
2742  << qPrintable(rec->getScanName().leftJustified(8, ' ')) << "\n";
2743  };
2744 
2745  // Cable cals:
2746  s << "#\n";
2747  s << "NUMB_CAB: " << cableCals_.size() << "\n";
2748 
2749  if (cableCals_.size())
2750  {
2751  s << "#\n";
2752  s << "SIGN_CAB: " << (cableSign_==0?"UNDEF":(cableSign_<0?"-1":"+1")) << "\n";
2753  s << "#\n";
2754  s << "# Date Cable delay (sec)\n";
2755  s << "#\n";
2756  for (int i=0; i<cableCals_.size(); i++)
2757  {
2758  SgCableCalReading *cc=cableCals_.at(i);
2759  s << "CABLE: "
2760  << qPrintable(cc->getT().toString(SgMJD::F_SOLVE_SPLFL_V3)) << " "
2761  << qPrintable(QString("").sprintf("%12.5E", cc->getV())) << "\n";
2762  };
2763  };
2764 
2765  // meteo:
2766  s << "#\n";
2767  s << "NUMB_METEO: " << meteoPars_.size() << "\n";
2768 
2769  if (meteoPars_.size())
2770  {
2771  s << "#\n";
2772  s << "# Date Temp Pres Humid\n";
2773  s << "#\n";
2774  for (int i=0; i<meteoPars_.size(); i++)
2775  {
2776  SgMeteoReading *mr=meteoPars_.at(i);
2777  s << "METEO: "
2778  << qPrintable(mr->getT().toString(SgMJD::F_SOLVE_SPLFL_V3)) << " "
2779  << qPrintable(QString("").sprintf("%6.2f %7.1f %4.1f",
2780  mr->getM().getTemperature() + 273.15,
2781  mr->getM().getPressure()*100.0,
2782  mr->getM().getRelativeHumidity()*100.0))
2783  << "\n";
2784  };
2785  };
2786  s << "#\n";
2787 
2788  if (tSyses_.size())
2789  {
2790  if (setup2use == CSU_NATIVE)
2792  else if (setup2use == CSU_VGOS)
2794  else if (setup2use == CSU_SKED && channelSkeded->stnCfgByKey_.contains(stnKey))
2795  export2antabFrqs_skededSetup(s, channelSkeded->stnCfgByKey_.value(stnKey));
2796  else if (setup2use == CSU_NONE)
2798  else
2799  {
2800  s << "#\n";
2801  s << "#No FRQ data available\n";
2802  s << "#\n";
2803  };
2804  //
2805  //
2806  int numOfTsyses=0;
2807  if (!reportAllTsysData)
2808  {
2809  s << "# Scan Scan_name Src_name UTC_Time_tag ";
2810  int idx;
2811  idx = 1;
2812  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
2813  it!=channelSetup_.ifIdBySensorKey().end(); ++it, idx++)
2814  s << " Ts#" << QString("").sprintf("%03d", idx);
2815  s << "\n#\n";
2816 
2817  // tsyses only for data_valid=on:
2818  for (int i=0; i<onSourceRecords_.size(); i++)
2819  numOfTsyses += onSourceRecords_.at(i)->tSyses().size();
2820  s << "NUMB_TSYS: " << numOfTsyses << "\n";
2821  s << "#\n";
2822  int counter=1;
2823  for (int i=0; i<onSourceRecords_.size(); i++)
2824  {
2826  SgTsysReading *tsr=NULL;
2827  for (int j=0; j<sOn->tSyses().size(); j++)
2828  {
2829  tsr = sOn->tSyses().at(j);
2830  s << str.sprintf("TSYS: %6d ", counter);
2831  str = sOn->getScanName().leftJustified(9, ' ') + " " +
2832  sOn->getSourceName().leftJustified(8, ' ') + " ";
2833  s << str;
2834 
2835  if (tsr && tsr->osRec())
2836  s << tsr->getT().toString(SgMJD::F_SOLVE_SPLFL_V3) << " ";
2837  else
2838  s << sOn->getTstart().toString(SgMJD::F_SOLVE_SPLFL_V3) << " ";
2839 
2840  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
2841  it!=channelSetup_.ifIdBySensorKey().end(); ++it)
2842  {
2843  double v;
2844  v = -2.0;
2845  if (tsr && tsr->getTsys().contains(it.value()))
2846  v = tsr->getTsys().value(it.value());
2847  s << str.sprintf(" %7.1f", v);
2848  };
2849  s << "\n";
2850  counter++;
2851  };
2852  };
2853  }
2854  else // all tsys collected from a log file:
2855  {
2856  s << "# Idx Azimuth Elevation UTC_Time_tag ";
2857  int idx;
2858  idx = 1;
2859  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
2860  it!=channelSetup_.ifIdBySensorKey().end(); ++it, idx++)
2861  s << " Ts#" << QString("").sprintf("%03d", idx);
2862  s << "\n# (deg) (deg)\n";
2863 
2864  for (int i=0; i<tSyses_.size(); i++)
2865  {
2866  SgTsysReading *tsr=tSyses_.at(i);
2867  s << str.sprintf("TSYS: %6d ", i+1);
2868  str = "SLWEING SLEWING ";
2869  //
2870  SgTraklReading *trakl=NULL;
2871  double dt=1.0e3, d=0.0;
2872  for (int j=0; j<tsr->trakls().size(); j++)
2873  {
2874  if (tsr->trakls().at(j))
2875  {
2876  if ((d=fabs(tsr->getT() - tsr->trakls().at(j)->getT())) < dt)
2877  {
2878  dt = d;
2879  trakl = tsr->trakls().at(j);
2880  };
2881  };
2882  };
2883  if (trakl)
2884  str.sprintf("%10.5f %10.5f", trakl->getAz(), trakl->getEl());
2885 // str.sprintf("%8.3f %8.3f %2d %8.3f",
2886 // trakl->getAz(), trakl->getEl(), tsr->trakls().size(), dt*DAY2SEC);
2887 
2888  s << str << " " << tsr->getT().toString(SgMJD::F_SOLVE_SPLFL_V3) << " ";
2889  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
2890  it!=channelSetup_.ifIdBySensorKey().end(); ++it)
2891  {
2892  double v;
2893  v = -2.0;
2894  if (tsr && tsr->getTsys().contains(it.value()))
2895  v = tsr->getTsys().value(it.value());
2896  s << str.sprintf(" %7.1f", v);
2897  };
2898  s << "\n";
2899  };
2900  };
2901  }
2902  else
2903  {
2904  s << "#\nNUMB_FRQ: 0\n#\n";
2905  s << "NUMB_TSYS: 0\n";
2906  s << "#\n#\n# No TSYS records found in the log file\n#\n";
2907  };
2908 
2909 
2910  s << "#\n";
2911  f.close();
2912  s.setDevice(NULL);
2913  };
2914 
2915  return true;
2916 };
2917 
2918 
2919 
2920 //
2921 //
2923 {
2924  QString str("");
2925  QString sPol("");
2926  QString sSbd("");
2927  int idx;
2928 
2930  return;
2931  else
2932  tSensorsPrinted2AntCal_ = true;
2933 
2934  s << "#\nNUM_TP_SENSOR: " << channelSetup_.ifIdBySensorKey().size() << "\n";
2935  s << "#\n";
2936  s << "# Sensor IF_Freq LO_Freq Sky_frq_Cen Bdw Pol SensorId IF# SideBand\n";
2937  s << "# tag MHz MHz MHz MHz\n";
2938  s << "#\n";
2939  idx = 1;
2940 
2941  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
2942  it!=channelSetup_.ifIdBySensorKey().end(); ++it)
2943  {
2944  QString sensorKey(it.key());
2945  QString ifId(it.value());
2946 
2947  int cIdx=-1;
2948  if (!channelSetup_.ifIdxById().contains(ifId))
2949  {
2951  "::export2antCalFrqs_nativeSetup(): station " + stationName_ +
2952  ": cannot find IF index for if with the id \"" + ifId + "\"");
2953  continue;
2954  }
2955  else
2956  cIdx = channelSetup_.ifIdxById().value(ifId);
2957 
2958  QString loId("");
2961  SgChannelPolarization polarization=CP_UNDEF;
2962  double ifFrq, loFrq, skyFrq, bw;
2963  ifFrq = loFrq = skyFrq = bw = dFiller_;
2964 
2965  if (channelSetup_.loIdByIdx().contains(cIdx))
2966  loId = channelSetup_.loIdByIdx().value(cIdx);
2967  else if (channelSetup_.loIdByCid().contains(ifId))
2968  loId = channelSetup_.loIdByCid().value(ifId);
2969  if (loId.size())
2970  {
2971  // LO side band:
2972  if (channelSetup_.loSideBandById().contains(loId))
2973  loSb = channelSetup_.loSideBandById().value(loId);
2974  else
2976  "::export2antCalFrqs_nativeSetup(): station " + stationName_ + ": cannot find side band for LO \"" +
2977  loId + "\"");
2978 
2979  // channel side band:
2980  if (channelSetup_.ifSideBandById().contains(ifId))
2981  ifSb = channelSetup_.ifSideBandById().value(ifId);
2982  else
2984  "::export2antCalFrqs_nativeSetup(): station " + stationName_ + ": cannot find side band for channel #" +
2985  QString("").setNum(cIdx) + ", ID: \"" + ifId + "\"");
2986 
2987  // polarization:
2988  if (channelSetup_.loPolarizationById().contains(loId))
2989  polarization = channelSetup_.loPolarizationById().value(loId);
2990  else
2992  "::export2antCalFrqs_nativeSetup(): station " + stationName_ + ": cannot find polarization for LO \"" +
2993  loId + "\"");
2994 
2995  // bandwidth:
2996  if (channelSetup_.bbcBandwidthByIdx().contains(cIdx))
2997  bw = channelSetup_.bbcBandwidthByIdx().value(cIdx);
2998  else
3000  "::export2antCalFrqs_nativeSetup(): station " + stationName_ + ": cannot find bandwidth for channel #" +
3001  QString("").setNum(cIdx) + ", ID=" + ifId);
3002 
3003  if (channelSetup_.bbcFreqByIdx().contains(cIdx))
3004  {
3005  ifFrq = channelSetup_.bbcFreqByIdx().value(cIdx);
3006  //
3007  if (loSb == CSB_USB && ifSb == CSB_USB)
3008  ifFrq = channelSetup_.bbcFreqByIdx().value(cIdx);
3009  else if (loSb == CSB_USB && ifSb == CSB_LSB)
3010  ifFrq = channelSetup_.bbcFreqByIdx().value(cIdx) - bw;
3011  else if (loSb == CSB_LSB && ifSb == CSB_LSB)
3012  ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx) - bw;
3013  else if (loSb == CSB_LSB && ifSb == CSB_USB)
3014  ifFrq = - channelSetup_.bbcFreqByIdx().value(cIdx);
3015  // report central frq:
3016  ifFrq += bw/2.0;
3017  }
3018  else
3020  "::export2antCalFrqs_nativeSetup(): station " + stationName_ + ": cannot find BBC_FRQ for channel #" +
3021  QString("").setNum(cIdx));
3022 
3023  if (channelSetup_.loFreqById().contains(loId))
3024  loFrq = channelSetup_.loFreqById().value(loId);
3025  else
3027  "::export2antCalFrqs_nativeSetup(): station " + stationName_ + ": cannot find LO frq for channel #" +
3028  QString("").setNum(cIdx) + ", loID=" + loId);
3029 
3030  skyFrq = loFrq + ifFrq;
3031  }
3032  else
3034  "::export2antCalFrqs_nativeSetup(): station " + stationName_ + ": cannot find LO ID for channel #" +
3035  QString("").setNum(cIdx));
3036 
3037  channelSetup_.ifFreqByIdx()[cIdx] = skyFrq;
3038  channelSetup_.ifPolarizationById()[ifId] = polarization;
3039 
3040  sPol = sFiller_;
3041  if (polarization == CP_RightCP)
3042  sPol = "R";
3043  else if (polarization == CP_LeftCP)
3044  sPol = "L";
3045  else if (polarization == CP_HorizontalLP)
3046  sPol = "H";
3047  else if (polarization == CP_VerticalLP)
3048  sPol = "V";
3049 
3050  sSbd = sFiller_;
3051  if (ifSb == CSB_USB)
3052  sSbd = "USB";
3053  else if (ifSb == CSB_LSB)
3054  sSbd = "LSB";
3055  else if (ifSb == CSB_DUAL)
3056  sSbd = "USB/LSB";
3057 
3058  str.sprintf("TP_SENSOR: TS_%03d %8.2f %10.2f %10.2f %6.2f %3s %8s %3d %7s",
3059  idx, ifFrq, loFrq, skyFrq, bw,
3060  qPrintable(sPol),
3061  qPrintable(ifId),
3062  cIdx,
3063  qPrintable(sSbd)
3064  );
3065  s << str << "\n";
3066 
3067  idx++;
3068  };
3069  s << "#\n";
3070 };
3071 
3072 
3073 
3074 //
3076 {
3077  QString str("");
3078  QString sPol("");
3079  QString sSensorSbd("");
3080  QString sNetSbd("");
3081  int idx;
3082  QString sortingKey("");
3083  QMap<QString, QString> sensorSetupByKey;
3084 
3085 
3087  return;
3088  else
3089  tSensorsPrinted2AntCal_ = true;
3090 
3091  s << "#\nNUM_TP_SENSOR: " << channelSetup_.ifIdBySensorKey().size() << "\n";
3092  s << "#\n";
3093  //
3094  // let know the user about duality of sensors:
3095  if (channelSetup_.origSensorIdById().size())
3096  {
3097  s << "# Note, the following sensor ID(s) were splitted by two sidebands: \n";
3098  for (QMap<QString, QList<QString> >::iterator it=channelSetup_.origSensorIdById().begin();
3099  it!=channelSetup_.origSensorIdById().end(); ++it)
3100  {
3101  const QString& key=it.key();
3102  const QList<QString>& lst=it.value();
3103  str = "# sensor " + key + " => (";
3104  for (int i=0; i<lst.size(); i++)
3105  str += lst.at(i) + ", ";
3106  str.chop(2);
3107  s << str << ")\n";
3108  };
3109  s << "#\n";
3110  };
3111  s << "# Sensor IF_Freq LO_Freq Sky_frq_Cen BndWd Pol SensorId IF# Sensor Net Comments\n";
3112  s << "# tag MHz MHz MHz MHz SideBand SideBand\n";
3113  s << "#\n";
3114  idx = 1;
3115 
3116  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
3117  it!=channelSetup_.ifIdBySensorKey().end(); ++it)
3118  {
3119  QString sensorKey(it.key());
3120  QString ifId(it.value());
3121  QString loId("");
3122 
3123  int cIdx=-1;
3124  if (!channelSetup_.ifIdxById().contains(ifId))
3125  {
3127  "::export2antCalFrqs_vgosSetup(): station " + stationName_ +
3128  ": cannot find IF index for IF with ID \"" + ifId + "\"");
3129  continue;
3130  }
3131  else
3132  cIdx = channelSetup_.ifIdxById().value(ifId);
3133 
3136  SgChannelPolarization polarization=CP_UNDEF;
3137  double ifFrq, loFrq, skyFrq, bw;
3138  ifFrq = loFrq = skyFrq = bw = dFiller_;
3139  //
3140  /*
3141  if (channelSetup_.loIdByIdx().contains(cIdx))
3142  loId = channelSetup_.loIdByIdx().value(cIdx);
3143  else if (channelSetup_.loIdByCid().contains(ifId))
3144  loId = channelSetup_.loIdByCid().value(ifId);
3145 */
3146  if (channelSetup_.loIdBySensorKey().contains(sensorKey))
3147  loId = channelSetup_.loIdBySensorKey().value(sensorKey);
3148  else
3150  "::export2antCalFrqs_vgosSetup(): station " + stationName_ +
3151  ": cannot find LO ID for sensorKey \"" + sensorKey + "\"");
3152  //
3153  // lo sideband:
3154  if (channelSetup_.loSideBandBySensorKey().contains(sensorKey))
3155  loSb = channelSetup_.loSideBandBySensorKey().value(sensorKey);
3156  else
3158  "::export2antCalFrqs_vgosSetup(): station " + stationName_ +
3159  ": cannot find LO sideband for sensorKey \"" + sensorKey + "\"");
3160 
3161  // channel side band:
3162  if (channelSetup_.ifSideBandById().contains(ifId))
3163  ifSb = channelSetup_.ifSideBandById().value(ifId);
3164  else
3166  "::export2antCalFrqs_vgosSetup(): station " + stationName_ +
3167  ": cannot find side band for channel #" + QString("").setNum(cIdx) + ", ID: \"" + ifId + "\"");
3168 
3169  // LO freq:
3170  if (channelSetup_.loFreqBySensorKey().contains(sensorKey))
3171  loFrq = channelSetup_.loFreqBySensorKey().value(sensorKey);
3172  else
3174  "::export2antCalFrqs_vgosSetup(): station " + stationName_ +
3175  ": cannot find LO frq for sensorKey \"" + sensorKey + "\"");
3176 
3177  // IF freq:
3178  if (channelSetup_.ifFreqBySensorKey().contains(sensorKey))
3179  ifFrq = channelSetup_.ifFreqBySensorKey().value(sensorKey);
3180  else
3182  "::export2antCalFrqs_vgosSetup(): station " + stationName_ +
3183  ": cannot find BBC_FRQ for channel #" + QString("").setNum(cIdx));
3184 
3185  // bandwidth:
3186  if (channelSetup_.ifBandwidthBySensorKey().contains(sensorKey))
3187  bw = channelSetup_.ifBandwidthBySensorKey().value(sensorKey);
3188  else
3190  "::export2antCalFrqs_vgosSetup(): station " + stationName_ +
3191  ": cannot find bandwidth for sensor key \"" + sensorKey + "\", ID=" + ifId);
3192 
3193  skyFrq = SgChannelSetup::calcSkyFreq(loFrq, ifFrq, bw, loSb, ifSb);
3194 
3195  // polarization:
3196  if (channelSetup_.loPolarizationBySensorKey().contains(sensorKey))
3197  polarization = channelSetup_.loPolarizationBySensorKey().value(sensorKey);
3198  else
3200  "::export2antCalFrqs_vgosSetup(): station " + stationName_ +
3201  ": cannot find LO polarization for sensorKey \"" + sensorKey + "\"");
3202 
3203  channelSetup_.ifPolarizationById()[ifId] = polarization;
3204 
3205  sPol = sFiller_;
3206  if (polarization == CP_RightCP)
3207  sPol = "R";
3208  else if (polarization == CP_LeftCP)
3209  sPol = "L";
3210  else if (polarization == CP_HorizontalLP)
3211  sPol = "H";
3212  else if (polarization == CP_VerticalLP)
3213  sPol = "V";
3214 
3215  sSensorSbd = sNetSbd = sFiller_;
3216  if (ifSb == CSB_USB)
3217  sSensorSbd = "USB";
3218  else if (ifSb == CSB_LSB)
3219  sSensorSbd = "LSB";
3220  else if (ifSb == CSB_DUAL)
3221  sSensorSbd = "USB/LSB";
3222 
3223  if (loSb == CSB_USB)
3224  sNetSbd = "USB";
3225  else if (loSb == CSB_LSB)
3226  sNetSbd = "LSB";
3227  else if (loSb == CSB_DUAL)
3228  sNetSbd = "USB/LSB";
3229 
3230 
3231  str.sprintf("TP_SENSOR: TS_%03d %8.2f %10.2f %10.2f %6.2f %3s %8s %3d %7s %7s %s",
3232  idx, ifFrq, loFrq, skyFrq, bw,
3233  qPrintable(sPol),
3234  qPrintable(ifId),
3235  cIdx,
3236  qPrintable(sSensorSbd),
3237  qPrintable(sNetSbd)
3238  , qPrintable(sensorKey)
3239  );
3240  s << str << "\n";
3241  idx++;
3242 /*
3243 // sortingKey.sprintf("%10.2f %s %s",
3244 // skyFrq, qPrintable(sPol), qPrintable(sensorKey));
3245 
3246  sortingKey.sprintf("%s %10.2f %s",
3247  qPrintable(sPol),
3248  skyFrq,
3249  qPrintable(sensorKey));
3250 
3251  if (!sensorSetupByKey.contains(sortingKey))
3252  sensorSetupByKey[sortingKey] = str;
3253 */
3254  };
3255 /*
3256  // make sorted output:
3257  for (QMap<QString, QString>::iterator it=sensorSetupByKey.begin(); it!=sensorSetupByKey.end(); ++it)
3258  s << it.value() << "\n";
3259 */
3260 
3261  s << "#\n";
3262 };
3263 
3264 
3265 
3266 //
3268 {
3269  QString str("");
3270  QString sPol("");
3271  QString sSbd("");
3272  int idx;
3273 
3275  return;
3276  else
3277  tSensorsPrinted2AntCal_ = true;
3278 
3279  s << "#\nNUM_TP_SENSOR: " << channelSetup_.ifIdBySensorKey().size() << "\n";
3280  s << "#\n";
3281  s << "# Sensor IF_Freq LO_Freq Sky_frq_Cen Bdw Pol SensorId IF# SideBand\n";
3282  s << "# tag MHz MHz MHz MHz\n";
3283  s << "#\n";
3284  idx = 1;
3285 
3286  if (channelSetup_.ifIdxById().size() != sCfg.getChannelCfgs().size())
3287  {
3289  "::export2antCalFrqs_skededSetup(): station " + stationName_ +
3290  ": number of channels are different");
3291  return;
3292  };
3293 
3294  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
3295  it!=channelSetup_.ifIdBySensorKey().end(); ++it)
3296  {
3297  QString sensorKey(it.key());
3298  QString ifId(it.value());
3299 
3300  int cIdx=-1;
3301  if (!channelSetup_.ifIdxById().contains(ifId))
3302  {
3304  "::export2antCalFrqs_skededSetup(): station " + stationName_ +
3305  ": cannot find IF index for if with the id \"" + ifId + "\"");
3306  continue;
3307  }
3308  else
3309  cIdx = channelSetup_.ifIdxById().value(ifId);
3310 
3312  double ifFrq, loFrq, skyFrq, bw;
3313  ifFrq = loFrq = skyFrq = bw = dFiller_;
3314 
3315  // channel side band:
3316  if (channelSetup_.ifSideBandById().contains(ifId))
3317  ifSb = channelSetup_.ifSideBandById().value(ifId);
3318  else
3320  "::export2antCalFrqs_skededSetup(): station " + stationName_ + ": cannot find side band for channel #" +
3321  QString("").setNum(cIdx) + ", ID: \"" + ifId + "\"");
3322 
3323  // bandwidth:
3324  bw = sCfg.getChannelCfgs().at(idx - 1).getBandWidth();
3325  skyFrq = sCfg.getChannelCfgs().at(idx - 1).getSkyFrq();
3326  channelSetup_.ifFreqByIdx()[cIdx] = skyFrq;
3328 
3329  skyFrq += bw/2.0;
3330 
3331  sPol = sFiller_;
3332  sSbd = sFiller_;
3333  if (ifSb == CSB_USB)
3334  sSbd = "USB";
3335  else if (ifSb == CSB_LSB)
3336  sSbd = "LSB";
3337  else if (ifSb == CSB_DUAL)
3338  sSbd = "USB/LSB";
3339 
3340  str.sprintf("TP_SENSOR: TS_%03d %8.2f %10.2f %10.2f %6.2f %1s %8s %3d %7s",
3341  idx, ifFrq, loFrq, skyFrq, bw,
3342  qPrintable(sPol),
3343  qPrintable(ifId),
3344  cIdx,
3345  qPrintable(sSbd)
3346  );
3347  s << str << "\n";
3348  idx++;
3349  };
3350  s << "#\n";
3351 };
3352 
3353 
3354 
3355 //
3357 {
3358  QString str("");
3359  QString sPol("");
3360  QString sSbd("");
3361  int idx;
3362 
3363  s << "#\nNUM_PC_SENSOR: " << channelSetup_.pcalIdByKey().size() << "\n";
3364  s << "# Sensor Sky_frq_Cen Pol SensorId IF# SideBand\n";
3365  s << "# tag MHz\n";
3366  s << "#\n";
3367 
3368  idx = 1;
3369 
3370  for (QMap<QString, QString>::const_iterator it=channelSetup_.pcalIdByKey().begin();
3371  it!=channelSetup_.pcalIdByKey().end(); ++it)
3372  {
3373  QString key(it.key());
3374  QString id(it.value());
3375 
3376  SgChannelSideBand sideBand=CSB_UNDEF;
3377  SgChannelPolarization polarization=CP_UNDEF;
3378  double skyFrq;
3379  skyFrq = dFiller_;
3380 
3381  // channel side band:
3382  /*
3383  if (channelSetup_.ifSideBandById().contains(ifId))
3384  ifSb = channelSetup_.ifSideBandById().value(ifId);
3385  else
3386  logger->write(SgLogger::WRN, SgLogger::IO, className() +
3387  "::export2antCalFrqs_vgosSetup(): station " + stationName_ +
3388  ": cannot find side band for channel #" + QString("").setNum(cIdx) + ", ID: \"" + ifId + "\"");
3389  */
3390 
3391  // polarization:
3392  if (channelSetup_.pcalPolarizationById().contains(id))
3393  polarization = channelSetup_.pcalPolarizationById().value(id);
3394  else
3396  "::export2antCalPcal_vgosSetup(): station " + stationName_ +
3397  ": cannot find polarization for PCAL \"" + id + "\"");
3398 
3399  sPol = sFiller_;
3400  if (polarization == CP_RightCP)
3401  sPol = "R";
3402  else if (polarization == CP_LeftCP)
3403  sPol = "L";
3404  else if (polarization == CP_HorizontalLP)
3405  sPol = "H";
3406  else if (polarization == CP_VerticalLP)
3407  sPol = "V";
3408 
3409  sSbd = sFiller_;
3410  if (sideBand == CSB_USB)
3411  sSbd = "USB";
3412  else if (sideBand == CSB_LSB)
3413  sSbd = "LSB";
3414  else if (sideBand == CSB_DUAL)
3415  sSbd = "USB/LSB";
3416 
3417  str.sprintf("PC_SENSOR: PC_%03d %14.2f %3s %8s %d %7s",
3418  idx, skyFrq,
3419  qPrintable(sPol),
3420  qPrintable(id),
3421  nFiller_,
3422  qPrintable(sSbd)
3423  );
3424  s << str << "\n";
3425  idx++;
3426  };
3427  s << "#\n";
3428 };
3429 
3430 
3431 
3432 //
3433 bool SgStnLogReadings::createAntCalFile(const QString& inputLogFileName,
3434  const QString& outputFileName, const QString& stnKey, const SgChannelSkeded *channelSkeded,
3435  bool useSkededChannelSetup, bool have2overwrite, bool reportAllReadings, bool supressNonUsedSensors,
3436  int wishedOutputData, const QString& ext4compress, const QString& userCommand)
3437 {
3438  enum ChannelSetup2Use {CSU_NONE, CSU_NATIVE, CSU_SKED, CSU_VEX, CSU_VGOS};
3439  const QString dataFlag[] = {"DATA:OFF", "DATA:ON_SOURCE", "DATA:VALID_ON"};
3440  bool haveSkeded;
3441  ChannelSetup2Use setup2use;
3442  int scanIdx;
3443  QString srcName(sFiller_);
3444  QString scnName(sFiller_);
3445  QString outputContent("");
3446  QString str("");
3447  float el, az;
3448  int outputData=wishedOutputData;
3449  int numOfRecs;
3450  int dataFlagIdx;
3451  bool hasSensor;
3452 
3453  tSensorsPrinted2AntCal_ = false;
3454  setup2use = CSU_NONE;
3455  haveSkeded = false;
3456 
3457  // check what user want and what we have:
3458  if (outputData & AOD_DATA_ON && onSourceRecords_.size()==0)
3459  outputData &= ~AOD_DATA_ON;
3460  if (outputData & AOD_CABLE_SIGN && cableSign_==0)
3461  outputData &= ~AOD_CABLE_SIGN;
3462  if (outputData & AOD_CABLE_CAL && cableCals_.size()==0)
3463  outputData &= ~AOD_CABLE_CAL;
3464  if (outputData & AOD_METEO && meteoPars_.size()==0)
3465  outputData &= ~AOD_METEO;
3466  if (outputData & AOD_TSYS && tSyses_.size()==0)
3467  outputData &= ~AOD_TSYS;
3468  if (outputData & AOD_TPI && tSyses_.size()==0)
3469  outputData &= ~AOD_TPI;
3470  if (outputData & AOD_PCAL && pcals_.size()==0)
3471  outputData &= ~AOD_PCAL;
3472  if (outputData & AOD_FMTGPS && dot2xpses_.size()==0)
3473  outputData &= ~AOD_FMTGPS;
3474  if (outputData & AOD_DBBC3TP && dbbc3Tps_.size()==0)
3475  outputData &= ~AOD_DBBC3TP;
3476  if (outputData & AOD_SEFD && sefds_.size()==0)
3477  outputData &= ~AOD_SEFD;
3478  //
3479  // form string with output info:
3480  if (outputData & AOD_DATA_ON)
3481  outputContent += "DATA_ON ";
3482  if (outputData & AOD_CABLE_SIGN)
3483  outputContent += "CABLE_SIGN ";
3484  if (outputData & AOD_CABLE_CAL)
3485  outputContent += "CABLE ";
3486  if (outputData & AOD_METEO)
3487  outputContent += "METEO ";
3488  if (outputData & AOD_TSYS)
3489  outputContent += "TP_SENSOR TSYS ";
3490  if (outputData & AOD_TPI)
3491  {
3492  if (outputData & AOD_TSYS)
3493  outputContent += "TPI ";
3494  else
3495  outputContent += "TP_SENSOR TPI ";
3496  };
3497  if (outputData & AOD_DBBC3TP)
3498  {
3499  if (outputData & AOD_TSYS)
3500  outputContent += "TPC ";
3501  else
3502  outputContent += "TP_SENSOR TPC ";
3503  };
3504  if (outputData & AOD_SEFD)
3505  {
3506  if (outputData & AOD_TSYS)
3507  outputContent += "SEFD ";
3508  else
3509  outputContent += "TP_SENSOR SEFD ";
3510  };
3511  if (outputData & AOD_PCAL)
3512  outputContent += "PC_SENSOR PCAL ";
3513  if (outputData & AOD_FMTGPS)
3514  outputContent += "FMT2GPS_TIMER FMTGPS ";
3515 
3516  if (!outputContent.size())
3517  {
3519  "::createAntCalFile(): station " + stnKey + ": nothing to output");
3520  return false;
3521  }
3522  else
3523  {
3524  outputContent.chop(1);
3526  "::createAntCalFile(): station " + stnKey + ": collected content for output: \"" +
3527  outputContent + "\"");
3528  };
3529  //
3530  if (!outputFileName.size())
3531  {
3532  str = inputLogFileName;
3534  if (filter)
3535  str.chop(filter->getDefaultExtension().size() + 1);
3536 
3537  // set up outut file name:
3538  if (5 < str.size() && str.right(4) == QString(".log"))
3539  str.chop(4);
3540  str += ".anc";
3541  if (ext4compress.size())
3542  str += "." + ext4compress;
3543  }
3544  else
3545  str = outputFileName;
3546 
3547  if (ext4compress.size() && str.right(ext4compress.size()) != ext4compress)
3548  str += "." + ext4compress;
3549 
3550  FILE *pipe=NULL;
3551  QTextStream s;
3552  QFile f(str);
3553  //
3555  "::createAntCalFile(): station " + stnKey + ": " +
3556  " going to create ANTCAL file \"" + f.fileName() + "\"");
3557  //
3558  if (f.exists())
3559  {
3560  if (have2overwrite)
3562  "::createAntCalFile(): the file " + f.fileName() + " already exists; it will be overwritten");
3563  else
3564  {
3566  "::createAntCalFile(): the file " + f.fileName() + " already exists, skipping");
3567  return false;
3568  };
3569  };
3570  //
3571  pipe = compressors.openFlt(str, f, s, FLTD_Output);
3572  //
3573 
3574 // if (haveTsys)
3575  if (outputData & (AOD_TSYS | AOD_DBBC3TP | AOD_TPI | AOD_SEFD))
3576  {
3577  // check channel set up:
3578  if (!channelSkeded)
3580  "::createAntCalFile(): station " + stnKey +
3581  ": the sked's channel setup is missing");
3582  else if (!channelSkeded->isOk())
3584  "::createAntCalFile(): station " + stnKey +
3585  ": the sked's channel setup is not good, skipping it");
3586  else if (!channelSkeded->stnCfgByKey_.contains(stnKey))
3588  "::createAntCalFile(): station " + stnKey +
3589  ": the sked's channel setup does not contain this station, skipping it");
3591  !compareChannelNumbers(channelSkeded->stnCfgByKey_.value(stnKey)))
3593  "::createAntCalFile(): station " + stnKey +
3594  ": the number of collected channels and number of channels in the sked are different, skipping it");
3595  else
3596  {
3597  haveSkeded = true;
3599  "::createAntCalFile(): station " + stnKey +
3600  ": looks like we have channel setup from sked");
3601  };
3602  //
3603  //
3604  if (channelSetup_.selfCheck(stnKey))
3605  {
3606  setup2use = CSU_NATIVE;
3609  setup2use = CSU_VGOS;
3611  "::createAntCalFile(): station " + stnKey +
3612  ": channel setup from the log file looks ok");
3613  if (haveSkeded && channelSetup_.getHwType() != SgChannelSetup::HT_VGOS)
3614  {
3616  "::createAntCalFile(): station " + stnKey +
3617  ": comparing sked's and FS log channel setups");
3618  compareChannelSetups(channelSkeded->stnCfgByKey_.value(stnKey));
3619  };
3620  }
3621  else if (haveSkeded)
3622  {
3623  setup2use = CSU_SKED;
3625  "::createAntCalFile(): station " + stnKey + ": cannot figure out channel setup from the log "
3626  "file, falling back to the set up from sked file");
3627  }
3628  else
3629  {
3630  setup2use = CSU_NONE;
3632  "::createAntCalFile(): station " + stnKey + ": cannot figure out the channel setup");
3633  };
3634 
3635  if (setup2use == CSU_NATIVE && useSkededChannelSetup)
3636  {
3637  setup2use = CSU_SKED;
3639  "::createAntCalFile(): station " + stnKey + ": forced to use the set up from sked file");
3640  };
3641  };
3642 
3643  // find associated onSource records for tsyses:
3644  // ...
3645  // ...
3646 
3647  if (s.device())
3648  {
3649  QFile fInpt(inputLogFileName);
3650  QFileInfo fi(fInpt);
3651 
3652  s << "# ANTCAL Format Version 0.96 of 2021.05.17\n#\n";
3653  s << "STATION: " << qPrintable(stnKey) << "\n#\n";
3654 
3655  s << "#\n# Created with command:\n";
3656  s << "#\n# " << qPrintable(userCommand) << "\n#\n";
3657 
3658  if (backEndInfo_.size())
3659  s << "# BACKEND INFO: " << qPrintable(backEndInfo_) << "\n";
3660  if (recorderInfo_.size())
3661  s << "# RECORDER INFO: " << qPrintable(recorderInfo_) << "\n#\n";
3662 
3663 
3664  s << "EXP_CODE: " << qPrintable(experimentName_.size()?experimentName_.toLower():sFiller_) << "\n#\n";
3665  s << "#\n# sec\n#\nUTC_MTAI: " << dFiller_ << "\n#\n#\n";
3666  s << "# Filler values\n# Real Integer Character\n#\n";
3667  s << "FILLERS: " << dFiller_ << " " << nFiller_ << " " << qPrintable(sFiller_) << "\n#\n";
3668 
3669  s << "#\n";
3670  s << "NUM_PROVENANCE: 1\n";
3671  s << "#\n";
3672 
3673  s << "PROVENANCE: 1 GENERATOR: " << qPrintable(libraryVersion.name()) << " / "
3674  << qPrintable(driverVersion->name()) << "\n";
3675  s << "PROVENANCE: 1 CREATED_VARS: " << qPrintable(outputContent) << "\n";
3676  s << "PROVENANCE: 1 CREATION_DATE: "
3677  << qPrintable(SgMJD().currentMJD().toString(SgMJD::F_SOLVE_SPLFL)) << "\n";
3678  s << "PROVENANCE: 1 NUM_FILES: 1\n";
3679 
3680  s << "PROVENANCE: 1 DATA_TYPE: 1 FS_LOG Version " << fsVersionLabel_ << "\n";
3681  s << "PROVENANCE: 1 DATA_FILE: " << qPrintable(fi.canonicalFilePath()) << "\n";
3682 // s << "PROVENANCE: 1 DATA_FILE: " << qPrintable(inputLogFileName) << "\n";
3683 
3684  s << "PROVENANCE: 1 DATA_CREATED: 1 "
3685  << qPrintable(SgMJD(fi.lastModified()).toString(SgMJD::F_SOLVE_SPLFL)) << "\n";
3686  s << "PROVENANCE: 1 NUM_COMMENTS: 1\n";
3687  s << "PROVENANCE: 1 COMMENT: Original field system log\n#\n";
3688  //
3689  //
3690  //
3691  // Data On/Off:
3692  if (outputData & AOD_DATA_ON)
3693  {
3694  s << "#\nNUM_DATA_ON: " << onSourceRecords_.size() << "\n#\n";
3695  s << "# ScanIdx Data_on UTC start Data_on UTC end Source ScanName\n";
3696  s << "# YYYY.DD.MM-hh:mm:ss.ff YYYY.DD.MM-hh:mm:ss.ff\n";
3697  s <<"#\n";
3698  for (int i=0; i<onSourceRecords_.size(); i++)
3699  {
3701  s << "DATA_ON: "
3702  << qPrintable(str.sprintf("%6d ", i+1) +
3703 // sOn->getTstart().toString(SgMJD::F_SOLVE_SPLFL_V3) + " " + // <- epoch of when antenna is on source
3704  sOn->getTdataOn().toString(SgMJD::F_SOLVE_SPLFL_V3) + " " + // <- epoch of data_valid=on
3705  sOn->getTfinis().toString(SgMJD::F_SOLVE_SPLFL_V3) + " " + // <- epoch of data_valid=off
3706  sOn->getSourceName().leftJustified(8, ' ') + " " +
3707  sOn->getScanName().leftJustified(8, ' ') )
3708  << "\n";
3709  };
3710  s << "#\n";
3711  };
3712  //
3713  //
3714  // Cable sign:
3715  if (outputData & AOD_CABLE_SIGN)
3716  s << "#\nCABLE_SIGN: " << (cableSign_<0?"-1":"+1") << "\n";
3717  //
3718  // Cable cals:
3719  if (outputData & AOD_CABLE_CAL)
3720  {
3721  numOfRecs = 0;
3722  if (reportAllReadings)
3723  numOfRecs = cableCals_.size();
3724  else
3725  for (int i=0; i<cableCals_.size(); i++)
3726  if (cableCals_.at(i)->getOsRec())
3727  numOfRecs++;
3728 
3729  s << "#\nNUM_CABLE: " << numOfRecs << "\n";
3730  s << "#\n";
3731  s << "# CblIdx UTC Date Cable delay Source ScanName\n";
3732  s << "# YYYY.DD.MM-hh:mm:ss.ff s\n";
3733  s << "#\n";
3734  for (int i=0; i<cableCals_.size(); i++)
3735  {
3736  SgCableCalReading *cc=cableCals_.at(i);
3737  const SgOnSourceRecord *sOn=cc->getOsRec();
3738  scanIdx = nFiller_;
3739  if (sOn)
3740  scanIdx = sOn->getIdx() + 1;
3741  if (reportAllReadings || sOn)
3742  {
3743  s << "CABLE: " << qPrintable(str.sprintf("%6d ", scanIdx));
3744  s << qPrintable(
3746  str.sprintf(" %12.5E ", cc->getV()) +
3747  (sOn?sOn->getSourceName():sFiller_).leftJustified(8, ' ') + " " +
3748  (sOn?sOn->getScanName():sFiller_).leftJustified(8, ' ') ) << "\n";
3749  };
3750  };
3751  s << "#\n";
3752  };
3753  //
3754  //
3755  // meteo:
3756  if (outputData & AOD_METEO)
3757  {
3758  numOfRecs = 0;
3759  if (reportAllReadings)
3760  numOfRecs = meteoPars_.size();
3761  else
3762  for (int i=0; i<meteoPars_.size(); i++)
3763  if (meteoPars_.at(i)->getOsRec())
3764  numOfRecs++;
3765 
3766  s << "#\nNUM_METEO: " << numOfRecs << "\n";
3767  s << "#\n";
3768  s << "# MeteoIdx UTC Date Temp Pres Humid ScanIdx Source Scan\n";
3769  s << "# YYYY.DD.MM-hh:mm:ss.ff K Pa %\n";
3770  s << "#\n";
3771  int meteoIdx;
3772  meteoIdx = 0;
3773  for (int i=0; i<meteoPars_.size(); i++)
3774  {
3775  SgMeteoReading *mr=meteoPars_.at(i);
3776  const SgOnSourceRecord *sOn=mr->getOsRec();
3777  scanIdx = nFiller_;
3778  if (sOn)
3779  scanIdx = sOn->getIdx() + 1;
3780  if (reportAllReadings || sOn)
3781  {
3782  s << "METEO: "
3783  << qPrintable(str.sprintf("%7d ", meteoIdx+1))
3784  << qPrintable(mr->getT().toString(SgMJD::F_SOLVE_SPLFL_V3)) << " "
3785  << qPrintable(QString("").sprintf("%6.2f %7.1f %5.1f ",
3786  mr->getM().getTemperature() + 273.15,
3787  mr->getM().getPressure()*100.0,
3788  mr->getM().getRelativeHumidity()*100.0))
3789  << qPrintable(str.sprintf("%6d ", scanIdx))
3790  << qPrintable(
3791  (sOn?sOn->getSourceName():sFiller_).leftJustified(8, ' ') + " " +
3792  (sOn?sOn->getScanName():sFiller_).leftJustified(8, ' ') )
3793  << "\n";
3794  meteoIdx++;
3795  };
3796  };
3797  s << "#\n";
3798  };
3799  //
3800  //
3801  // TP_SENSORS:
3802  if (outputData & (AOD_TSYS | AOD_TPI | AOD_SEFD | AOD_DBBC3TP))
3803  {
3804  // sensor info:
3805  s << "#\n#\n";
3806  if (setup2use == CSU_NATIVE)
3807  {
3808 // if (outputData & AOD_DBBC3TP)
3809 // export2antCalFrqs_dbbc3Setup(s);
3810 // else
3811  //export2antCalFrqs_nativeSetup(s);
3813  }
3814  else if (setup2use == CSU_VGOS)
3815  {
3816 // if (outputData & AOD_DBBC3TP)
3817 // export2antCalFrqs_dbbc3Setup(s);
3818 // else
3819 // export2antCalFrqs_dbbc3Setup(s);
3821  }
3822  else if (setup2use == CSU_SKED && channelSkeded->stnCfgByKey_.contains(stnKey))
3823  export2antCalFrqs_skededSetup(s, channelSkeded->stnCfgByKey_.value(stnKey));
3824  else if (setup2use == CSU_NONE)
3826  else
3827  {
3828  s << "#\n";
3829  s << "# No TP_SENSOR data available\n";
3830  s << "#\n";
3831  };
3832  };
3833  //
3834  //
3835  // TSYS:
3836  if (outputData & AOD_TSYS)
3837  {
3838  numOfRecs = 0;
3839  if (reportAllReadings)
3840  {
3841  for (int i=0; i<tSyses_.size(); i++)
3842  if (tSyses_.at(i)->getTsys().size())
3843  numOfRecs++;
3844  }
3845  else
3846  for (int i=0; i<tSyses_.size(); i++)
3847  if (tSyses_.at(i)->getOsRec() && tSyses_.at(i)->getTsys().size())
3848  numOfRecs++;
3849 
3850  s << "#\nNUM_TSYS: " << numOfRecs << "\n";
3851  s << "#\n";
3852  s << "# ScanIdx UTC_Time_tag Sensor Tsys Azimuth Elevat Source Scan DataScopeFlag\n";
3853  s << "# YYYY.DD.MM-hh:mm:ss.ff tag K deg deg\n";
3854  s << "#\n";
3855  //
3856  //
3857  for (int i=0; i<tSyses_.size(); i++)
3858  {
3859  SgTsysReading *tsr=tSyses_.at(i);
3860  if (tsr->getTsys().size())
3861  {
3862  el = az = dFiller_;
3863  //
3864  // check for az/el info:
3865  SgTraklReading *trakl=NULL;
3866  double dt=1.0e3, d=0.0;
3867  //
3868  for (int j=0; j<tsr->trakls().size(); j++)
3869  if (tsr->trakls().at(j) &&
3870  (d=fabs(tsr->getT() - tsr->trakls().at(j)->getT())) < dt)
3871  {
3872  dt = d;
3873  trakl = tsr->trakls().at(j);
3874  };
3875  if (trakl && dt < 4.0/DAY2SEC)
3876  {
3877  az = trakl->getAz();
3878  el = trakl->getEl();
3879  };
3880  //
3881  // src & scan names:
3882  srcName = scnName = sFiller_;
3883  scanIdx = nFiller_;
3884  const SgOnSourceRecord *osRec=tsr->getOsRec();
3885  if (osRec)
3886  {
3887  srcName = osRec->getSourceName();
3888  scnName = osRec->getScanName();
3889  scanIdx = osRec->getIdx() + 1;
3890  };
3891  //
3892  if (reportAllReadings || osRec)
3893  {
3894  int idx=1;
3895  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
3896  it!=channelSetup_.ifIdBySensorKey().end(); ++it, idx++)
3897  {
3898  QString sensorKey(it.key());
3899  double v;
3900  hasSensor = false;
3901  v = dFiller_;
3902  if (tsr->getTsys().contains(sensorKey))
3903  {
3904  v = tsr->getTsys().value(sensorKey);
3905  hasSensor = true;
3906  };
3907  if (!supressNonUsedSensors || hasSensor)
3908  {
3909  dataFlagIdx = osRec?(osRec->getTdataOn()<tsr->getT()?2:1):0;
3910  str.sprintf("TSYS: %6d %s TS_%03d %7.1f %9.4f %8.4f %s %s %s",
3911  scanIdx, qPrintable(tsr->getT().toString(SgMJD::F_SOLVE_SPLFL_V3)),
3912  idx, v, az, el,
3913  qPrintable(srcName.leftJustified(8, ' ')),
3914  qPrintable(scnName.leftJustified(9, ' ')),
3915  qPrintable(dataFlag[dataFlagIdx])
3916 // , qPrintable(it.key())
3917  );
3918  s << str << "\n";
3919  };
3920  };
3921  };
3922  };
3923  };
3924  s << "#\n";
3925  };
3926  //
3927  //
3928  // TPI data:
3929  if (outputData & AOD_TPI)
3930  {
3931  numOfRecs = 0;
3932  if (reportAllReadings)
3933  {
3934  for (int i=0; i<tSyses_.size(); i++)
3935  if (tSyses_.at(i)->getTpcont().size())
3936  numOfRecs++;
3937  }
3938  else
3939  for (int i=0; i<tSyses_.size(); i++)
3940  if (tSyses_.at(i)->getOsRec() && tSyses_.at(i)->getTpcont().size())
3941  numOfRecs++;
3942 
3943  s << "#\nNUM_TPI: " << numOfRecs << "\n";
3944  s << "#\n";
3945  s << "# ScanIdx UTC_Time_tag Sensor TpiOn TpiOff Azimuth Elevat Source Scan DataScopeFlag\n";
3946  s << "# YYYY.DD.MM-hh:mm:ss.ff tag K K deg deg\n";
3947  s << "#\n";
3948  //
3949  for (int i=0; i<tSyses_.size(); i++)
3950  {
3951  SgTsysReading *tsr=tSyses_.at(i);
3952  if (tsr->getTpcont().size())
3953  {
3954  el = az = dFiller_;
3955  //
3956  // check for az/el info:
3957  SgTraklReading *trakl=NULL;
3958  double dt=1.0e3, d=0.0;
3959  for (int j=0; j<tsr->trakls().size(); j++)
3960  if (tsr->trakls().at(j) &&
3961  (d=fabs(tsr->getT() - tsr->trakls().at(j)->getT())) < dt)
3962  {
3963  dt = d;
3964  trakl = tsr->trakls().at(j);
3965  };
3966  if (trakl && dt < 4.0/DAY2SEC)
3967  {
3968  az = trakl->getAz();
3969  el = trakl->getEl();
3970  };
3971  //
3972  // src & scan names:
3973  srcName = scnName = sFiller_;
3974  scanIdx = nFiller_;
3975  const SgOnSourceRecord *osRec=tsr->getOsRec();
3976  if (osRec)
3977  {
3978  srcName = osRec->getSourceName();
3979  scnName = osRec->getScanName();
3980  scanIdx = osRec->getIdx() + 1;
3981  };
3982  //
3983  if (reportAllReadings || osRec)
3984  {
3985  int idx=1;
3986  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
3987  it!=channelSetup_.ifIdBySensorKey().end(); ++it, idx++)
3988  {
3989  QString sensorKey(it.key());
3990  int vOn, vOf;
3991  vOn = vOf = dFiller_;
3992  hasSensor = false;
3993  if (tsr->getTpcont().contains(sensorKey))
3994  {
3995  vOn = tsr->getTpcont().value(sensorKey)[0];
3996  vOf = tsr->getTpcont().value(sensorKey)[1];
3997  hasSensor = true;
3998  };
3999  if (!supressNonUsedSensors || hasSensor)
4000  {
4001  dataFlagIdx = osRec?(osRec->getTdataOn()<tsr->getT()?2:1):0;
4002  str.sprintf("TPI: %6d %s TS_%03d %8d %8d %9.4f %8.4f %s %s %s",
4003  scanIdx, qPrintable(tsr->getT().toString(SgMJD::F_SOLVE_SPLFL_V3)),
4004  idx, vOn, vOf, az, el,
4005  qPrintable(srcName.leftJustified(8, ' ')),
4006  qPrintable(scnName.leftJustified(9, ' ')),
4007  qPrintable(dataFlag[dataFlagIdx]));
4008  s << str << "\n";
4009  };
4010  };
4011  };
4012  };
4013  };
4014  s << "#\n";
4015  //
4016  //
4017  };
4018  //
4019  if (outputData & AOD_PCAL)
4020  {
4021  // sensor setups:
4023  //
4024  numOfRecs = 0;
4025  if (reportAllReadings)
4026  numOfRecs = pcals_.size();
4027  else
4028  for (int i=0; i<pcals_.size(); i++)
4029  if (pcals_.at(i)->getOsRec())
4030  numOfRecs++;
4031 
4032  s << "#\nNUM_PCAL: " << numOfRecs << "\n";
4033  s << "#\n";
4034  //
4035  // pcal data:
4036  s << "#\n";
4037  s << "# ScanIdx UTC_Time_tag SensInd Ampl Phase Source Scan DataScopeFlag\n";
4038  s << "# YYYY.DD.MM-hh:mm:ss.ff rad [0,2pi)\n";
4039  s << "#\n";
4040 
4041  for (int i=0; i<pcals_.size(); i++)
4042  {
4043  SgPcalReading *pcr=pcals_.at(i);
4044  //
4045  // src & scan names:
4046  srcName = scnName = sFiller_;
4047  scanIdx = nFiller_;
4048  const SgOnSourceRecord *osRec=pcr->getOsRec();
4049  if (osRec)
4050  {
4051  srcName = osRec->getSourceName();
4052  scnName = osRec->getScanName();
4053  scanIdx = osRec->getIdx() + 1;
4054  };
4055  //
4056  if (reportAllReadings || osRec)
4057  {
4058  int idx=1;
4059  for (QMap<QString, QString>::const_iterator it=channelSetup_.pcalIdByKey().begin();
4060  it!=channelSetup_.pcalIdByKey().end(); ++it, idx++)
4061  {
4062  float vAmp, vPhs;
4063  vAmp = vPhs = dFiller_;
4064  hasSensor = false;
4065  if (pcr->getPcal().contains(it.value()))
4066  {
4067  vAmp = *pcr->getPcal().value(it.value());
4068  vPhs = *(pcr->getPcal().value(it.value()) + 1);
4069  vPhs = fmodf(vPhs + 360.0, 360.0)/RAD2DEG; // deg -> rad
4070  hasSensor = true;
4071  };
4072  if (!supressNonUsedSensors || hasSensor)
4073  {
4074  dataFlagIdx = osRec?(osRec->getTdataOn()<pcr->getT()?2:1):0;
4075  str.sprintf("PCAL: %6d %s PC_%03d %8.3f %10.5f %s %s %s",
4076  scanIdx, qPrintable(pcr->getT().toString(SgMJD::F_SOLVE_SPLFL_V3)),
4077  idx, vAmp, vPhs,
4078  qPrintable(srcName.leftJustified(8, ' ')),
4079  qPrintable(scnName.leftJustified(9, ' ')),
4080  qPrintable(dataFlag[dataFlagIdx]));
4081  s << str << "\n";
4082  };
4083  };
4084  };
4085  };
4086  s << "#\n";
4087  };
4088  //
4089  //
4090  if (outputData & AOD_FMTGPS)
4091  {
4092  // header:
4093  s << "#\nNUM_FMT2GPS_TIMER: " << channelSetup_.xpsIdByKey().size() << "\n";
4094  s << "# Timer Board\n";
4095  s << "# tag\n";
4096  s << "#\n";
4097  int idx=1;
4098  for (QMap<QString, QString>::const_iterator it=channelSetup_.xpsIdByKey().begin();
4099  it!=channelSetup_.xpsIdByKey().end(); ++it)
4100  {
4101  QString id(it.value());
4102  str.sprintf("FMT2GPS_TIMER: TMR_%03d %s",
4103  idx, qPrintable(id) );
4104  s << str << "\n";
4105  idx++;
4106  };
4107  //
4108  numOfRecs = 0;
4109  if (reportAllReadings)
4110  numOfRecs = dot2xpses_.size();
4111  else
4112  for (int i=0; i<dot2xpses_.size(); i++)
4113  if (dot2xpses_.at(i)->getOsRec())
4114  numOfRecs++;
4115 
4116  s << "#\nNUM_FMTGPS: " << numOfRecs << "\n";
4117  s << "#\n";
4118  s << "# Scan UTC_Time_tag Timer Formatter minus Source Scan\n";
4119  s << "# Idx tag GPS time\n";
4120  s << "# YYYY.DD.MM-hh:mm:ss.ff s\n";
4121  s << "#\n";
4122  for (int i=0; i<dot2xpses_.size(); i++)
4123  {
4124  SgDot2xpsReading *d2r=dot2xpses_.at(i);
4125  //
4126  // src & scan names:
4127  srcName = scnName = sFiller_;
4128  scanIdx = nFiller_;
4129  const SgOnSourceRecord *osRec=d2r->getOsRec();
4130  if (osRec)
4131  {
4132  srcName = osRec->getSourceName();
4133  scnName = osRec->getScanName();
4134  scanIdx = osRec->getIdx() + 1;
4135  };
4136  //
4137  if (reportAllReadings || osRec)
4138  {
4139  int idx=1;
4140  for (QMap<QString, QString>::const_iterator it=channelSetup_.xpsIdByKey().begin();
4141  it!=channelSetup_.xpsIdByKey().end(); ++it, idx++)
4142  {
4143  float v;
4144  v = dFiller_;
4145  hasSensor = false;
4146  if (d2r->getDot2gpsByBrd().contains(it.value()))
4147  {
4148  v = d2r->getDot2gpsByBrd().value(it.value());
4149  hasSensor = true;
4150  };
4151  if (!supressNonUsedSensors || hasSensor)
4152  {
4153  str.sprintf("FMTGPS: %6d %s TMR_%03d %16.9e %s %s",
4154  scanIdx, qPrintable(d2r->getT().toString(SgMJD::F_SOLVE_SPLFL_V3)),
4155  idx, v,
4156  qPrintable(srcName.leftJustified(8, ' ')),
4157  qPrintable(scnName.leftJustified(9, ' ')) );
4158  s << str << "\n";
4159  };
4160  };
4161  };
4162  };
4163  s << "#\n";
4164  };
4165  //
4166  //
4167  if (outputData & AOD_DBBC3TP)
4168  {
4169  // header:
4170  s << "#\n#\n";
4171 // export2antCalFrqs_dbbc3Setup(s);
4173 
4174  numOfRecs = 0;
4175  if (reportAllReadings)
4176  numOfRecs = dbbc3Tps_.size();
4177  else
4178  for (int i=0; i<dbbc3Tps_.size(); i++)
4179  if (dbbc3Tps_.at(i)->getOsRec())
4180  numOfRecs++;
4181 
4182  s << "#\nNUM_TPC: " << numOfRecs << "\n";
4183  s << "#\n";
4184  s << "# ScanIdx UTC_Time_tag Sensor Gain TpCalOn TpCalOff SEFD Azimuth Elevat Source Scan DataScopeFlag\n";
4185  s << "# YYYY.DD.MM-hh:mm:ss.ff tag Jy deg deg\n";
4186  s << "#\n";
4187  //
4188  for (int i=0; i<dbbc3Tps_.size(); i++)
4189  {
4190  SgDbbc3TpReading *rec=dbbc3Tps_.at(i);
4191  el = az = dFiller_;
4192  //
4193  // check for az/el info:
4194  // ...
4195  //
4196  // src & scan names:
4197  srcName = scnName = sFiller_;
4198  scanIdx = nFiller_;
4199  const SgOnSourceRecord *osRec=rec->getOsRec();
4200  if (osRec)
4201  {
4202  srcName = osRec->getSourceName();
4203  scnName = osRec->getScanName();
4204  scanIdx = osRec->getIdx() + 1;
4205  };
4206  //
4207  if (reportAllReadings || osRec)
4208  {
4209  int idx=1;
4210  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
4211  it!=channelSetup_.ifIdBySensorKey().end(); ++it, idx++)
4212  {
4213  double vGain, vOn, vOf, vSefd;
4214  vGain = vOn = vOf = vSefd = dFiller_;
4215  QString bbcId(it.value());
4216 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
4217  QString sbId(it.value().at(it.value().size() - 1));
4218 #else
4219  QString sbId(it.value().back());
4220 #endif
4221  bbcId.chop(1);
4222  hasSensor = false;
4223  if (rec->getTpBySensor().contains(bbcId))
4224  {
4225  if (sbId == "l")
4226  {
4227  vGain = rec->getTpBySensor().value(bbcId).gainL_;
4228  vOn = rec->getTpBySensor().value(bbcId).tpOnL_;
4229  vOf = rec->getTpBySensor().value(bbcId).tpOffL_;
4230  vSefd = rec->getTpBySensor().value(bbcId).sefdL_;
4231  }
4232  else if (sbId == "u")
4233  {
4234  vGain = rec->getTpBySensor().value(bbcId).gainU_;
4235  vOn = rec->getTpBySensor().value(bbcId).tpOnU_;
4236  vOf = rec->getTpBySensor().value(bbcId).tpOffU_;
4237  vSefd = rec->getTpBySensor().value(bbcId).sefdU_;
4238  }
4239  else
4241  "::createAntCalFile(): station " + stnKey +
4242  ": got an unknown sideband id: \"" + sbId + "\", IF id is \"" +
4243  it.value() + "\"");
4244  hasSensor = true;
4245  };
4246  if (!supressNonUsedSensors || hasSensor)
4247  {
4248  dataFlagIdx = osRec?(osRec->getTdataOn()<rec->getT()?2:1):0;
4249  str.sprintf("TPC: %6d %s TS_%03d %8.1f %10.1f %10.1f %10.1f %9.4f %8.4f %s %s %s",
4250  scanIdx, qPrintable(rec->getT().toString(SgMJD::F_SOLVE_SPLFL_V3)),
4251  idx, vGain, vOn, vOf, vSefd, az, el,
4252  qPrintable(srcName.leftJustified(8, ' ')),
4253  qPrintable(scnName.leftJustified(9, ' ')),
4254  qPrintable(dataFlag[dataFlagIdx])
4255  );
4256  s << str << "\n";
4257  };
4258  };
4259  };
4260  };
4261  s << "#\n";
4262  };
4263  //
4264  //
4265  if (outputData & AOD_SEFD)
4266  {
4267  // header:
4268  s << "#\n#\n";
4269 // export2antCalFrqs_dbbc3Setup(s);
4271  s << "#\nNUM_SEFD: " << sefds_.size() << "\n#\n";
4272  s << "# some docs on OnOff measurements can be found in FS sources, fs-master/onoff/onoff.txt\n";
4273  s << "# and fs-master/onoff/gain.txt\n";
4274  s << "#\n";
4275  s << "# Sensor UTC_Time_tag SEFD Tsys Tcal Trat Gain Az El Source\n";
4276  s << "# tag YYYY.DD.MM-hh:mm:ss.ff Jy K Jy Compress deg deg\n";
4277  s << "#\n";
4278  //
4279  for (int i=0; i<sefds_.size(); i++)
4280  {
4281  SgSefdReading *sefd=sefds_.at(i);
4282  az = sefd->getAz();
4283  el = sefd->getEl();
4284  srcName = sefd->getSrcName();
4285  //
4286  int idx=1;
4287  for (QMap<QString, QString>::const_iterator it=channelSetup_.ifIdBySensorKey().begin();
4288  it!=channelSetup_.ifIdBySensorKey().end(); ++it, idx++)
4289  {
4290  QString sensorKey(it.key());
4291  double v2, v3, v4, v5, v6;
4292  v2 = v3 = v4 = v5 = v6 = dFiller_;
4293  hasSensor = false;
4294  if (sefd->getValByChanKey().contains(sensorKey))
4295  {
4296  const QVector<double>
4297  *vec=sefd->getValByChanKey().value(sensorKey);
4298  v2 = vec->at(1);
4299  v3 = vec->at(2);
4300  v4 = vec->at(3);
4301  v5 = vec->at(4);
4302  v6 = vec->at(5);
4303  hasSensor = true;
4304  }
4305  else
4307  "::createAntCalFile(): station " + stnKey +
4308  ": the sensor key \"" + sensorKey + "\" is not found in the SEFD map");
4309  if (!supressNonUsedSensors || hasSensor)
4310  {
4311  str.sprintf("SEFD: TS_%03d %s %10.3f %10.3f %10.3f %10.3f %10.3f %9.4f %9.4f %s",
4312  idx, qPrintable(sefd->getT().toString(SgMJD::F_SOLVE_SPLFL_V3)),
4313  v4, v3, v5, v6, v2,
4314  az, el,
4315  qPrintable(srcName));
4316  s << str << "\n";
4317  };
4318  };
4319  };
4320  s << "#\n";
4321  };
4322  //
4323  // end of output
4324  //
4325  s << "#\n";
4326  s << "#\n";
4327  s << "# End of file\n";
4328  compressors.closeFlt(pipe, f, s);
4329  };
4330 
4331  return true;
4332 };
4333 /*=====================================================================================================*/
4334 
4335 
4336 
4337 
4338 
4339 
4340 
4341 
4342 /*=======================================================================================================
4343 *
4344 * SgStnLogCollector's METHODS:
4345 *
4346 *======================================================================================================*/
4347 const QRegularExpression SgStnLogCollector::reFsOld_("^\\d{9}\\D+");
4348 const QRegularExpression SgStnLogCollector::reFsNew_("^\\d{13}\\D+");
4349 //const QRegularExpression SgStnLogCollector::reFsNewest_("^(\\d{4})\\.(\\d{3})\\.(\\d{2}):(\\d{2})[:\\s]"
4350 //"(\\d{2}\\.\\d{1,3})\\D+");
4351 const QRegularExpression SgStnLogCollector::reFsNewest_("^(\\d{4})\\.([0-9\\s]{3})\\.(\\d{2}):(\\d{2})[:\\s]"
4352  "(\\d{2}\\.?\\d{0,3})\\D+");
4353 const QRegularExpression SgStnLogCollector::rePcmt_("^\\s*\\d{4}\\s+\\d{1,2}\\s+\\d{1,2}\\s+\\d{1,2}\\s+"
4354  "\\d{1,2}\\s+\\d{1,2}\\s+[\\d\\.eEdD+-]{1,}\\s+[\\dA-Z+-]{2,}\\s+\\d{3}-\\d{4}[a-z]?\\s*$");
4355 const QRegularExpression SgStnLogCollector::reMet_("^\\s*\\d{2,4}\\s+\\d{1,2}\\s+\\d{1,2}\\s+\\"
4356  "d{1,2}\\s+\\d{1,2}\\s+\\d{1,2}\\s+[+-]?[\\d\\.]{1,}\\s+[+-]?[\\d\\.]{1,}\\s+[+-]?[\\d\\.]{1,}\\s*$");
4357 
4358 
4359 //
4360 // static first:
4361 //
4363 {
4364  return "SgStnLogCollector";
4365 };
4366 
4367 
4368 
4369 // An empty constructor:
4371  stationName_(""),
4372  logReadings_(),
4373  inputLogFileName_(""),
4374  userCommand_("")
4375 {
4377  fsFmt_ = FSEF_UNDEF;
4378  inYear_ = 0;
4379  defaultCableSignByStn_ = NULL;
4380  rinexFileNameByStn_ = NULL;
4383  useSkededChannelSetup_ = false;
4384  channelSkeded_ = NULL;
4385 };
4386 
4387 
4388 
4389 //
4390 // A destructor:
4392 {
4393  for (QMap<QString, Procedure*>::iterator it=procedureByName_.begin();
4394  it!=procedureByName_.end(); ++it)
4395  delete it.value();
4396  procedureByName_.clear();
4397 };
4398 
4399 
4400 
4401 //
4402 bool SgStnLogCollector::readLogFile(const QString& fileName, const QString& stnName,
4403  const SgMJD& tFirst, const SgMJD& tLast, const QString& orderOfMeteo)
4404 {
4405  stationName_ = stnName; // simplified name, no spaces
4406  if (!stationName_.size())
4407  stationName_ = "n/a";
4408 
4410  inputLogFileName_ = fileName;
4411 
4412  QString str("");
4413  QString strTmp("");
4414  QString sScanName("");
4415  QString sSourceName("");
4416  QString versionStr("");
4417  QFile f(fileName);
4418  FILE *pipe=NULL;
4419  SgMJD t, lastReadTsys(tZero), lastReadPcal(tZero);
4420  SgMJD lastReadDot2xps(tZero), lastReadSefd(tZero);
4421  SgMJD tRightMargin(tLast + 5.0/24.0/60.0); // 5 min
4422  SgMJD tAtTheEnd(tLast - 75.0/24.0/60.0); // 75 min
4423  SgMJD tAtTheBegin(tFirst - 7.0/24.0/60.0); // 7 min
4424  SgOnSourceRecord *osRec;
4425  bool isDataOn, isOnSource, reachedEndOfSession, hasStnName;
4426  int oom[3];
4427  hasStnName = (0 < stnName.size());
4428 
4429  // define meteo parameters order:
4430  // natural order:
4431  oom[0] = 0;
4432  oom[1] = 1;
4433  oom[2] = 2;
4434  //
4435  //
4436  if (orderOfMeteo.size())
4437  {
4438  str = "";
4439  for (int i=0; i<orderOfMeteo.size(); i++)
4440  {
4441  if (orderOfMeteo.at(i) == 'T')
4442  {
4443  oom[0] = i;
4444  str += "T";
4445  }
4446  else if (orderOfMeteo.at(i) == 'P')
4447  {
4448  oom[1] = i;
4449  str += "P";
4450  }
4451  else if (orderOfMeteo.at(i) == 'H')
4452  {
4453  oom[2] = i;
4454  str += "H";
4455  }
4456  };
4458  "::readLogFile(): the order of meteoparamters is set to \"" + str + "\"");
4459  };
4460 
4461 
4462 // /500/sessions/2001/cb901/cb90145.log:2001.127.20:06:01.66:"data_valid=on
4463 
4464 //QRegularExpression reOnSource(":preob|#trakl#\\s*Source acquired|#flagr#flagr/antenna,acquired|/onsource/TRACKING",
4465 // "/onsource/TRACKING" occured between data_valid=on and data_valid=off too (e.g., r1980ht.log)
4466 
4467  QRegularExpression reOnSource(":preob|#trakl#\\s*Source acquired|"
4468  "#flagr#flagr/antenna,acquired|&preob/onsource|&preob/track",
4469  QRegularExpression::CaseInsensitiveOption);
4470  QRegularExpression reDataOn(":data_valid=on|data start\\W+|:midob",
4471  QRegularExpression::CaseInsensitiveOption);
4472  QRegularExpression reDataOff(":data_valid=off|data stop\\W+|;terminate|;halt|:postob",
4473  QRegularExpression::CaseInsensitiveOption);
4474 
4475  QRegularExpression reTapeOn("/tape\\d?/.*moving,.*(?:nostop|locked)",
4476  QRegularExpression::CaseInsensitiveOption);
4477  QRegularExpression reTapeOff("/tape\\d?/.*(?:stopped,.*unlocked|moving,.*stop|"
4478  "stopped,.*stop)", QRegularExpression::CaseInsensitiveOption);
4479 
4480  QRegularExpression reScanName(":scan_name=([_a-zA-Z0-9+-]{1,}),([a-zA-Z0-9_+-]+),?.*",
4481  QRegularExpression::CaseInsensitiveOption);
4482  QRegularExpression reSourceName(":source=([\\.a-zA-Z0-9_+-]{1,10}),.*",
4483  QRegularExpression::CaseInsensitiveOption);
4484 
4485  QRegularExpression reMeteo("(#wx#/WX/|/?wx/|DSNWX/|wx/weather:)([^,]+),([^,]+),([^,]+).*",
4486  QRegularExpression::CaseInsensitiveOption);
4487 
4488  QRegularExpression reCableCal("(/cable/|cableget/)(.+)",
4489  QRegularExpression::CaseInsensitiveOption);
4490 
4491  QRegularExpression reCableLong("(/cablelong/)(.+)",
4492  QRegularExpression::CaseInsensitiveOption);
4493  QRegularExpression reVersion("(mark\\s+.+\\s+field system\\s+v\\w*\\s*)(.+)",
4494  QRegularExpression::CaseInsensitiveOption);
4495 
4496 //2010.140.18:22:06.70/cablediff/683.3e-6,+
4497  QRegularExpression reCableDiff("((?:/|;\"*\\s*)cable\\s*diff(?:/|;*\\s*))([^,]+),([+-])",
4498  QRegularExpression::CaseInsensitiveOption);
4499 //2012.068.18:11:48.08;"cable sign is positive, OK
4500  QRegularExpression reCableSign("(c\\w?a\\w?b\\w?l\\w?e\\w?|ca\\w{2,2}e)\\s+sign\\s+is\\s+"
4501  "(positive|negative)", QRegularExpression::CaseInsensitiveOption);
4502  QRegularExpression reCableDiffIs("cable\\s+dif{1,2}e\\w{2,3}ce\\s+(?:is|was)",
4503  QRegularExpression::CaseInsensitiveOption);
4504  QRegularExpression reOpComments("\\d+;\"(.+)", QRegularExpression::CaseInsensitiveOption);
4505  //
4506  //2017 9 11 18 3 46 7.92e-12 254-1803
4507  QRegularExpression rePcmt("(\\d{4})\\s+(\\d{1,2})\\s+(\\d{1,2})\\s+"
4508  "(\\d{1,2})\\s+(\\d{1,2})\\s+(\\d{1,2})\\s+"
4509  "(.+)\\s+([\\dA-Z+-]{2,8})\\s+([0-9a-z-]{0,}).*",
4510  QRegularExpression::CaseInsensitiveOption);
4511 // 2017 09 11 18 05 8 -2.8e-12 1300+580 254-1805
4512 // 2017 09 11 18 06 16 -1.765e-11 NRAO512 254-1806
4513  QRegularExpression reMet("(\\d{2,4})\\s+(\\d{1,2})\\s+(\\d{1,2})\\s+"
4514  "(\\d{1,2})\\s+(\\d{1,2})\\s+(\\d{1,2})\\s+"
4515  "([\\d\\.+-]+)\\s+([\\d\\.+-]+)\\s+([\\d\\.+-]+).*",
4516  QRegularExpression::CaseInsensitiveOption);
4517 
4518  QRegularExpression reCdms("([/#]CDMS/)(.+)", QRegularExpression::CaseInsensitiveOption);
4519 
4520  // tsys:
4521  //2019.007.19:06:32.52/tsys/1l,62.2,1u,65.6,2u,56.4,3u,68.0,4u,61.6,ia,60.4
4522  //2019.007.19:06:32.52/tsys/5u,66.5,6u,58.4,7u,61.2,8l,59.1,8u,58.6,ib,55.0
4523  //2019.007.19:06:32.52/tsys/9u,89.3,au,85.7,bu,51.5,cu,92.3,ic,82.8
4524  //2019.007.19:06:32.52/tsys/du,118.7,eu,168.7,id,46.5
4525  QRegularExpression reTsys("([/#]tsys/)([^,]+),([^,]+).*",
4526  QRegularExpression::CaseInsensitiveOption);
4527 
4528  //2020.021.18:00:00.15#rdtca#tsys/ 00a0,217.6, 01a0,126.9, 02a0,123.6, 03a0,106.4, 04a0, 95.2, 05a0, 92.7, 06a0, 98.3, 07a0,119.9
4529  //2020.021.18:00:00.15#rdtca#tsys/ 08a0, 50.6, 09a0, 84.7, 10a0, 87.4, 11a0,118.1, 12a0,$$$$$, 13a0, 86.5, 14a0, 80.5, 15a0, 79.4
4530  //2020.021.18:00:00.15#rdtca#tsys/ AVa0,101.5, SMa0,233.4
4531  //2020.021.18:00:00.15#rdtca#tsys/ 00a1, 80.2, 01a1, 51.4, 02a1, 47.8, 03a1, 45.7, 04a1, 46.4, 05a1, 46.5, 06a1, 44.2, 07a1, 52.0
4532  //2020.021.18:00:00.15#rdtca#tsys/ 08a1, 35.5, 09a1, 46.0, 10a1, 43.8, 11a1, 43.8, 12a1, 60.6, 13a1, 44.5, 14a1, 48.7, 15a1, 49.4
4533  //2020.021.18:00:00.15#rdtca#tsys/ AVa1, 47.8, SMa1, 47.5
4534  /*
4535  */
4536  QRegularExpression reTsysVgos("(#rdtc\\w#tsys/ )([^,]+),([^,]+).*");
4537 
4538 
4539  //2020.021.18:00:00.17#rdtcd#tpcont/ 00d0, 12501, 12325, 01d0, 16054, 15765, 02d0, 20774, 20410, 03d0, 24388, 23985, 04d0, 27599, 27153
4540  //2020.021.18:00:00.17#rdtcd#tpcont/ 05d0, 28085, 27647, 06d0, 29475, 29027, 07d0, 30963, 30479, 08d0, 29392, 28953, 09d0, 30078, 29643
4541  //2020.021.18:00:00.17#rdtcd#tpcont/ 10d0, 37494, 36960, 11d0, 42335, 41705, 12d0, 46499, 45802, 13d0, 51354, 50535, 14d0, 49839, 48925
4542  //2020.021.18:00:00.17#rdtcd#tpcont/ 15d0, 43153, 42272
4543  QRegularExpression reTpcontVgos("(#rdtc\\w#tpcont/ )([^,]+),([^,]+).*");
4544 
4545  //2020.195.11:30:01.17#rdtca#pcal/ 1a0000, 8.686, -98.7, 1a0005, 78.913, 116.7, 1a0010, 8.729, 147.9, 1a0015, 81.273, 4.1
4546  //2020.195.11:30:01.17#rdtca#pcal/ 1a0020, 9.421, 37.5, 1a0025, 88.580, -105.5, 1a0030, 10.177, -72.2, 1a0035, 97.212, 144.1
4547  //2020.195.11:30:01.17#rdtca#pcal/ 1a0040, 11.646, 176.3, 1a0045, 89.248, 33.1, 1a0050, 10.577, 65.5, 1a0055, 93.330, -79.2
4548  //2020.195.11:30:01.17#rdtca#pcal/ 1a0060, 10.255, -47.4, 1a0065, 93.203, 169.1, 1a0070, 10.437, -155.9, 1a0075, 89.414, 59.5
4549  //2020.195.11:30:01.17#rdtca#pcal/ 1a0080, 10.014, 92.8, 1a0085, 84.492, -47.7, 1a0090, 9.561, -14.2, 1a0095, 82.770, -155.3
4550  //2020.195.11:30:01.17#rdtca#pcal/ 1a0100, 8.782, -120.1, 1a0105, 79.763, 101.6, 1a0110, 8.836, 137.8, 1a0115, 77.939, -3.8
4551  //2020.195.11:30:01.17#rdtca#pcal/ 1a0120, 8.740, 32.5, 1a0125, 73.421, -105.2, 1a0130, 8.134, -68.7, 1a0135, 74.094, 150.8
4552  //2020.195.11:30:01.17#rdtca#pcal/ 1a0140, 7.557, -168.7, 1a0145, 69.966, 50.6, 1a0150, 7.977, 88.8, 1a0155, 72.224, -54.9
4553  QRegularExpression rePcalVgos("(#rdtc\\w#pcal/ )([^,]+),([^,]+).*");
4554 
4555  //2020.034.17:11:35.51#onoff# source Az El De I P Center Comp Tsys SEFD Tcal(j) Tcal(r)
4556  //2020.034.17:11:35.51#onoff#VAL casa 295.4 63.4 001l 1 l 3464.40 0.9025 62.33 2139.2 58.787 0.93
4557  //2020.034.17:11:35.51#onoff#VAL casa 295.4 63.4 002l 1 l 3432.40 0.8950 63.19 2407.4 65.123 1.03
4558  //2020.034.17:11:35.51#onoff#VAL casa 295.4 63.4 003l 1 l 3368.40 0.9119 72.97 2638.0 73.812 0.98
4559  // for adults:
4560  QRegularExpression reSefd("#onoff#VAL\\s+([\\.\\d\\w+-]+)\\s+([\\.\\d+-]+)\\s+"
4561  "([\\.\\d+-]+)\\s+([\\w\\d]+)\\s+([\\w\\d]+)\\s+([\\w\\d]+)\\s+([\\.\\d+-]+)\\s+([\\.\\d+-]+)\\s+"
4562  "([\\.\\d+-]+)\\s+([\\.\\d+-]+)\\s+([\\.\\d+-]+)\\s+([\\.\\d+-]+).*");
4563 
4564 
4565  //2020.021.18:00:00.15#rdtca#dot2pps/-1.953124995e-08
4566  //2020.021.18:00:00.15#rdtca#dot2gps/-1.073085937e-04
4567  //QRegularExpression reDot2xpsVgos("(#rdtc\\w#dot2(?:g|p)ps/)([^,]+),([^,]+).*");
4568  //QRegularExpression reDot2xpsVgos("#rdtc(\\w)#dot2([gp])ps/\\s*([0-9eEdD\\.+-]+).*");
4569  QRegularExpression reDot2gpsVgos("#rdtc(\\w)#dot2gps/\\s*([0-9eEdD\\.+-]+).*");
4570 
4571 
4572  //2019.003.18:05:50.86&vcsx8/vc01=132.99,8.000,ul
4573  //2019.003.18:05:50.86&vcsx8/vc02=172.99,8.000,u
4574  QRegularExpression reVc("(/vc)([0-9]{2})=([0-9\\.]+),([^,]+).*");
4575 
4576  //2019.003.18:05:52.80&ifdsx/patch=lo1,1l,2l,3h,4h
4577  //2019.003.18:05:52.80&ifdsx/patch=lo2,9l,10h,11h,12h,13h,14h
4578  //2018.094.17:20:22.65&ifdsx/patch=lo1,a1,a2,a3,a4
4579  //2018.094.17:20:22.65&ifdsx/patch=lo2,b1,b2,b3,b4,b5,b6
4580  //2018.094.17:20:22.65&ifdsx/patch=lo3,a5,a6,a7,a8
4581  QRegularExpression rePatch("([&].+/\"?patch=lo)([^,]+),([^,]+).*");
4582  //2018.003.17:14:29.55&ifdsx/lo=loa,8080.00,usb,rcp,1
4583  QRegularExpression reLo("([&].+/\"?lo=lo)([^,]+),([0-9\\.]+),(\\w)+,(\\w)+.*");
4584  //2021.190.19:42:45.43/lo/rxg,loa0,2152.4,lcp,bb.rxg,range,1000,10000,2015,3,22,lcp,3.00000e-02,rcp,3.00000e-02
4585  //2021.190.19:42:45.43/lo/rxg,loa1,2152.4,rcp,bb.rxg,range,1000,10000,2015,3,22,lcp,3.00000e-02,rcp,3.00000e-02
4586  //2021.315.17:00:25.44/lo/rxg,loa,0,lcp,ottn.rxg,range,0,14000,2021,3,3,lcp,2.50000e-02,rcp,2.50000e-02
4587 
4588  QRegularExpression reLoRxg("[\\d](/lo/rxg,\\s*lo)([^,]+),\\s*([a-zA-Z0-9\\.+-]+),\\s*(\\w)+,\\s*(\\w)+.*");
4589 
4590 
4591  //2016.236.17:21:21.92&setupsx/"channel sky freq lo freq video
4592  //2016.236.17:21:21.92&setupsx/" 01 8210.99 8080.00 130.99
4593  //2016.236.17:21:21.92&setupsx/" 02 8220.99 8080.00 140.99
4594  //2016.236.17:21:21.92&setupsx/" 03 8250.99 8080.00 170.99
4595  //2016.236.17:21:21.92&setupsx/" 04 8310.99 8080.00 230.99
4596  //2016.236.17:21:21.92&setupsx/" 05 8420.99 8080.00 340.99
4597  //2016.236.17:21:21.92&setupsx/" 06 8500.99 8080.00 420.99
4598  //2016.236.17:21:21.92&setupsx/" 07 8550.99 8080.00 470.99
4599  //2016.236.17:21:21.92&setupsx/" 08 8570.99 8080.00 490.99
4600  //2016.236.17:21:21.92&setupsx/" 09 2212.99 2020.00 192.99
4601  //2016.236.17:21:21.92&setupsx/" 10 2227.99 2020.00 207.99
4602  //2016.236.17:21:21.92&setupsx/" 11 2237.99 2020.00 217.99
4603  //2016.236.17:21:21.92&setupsx/" 12 2267.99 2020.00 247.99
4604  //2016.236.17:21:21.92&setupsx/" 13 2287.99 2020.00 267.99
4605  //2016.236.17:21:21.92&setupsx/" 14 2292.99 2020.00 272.99
4606  QRegularExpression reChanSkyFreq("&setup.*/\"channel\\s+sky\\s+freq.*");
4607  QRegularExpression reChanSkyFreqValues("&setup.*/\"\\s+([0-9]+)\\s+([0-9\\.]+)\\s+"
4608  "([0-9\\.]+)\\s+([0-9\\.]+).*");
4609 
4610  //2016.236.17:21:21.92&setupsx/vci01=130.99,4r
4611  //2016.236.17:21:21.92&setupsx/vci02=140.99,4r
4612  //2016.236.17:21:21.92&setupsx/vci14=272.99,4r
4613  //2016.236.17:21:21.92&setupsx/vci15=272.99,4r
4614  //2016.236.17:21:21.92&setupsx/vci16=272.99,4r
4615  QRegularExpression reVci("(/\"?vci)([0-9]{2})=([0-9\\.]+),([^,]+).*");
4616 
4617 
4618  //2019.003.19:31:02.40&bbcsx8/bbc01=612.99,a,8.000,8.000
4619  //2019.070.21:51:37.16&dbbcsx8/bbc01=612.99,a,8.00
4620  //2019.344.18:07:19.78&dbbc_bb/dbbc3=dbbc01=3480.4,a,32,1
4621  //QRegularExpression reBbc("([&]d?bbc.+(?:/|=d)bbc)([0-9]+)=([0-9\\.]+),([^,]+).*");
4622  //2021.315.17:00:17.91&dbbcbb32/bbc041=859.6,f,32.0
4623  //2021.271.20:19:39.04&freq_001/bbc01=612.99,a,8.000,8.000
4624  QRegularExpression reBbc("([&].+(?:/|=d)bbc)([0-9]+)=([0-9\\.]+),([^,]+).*");
4625 
4626  //2020.202.18:01:44.03/dbbc3/dbbc001/ 3480.400000,a,32,1,agc,79,84,15299,15290,14977,14972;
4627  QRegularExpression reDbbc3Tp("/dbbc3/dbbc(\\d{3})/\\s*([0-9\\.+-]+),([^,]+),(\\d+),(\\d+),"
4628  "(\\w+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+);.*");
4629 
4630  // /dbbc3/version/
4631  // /dbbc3/pps_delay/
4632 
4633  //2020.203.18:21:45.11#trakl#[az 10.0149 el 50.0437 azv 0.00000000 elv 0.00000000 mjd 59051 s 66104 ms 980 ]
4634  QRegularExpression reTrakl("#trakl#\\[az\\s+([\\.0-9+-]+)\\s+el\\s+([\\.0-9+-]+)\\s+azv"
4635  "\\s+([\\.0-9+-]+)\\s+elv\\s+([\\.0-9+-]+)\\s+mjd\\s+"
4636  "([\\.0-9+-]+)\\s+s\\s+([\\.0-9+-]+)\\s+ms\\s+"
4637  "([\\.0-9+-]+)\\s*\\]");
4638  // catch a procedure:
4639  QRegularExpression reProcedureDecl("[\\.0-9+-]{2}:\"%\\s+define\\s+(\\S+).*");
4640 
4641  QRegularExpression reEndOfSchd(":(sched_end|\\*end of schedule).*");
4642 
4643  //2015.182.16:40:02.73;proc=t2104ke
4644  QRegularExpression reProc(";proc=(\\S+)");
4645 
4646  // FS 10:
4647  //2021.315.16:59:18.48;equip1,dbbc3_ddc_v,flexbuff,none,none,500.10,3,a/d,101,60,20,none,40,1,in,8bit,cdp,3,return
4648  //2021.315.16:59:18.48;equip2,v107,v15_1,1,1,1,1,15000,15000,15000,15000,128,vsi1-2
4649  //2021.315.16:59:18.48;dbbc3,8,8,v125,v124,57,1
4650  QRegularExpression reEquip("\\d{2}.equip1{0,1},([^,]+),([^,]+),(.+)");
4651 //QRegularExpression reEquip("\\d{2}.equip,([^,]+),([^,]+),(.+)");
4652 
4653  bool hasProc;
4654  QString procName("");
4655  bool hasEquip;
4656  QString backEndName("");
4657  QString recorderName("");
4658 
4659  bool hasProcedures;
4660  bool isProcedureContentMode;
4661  QMap<QString, QString> procedureNameByName;
4662  QList<QString> procedureContent;
4663  QRegularExpression reProcedures("");
4664  QRegularExpression reProcedureContent("");
4665  QString currentProcedureName("");
4666  QString currentProcedureTimeStamp("");
4667 
4668  bool wantTsys;
4669  wantTsys = antcalOutputData_ & AOD_TSYS;
4670 
4671  // what to skip:
4673  {
4674  str = "#trakl#(?!\\[az)|#rdtc.#(?!";
4675  if (wantTsys)
4676  str += "tsys|";
4677  if (antcalOutputData_ & AOD_TPI)
4678  str += "tpcont|";
4680  str += "pcal|";
4682  str += "dot2gps|";
4683  str.chop(1);
4684  str += ")|#antcn#(?!/wx)|\\d[:/]mk6a[=/]/";
4685  }
4686  else
4687  str = "#trakl#(?!\\[az)|#rdtc.#|#antcn#(?!/wx)|\\d[:/]mk6a[=/]/";
4688 
4689 
4690  QRegularExpression re2skip(str);
4691 
4692 
4693 //2020.174.13:46:04.25;location,MGO12M ,104.02,30.68,1890.6
4694  QRegularExpression reLocation(";location,(\\S{1,8})\\s*,\\s*([-+\\.\\d]+)\\s*,"
4695  "\\s*([-+\\.\\d]+)\\s*,\\s*([-+\\.\\d]+).*", QRegularExpression::CaseInsensitiveOption);
4696  bool hasLocation=false;
4697 
4698 //2010.349.17:30:36.87:" APSG27 2010 URUMQI U Ur
4699 //2020.201.05:08:53.14:" VO0202 2020 ONSA13NE 1 Oe
4700  QRegularExpression reStnId("\\d:\"\\s+([A-Z0-9]{1,6})\\s+([0-9]{4})\\s+"
4701  "([_A-Z0-9-]{2,8})\\s+([A-Z0-9])\\s+([A-Z0-9][a-z0-9+-])");
4702 
4703 
4704 
4705  SgTraklReading trakl;
4706  bool have2checkT;
4707  bool hasVersionStr, hasCableSign, needCableSign;
4708  int val, numOfSkippedStrs, numOfReadStrs, numOfProcedureExpanded;
4709  int numOfTries;
4710  qint64 flogSize;
4711  double d;
4712 //bool isData, isTape;
4713  QList<QString> operatorComments;
4714  // /500/sessions/2003/r1083/r1083tc.log ^--??
4715 
4716  QRegularExpressionMatch match;
4717 
4718 
4719  // adjust:
4720  if ((tLast - tFirst) < 3.0/24.0)
4721  tAtTheEnd = tLast - 5.0/24.0/60.0; // for short sessions
4722 
4723 
4724  numOfSkippedStrs = numOfReadStrs = numOfProcedureExpanded = 0;
4725  flogSize = 0;
4726  have2checkT = false;
4727  hasVersionStr = hasCableSign = needCableSign = false;
4728  hasProc = hasEquip = false;
4729 
4731  needCableSign = true;
4732 
4733 
4734 //isData = isTape = false;
4735  numOfTries = 0;
4736  //
4737  if (!f.exists())
4738  {
4740  "::readLogFile(): the log file " + fileName + " does not exist");
4741  return false;
4742  };
4743  //
4744  //
4745  //
4747  "::readLogFile(): station \"" + stationName_ + "\": reading log file " + fileName);
4748  //
4749  if (tZero < tFirst)
4750  inYear_ = tFirst.calcYear();
4751  //
4752  if (fileName.right(9).toLower() == ".cdms.dat")
4754  else if (fileName.right(4).toLower() == ".dat" && fileName.toLower().contains(".pcmt."))
4756  else if (fileName.right(8).toLower() == ".met.dat")
4758  else
4760 
4761  //
4762  isDataOn = false;
4763  isOnSource = false;
4764  reachedEndOfSession = false;
4765  osRec = new SgOnSourceRecord;
4766  osRec->setScanName("");
4767  osRec->setSourceName("");
4768 
4769  hasProcedures = false;
4770  isProcedureContentMode = false;
4771 
4772  flogSize = QFileInfo(fileName).size();
4773  QTextStream s;
4774  pipe = compressors.openFlt(fileName, f, s, FLTD_Input);
4775  if (s.device())
4776  {
4777  bool have2reportNumOfStrings;
4778  have2reportNumOfStrings = (10000000 < flogSize) && logger->isEligible(SgLogger::INF, SgLogger::IO);
4779  while (!s.atEnd() && !reachedEndOfSession)
4780  {
4781  if (procedureContent.size())
4782  {
4783  str = currentProcedureTimeStamp + "&" + currentProcedureName + "/" + procedureContent.takeFirst();
4784  if (procedureContent.size() == 0)
4785  {
4786  currentProcedureName = "";
4787  currentProcedureTimeStamp = "";
4788  };
4789  }
4790  else
4791  {
4792  str = s.readLine();
4793  numOfReadStrs++;
4794  };
4795 
4796 
4797 if (have2reportNumOfStrings && numOfReadStrs%100000 == 0)
4798 std::cout << " -- read " << numOfReadStrs/1000 << "K strings file size: " << flogSize << "\n";
4799 
4800  //
4801  if (str.right(4) == "\\par")
4802  str.chop(4);
4803  //
4804  // guess format of the file:
4805  if ( fsFmt_==FSEF_UNDEF &&
4806  (fsFmt_=guessFsFormat(str))==FSEF_UNDEF &&
4807  numOfTries++>10 && str.size())
4808  {
4810  "::readLogFile(): station " + stationName_ +
4811  ": cannot determine the time mark format after " + QString("").setNum(numOfTries) +
4812  " tries, the log file: " + fileName);
4814  "::readLogFile(): station " + stationName_ +
4815  ": input: \"" + asciifyString(str) + "\"");
4816  f.close();
4817  s.setDevice(NULL);
4818  return false;
4819  };
4820  //
4821  // lookup "version" string:
4822  if (!hasVersionStr && (match=reVersion.match(str)).hasMatch())
4823  {
4824  versionStr = match.captured(0);
4825  logReadings_.setFsVersionLabel(versionStr);
4826  hasVersionStr = true;
4827  };
4828  //
4829  //
4830  // check for lines to skip:
4831  if(str.size()==0 || re2skip.match(str).hasMatch())
4832  {
4833  numOfSkippedStrs++;
4834  }
4835  else if (fsFmt_ == FSEF_PCMT) // simple readings:
4836  {
4837  if ((match=rePcmt.match(str)).hasMatch() &&
4838  extractDataFromPcmtRecord(str, match, t, d, sSourceName, sScanName))
4839  {
4840  SgCableCalReading *cableRec=new SgCableCalReading(t, d); // input is in seconds
4841  logReadings_.cableCals() << cableRec;
4842 
4843  osRec->tStart() = t;
4844  osRec->setScanName(sScanName.toLower());
4845  osRec->setSourceName(sSourceName);
4846  osRec->cableCals() << cableRec;
4847 
4848  if (logReadings_.onSourceRecords().size())
4849  osRec->tFinis() = logReadings_.onSourceRecords().last()->tStart();
4850 
4851  osRec->setIdx(logReadings_.onSourceRecords().size());
4852  logReadings_.onSourceRecords() << osRec;
4853  osRec = new SgOnSourceRecord;
4854 
4855  if (tRightMargin <= t && (!needCableSign || hasCableSign) )
4856  {
4857  reachedEndOfSession = true;
4859  "::readLogFile(): station " + stationName_ +
4860  ": got to the end of the session: " +
4861  tRightMargin.toString(SgMJD::F_Simple) + " <= " +
4863  };
4864  //
4865  if (!hasVersionStr)
4866  {
4867  versionStr = "PCMT or CDMS file";
4868  hasVersionStr = true;
4869  };
4870  };
4871  }
4872  else if (fsFmt_ == FSEF_MET) // simple readings too:
4873  {
4874  SgMeteoData m;
4875  if ((match=reMet.match(str)).hasMatch() &&
4876  extractDataFromMetRecord(str, match, t, m))
4877  {
4878  SgMeteoReading *meteoRec=new SgMeteoReading(t, m);
4879  logReadings_.meteoPars() << meteoRec;
4880  if (tRightMargin <= t && (!needCableSign || hasCableSign))
4881  {
4882  reachedEndOfSession = true;
4884  "::readLogFile(): station " + stationName_ +
4885  ": got to the end of the session: " +
4886  tRightMargin.toString(SgMJD::F_Simple) + " <= " +
4888  };
4889  //
4890  if (!hasVersionStr)
4891  {
4892  versionStr = "External file with meteo data";
4893  hasVersionStr = true;
4894  };
4895  };
4896  }
4897  else // FS log file:
4898  {
4899  //
4900  // first, deal with macroses:
4901  if ((match=reProcedureDecl.match(str)).hasMatch())
4902  {
4903  hasProcedures = true;
4904  procedureNameByName.insert(match.captured(1), match.captured(1));
4905  str = "[\\.0-9]{2}:(";
4906  for (QMap<QString, QString>::iterator it=procedureNameByName.begin();
4907  it!=procedureNameByName.end(); ++it)
4908  str += it.key() + "|";
4909  str.chop(1);
4910  reProcedures.setPattern(str + ")");
4912  "::readLogFile(): station " + stationName_ +
4913  ": found declaration of procedure \"" + match.captured(1) + "\"");
4914  continue;
4915  }
4916  else if (hasProcedures && (match=reProcedures.match(str)).hasMatch())
4917  {
4918  // empty procedure + another one:
4919  if (isProcedureContentMode && currentProcedureName.size() &&
4920  procedureByName_.contains(currentProcedureName) &&
4921  procedureNameByName.contains(currentProcedureName) )
4922  {
4923  procedureByName_.remove(currentProcedureName);
4924  procedureNameByName.remove(currentProcedureName);
4925  // redefine the regExp:
4926  strTmp = "[\\.0-9]{2}:(";
4927  for (QMap<QString, QString>::iterator it=procedureNameByName.begin();
4928  it!=procedureNameByName.end(); ++it)
4929  strTmp += it.key() + "|";
4930  strTmp.chop(1);
4931  reProcedures.setPattern(strTmp + ")");
4933  "::readLogFile(): station " + stationName_ +
4934  ": procedure \"" + currentProcedureName +
4935  "\" is empty, removed from the substitution pool");
4936  };
4937  currentProcedureName = match.captured(1);
4938  currentProcedureTimeStamp = str.left(fsContentStartsAt_[fsFmt_]);
4939  if (procedureByName_.contains(currentProcedureName)) // procedure use mode:
4940  {
4941  Procedure *prc=procedureByName_.value(currentProcedureName);
4942  for (int i=0; i<prc->content().size(); i++)
4943  procedureContent.append(prc->content().at(i));
4944  prc->incNumOfExpanded();
4945  numOfProcedureExpanded++;
4946  continue;
4947  }
4948  else // procedure content mode:
4949  {
4950  procedureByName_.insert(currentProcedureName, new Procedure(currentProcedureName));
4951  isProcedureContentMode = true;
4952  reProcedureContent.setPattern("[\\.0-9]{2}&" + currentProcedureName + "/(.*)");
4954  "::readLogFile(): station " + stationName_ +
4955  ": found content of procedure \"" + currentProcedureName + "\"");
4956  };
4957  }
4958  else if (isProcedureContentMode)
4959  {
4960  Procedure *prc=NULL;
4961  if (procedureByName_.contains(currentProcedureName))
4962  {
4963  prc = procedureByName_.value(currentProcedureName);
4964  if ((match=reProcedureContent.match(str)).hasMatch())
4965  prc->content().append(match.captured(1));
4966  else
4967  {
4969  "::readLogFile(): station " + stationName_ +
4970  ": collected content of procedure \"" + currentProcedureName + "\", " +
4971  QString("").setNum(prc->content().size()) + " record(s) total");
4972  if (!prc->content().size())
4973  {
4974  procedureByName_.remove(currentProcedureName);
4975  procedureNameByName.remove(currentProcedureName);
4976  // redefine the regExp:
4977  strTmp = "[\\.0-9]{2}:(";
4978  for (QMap<QString, QString>::iterator it=procedureNameByName.begin();
4979  it!=procedureNameByName.end(); ++it)
4980  strTmp += it.key() + "|";
4981  strTmp.chop(1);
4982  reProcedures.setPattern(strTmp + ")");
4984  "::readLogFile(): station " + stationName_ +
4985  ": procedure \"" + currentProcedureName +
4986  "\" is empty, removed from the substitution pool");
4987  };
4988  isProcedureContentMode = false;
4989  currentProcedureName = "";
4990  currentProcedureTimeStamp = "";
4991  };
4992  }
4993  else
4995  "::readLogFile(): station " + stationName_ +
4996  ": cannot find procedure \"" + currentProcedureName + "\" in the map; input: \"" +
4997  asciifyString(str) + "\"");
4998  }
4999  //
5000  // check proc:
5001  else if ((match=reProc.match(str)).hasMatch() && extractEpoch(str, t))
5002  {
5003  hasProc = true;
5004  if (t < tFirst) // session is not started yet:
5005  {
5006  procName = match.captured(1);
5007  }
5008  else if (procName != match.captured(1)) // another session?:
5009  {
5010  if (procName.size())
5012  "::readLogFile(): station " + stationName_ +
5013  ": proc has changed: \"" + procName + "\" => \"" + match.captured(1) +
5014  "\"; input: \"" + asciifyString(str) + "\"");
5015  procName = match.captured(1);
5016  if (tRightMargin <= t && (!needCableSign || hasCableSign))
5017  {
5018  reachedEndOfSession = true;
5020  "::readLogFile(): station " + stationName_ +
5021  ": got to the end of the session: " +
5022  tRightMargin.toString(SgMJD::F_Simple) + " <= " +
5024  };
5025  };
5026  };
5027  if ((match=reEquip.match(str)).hasMatch() && extractEpoch(str, t))
5028  {
5029  if (backEndName.size() && backEndName != match.captured(1))
5030  {
5032  "::readLogFile(): station " + stationName_ +
5033  ": equip (backEnd) has changed: \"" + backEndName + "\" => \"" + match.captured(1) +
5034  "\"; input: \"" + asciifyString(str) + "\"");
5035  };
5036  backEndName = match.captured(1);
5037  //
5038  if (recorderName.size() && recorderName != match.captured(2))
5039  {
5041  "::readLogFile(): station " + stationName_ +
5042  ": equip (recorder) has changed: \"" + recorderName + "\" => \"" + match.captured(2) +
5043  "\"; input: \"" + asciifyString(str) + "\"");
5044  };
5045  recorderName = match.captured(2);
5046  hasEquip = true;
5047  //
5048  if (backEndName == "dbbc3")
5050  if (backEndName.contains("dbbc3_")) // FS 10 whims
5052  else if (backEndName == "dbbc")
5054  else if (backEndName == "rdbe")
5055  {
5058  }
5059  else if (backEndName == "none")
5061  else
5063  logReadings_.setBackEndInfo(backEndName);
5064  logReadings_.setRecorderInfo(recorderName);
5065 
5067  "::readLogFile(): station " + stationName_ +
5068  ": found: backend=\"" + logReadings_.getBackEndInfo() +
5069  "\", recorder=\"" + logReadings_.getRecorderInfo() + "\"");
5070  };
5071  //
5072  //
5073  if (!hasStnName)
5074  {
5075  if ((match=reStnId.match(str)).hasMatch())
5076  {
5077  stationName_ = match.captured(3).leftJustified(8, ' ');
5078  hasStnName = true;
5079  hasLocation = true; // do not need to check location
5081  "::readLogFile(): station " + stationName_ +
5082  ": found a name of the station (from \"stnId\"): \"" + stationName_ + "\"");
5083  };
5084  };
5085  if (!hasLocation)
5086  {
5087  if ((match=reLocation.match(str)).hasMatch())
5088  {
5089  if (!hasStnName)
5090  {
5091  stationName_ = match.captured(1).leftJustified(8, ' ');
5092  hasLocation = true;
5094  "::readLogFile(): station " + stationName_ +
5095  ": found a name of the station (from \"location\"): \"" + stationName_ + "\"");
5096  }
5097  else if (stationName_ != match.captured(1))
5098  {
5100  "::readLogFile(): station " + stationName_ +
5101  ": the station name from \"location\" (\"" + match.captured(1) +
5102  "\") is different");
5103  };
5104  };
5105  };
5106  //
5107  if (have2checkT && extractEpoch(str, t) && tRightMargin <= t && (!needCableSign || hasCableSign))
5108  {
5109  reachedEndOfSession = true;
5111  "::readLogFile(): station " + stationName_ +
5112  ": got to the end of the session: " +
5113  tRightMargin.toString(SgMJD::F_Simple) + " <= " +
5115  };
5116  //
5117  if (reEndOfSchd.match(str).hasMatch() && extractEpoch(str, t) && tFirst < t &&
5118  (!needCableSign || hasCableSign))
5119  {
5120  reachedEndOfSession = true;
5122  "::readLogFile(): station " + stationName_ +
5123  ": got to the end of the session: end of schedule at " +
5125  };
5126  //
5127  if (reachedEndOfSession)
5128  continue;
5129  //
5130  //
5131  //
5132  // search for on source:
5133  if (reOnSource.match(str).hasMatch() ||
5134  reTapeOn.match(str).hasMatch() )
5135  {
5136  if (extractEpoch(str, t))
5137  {
5138  if (!isOnSource)
5139  {
5140  osRec->tStart() = t;
5141  isOnSource = true;
5142  if (tRightMargin <= t && (!needCableSign || hasCableSign))
5143  {
5144  reachedEndOfSession = true;
5146  "::readLogFile(): station " + stationName_ +
5147  ": got to the end of a session: " +
5148  tRightMargin.toString(SgMJD::F_Simple) + " <= " +
5149  t.toString(SgMJD::F_Simple) + " (tRightMargin <= osRec->tStart())");
5150  };
5151  if (tAtTheEnd <= t)
5152  have2checkT = true;
5153  }
5154  else if (420.0/DAY2SEC < (t-osRec->tStart()))
5156  "::readLogFile(): station " + stationName_ +
5157  ": got unexpected `source on' record; string: \"" + asciifyString(str) + "\"");
5158  };
5159  }
5160  else if ((match=reScanName.match(str)).hasMatch())
5161  {
5162  if (3<osRec->getScanName().size() && osRec->getScanName()!=match.captured(1))
5163  {
5165  "::readLogFile(): station " + stationName_ + ": the scan name \"" +
5166  osRec->getScanName() + "\" will be replaced with \"" + match.captured(1) +
5167  "\", looks like discontinuity in the log file");
5168  // check if we already got accumulated data:
5169  if (osRec->cableCals().size())
5171  "::readLogFile(): station " + stationName_ +
5172  ": the scan is not empty: size of cable cal list is " +
5173  QString("").setNum(osRec->cableCals().size()));
5174  if (osRec->meteoPars().size())
5176  "::readLogFile(): station " + stationName_ +
5177  ": the scan is not empty: size of meteo parameters list is " +
5178  QString("").setNum(osRec->meteoPars().size()));
5179  };
5180  osRec->setScanName(match.captured(1).toLower());
5181  //
5182  // check experiment name:
5183  if (match.captured(2).size())
5184  {
5185  if (logReadings_.getExperimentName() != match.captured(2))
5186  {
5187  if (logReadings_.getExperimentName().size())
5189  "::readLogFile(): station " + stationName_ +
5190  ": the experiment name has been changed: \"" +
5191  logReadings_.getExperimentName() + "\" => \"" +
5192  match.captured(2) + "\"");
5193  else
5195  "::readLogFile(): station " + stationName_ +
5196  ": found experiment name: \"" + match.captured(2) + "\"");
5197  logReadings_.setExperimentName(match.captured(2));
5198  };
5199  };
5200  //
5201  }
5202  else if ((match=reSourceName.match(str)).hasMatch()
5203 // &&
5204 // !(str.contains("idle", Qt::CaseInsensitive) ||
5205 // str.contains("azel", Qt::CaseInsensitive))
5206  )
5207  {
5208  if (3<osRec->getSourceName().size() &&
5209  osRec->getSourceName()!= QString("idle") &&
5210  osRec->getSourceName()!= QString("azel") &&
5211  osRec->getSourceName()!=match.captured(1).toUpper())
5213  "::readLogFile(): station " + stationName_ +
5214  ": the source name \"" + osRec->getSourceName() +
5215  "\" will be replaced with \"" + match.captured(1).toUpper() +
5216  "\", looks like discontinuity in the log file");
5217  osRec->setSourceName(match.captured(1).toUpper());
5218  }
5219  // search for data on:
5220  else if (reDataOn.match(str).hasMatch() && extractEpoch(str, osRec->tDataOn()))
5221  {
5222  isDataOn = true;
5223  }
5224  // data_valid=off:
5225  else if (reDataOff.match(str).hasMatch() ||
5226  reTapeOff.match(str).hasMatch() )
5227  {
5228  if (extractEpoch(str, t))
5229  {
5230  if (isOnSource)
5231  {
5232  osRec->tFinis() = t;
5233  if (tRightMargin <= t && (!needCableSign || hasCableSign))
5234  {
5235  reachedEndOfSession = true;
5237  "::readLogFile(): station " + stationName_ +
5238  ": got to the end of a session: " +
5239  tRightMargin.toString(SgMJD::F_Simple) + " <= " +
5240  t.toString(SgMJD::F_Simple) + " (tRightMargin <= osRec->tFinis())");
5241  };
5242  //
5243  if (tFirst < t)
5244  {
5245  osRec->setIdx(logReadings_.onSourceRecords().size());
5246  logReadings_.onSourceRecords() << osRec;
5247  };
5248  // check:
5249  if (osRec->getScanName().size() < 3)
5250  {
5252  "::readLogFile(): station " + stationName_ + ": the scan name \"" +
5253  osRec->getScanName() +
5254  "\" too short and cannot be used; the `data_valid=off' string: \"" +
5255  asciifyString(str) + "\"");
5256  };
5257  osRec = new SgOnSourceRecord;
5258  osRec->setScanName("");
5259  osRec->setSourceName("");
5260  isOnSource = false;
5261  isDataOn = false;
5262  }
5263  else if (logReadings_.onSourceRecords().size() &&
5264  420.0/DAY2SEC < (t - logReadings_.onSourceRecords().at(logReadings_.onSourceRecords().size()-1)->getTfinis()))
5266  "::readLogFile(): station " + stationName_ +
5267  ": got unexpected data_valid=off record; string: \"" + asciifyString(str) + "\"");
5268  };
5269  };
5270  //
5271  //
5272  //
5273  //
5274  // end of data on/off switches
5275  //
5276  // check for operator comments:
5277  QRegularExpression reNotUserComments(";\"(?:/| Command from |FiLa10G:|Flexbuff:|"
5278  "start transferring scan|Error opening connection to FILA10G|"
5279  "Error opening connection to flexbuff|.+\\s+1pps diff:).*",
5280  QRegularExpression::CaseInsensitiveOption);
5281  QRegularExpression reFilter1(";\"\\s*Comment from\\s+'\\w+\\(?\\d?\\)?':\\s+\""
5282  "\\s+CHECKLIST\\(?\\w*\\)?:\\s+(\\b.+)", QRegularExpression::CaseInsensitiveOption);
5283  QRegularExpression reFilter2(";\"\\s*CHECKLIST:\\s+(.+)",
5284  QRegularExpression::CaseInsensitiveOption);
5285  QRegularExpression reFilter3(";\"\\s*Comment from\\s+'\\w+\\(?\\w*\\)?':\\s+\"\\s+(\\b.+)",
5286  QRegularExpression::CaseInsensitiveOption);
5287  QRegularExpression reFilterLast(";\"\\s*(\\b.+)",
5288  QRegularExpression::CaseInsensitiveOption);
5289  if (reOpComments.match(str).hasMatch())
5290  {
5291  if (extractEpoch(str, t))
5292  {
5293  extractContent(str, strTmp);
5294  if (!reNotUserComments.match(strTmp).hasMatch())
5295  {
5296  if ((match=reFilter1.match(strTmp)).hasMatch())
5297  strTmp = match.captured(1);
5298  else if ((match=reFilter2.match(strTmp)).hasMatch())
5299  strTmp = match.captured(1);
5300  else if ((match=reFilter3.match(strTmp)).hasMatch())
5301  strTmp = match.captured(1);
5302  else if ((match=reFilterLast.match(strTmp)).hasMatch())
5303  strTmp = match.captured(1);
5304  //
5305  if (strTmp.size() < 100)
5306  operatorComments << t.toString(SgMJD::F_Simple) + ": " + strTmp;
5307  else // split too long strings:
5308  {
5309  QStringList sLst=strTmp.split(QRegExp("\\s"));
5310  QString sAux("");
5311  for (int i=0; i<sLst.size(); i++)
5312  {
5313  sAux += " " + sLst.at(i);
5314  if (sAux.size() > 81)
5315  {
5316  operatorComments << t.toString(SgMJD::F_Simple) + ":" + sAux;
5317  sAux = "";
5318  };
5319  };
5320  if (sAux.size())
5321  operatorComments << t.toString(SgMJD::F_Simple) + ":" + sAux;
5322  };
5323  };
5324  };
5325  };
5326  //
5327  //
5328  if ((match=reTrakl.match(str)).hasMatch()) // VGOS has these records every sec
5329  {
5330  if (extractTraklReading(str, match, t, trakl, tFirst))
5331  {
5332  SgTraklReading *pTrakl=new SgTraklReading(trakl);
5333  logReadings_.trakls() << pTrakl;
5334  //
5335  // add to tsys recs:
5336  int idx=logReadings_.tSyses().size() - 1;
5337  SgTsysReading *pTs=NULL;
5338  while (0 < idx &&
5339  (pTs=logReadings_.tSyses().at(idx)) &&
5340  (t - pTs->getT()) < 60.0/DAY2SEC)
5341  {
5342  if (pTs->trakls().size() < 10)
5343  pTs->trakls() << pTrakl;
5344  idx--;
5345  };
5346  };
5347  }
5348  //
5349  //
5350  // vgos tsys:
5351  else if (reTsysVgos.match(str).hasMatch())
5352  {
5353  QMap<QString, float> tsys;
5354  if (extractTsysVgosReading(str, reTsysVgos, t, tsys, tAtTheBegin) && tsys.size())
5355  {
5356  SgTsysReading *tsr=NULL;
5357  if (0.3/DAY2SEC < fabs(lastReadTsys - t))
5358  {
5359  tsr = new SgTsysReading;
5360  tsr->setT(t);
5361  tsr->setOsRec(isOnSource?osRec:NULL);
5362  tsr->setIsOnSource(isOnSource);
5363  tsr->setIsDataOn(isDataOn);
5364  logReadings_.tSyses() << tsr;
5365  osRec->tSyses() << tsr;
5366  //
5367  // add trakls:
5368  int idx=logReadings_.trakls().size() - 1;
5369  SgTraklReading *pTrakl=NULL;
5370  while (0 < idx &&
5371  (pTrakl=logReadings_.trakls().at(idx)) &&
5372  (t - pTrakl->getT()) < 100.0/DAY2SEC)
5373  {
5374  if (tsr->trakls().size() < 5)
5375  tsr->trakls() << pTrakl;
5376  idx--;
5377  };
5378  }
5379  else
5380  tsr = logReadings_.tSyses().last();
5381  tsr->addTsyses(tsys);
5382  lastReadTsys = t;
5383  };
5384  tsys.clear();
5385  }
5386  //
5387  // vgos tpcont:
5388  else if (reTpcontVgos.match(str).hasMatch())
5389  {
5390  QMap<QString, QVector<int> >
5391  tpcont;
5392  if (extractTpcontVgosReading(str, reTpcontVgos, t, tpcont, tAtTheBegin) && tpcont.size())
5393  {
5394  SgTsysReading *tsr=NULL;
5395  if (0.2/DAY2SEC < fabs(lastReadTsys - t))
5396  {
5397  tsr = new SgTsysReading;
5398  tsr->setT(t);
5399  tsr->setOsRec(isOnSource?osRec:NULL);
5400  tsr->setIsOnSource(isOnSource);
5401  tsr->setIsDataOn(isDataOn);
5402  logReadings_.tSyses() << tsr;
5403  osRec->tSyses() << tsr;
5404  //
5405  // add trakls:
5406  int idx=logReadings_.trakls().size() - 1;
5407  SgTraklReading *pTrakl=NULL;
5408  while (0 < idx &&
5409  (pTrakl=logReadings_.trakls().at(idx)) &&
5410  (t - pTrakl->getT()) < 100.0/DAY2SEC)
5411  {
5412  if (tsr->trakls().size() < 5)
5413  tsr->trakls() << pTrakl;
5414  idx--;
5415  };
5416  }
5417  else
5418  tsr = logReadings_.tSyses().last();
5419  tsr->addTpconts(tpcont);
5420  lastReadTsys = t;
5421  };
5422  tpcont.clear();
5423  }
5424  //
5425  //
5426  // vgos pcal:
5427  else if (rePcalVgos.match(str).hasMatch())
5428  {
5429  QMap<QString, float*> pcals;
5430  if (extractPcalVgosReading(str, rePcalVgos, t, pcals, tAtTheBegin) && pcals.size())
5431  {
5432  SgPcalReading *pcr=NULL;
5433  if (0.2/DAY2SEC < fabs(lastReadPcal - t))
5434  {
5435  pcr = new SgPcalReading;
5436  pcr->setT(t);
5437  pcr->setOsRec(isOnSource?osRec:NULL);
5438  logReadings_.pcals() << pcr;
5439  }
5440  else
5441  pcr = logReadings_.pcals().last();
5442 
5443  if (!pcr->addPcals(pcals))
5445  "::readLogFile(): station " + stationName_ +
5446  ": got duplicate pcals; input: \"" + asciifyString(str) + "\"");
5447  lastReadPcal = t;
5448  };
5449  for (QMap<QString, float*>::iterator it=pcals.begin(); it!=pcals.end(); ++it)
5450  delete[] it.value();
5451  pcals.clear();
5452  }
5453  //
5454  // vgos dot2pps/gps:
5455  else if ((match=reDot2gpsVgos.match(str)).hasMatch())
5456  {
5457  float dot2gps=1.0e20;
5458  QString sKey("");
5459  if (extractDot2gpsVgosReading(str, match, t, sKey, dot2gps, tAtTheBegin) && dot2gps < 1.0e6)
5460  {
5461  if (!logReadings_.channelSetup().xpsIdByKey().contains(sKey))
5462  logReadings_.channelSetup().xpsIdByKey().insert(sKey, sKey);
5463  SgDot2xpsReading *d2r=NULL;
5464  if (0.2/DAY2SEC < fabs(lastReadDot2xps - t))
5465  {
5466  d2r = new SgDot2xpsReading;
5467  d2r->setT(t);
5468  d2r->setOsRec(isOnSource?osRec:NULL);
5469  logReadings_.dot2xpses() << d2r;
5470  }
5471  else
5472  d2r = logReadings_.dot2xpses().last();
5473 // if (!d2r->addDot2gpsByBrd(sKey.toLatin1(), dot2gps))
5474  if (!d2r->addDot2gpsByBrd(sKey, dot2gps))
5475  {
5477  "::readLogFile(): station " + stationName_ +
5478  ": got duplicate dot2gps; input: \"" + asciifyString(str) + "\"");
5479  };
5480  lastReadDot2xps = t;
5481  };
5482  }
5483  // dbbc3 tp reading:
5484  else if ((match=reDbbc3Tp.match(str)).hasMatch())
5485  {
5486  extractEpoch(str, t);
5487 
5488  QString sensorId(match.captured( 1));
5489  QString boardId(match.captured( 3));
5490  QString agc(match.captured( 6));
5491  double bw=0.0;
5492  double gainU=0.0;
5493  double gainL=0.0;
5494  double tpOffU=0.0;
5495  double tpOffL=0.0;
5496  double tpOnU=0.0;
5497  double tpOnL=0.0;
5498  double sefdU=0.0;
5499  double sefdL=0.0;
5500  bw = match.captured( 4).toDouble();
5501  gainU = match.captured( 7).toDouble();
5502  gainL = match.captured( 8).toDouble();
5503  tpOffU = match.captured( 9).toDouble();
5504  tpOffL = match.captured(10).toDouble();
5505  tpOnU = match.captured(11).toDouble();
5506  tpOnL = match.captured(12).toDouble();
5507  sensorId= sensorId.simplified().rightJustified(5, ' ');
5508  QString chanKey=setupTpSensor(sensorId + 'l', "readLogFile()");
5509  if (chanKey.size())
5510  {
5511  chanKey = setupTpSensor(sensorId + 'u', "readLogFile()");
5512  if (chanKey.size())
5513  {
5514  SgDbbc3TpReading *tp=NULL;
5515  if (1.0/DAY2SEC < fabs(lastReadTsys - t))
5516  {
5517  tp = new SgDbbc3TpReading;
5518  tp->setT(t);
5519  tp->setOsRec(isOnSource?osRec:NULL);
5520  tp->setIsOnSource(isOnSource);
5521  tp->setIsDataOn(isDataOn);
5522  logReadings_.dbbc3Tps() << tp;
5523  osRec->dbbc3Tps() << tp;
5524  }
5525  else
5526  tp = logReadings_.dbbc3Tps().last();
5527  tp->addRecord(sensorId, boardId, bw, agc, gainU, gainL, tpOffU, tpOffL, tpOnU, tpOnL,
5528  sefdU, sefdL);
5529  lastReadTsys = t;
5530  }
5531  else
5533  "::readLogFile(): station " + stationName_ + ": parsing chanKey has failed for \"" +
5534  sensorId + 'u' + "\"; input: \"" + asciifyString(str) + "\"");
5535  }
5536  else
5538  "::readLogFile(): station " + stationName_ + ": parsing chanKey has failed for \"" +
5539  sensorId + 'l' + "\"; input: \"" + asciifyString(str) + "\"");
5540  }
5541  //
5542  // SEFD:
5543  else if ((match=reSefd.match(str)).hasMatch())
5544  {
5545  QString sensId("");
5546  QString srcNam("");
5547  double az, de;
5548  QVector<double> vec;
5549  if (extractSefdReading(str, match, t, sensId, srcNam, az, de, vec, tAtTheBegin))
5550  {
5551  SgSefdReading *sefd=NULL;
5552  if (0.3/DAY2SEC < fabs(lastReadSefd - t))
5553  logReadings_.sefds() << (sefd=new SgSefdReading);
5554  else
5555  sefd = logReadings_.sefds().last();
5556  if (!sefd->addValByChanKey(t, srcNam, az, de, sensId, vec))
5558  "::readLogFile(): station " + stationName_ +
5559  ": got duplicate SEFD; input: \"" + asciifyString(str) + "\"");
5560  lastReadSefd = t;
5561  };
5562  }
5563  //
5564  //
5565  // SX tsys reading:
5566  else if (wantTsys && reTsys.match(str).hasMatch())
5567  {
5568  QMap<QString, float> tsys;
5569  if (extractTsysReading(str, reTsys, t, tsys, tAtTheBegin) && tsys.size())
5570  {
5571  if (fabs(lastReadTsys - t) < 0.1/DAY2SEC)
5572  logReadings_.tSyses().last()->addTsyses(tsys);
5573  else
5574  {
5575  SgTsysReading *tsr=new SgTsysReading;
5576  tsr->setT(t);
5577  tsr->addTsyses(tsys);
5578  tsr->setOsRec(isOnSource?osRec:NULL);
5579  logReadings_.tSyses() << tsr;
5580  osRec->tSyses() << tsr;
5581  //
5582  // add trakls:
5583  int idx=logReadings_.trakls().size() - 1;
5584  SgTraklReading *pTrakl=NULL;
5585  while (0 < idx && (pTrakl=logReadings_.trakls().at(idx)) &&
5586  (t - pTrakl->getT()) < 60.0/DAY2SEC)
5587  {
5588  if (tsr->trakls().size() < 5)
5589  tsr->trakls() << pTrakl;
5590  idx--;
5591  };
5592  };
5593  lastReadTsys = t;
5594  };
5595  tsys.clear();
5596  }
5597  //
5598  // meteo parameters:
5599  else if (reMeteo.match(str).hasMatch())
5600  {
5601  SgMeteoData m;
5602  if (extractMeteoReading(str, reMeteo, t, m, oom) && tFirst < t)
5603  {
5604  SgMeteoReading *meteoRec=new SgMeteoReading(t, m);
5605  logReadings_.meteoPars() << meteoRec;
5606  if (isOnSource)
5607  {
5608  osRec->meteoPars() << meteoRec;
5609  meteoRec->setOsRec(osRec);
5610  };
5611  };
5612  }
5613  //
5614  // bbc reading:
5615  else if ((match=reBbc.match(str)).hasMatch())
5616  {
5617  extractBbcReading(str, match, t, tAtTheEnd, logReadings_.channelSetup(), tFirst);
5618  }
5619  // vc reading:
5620  else if ((match=reVc.match(str)).hasMatch())
5621  {
5622  extractVcReading(str, match, t, tAtTheEnd, logReadings_.channelSetup(), tFirst);
5623  }
5624  // patch reading:
5625  else if ((match=rePatch.match(str)).hasMatch())
5626  {
5627  extractPatchReading(str, match, t, tAtTheEnd, logReadings_.channelSetup(), tFirst);
5628  }
5629  else if ((match=reLo.match(str)).hasMatch())
5630  {
5631  extractLoReading(str, match, t, tAtTheEnd, logReadings_.channelSetup(), tFirst);
5632  }
5633  else if ((match=reLoRxg.match(str)).hasMatch())
5634  {
5635  extractLoRxgReading(str, match, t, tAtTheEnd, logReadings_.channelSetup(), tFirst);
5636  }
5637  else if ((match=reChanSkyFreqValues.match(str)).hasMatch())
5638  {
5639  extractChanSkyFrqReading(str, match, t, tAtTheEnd, logReadings_.channelSetup(), tFirst);
5640  }
5641  else if ((match=reVci.match(str)).hasMatch())
5642  {
5643  extractVciReading(str, match, t, tAtTheEnd, logReadings_.channelSetup(), tFirst);
5644  }
5645  //
5646  //
5647  // cable calibration:
5648  else if ((match=reCableCal.match(str)).hasMatch())
5649  {
5650  hasCableRecord_ = true;
5651  if (extractCableCalibration(str, match, t, d) && tFirst < t)
5652  {
5653  double scale = 4.0e5;
5654  SgCableCalReading *cableRec=new SgCableCalReading(t, d/scale);
5655  logReadings_.cableCals() << cableRec;
5656  if (isOnSource)
5657  {
5658  osRec->cableCals() << cableRec;
5659  cableRec->setOsRec(osRec);
5660  };
5661 // if (tRightMargin <= t)
5662 // reachedEndOfSession = true;
5663  };
5664  }
5665  else if ((match=reCdms.match(str)).hasMatch())
5666  {
5667  hasCdmsRecord_ = true;
5668  if (extractCableCalibration(str, match, t, d) && tFirst < t)
5669  {
5670  double scale = 2e12;
5671  SgCableCalReading *cableRec=new SgCableCalReading(t, d/scale);
5672  logReadings_.cableCals() << cableRec;
5673  if (isOnSource)
5674  {
5675  osRec->cableCals() << cableRec;
5676  cableRec->setOsRec(osRec);
5677  };
5678 // if (tRightMargin <= t)
5679 // reachedEndOfSession = true;
5680  };
5681  }
5682  // cablelong measurements:
5683  else if ((match=reCableLong.match(str)).hasMatch())
5684  {
5685  double scale = 4.0e5;
5686  if (extractCableCalibration(str, match, t, d))
5687  logReadings_.cableLongs() << new SgCableCalReading(t, d/scale);
5688  }
5689  // cable calibration sign:
5690  else if (!hasCableSign)
5691  {
5692  // 1) 2014.252.16:54:02.27/cablediff/647.7e-6,-
5693  if ((match=reCableDiff.match(str)).hasMatch())
5694  {
5695  if (extractCableCalibrationSignByDiff(match, val))
5696  {
5698  hasCableSign = true;
5700  "::readLogFile(): station " + stationName_ +
5701  ": the cable calibration sign was set to \"" +
5702  QString(logReadings_.getCableSign()==1?"+":"-") + "\". Source: cable_diff");
5703  };
5704  }
5705  // 2) 2012.150.17:40:46.48;"cabvle sign is positive, OK
5706  else if (reCableSign.match(str).hasMatch())
5707  {
5708  if (str.contains("positive", Qt::CaseInsensitive))
5709  {
5711  hasCableSign = true;
5713  "::readLogFile(): station " + stationName_ +
5714  ": the cable calibration sign was set to \"+\". Source: cable_sign_is");
5715  }
5716  else if (str.contains("negative", Qt::CaseInsensitive))
5717  {
5719  hasCableSign = true;
5721  "::readLogFile(): station " + stationName_ +
5722  ": the cable calibration sign was set to \"-\". Source: cable_sign_is");
5723  }
5724  else
5726  "::readLogFile(): station " + stationName_ + ": cannot determine proper cable sign "
5727  "from cable_sign_is pattern; input: \"" + asciifyString(str) + "\"");
5728  }
5729  else if (reCableDiffIs.match(str).hasMatch())
5730  {
5731  if (str.contains("positive", Qt::CaseInsensitive) ||
5732  str.contains("larger", Qt::CaseInsensitive) )
5733  {
5735  hasCableSign = true;
5737  "::readLogFile(): station " + stationName_ +
5738  ": the cable calibration sign was set to \"+\". Source: cable_diff_is");
5739  }
5740  else if ( str.contains("negative", Qt::CaseInsensitive) ||
5741  str.contains("smaller", Qt::CaseInsensitive) )
5742  {
5744  hasCableSign = true;
5746  "::readLogFile(): station " + stationName_ +
5747  ": the cable calibration sign was set to \"-\". Source: cable_diff_is");
5748  }
5749  else
5751  "::readLogFile(): station " + stationName_ +
5752  ": cannot determine proper cable sign from cable_diff_is pattern; input: \"" +
5753  asciifyString(str) + "\"");
5754  };
5755  };
5756  };
5757  };
5758  compressors.closeFlt(pipe, f, s);
5759 
5760  // pick up the last data on if the log has been terminated:
5761  if (osRec && osRec->getScanName().size() && osRec->getSourceName().size() &&
5762  (osRec->cableCals().size() || osRec->meteoPars().size() || osRec->tSyses().size()))
5763  {
5764  osRec->tFinis() = t;
5765  osRec->setIdx(logReadings_.onSourceRecords().size());
5766  logReadings_.onSourceRecords() << osRec;
5768  "::readLogFile(): station " + stationName_ + ": picked up not finished onSource record");
5769  };
5770  };
5771  //
5772  if (!hasProc)
5774  "::readLogFile(): station " + stationName_ + ": no proc record has been found in the log file");
5775  //
5776  if (operatorComments.size())
5777  {
5779  "::readLogFile(): station " + stationName_ + ": collected operator's comments: ");
5780  for (int i=0; i<operatorComments.size(); i++)
5782  "::readLogFile(): station " + stationName_ + ": " + operatorComments.at(i));
5783  };
5784  //
5785  // ok, end of parsing.
5786  //
5787  if (flogSize < 1024)
5788  {
5789  str.setNum(flogSize);
5790  str += "b";
5791  }
5792  else if (flogSize < 1048576)
5793  {
5794  str.setNum(flogSize/1024);
5795  str += "K";
5796  }
5797  else if (flogSize < 1073741824)
5798  {
5799  str.setNum(flogSize/1048576);
5800  str += "M";
5801  }
5802  else
5803  {
5804  str.setNum(flogSize/1073741824);
5805  str += "G";
5806  };
5808  "::readLogFile(): station " + stationName_ + ": " + QString("").setNum(numOfReadStrs) +
5809  " strings of the log file (" + str + ") were read" +
5810  (numOfSkippedStrs>1?" (" + QString("").setNum(numOfSkippedStrs) + " strings were skipped)":""));
5812  "::readLogFile(): station " + stationName_ + ": the log file version: " + versionStr);
5813  if (numOfProcedureExpanded)
5814  {
5816  "::readLogFile(): station " + stationName_ + ": " + QString("").setNum(numOfProcedureExpanded) +
5817  " time(s) procedure(s) were expanded:");
5818  for (QMap<QString, Procedure*>::iterator it=procedureByName_.begin(); it!=procedureByName_.end();
5819  ++it)
5821  "::readLogFile(): station " + stationName_ + ": " + it.value()->getName() + ": " +
5822  QString("").setNum(it.value()->getNumOfExpanded()));
5823  };
5825  "::readLogFile(): station " + stationName_ + ": collected " +
5826  QString("").setNum(logReadings_.onSourceRecords().size()) + " on_source, " +
5827  QString("").setNum(logReadings_.cableCals().size()) + " cable_cal and " +
5828  QString("").setNum(logReadings_.meteoPars().size()) + " meteo records");
5829  //
5831  "::readLogFile(): station " + stationName_ + ": collected " +
5832  QString("").setNum(logReadings_.tSyses().size()) + " tsys records");
5834  "::readLogFile(): station " + stationName_ + ": collected " +
5835  QString("").setNum(logReadings_.dbbc3Tps().size()) + " dbbc3 TP records");
5836 
5838  "::readLogFile(): station " + stationName_ + ": collected " +
5839  QString("").setNum(logReadings_.sefds().size()) + " SEFD evaluation records");
5840 
5841  //
5842  if (5 < logReadings_.tSyses().size())
5843  hasTsysRecord_ = true;
5844 
5845  if (rinexFileNameByStn_ &&
5846  rinexFileNameByStn_->contains(stationName_) && logReadings_.meteoPars().size()==0)
5847  {
5848  if (checkRinexFile(fileName, tFirst, tLast, rinexFileNameByStn_->value(stationName_)))
5850  "::readLogFile(): station " + stationName_ + ": collected " +
5851  QString("").setNum(logReadings_.meteoPars().size()) +
5852  " meteo records from RINEX files");
5853  else
5855  "::readLogFile(): station " + stationName_ + ": nothing to get from RINEX files");
5856  };
5857  //
5858  return true;
5859 };
5860 
5861 
5862 
5863 //
5865 {
5866  FieldSystemEpochFormat retFsFmt;
5867  if (reFsNewest_.match(str).hasMatch())
5868  retFsFmt = FSEF_NEWEST;
5869  else if (reFsNew_.match(str).hasMatch())
5870  retFsFmt = FSEF_NEW;
5871  else if (reFsOld_.match(str).hasMatch())
5872  retFsFmt = FSEF_OLD;
5873  else if (rePcmt_.match(str).hasMatch())
5874  retFsFmt = FSEF_PCMT;
5875  else if (reMet_.match(str).hasMatch())
5876  retFsFmt = FSEF_MET;
5877  else
5878  retFsFmt = FSEF_UNDEF;
5879 
5880  return retFsFmt;
5881 };
5882 
5883 
5884 
5885 //
5886 bool SgStnLogCollector::extractEpoch(const QString& str, SgMJD& t)
5887 {
5888  int nYear=0, nMonth=0, nDay=0, nHour=0, nMin=0;
5889  double dSecond=0.0, f=0.0;
5890  bool isOk=true;
5891  QRegularExpressionMatch match;
5892  //
5893  switch (fsFmt_)
5894  {
5895  //340184033;MARK III PC FIELD SYSTEM V 3.65 EFLSBERG 1995 00000000
5896  case FSEF_OLD: // DDDHHMMSS
5897 /* if (reFsOld_.indexIn(str) != -1) */
5898  if (reFsOld_.match(str).hasMatch())
5899  {
5900  nDay = str.mid(0,3).toInt(&isOk);
5901  if (isOk)
5902  {
5903  nHour = str.mid(3,2).toInt(&isOk);
5904  if (isOk)
5905  {
5906  nMin = str.mid(5,2).toInt(&isOk);
5907  if (isOk)
5908  {
5909  dSecond = str.mid(7,2).toInt(&isOk);
5910  nYear = inYear_;
5911  };
5912  };
5913  };
5914  }
5915  else
5916  {
5917  isOk = false;
5919  "::extractEpoch(): looks like not OLD FS format, string: \"" + asciifyString(str) + "\"");
5920 // "::extractEpoch(): looks like not OLD FS format, string: \"" + str + "\"");
5921  };
5922  break;
5923  //9903209333995;Log Opened: Mark IV Field System Version 9.3.17
5924  case FSEF_NEW: // YYDDDHHMMSSss
5925 /* if (reFsNew_.indexIn(str) != -1)*/
5926  if (reFsNew_.match(str).hasMatch())
5927  {
5928  nYear = str.mid(0,2).toInt(&isOk);
5929  if (isOk)
5930  {
5931  nDay = str.mid(2,3).toInt(&isOk);
5932  if (isOk)
5933  {
5934  nHour = str.mid(5,2).toInt(&isOk);
5935  if (isOk)
5936  {
5937  nMin = str.mid(7,2).toInt(&isOk);
5938  if (isOk)
5939  {
5940  dSecond = str.mid(9,2).toInt(&isOk);
5941  if (isOk)
5942  {
5943  f = str.mid(11,2).toInt(&isOk);
5944  if (isOk)
5945  {
5946  dSecond += 0.01*f;
5947  nYear += (nYear>68)?1900:2000;
5948  };
5949  };
5950  };
5951  };
5952  };
5953  };
5954  }
5955  else
5956  {
5957  isOk = false;
5959  "::extractEpoch(): looks like not NEW FS format, string: \"" + asciifyString(str) + "\"");
5960 // "::extractEpoch(): looks like not NEW FS format, string: \"" + str + "\"");
5961  };
5962  break;
5963  //012345678901234567890
5964  //2006.214.20:21:46.26
5965  //2016.019.14:17:00.08;Log Opened: Mark IV Field System Version 9.12.2
5966  //2002.247.18:20:00.0 /wx/ 9.1,1017.0,90.0 -- surprise?
5967  //2020.356.17:00:05 /wx/14.7,84.0,1023.1,4.0,-2 --"--
5968  case FSEF_NEWEST: // YYYY.DDD.HH.MM.SS.ss
5969 /* if (reFsNewest_.indexIn(str) != -1) */
5970  if ((match=reFsNewest_.match(str)).hasMatch())
5971  {
5972  nYear = match.captured(1).toInt(&isOk);
5973  if (isOk)
5974  {
5975  nDay = match.captured(2).toInt(&isOk);
5976  if (isOk)
5977  {
5978  nHour = match.captured(3).toInt(&isOk);
5979  if (isOk)
5980  {
5981  nMin = match.captured(4).toInt(&isOk);
5982  if (isOk)
5983  {
5984  dSecond = match.captured(5).toDouble(&isOk);
5985  fsContentStartsAt_[FSEF_NEWEST] = 15 + match.captured(5).size();
5986  };
5987  };
5988  };
5989  };
5990  /*
5991  nYear = str.mid(0,4).toInt(&isOk);
5992  if (isOk)
5993  {
5994  nDay = str.mid(5,3).toInt(&isOk);
5995  if (isOk)
5996  {
5997  nHour = str.mid(9,2).toInt(&isOk);
5998  if (isOk)
5999  {
6000  nMin = str.mid(12,2).toInt(&isOk);
6001  if (isOk)
6002  {
6003  dSecond = str.mid(15,5).toDouble(&isOk);
6004  if (!isOk) // try as exception:
6005  {
6006  dSecond = str.mid(15,4).toDouble(&isOk);
6007  fsContentStartsAt_[FSEF_NEWEST] = 19;
6008  }
6009  else if (fsContentStartsAt_[FSEF_NEWEST] == 19)
6010  fsContentStartsAt_[FSEF_NEWEST] = 20;
6011  };
6012  };
6013  };
6014  };
6015  */
6016  }
6017  else
6018  {
6019  isOk = false;
6021  "::extractEpoch(): looks like not NEWEST FS format, string: \"" + asciifyString(str) + "\"");
6022 // "::extractEpoch(): looks like not NEWEST FS format, string: \"" + str + "\"");
6023  };
6024  break;
6025  case FSEF_PCMT: //
6026  case FSEF_MET: //
6027  //2017 9 11 18 50 29 1.196e-11 254-1850
6028 /* if (rePcmt_.indexIn(str) != -1) */
6029  if (rePcmt_.match(str).hasMatch())
6030  {
6031  QStringList l=str.split(QRegExp("\\s+"));
6032  if (l.size() >= 6)
6033  {
6034  nYear = l.at(0).toInt(&isOk);
6035  if (isOk)
6036  {
6037  nMonth = l.at(1).toInt(&isOk);
6038  if (isOk)
6039  {
6040  nDay = l.at(2).toInt(&isOk);
6041  if (isOk)
6042  {
6043  nHour = l.at(3).toInt(&isOk);
6044  if (isOk)
6045  {
6046  nMin = l.at(4).toInt(&isOk);
6047  if (isOk)
6048  dSecond = l.at(5).toDouble(&isOk);
6049  };
6050  };
6051  };
6052  };
6053  }
6054  else
6056  "::extractEpoch(): not enough data for PCMT format, the string: \"" +
6057  asciifyString(str) + "\"");
6058 // "::extractEpoch(): not enough data for PCMT format, the string: \"" + str + "\"");
6059  }
6060  else
6061  {
6062  isOk = false;
6064  "::extractEpoch(): looks like not PCMT format, the string: \"" + asciifyString(str) + "\"");
6065 // "::extractEpoch(): looks like not PCMT format, the string: \"" + str + "\"");
6066  };
6067  break;
6068  default:
6069  case FSEF_UNDEF:
6070  isOk = false;
6071  break;
6072  };
6073  //
6074  if (isOk)
6075  {
6076  if (0 < inYear_ && nYear != inYear_)
6077  {
6079  "::extractEpoch(): year has changed: " + QString("").setNum(inYear_) + " => " +
6080  QString("").setNum(nYear) + "; input: \"" + asciifyString(str) + "\"");
6081  inYear_ = nYear;
6082  }
6083  else if (inYear_ == 0)
6084  inYear_ = nYear;
6085  };
6086  //
6087  if (!isOk)
6088  {
6089  if (fsFmt_==FSEF_NEWEST)
6090  {
6091  fsFmt_ = FSEF_NEW;
6092  isOk = extractEpoch(str, t);
6093  if (isOk)
6095  "::extractEpoch(): looks like FS format has changed NEWEST=>NEW: \"" +
6096  asciifyString(str) + "\"");
6097 // "::extractEpoch(): looks like FS format has changed NEWEST=>NEW: \"" + str + "\"");
6098  else
6099  fsFmt_ = FSEF_NEWEST;
6100  }
6101  else if (fsFmt_==FSEF_NEW)
6102  {
6103  // e.g.: /500/sessions/1998/na253/na253ft.log
6104  // olf version of FS has been launched while station observed
6105  fsFmt_ = FSEF_OLD;
6106  isOk = extractEpoch(str, t);
6107  if (isOk)
6109  "::extractEpoch(): looks like FS format has changed NEW=>OLD: \"" + asciifyString(str) + "\"");
6110 // "::extractEpoch(): looks like FS format has changed NEW=>OLD: \"" + str + "\"");
6111  else
6112  fsFmt_ = FSEF_NEW;
6113  };
6114  if (!isOk)
6116  "::extractEpoch(): failed to parse, string: \"" + asciifyString(str) + "\"");
6117 // "::extractEpoch(): failed to parse, string: \"" + str + "\"");
6118  }
6119  else
6120  t.setUpEpoch(nYear, nMonth, nDay, nHour, nMin, dSecond);
6121  return isOk;
6122 };
6123 
6124 
6125 
6126 //
6127 bool SgStnLogCollector::extractContent(const QString& str, QString& content)
6128 {
6129  content = str.mid(fsContentStartsAt_[fsFmt_]);
6130  return content.size() > 0;
6131 };
6132 
6133 
6134 
6135 //
6136 bool SgStnLogCollector::extractMeteoReading(const QString& str, const QRegularExpression& reMeteo,
6137  SgMJD& t, SgMeteoData& m, const int* oom)
6138 {
6139  double d;
6140  bool isOk=false;
6141 
6142  if (!extractEpoch(str, t))
6143  return false;
6144 
6145  //
6146  // here a little bit different approach: there can be meteo parameters:
6147  // either (T,P,RH) or (T,P,RH,WindVel,WindAzimuth)
6148  // PS: we do not use wind velocity and direction.
6149  //
6150 //#if QT_VERSION >= 0x040800
6151 // QString metStr(str.mid(reMeteo.indexIn(str) + reMeteo.cap(1).size()));
6152 //#else
6153 // QRegExp reMeteo2(reMeteo);
6154 // QString metStr(str.mid(reMeteo2.indexIn(str) + reMeteo2.cap(1).size()));
6155 //#endif
6156 
6157  QString metStr(str.mid(reMeteo.match(str).capturedEnd(1)));
6158 
6159  if (metStr.contains("C"))
6160  metStr = metStr.remove("C");
6161  if (metStr.contains("mB"))
6162  metStr = metStr.remove("mB");
6163  if (metStr.contains("%"))
6164  metStr = metStr.remove("%");
6165  if (metStr.contains("weather:"))
6166  metStr = metStr.remove("weather:");
6167 
6168  if (!metStr.size())
6169  {
6171  "::extractMeteoReading(): cannot extract meteo data from \"" + asciifyString(str) + "\"");
6172 // "::extractMeteoReading(): cannot extract meteo data from \"" + str + "\"");
6173  return isOk;
6174  };
6175 
6176  QStringList lst=metStr.split(",");
6177 
6178  if (lst.size() > 2)
6179  {
6180  const QString &strT =lst.at(oom[0]);
6181  const QString &strP =lst.at(oom[1]);
6182  const QString &strRh=lst.at(oom[2]);
6183 
6184  d = strT.toDouble(&isOk);
6185  if (isOk)
6186  {
6187  if (-50.0<=d && d<=80.0) // ?? is it ok, can stations operate in worse conditions?
6188  {
6189  m.setTemperature(d);
6190  d = strP.toDouble(&isOk);
6191  if (isOk)
6192  {
6193  if (d == 1100.0)
6194  {
6195  isOk = false;
6197  "::extractMeteoReading(): the extracted atmospheric pressure looks suspicious: " +
6198  QString("").setNum(d) + "hPa (i.e.,==std.atm.); skipped");
6199  }
6200  else if (d >= 500.0) // 500kPa is at ~5.5km height of the standard atmosphere
6201  {
6202  m.setPressure(d);
6203  d = strRh.toDouble(&isOk);
6204  if (isOk)
6205  {
6206  if (-9.9<=d && d<=120.0)
6207  {
6208  if (d < 0.0)
6209  {
6211  "::extractMeteoReading(): the extracted relative humidity looks suspicious: " +
6212  QString("").setNum(d) + "%; adjusted it to zero");
6213  m.setRelativeHumidity(0.0);
6214  }
6215  else if (100.0 < d)
6216  {
6218  "::extractMeteoReading(): the extracted relative humidity looks suspicious: " +
6219  QString("").setNum(d) + "%; adjusted it to 100%");
6220  m.setRelativeHumidity(1.0);
6221  }
6222  else
6223  m.setRelativeHumidity(d*0.01);
6224  }
6225  else
6226  {
6227  isOk = false;
6229  "::extractMeteoReading(): the extracted relative humidity looks unrealstic: " +
6230  QString("").setNum(d) + "%; skipped");
6231  };
6232  }
6233  else if (strRh.contains("EE.0", Qt::CaseInsensitive))
6234  {
6235  m.setRelativeHumidity(1.0);
6237  "::extractMeteoReading(): forcefully set relative humidity to 1.00 from the string \"" +
6238  strRh + "\"");
6239  }
6240  else
6242  "::extractMeteoReading(): failed to extract relative humidity from \"" + strRh + "\"");
6243  }
6244  else
6245  {
6246  isOk = false;
6248  "::extractMeteoReading(): the extracted atmospheric pressure is too low: " +
6249  QString("").setNum(d) + "hPa; skipped");
6250  };
6251  }
6252  else
6254  "::extractMeteoReading(): failed to extract pressure from \"" + strP + "\"");
6255  }
6256  else
6257  {
6258  isOk = false;
6260  "::extractMeteoReading(): the extracted atmospheric temperature looks unreal: " +
6261  QString("").setNum(d) + "C; skipped");
6262  };
6263  }
6264  else
6266  "::extractMeteoReading(): failed to extract temperature: from \"" + strT + "\"");
6267  }
6268  else
6270  "::extractMeteoReading(): the number of data less than 3: \"" + metStr + "\"");
6271  return isOk;
6272 };
6273 
6274 
6275 
6276 //
6277 //bool SgStnLogCollector::extractBbcReading(const QString& str, const QRegExp& re, SgMJD& t,
6278 bool SgStnLogCollector::extractBbcReading(const QString& str, const QRegularExpressionMatch& match,
6279  SgMJD& t, const SgMJD& nearTheEnd, SgChannelSetup& cs, const SgMJD& tFirst)
6280 {
6281  QString bbcStr(str.mid(match.capturedEnd(2) + 1));
6282  QString bbcId(match.captured(2));
6283 
6284  if (!extractEpoch(str, t))
6285  return false;
6286 
6287  if (nearTheEnd <= t)
6288  return false;
6289 
6290  bool isOk;
6291  int cIdx;
6292  cIdx = bbcId.toInt(&isOk);
6293  if (!isOk)
6294  {
6296  "::extractBbcReading(): station " + stationName_ +
6297  ": cannot convert \"" + bbcId + "\" to int; input: \"" + asciifyString(str) + "\"");
6298  return false;
6299  };
6300 
6301  QStringList lst=bbcStr.split(",");
6302 /*
6303 Syntax: bbcnn=freq,ifsource,bwu,bwl,avper,gainmode,gainu,gainl
6304 
6305 Response: bbcnn/freq,ifsource,bwu,bwl,avper,gainmode,gainu,gainl,lock,USBpwr,LSBpwr,serno,err
6306 
6307 nn is the BBC index number corresponding to its position in the rack, 01 to 14. Not all racks
6308  have all BBCs.
6309 
6310 Settable Parameters:
6311 
6312 freq -- L.O. frequency in MHz, between 450.00 and 1050.00, inclusive. No default. This frequency
6313  range is greater than the normal range over which the BBC is specified to lock (500 to 1000 MHz)
6314  to allow for testing.
6315 
6316 ifsource -- I.F. input source, one of A, B, C, D. No default.
6317 
6318 bwu -- Bandwidth for USB in MHz. One of 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16. Default 2.
6319 
6320 bwl -- Bandwidth for LSB in MHz. One of 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16. Default bwu.
6321 
6322 avper -- Averaging period in seconds for TPI. May be 0, 1, 2, 4, 10, 20, 40, or 60 seconds. A value
6323  of 0 results in 1/80 sec averaging time. Default 1. The averaging period is common to both
6324  upper and lower sideband. The averaging period is synchronous with the 1 pps.
6325 */
6326  //
6327  //2018.003.17:14:29.54&dbbcsx8/bbc03=285.75,a,8.00
6328  //2018.003.17:14:29.54&dbbcsx8/bbc04=365.75,a,8.00
6329  //2018.003.17:14:29.54&dbbcsx8/bbc05=725.75,b,8.00
6330  //
6331  if (3 <= lst.size())
6332  {
6333  double d;
6334  // BBC freq:
6335  d = lst.at(0).toDouble(&isOk);
6336  if (!isOk)
6337  {
6339  "::extractBbcReading(): station " + stationName_ +
6340  ": cannot convert \"" + lst.at(0) + "\" to double; input: \"" +
6341  asciifyString(str) + "\"");
6342  return false;
6343  };
6344  // IFD ID:
6345  if (cs.bbcFreqByIdx().contains(cIdx) &&
6346  cs.bbcFreqByIdx()[cIdx] != d &&
6347  tFirst < t)
6349  "::extractBbcReading(): station " + stationName_ +
6350  ": IF frequency has changed for BBC #" + bbcId + ": " +
6351  QString("").sprintf("%.2f => %.2f", cs.bbcFreqByIdx()[cIdx], d) +
6352  "; input: \"" + asciifyString(str) + "\"");
6353  cs.bbcFreqByIdx()[cIdx] = d;
6354  cs.loIdByIdx()[cIdx] = lst.at(1);
6355 
6356  // bandwidth:
6357  d = lst.at(2).toDouble(&isOk);
6358  if (!isOk)
6359  {
6361  "::extractBbcReading(): station " + stationName_ +
6362  ": cannot convert \"" + lst.at(2) + "\" to double; input: \"" +
6363  asciifyString(str) + "\"");
6364  return false;
6365  };
6366  if (cs.bbcBandwidthByIdx().contains(cIdx) &&
6367  cs.bbcBandwidthByIdx()[cIdx] != d &&
6368  tFirst < t)
6370  "::extractBbcReading(): station " + stationName_ +
6371  ": IF bandwidth has changed for BBC #" + bbcId + ": " +
6372  QString("").sprintf("%.2f => %.2f", cs.bbcBandwidthByIdx()[cIdx], d) +
6373  "; input: \"" + asciifyString(str) + "\"");
6374  cs.bbcBandwidthByIdx()[cIdx] = d;
6375  //
6376  if (4 < lst.size())
6378  "::extractBbcReading(): station " + stationName_ +
6379  ": got extra data; input: \"" + asciifyString(str) + "\"");
6380  if (cs.getHwType() == SgChannelSetup::HT_UNDEF)
6382  else if (cs.getHwType() != SgChannelSetup::HT_BBC)
6383  {
6385  "::extractBbcReading(): station " + stationName_ +
6386  ": got an unexpected \"bbc\" record; input: \"" + asciifyString(str) + "\"");
6388  };
6389  }
6390  else
6391  {
6393  "::extractBbcReading(): station " + stationName_ +
6394  ": the number of data less than 3: \"" + bbcStr + "\"");
6395  return false;
6396  };
6397  return true;
6398 };
6399 
6400 
6401 
6402 //
6403 bool SgStnLogCollector::extractVcReading(const QString& str, const QRegularExpressionMatch& match,
6404  SgMJD& t, const SgMJD& nearTheEnd, SgChannelSetup& cs, const SgMJD& tFirst)
6405 {
6406 // QString vcStr(str.mid(re.indexIn(str) + re.cap(1).size() +
6407 // re.cap(2).size() + 1));
6408  QString vcStr(str.mid(match.capturedEnd(2) + 1));
6409 
6410  if (!extractEpoch(str, t))
6411  return false;
6412 
6413  if (nearTheEnd <= t)
6414  return false;
6415 
6416  QString bbcId(match.captured(2));
6417  bool isOk;
6418  int cIdx;
6419  cIdx = bbcId.toInt(&isOk);
6420  if (!isOk)
6421  {
6423  "::extractVcReading(): station " + stationName_ +
6424  ": cannot convert \"" + bbcId + "\" to int; input: \"" + asciifyString(str) + "\"");
6425  return false;
6426  };
6427 
6428  QStringList lst=vcStr.split(",");
6429 
6430 /*
6431 Syntax: vcnn=freq,bandwidth,TPIsel,attenU,attenL
6432 
6433 Response: vcnn/freq,bandwidth,TPIsel,attenU,attenl,rem/lcl,LOlock,TP
6434 
6435 Settable parameters:
6436 
6437 freq - Synthesizer frequency in MHz, value must be less than 500.00 MHz. No default.
6438 bandwidth - Final filter bandwidth in MHz, default 2. Choices for Mark III are: 0.125, 0.25, 0.5,
6439  1.0, 2.0, 4.0, 0 (external filter). Choices for Mark IV are: 0.125, 0.5, 2.0, 4.0, 8.0,
6440  16.0, 0 (external filter). Value may be integer for bandwidths of 1, 2, 4, 8, or 16 MHz.
6441 TPIsel - Total power integrator selection. Choices are ul, l, u, if, lo, gr (ground). Default u.
6442 attenU - USB attenuator, 0 or 10 db (default) only.
6443 attenL - LSB attenuator, 0 or 10 db (default) only.*
6444 */
6445  //
6446  //2019.003.18:05:50.86&vcsx8/vc01=132.99,8.000,ul
6447  //2019.003.18:05:50.86&vcsx8/vc02=172.99,8.000,u
6448  //2019.003.18:05:50.86&vcsx8/vc03=272.99,8.000,u
6449 
6450  if (lst.size())
6451  {
6452  double d;
6453  // VC freq:
6454  d = lst.at(0).toDouble(&isOk);
6455  if (!isOk)
6456  {
6458  "::extractVcReading(): station " + stationName_ +
6459  ": cannot convert \"" + lst.at(0) + "\" to double; input: \"" +
6460  asciifyString(str) + "\"");
6461  return false;
6462  };
6463  // IFD ID:
6464  if (cs.bbcFreqByIdx().contains(cIdx) &&
6465  cs.bbcFreqByIdx()[cIdx] != d &&
6466  tFirst < t)
6468  "::extractVcReading(): station " + stationName_ +
6469  ": video frequency has changed for IF #" + bbcId + ": " +
6470  QString("").sprintf("%.2f => %.2f", cs.bbcFreqByIdx()[cIdx], d) +
6471  "; input: \"" + asciifyString(str) + "\"");
6472  cs.bbcFreqByIdx()[cIdx] = d;
6473 
6474  // bandwidth:
6475  d = 2.0;
6476  if (1 < lst.size())
6477  {
6478  d = lst.at(1).toDouble(&isOk);
6479  if (!isOk)
6480  {
6482  "::extractVcReading(): station " + stationName_ +
6483  ": cannot convert \"" + lst.at(2) + "\" to double; input: \"" +
6484  asciifyString(str) + "\"");
6485  return false;
6486  };
6487  };
6488  if (cs.bbcBandwidthByIdx().contains(cIdx) &&
6489  cs.bbcBandwidthByIdx()[cIdx] != d &&
6490  tFirst < t)
6492  "::extractVcReading(): station " + stationName_ +
6493  ": bandwidth has changed for IF #" + bbcId + ": " +
6494  QString("").sprintf("%.2f => %.2f", cs.bbcBandwidthByIdx()[cIdx], d) +
6495  "; input: \"" + asciifyString(str) + "\"");
6496  cs.bbcBandwidthByIdx()[cIdx] = d;
6497  //
6498 
6499  if (cs.getHwType() == SgChannelSetup::HT_UNDEF)
6501  else if (cs.getHwType() != SgChannelSetup::HT_VC)
6502  {
6504  "::extractVcReading(): station " + stationName_ +
6505  ": got unexpected \"vc\" record; input: \"" + asciifyString(str) + "\"");
6507  };
6508  }
6509  else
6510  {
6512  "::extractVcReading(): station " + stationName_ +
6513  ": the number of data less than 2: \"" + vcStr + "\"");
6514  return false;
6515  };
6516  return true;
6517 };
6518 
6519 
6520 
6521 //
6522 bool SgStnLogCollector::extractLoReading(const QString& str, const QRegularExpressionMatch& match,
6523  SgMJD& t, const SgMJD& nearTheEnd, SgChannelSetup& cs, const SgMJD& tFirst)
6524 {
6525 //QString loStr(str.mid(re.indexIn(str) + re.cap(1).size()));
6526  QString loStr(str.mid(match.capturedEnd(1)));
6527 
6528  if (!extractEpoch(str, t))
6529  return false;
6530 
6531  if (nearTheEnd <= t)
6532  return false;
6533 
6534  bool isOk;
6535  QString loId(match.captured(2));
6536  QStringList lst=loStr.split(",");
6537 
6538  //2018.003.17:14:29.55&ifdsx/lo=loa,8080.00,usb,rcp,1
6539  //2018.003.17:14:29.55&ifdsx/lo=lob,8080.00,usb,rcp,1
6540  //2018.003.17:14:29.55&ifdsx/lo=loc,2020.00,usb,rcp,1
6541  //2018.003.17:14:29.55&ifdsx/lo=lod,2020.00,usb,rcp,1
6542  //
6543  if (4 <= lst.size())
6544  {
6545  double d;
6546  d = lst.at(1).toDouble(&isOk);
6547  if (!isOk)
6548  {
6550  "::extractLoReading(): station " + stationName_ +
6551  ": cannot convert \"" + lst.at(1) + "\" to double; input: \"" + asciifyString(str) + "\"");
6552  return false;
6553  };
6554 
6555  if (cs.loFreqById().contains(loId) &&
6556  cs.loFreqById()[loId] != d &&
6557  tFirst < t)
6559  "::extractLoReading(): station " + stationName_ + ": LO frequency changed for LO \"" + loId +
6560  "\": " +
6561  QString("").sprintf("%.2f", cs.loFreqById()[loId]) + " => " +
6562  QString("").sprintf("%.2f", d) + "; input: \"" + asciifyString(str) + "\"");
6563 
6564  cs.loFreqById()[loId] = d;
6565  const QString &sb=lst.at(2);
6566  const QString &pz=lst.at(3);
6567 
6568  if (sb == "usb")
6569  cs.loSideBandById()[loId] = CSB_USB;
6570  else if (sb == "lsb")
6571  cs.loSideBandById()[loId] = CSB_LSB;
6572  else
6573  {
6574  cs.loSideBandById()[loId] = CSB_UNDEF;
6576  "::extractLoReading(): station " + stationName_ +
6577  ": cannot figure out side band form the string \"" + asciifyString(str) + "\"");
6578  };
6579  // polarization:
6580  if (pz == "rcp")
6581  cs.loPolarizationById()[loId] = CP_RightCP;
6582  else if (pz == "lcp")
6583  cs.loPolarizationById()[loId] = CP_LeftCP;
6584  else
6585  {
6586  cs.loPolarizationById()[loId] = CP_UNDEF;
6588  "::extractLoReading(): station " + stationName_ +
6589  ": cannot figure out polarization form the string \"" + asciifyString(str) + "\"");
6590  };
6591  // aux:
6592  if (5 < lst.size())
6594  "::extractLoReading(): station " + stationName_ +
6595  ": got extra data; input: \"" + asciifyString(str) + "\"");
6596  }
6597  else
6598  {
6600  "::extractLoReading(): station " + stationName_ +
6601  ": the number of data less than 4: \"" + loStr + "\"");
6602  return false;
6603  };
6604 
6605  return true;
6606 };
6607 
6608 
6609 
6610 //
6611 //
6612 bool SgStnLogCollector::extractLoRxgReading(const QString& str, const QRegularExpressionMatch& match,
6613  SgMJD& t, const SgMJD& nearTheEnd, SgChannelSetup& cs, const SgMJD& tFirst)
6614 {
6615  QString loStr(str.mid(match.capturedEnd(1)));
6616 
6617 
6618  if (!extractEpoch(str, t))
6619  return false;
6620  if (nearTheEnd <= t)
6621  return false;
6622 
6623  bool isOk;
6624  QString loId(match.captured(2));
6625  QStringList lst=loStr.split(",");
6626 
6627  //2021.190.19:40:27.52/lo/rxg,loa0,3592.4,lcp,bb.rxg,range,1000,10000,2015,3,22,lcp,3.00000e-02,rcp,3.00000e-02
6628  //2021.190.19:40:27.52/lo/rxg,loa1,3592.4,rcp,bb.rxg,range,1000,10000,2015,3,22,lcp,3.00000e-02,rcp,3.00000e-02
6629  //2021.190.19:40:27.52/lo/rxg,lob0,3990.4,lcp,bb.rxg,range,1000,10000,2015,3,22,lcp,3.00000e-02,rcp,3.00000e-02
6630  //2021.190.19:40:27.53/lo/rxg,lob1,3990.4,rcp,bb.rxg,range,1000,10000,2015,3,22,lcp,3.00000e-02,rcp,3.00000e-02
6631  //2021.190.19:40:27.53/lo/rxg,loc0,10354.4,lcp,undefined
6632  //2021.190.19:40:27.53/lo/rxg,loc1,10354.4,rcp,undefined
6633  //2021.190.19:40:27.53/lo/rxg,lod0,10498.4,lcp,undefined
6634  //2021.190.19:40:27.53/lo/rxg,lod1,10498.4,rcp,undefined
6635  if (3 <= lst.size())
6636  {
6637  double d;
6638  d = lst.at(1).toDouble(&isOk);
6639  if (!isOk)
6640  {
6642  "::extractLoRxgReading(): station " + stationName_ +
6643  ": cannot convert \"" + lst.at(1) + "\" to double; input: \"" + asciifyString(str) + "\"");
6644  return false;
6645  };
6646  if (cs.loFreqById().contains(loId) &&
6647  cs.loFreqById()[loId] != d &&
6648  tFirst < t)
6650  "::extractLoRxgReading(): station " + stationName_ + ": frequency changed for LO \"" + loId +
6651  "\": " +
6652  QString("").sprintf("%.2f", cs.loFreqById()[loId]) + " => " +
6653  QString("").sprintf("%.2f", d) + "; input: \"" + asciifyString(str) + "\"");
6654 
6655  cs.loFreqById()[loId] = d;
6656 
6657  const QString &pz=lst.at(2);
6659 
6660  if (pz == "rcp")
6661  polariz = CP_RightCP;
6662  else if (pz == "lcp")
6663  polariz = CP_LeftCP;
6664  else
6666  "::extractLoRxgReading(): station " + stationName_ +
6667  ": cannot figure out polarization form the string \"" + asciifyString(str) + "\"");
6668  if (cs.loPolarizationById().contains(loId) &&
6669  cs.loPolarizationById()[loId] != polariz &&
6670  tFirst < t)
6672  "::extractLoRxgReading(): station " + stationName_ + ": polarization changed for LO \"" +
6673  loId + "\": " +
6674  polarization2Str(cs.loPolarizationById()[loId]) + " => " +
6675  polarization2Str(polariz) + "; input: \"" + asciifyString(str) + "\"");
6676  cs.loPolarizationById()[loId] = polariz;
6677  }
6678  else
6679  {
6681  "::extractLoRxgReading(): station " + stationName_ +
6682  ": the number of data less than 3: \"" + loStr + "\"");
6683  return false;
6684  };
6685  return true;
6686 };
6687 
6688 
6689 
6690 //
6691 bool SgStnLogCollector::extractPatchReading(const QString& str, const QRegularExpressionMatch& match,
6692  SgMJD& t, const SgMJD& nearTheEnd, SgChannelSetup& cs, UNUSED const SgMJD& tFirst)
6693 {
6694 //QString patchStr(str.mid(re.indexIn(str) + re.cap(1).size()));
6695  QString patchStr(str.mid(match.capturedEnd(1)));
6696 
6697  if (!extractEpoch(str, t))
6698  return false;
6699  if (nearTheEnd <= t)
6700  return false;
6701 
6702  bool isOk;
6703  QStringList lst=patchStr.split(",");
6704 
6705  //2019.003.18:05:52.80&ifdsx/patch=lo1,1l,2l,3h,4h
6706  //2019.003.18:05:52.80&ifdsx/patch=lo2,9l,10h,11h,12h,13h,14h
6707  //2019.003.18:05:52.80&ifdsx/patch=lo3,5h,6h,7h,8h
6708  //
6709  //2018.094.17:20:22.65&ifdsx/patch=lo1,a1,a2,a3,a4
6710  //2018.094.17:20:22.65&ifdsx/patch=lo2,b1,b2,b3,b4,b5,b6
6711  //2018.094.17:20:22.65&ifdsx/patch=lo3,a5,a6,a7,a8
6712 
6713  if (1 < lst.size())
6714  {
6715  QString loId(lst.at(0));
6716 
6717  for (int i=1; i<lst.size(); i++)
6718  {
6719  QString cid(lst.at(i));
6720  QChar sb(cid.at(cid.size() - 1));
6721  if (sb == 'l' || sb == 'h')
6722  {
6723  cid.chop(1);
6724  int cIdx=-1;
6725  cIdx = cid.toInt(&isOk);
6726  if (!isOk)
6727  {
6729  "::extractPatchReading(): station " + stationName_ +
6730  ": cannot convert \"" + cid + "\" to int; input: \"" + asciifyString(str) + "\"");
6731  }
6732  else
6733  cs.loIdByIdx()[cIdx] = loId;
6734  }
6735  else
6736  cs.loIdByCid()[cid] = loId;
6737 // else
6738 // logger->write(SgLogger::ERR, SgLogger::IO, className() +
6739 // "::extractPatchReading(): unexpected patch record #" + QString("").setNum(i) +
6740 // " \"" + cid + "\"; the string \"" + str + "\"");
6741  };
6742  }
6743  else
6744  {
6746  "::extractPatchReading(): station " + stationName_ +
6747  ": nothing found: \"" + asciifyString(str) + "\"");
6748 // ": nothing found: \"" + str + "\"");
6749  return false;
6750  };
6751 
6752  return true;
6753 };
6754 
6755 
6756 
6757 
6758 //
6760  const QRegularExpressionMatch& match,
6761  SgMJD& t, const SgMJD& nearTheEnd, SgChannelSetup& cs, const SgMJD& tFirst)
6762 {
6763  if (!extractEpoch(str, t))
6764  return false;
6765  if (nearTheEnd <= t)
6766  return false;
6767 
6768  bool isOk;
6769  int cIdx=-1;
6770  double skyFrq=-1.0, loFrq=-1.0, videoFrq=-1.0;
6771  QString bbcId(match.captured(1));
6772 
6773  cIdx = bbcId.toInt(&isOk);
6774  if (!isOk)
6775  {
6777  "::extractChanSkyFrqReading(): station " + stationName_ +
6778  ": cannot get channel index; input: \"" + asciifyString(str) + "\"");
6779  return isOk;
6780  };
6781  skyFrq = match.captured(2).toDouble(&isOk);
6782  if (!isOk)
6783  {
6785  "::extractChanSkyFrqReading(): station " + stationName_ +
6786  ": cannot get sky frequency; input: \"" + asciifyString(str) + "\"");
6787  return isOk;
6788  };
6789  loFrq = match.captured(3).toDouble(&isOk);
6790  if (!isOk)
6791  {
6793  "::extractChanSkyFrqReading(): station " + stationName_ +
6794  ": cannot get LO frequency; input: \"" + asciifyString(str) + "\"");
6795  return isOk;
6796  };
6797  videoFrq = match.captured(4).toDouble(&isOk);
6798  if (!isOk)
6799  {
6801  "::extractChanSkyFrqReading(): station " + stationName_ +
6802  ": cannot get video frequency; input: \"" + asciifyString(str) + "\"");
6803  return isOk;
6804  };
6805 
6806  QString loId(""), cId("");
6807  char sbIds[2] = {'l', 'u'};
6808 
6809  if (loFrq < 4000.0)
6810  loId = "b";
6811  else
6812  loId = "a";
6813 
6814  //2016.236.17:21:21.92&setupsx/"channel sky freq lo freq video
6815  //2016.236.17:21:21.92&setupsx/" 01 8210.99 8080.00 130.99
6816  //2016.236.17:21:21.92&setupsx/" 02 8220.99 8080.00 140.99
6817  //...
6818  //2016.236.17:21:21.92&setupsx/" 14 2292.99 2020.00 272.99
6819 
6820  for (int i=0; i<2; i++)
6821  {
6822  cId = QString("").sprintf("%02d%c", cIdx, sbIds[i]);
6823 
6824  if (cs.bbcFreqByIdx().contains(cIdx) &&
6825  cs.bbcFreqByIdx()[cIdx] != videoFrq &&
6826  tFirst < t)
6828  "::extractChanSkyFrqReading(): station " + stationName_ +
6829  ": video frequency has changed for IF #" + bbcId + ": " +
6830  QString("").sprintf("%.2f => %.2f", cs.bbcFreqByIdx()[cIdx], videoFrq) +
6831  "; input: \"" + asciifyString(str) + "\"");
6832 
6833  cs.bbcFreqByIdx()[cIdx] = videoFrq;
6834  cs.loIdByIdx()[cIdx] = loId;
6835  cs.loIdByCid()[cId] = loId;
6836  cs.loFreqById()[loId] = loFrq;
6837  cs.ifSideBandById()[cId] = (i==0?CSB_LSB:CSB_USB);
6838 
6839  if (1.0e-2 < fabs(loFrq + videoFrq - skyFrq)) // check set up:
6841  "::extractChanSkyFrqReading(): station " + stationName_ +
6842  ": got unexpected frequency setup; input: \"" + asciifyString(str) + "\"");
6843  };
6844  //
6845  // just assumption:
6846  cs.loSideBandById()[loId] = CSB_USB;
6847 
6848  if (cs.getHwType() == SgChannelSetup::HT_UNDEF)
6850  else if (cs.getHwType() != SgChannelSetup::HT_NN)
6851  {
6853  "::extractChanSkyFrqReading(): station " + stationName_ +
6854  ": got unexpected \"setup\" record (expected type #" + QString("").setNum(cs.getHwType()) +
6855  "); input: \"" + asciifyString(str) + "\"");
6857  };
6858 
6859  return true;
6860 };
6861 
6862 
6863 
6864 //
6865 bool SgStnLogCollector::extractVciReading(const QString& str, const QRegularExpressionMatch& match,
6866  SgMJD& t, const SgMJD& nearTheEnd, SgChannelSetup& cs, const SgMJD& tFirst)
6867 {
6868 //QString targetStr(str.mid(re.indexIn(str) + re.cap(1).size() +
6869 // re.cap(2).size() + 1));
6870  QString targetStr(str.mid(match.capturedEnd(2) + 1));
6871 
6872  if (!extractEpoch(str, t))
6873  return false;
6874 
6875  if (nearTheEnd <= t)
6876  return false;
6877 
6878  bool isOk;
6879  int cIdx;
6880  QString bbcId(match.captured(2));
6881  cIdx = bbcId.toInt(&isOk);
6882  if (!isOk)
6883  {
6885  "::extractVciReading(): station " + stationName_ +
6886  ": cannot convert \"" + bbcId + "\" to int; input: \"" + asciifyString(str) + "\"");
6887  return false;
6888  };
6889  //2016.236.17:21:21.92&setupsx/vci01=130.99,4r
6890  //2016.236.17:21:21.92&setupsx/vci02=140.99,4r
6891  QStringList lst=targetStr.split(",");
6892  if (2 <= lst.size())
6893  {
6894  double d;
6895  // video freq:
6896  d = lst.at(0).toDouble(&isOk);
6897  if (!isOk)
6898  {
6900  "::extractVciReading(): station " + stationName_ + ": cannot convert \"" + lst.at(0) +
6901  "\" to double; input: \"" + asciifyString(str) + "\"");
6902  return false;
6903  };
6904  // IFD ID:
6905  if (!cs.bbcFreqByIdx().contains(cIdx))
6906  cs.bbcFreqByIdx()[cIdx] = d;
6907  else if (cs.bbcFreqByIdx()[cIdx] != d &&
6908  tFirst < t)
6909  {
6911  "::extractVciReading(): station " + stationName_ +
6912  ": video frequency has changed for IF #" + bbcId + ": " +
6913  QString("").sprintf("%.2f => %.2f", cs.bbcFreqByIdx()[cIdx], d) +
6914  "; input: \"" + asciifyString(str) + "\"");
6915  cs.bbcFreqByIdx()[cIdx] = d;
6916  };
6917  // bandwidth:
6918  QString ss(lst.at(1));
6919  if (1 < ss.size())
6920  {
6921  QString pc(ss.at(ss.size() - 1));
6922  if (pc == "r")
6923  {
6924  cs.loPolarizationById()["a"] = CP_RightCP;
6925  cs.loPolarizationById()["b"] = CP_RightCP;
6926  }
6927  else if (pc == "l")
6928  {
6929  cs.loPolarizationById()["a"] = CP_LeftCP;
6930  cs.loPolarizationById()["b"] = CP_LeftCP;
6931  }
6932  else
6933  {
6934  cs.loPolarizationById()["a"] = CP_UNDEF;
6935  cs.loPolarizationById()["b"] = CP_UNDEF;
6936  };
6937 
6938  ss.chop(1);
6939  d = ss.toDouble(&isOk);
6940  if (!isOk)
6941  {
6943  "::extractVciReading(): station " + stationName_ + ": cannot convert \"" + lst.at(2) +
6944  "\" to double; input: \"" + asciifyString(str) + "\"");
6945  return false;
6946  };
6947  cs.bbcBandwidthByIdx()[cIdx] = d;
6948  };
6949 
6950  if (!cs.loIdByIdx().contains(cIdx))
6951  {
6952  cs.loIdByIdx()[cIdx] = "b";
6954  "::extractVciReading(): station " + stationName_ + ": found unused channel #" +
6955  QString("").sprintf("%02d", cIdx) +
6956  ", attached it to the LO \"b\"; input: \"" + asciifyString(str) + "\"");
6957  };
6958 
6959  //
6960  if (cs.getHwType() == SgChannelSetup::HT_UNDEF)
6962  else if (cs.getHwType() != SgChannelSetup::HT_NN)
6963  {
6965  "::extractVciReading(): station " + stationName_ +
6966  ": got unexpected \"vci\" record; input: \"" + asciifyString(str) + "\"");
6968  };
6969  }
6970  else
6971  {
6973  "::extractVciReading(): station " + stationName_ +
6974  ": the number of data less than 2; input: \"" + asciifyString(str) + "\"");
6975  return false;
6976  };
6977  return true;
6978 };
6979 
6980 
6981 
6982 //
6983 bool SgStnLogCollector::extractTsysReading(const QString& str, const QRegularExpression& reTsys,
6984  SgMJD& t, QMap<QString, float>& tSys, const SgMJD& tAtTheBegin)
6985 {
6986  bool isOk=false;
6987  float f;
6988  QRegularExpression reNoData("\\$+");
6989  QRegularExpression reNotASensor("i([0-9A-Za-z])+");
6990  QRegularExpression reDualSideBand("([0-9A-Za-z])+d");
6991 
6992 
6993  if (!extractEpoch(str, t))
6994  return false;
6995  if (t < tAtTheBegin)
6996  return false;
6997  //
6998  QRegularExpressionMatch match;
6999  QString tsysStr(str.mid(reTsys.match(str).capturedEnd(1)));
7000 
7001  if (!tsysStr.size())
7002  {
7004  "::extractTsysReading(): station " + stationName_ +
7005  ": cannot extract tsys data from \"" + asciifyString(str) + "\"");
7006 // ": cannot extract tsys data from \"" + str + "\"");
7007  return isOk;
7008  };
7009 
7010  QStringList lst=tsysStr.split(",");
7011  if (lst.size()%2)
7013  "::extractTsysReading(): station " + stationName_ +
7014  ": got odd number of tsys readings: \"" + asciifyString(str) + "\"");
7015 // ": got odd number of tsys readings: \"" + str + "\"");
7016 
7017  int numOfRecs=lst.size()/2;
7018  for (int i=0; i<numOfRecs; i++)
7019  {
7020  const QString &strIdx=lst.at(2*i);
7021  const QString &strVal=lst.at(2*i + 1);
7022  QString chanId(strIdx);
7023  if (strIdx.size())
7024  {
7025  if (strVal.size())
7026  {
7027  // skip the averages:
7028  if (!reNotASensor.match(strIdx).hasMatch())
7029  {
7030  if (reNoData.match(strVal).hasMatch())
7031  {
7032  f = -1.0;
7033  isOk = true;
7034  }
7035  else
7036  f = strVal.toFloat(&isOk);
7037  if (isOk)
7038  {
7039  QString sensorKey("");
7040  // special case for sensors with "dual" sideband:
7041  if ((match=reDualSideBand.match(strIdx)).hasMatch())
7042  {
7043  QString sss(match.captured(1));
7044  sensorKey = setupTpSensor(sss + "u", "extractTsysReading()");
7045  if (sensorKey.size())
7046  {
7047  tSys.insert(sensorKey, f);
7048  if (!logReadings_.channelSetup().origSensorIdById().contains(strIdx) ||
7049  (logReadings_.channelSetup().origSensorIdById().contains(strIdx) &&
7050  logReadings_.channelSetup().origSensorIdById().value(strIdx).size()<2))
7051  logReadings_.channelSetup().origSensorIdById()[strIdx].append(sss + "u");
7052  };
7053  sensorKey = setupTpSensor(sss + "l", "extractTsysReading()");
7054  if (sensorKey.size())
7055  {
7056  tSys.insert(sensorKey, f);
7057  if (!logReadings_.channelSetup().origSensorIdById().contains(strIdx) ||
7058  (logReadings_.channelSetup().origSensorIdById().contains(strIdx) &&
7059  logReadings_.channelSetup().origSensorIdById().value(strIdx).size()<2))
7060  logReadings_.channelSetup().origSensorIdById()[strIdx].append(sss + "l");
7061  };
7062  }
7063  else // regular sensors:
7064  {
7065  sensorKey = setupTpSensor(strIdx, "extractTsysReading()");
7066  if (sensorKey.size())
7067  tSys.insert(sensorKey, f);
7068  };
7069  };
7070  };
7071  }
7072  else
7074  "::extractTsysReading(): station " + stationName_ + ": tsysVal #" + QString("").setNum(i) +
7075  " is empty of tsys readings: \"" + asciifyString(str) + "\"");
7076 // " is empty of tsys readings: \"" + str + "\"");
7077  }
7078  else
7080  "::extractTsysReading(): station " + stationName_ + ": chanKey #" + QString("").setNum(i) +
7081  " is empty of tsys readings: \"" + asciifyString(str) + "\"");
7082 // " is empty of tsys readings: \"" + str + "\"");
7083  };
7084  return isOk;
7085 };
7086 
7087 
7088 
7089 //
7090 bool SgStnLogCollector::extractTsysVgosReading(const QString& str, const QRegularExpression& reTsys,
7091  SgMJD& t, QMap<QString, float>& tSys, const SgMJD& tAtTheBegin)
7092 {
7093  bool isOk=false;
7094  float f;
7095  QRegularExpression reNoData("\\$+");
7096  QRegularExpression reNoChan("(AV|SM)(\\w)(\\d)");
7097 
7098  if (!extractEpoch(str, t))
7099  return false;
7100  if (t < tAtTheBegin)
7101  return false;
7102 
7103  QString tsysStr(str.mid(reTsys.match(str).capturedEnd(1)));
7104 
7105  if (!tsysStr.size())
7106  {
7108  "::extractTsysVgosReading(): station " + stationName_ +
7109  ": cannot extract tsys data from \"" + asciifyString(str) + "\"");
7110 // ": cannot extract tsys data from \"" + str + "\"");
7111  return isOk;
7112  };
7113 
7114  QStringList lst=tsysStr.split(",");
7115  if (lst.size()%2)
7117  "::extractTsysVgosReading(): station " + stationName_ +
7118  ": got odd number of tsys readings: \"" + asciifyString(str) + "\"");
7119 // ": got odd number of tsys readings: \"" + str + "\"");
7120 
7121 //2020.021.18:15:39.17#rdtcb#tsys/ 00b0, 53.5, 01b0, 43.6, 02b0, 40.5, 03b0, 41.6, 04b0, 42.7, 05b0, 44.6, 06b0, 44.7, 07b0, 45.6
7122 //2020.021.18:15:39.17#rdtcb#tsys/ 08b0, 46.8, 09b0, 47.7, 10b0, 47.4, 11b0, 50.9, 12b0, 47.7, 13b0, 43.1, 14b0, 46.6, 15b0, 50.2
7123 //2020.021.18:15:39.17#rdtcb#tsys/ AVb0, 45.8, SMb0, 45.7
7124 //2020.021.18:15:39.17#rdtcb#tsys/ 00b1, 53.2, 01b1, 49.8, 02b1, 49.1, 03b1, 49.4, 04b1, 49.5, 05b1, 52.1, 06b1, 53.8, 07b1, 54.7
7125 //2020.021.18:15:39.17#rdtcb#tsys/ 08b1, 57.8, 09b1, 50.6, 10b1, 52.5, 11b1, 49.5, 12b1, 52.3, 13b1, 48.5, 14b1, 48.3, 15b1, 49.5
7126 //2020.021.18:15:39.17#rdtcb#tsys/ AVb1, 51.2, SMb1, 51.2
7127 
7128  int numOfRecs=lst.size()/2;
7129  for (int i=0; i<numOfRecs; i++)
7130  {
7131  const QString &strIdx=lst.at(2*i);
7132  const QString &strVal=lst.at(2*i + 1);
7133  if (strIdx.size())
7134  {
7135  if (strVal.size())
7136  {
7137  // skip the averages:
7138  if (!reNoChan.match(strIdx).hasMatch() && !reNoData.match(strIdx).hasMatch())
7139  {
7140  if (reNoData.match(strVal).hasMatch())
7141  {
7142  f = -1.0;
7143  isOk = true;
7144  }
7145  else
7146  f = strVal.toFloat(&isOk);
7147  //
7148  if (isOk)
7149  {
7150  QString sensorKey=setupTpSensor(strIdx, "extractTsysVgosReading()");
7151  if (sensorKey.size())
7152  tSys.insert(sensorKey, f);
7153  };
7154  };
7155  }
7156  else
7158  "::extractTsysVgosReading(): station " + stationName_ + ": tsysVal #" + QString("").setNum(i) +
7159  " is empty of tsys readings: \"" + asciifyString(str) + "\"");
7160  }
7161  else
7163  "::extractTsysVgosReading(): station " + stationName_ + ": chanKey #" + QString("").setNum(i) +
7164  " is empty of tsys readings: \"" + asciifyString(str) + "\"");
7165  };
7166 
7170  {
7172  "::extractTsysVgosReading(): station " + stationName_ +
7173  ": got an unexpected \"bbc\" record; input: \"" + asciifyString(str) + "\"");
7175  };
7176 
7177  return isOk;
7178 };
7179 
7180 
7181 
7182 //
7183 QString SgStnLogCollector::setupTpSensor(const QString& sensorTag, const QString& callerName)
7184 {
7185  const double rdbeChannelBandwidth=32.0;
7186 // DBBC3:
7187 //2020.201.05:14:29.04#onoff#VAL casa 290.1 70.9 001l 1 l 3464.40 1.1078 65.39 2466.4 64.613 1.02
7188 // detector ID: "001l -- 064l, 001u -- 064u:
7189 //
7190 // RDBE:
7191 //2021.028.15:55:34.15#rdtcc#tpcont/ 00c0, 23583, 22926, 01c0, 36283, 35218, 02c0, 41679, 40468, 03c0, 41843, 40647, 04c0, 44458, 43162
7192 // detector ID: "00c0 -- 15c0, 00c1 -- 15c1, ..."
7193 //
7194 //2021.004.16:11:41.88#onoff# source Az El De I P Center Comp Tsys SEFD Tcal(j) Tcal(r)
7195 //2021.004.16:11:41.88#onoff#VAL virgoa 177.3 80.1 1l 1 r 8208.99 0.9961 109.6 2523.7 126.611 0.03
7196 
7198  double loFreq=-9999.9, ifFreq=-9999.9, ifBw=-9.9;
7202  QString chanId(sensorTag.simplified().rightJustified(6, ' '));
7203  QString loId;
7204  QChar cSideBand('-');
7205  QString sFreqSfx(""), sPlrzSfx("x"), sLoSBndSfx("x"), sIfSBndSfx("x");
7206  bool isOk;
7207  int sensorIdx;
7208 
7210  {
7211  QString cPlrz=sensorTag.at(sensorTag.size() - 1);
7212  QString cBand=sensorTag.at(sensorTag.size() - 2);
7213  QString sIdx =sensorTag.left(sensorTag.size() - 2);
7214  loId = QString(cBand) + cPlrz;
7215  //
7216  int offset;
7217  //
7218  if (cBand == 'a')
7219  offset = 0;
7220  else if (cBand == 'b')
7221  offset = 16;
7222  else if (cBand == 'c')
7223  offset = 32;
7224  else if (cBand == 'd')
7225  offset = 48;
7226  else if (cBand == 'e')
7227  offset = 64;
7228  else if (cBand == 'f')
7229  offset = 80;
7230  else if (cBand == 'g')
7231  offset = 96;
7232  else if (cBand == 'h')
7233  offset =112;
7234  else
7235  {
7236  offset = 0;
7238  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7239  ": get unexpected LO key \"" + cBand +
7240  "\"; the tag is \"" + asciifyString(sensorTag) + "\"");
7241  return "";
7242  };
7243  sensorIdx = 0;
7244  sensorIdx = sIdx.toInt(&isOk);
7245  if (isOk)
7246  sensorIdx += offset;
7247  else
7248  {
7250  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7251  ": cannot convert \"" + sIdx + "\" to int; the tag is \"" +
7252  asciifyString(sensorTag) + "\", VGOS");
7253  return "";
7254  };
7255  //
7256  if (cPlrz == '0')
7257  loPlrz = CP_HorizontalLP;
7258  else if (cPlrz == '1')
7259  loPlrz = CP_VerticalLP;
7260  else
7261  {
7262  loPlrz = CP_UNDEF;
7264  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7265  ": cannot figure out RDBE polarization from \"" + cPlrz + "\"; the tag is: \"" +
7266  asciifyString(sensorTag) + "\"");
7267  };
7268  // there is no channel setup:
7269  if (stationName_ == "ISHIOKA ")
7270  ifFreq = 512.0 + rdbeChannelBandwidth/2.0 + rdbeChannelBandwidth*(sensorIdx%16);
7271  else
7272  ifFreq = 512.0 + rdbeChannelBandwidth/2.0 + rdbeChannelBandwidth*(15 - sensorIdx%16);
7273  //
7274  ifSBnd = CSB_USB;
7275  //
7276  ifBw = rdbeChannelBandwidth;
7277  }
7278  else //
7279  {
7280  QString sIdx=sensorTag.left(sensorTag.size() - 1);
7281  cSideBand = sensorTag.at(sensorTag.size() - 1);
7282  //
7285  {
7286  sensorIdx = sIdx.toInt(&isOk);
7287  if (!isOk)
7288  sensorIdx = sIdx.toInt(&isOk, 16); //?
7289  }
7290  else
7291  sensorIdx = sIdx.toInt(&isOk, 16);
7292  if (!isOk)
7293  {
7295  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7296  ": cannot convert \"" + sIdx + "\" to int; the tag is \"" +
7297  sensorTag + "\", other");
7298  return "";
7299  };
7300  // LO id:
7301  if (cs.loIdByIdx().contains(sensorIdx))
7302  loId = cs.loIdByIdx()[sensorIdx];
7303  else
7304  {
7306  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7307  ": cannot find LO id for the sensorIdx " + QString("").setNum(sensorIdx) +
7308  "; the tag is \"" + sensorTag + "\"");
7309  return "";
7310  };
7311  //
7312  if (cs.loPolarizationById().contains(loId))
7313  loPlrz = cs.loPolarizationById().value(loId);
7314  else
7315  {
7317  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7318  ": LO polarization for LO \"" + loId + "\" is not defined; the tag is: \"" +
7319  asciifyString(sensorTag) + "\"");
7320  return "";
7321  };
7322  //
7323  // if frequency:
7324  if (cs.bbcFreqByIdx().contains(sensorIdx))
7325  ifFreq = cs.bbcFreqByIdx()[sensorIdx];
7326  else
7327  {
7329  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7330  ": cannot find BBC frequency for the sensorIdx " + QString("").setNum(sensorIdx) +
7331  "; the tag is \"" + sensorTag + "\"");
7332  return "";
7333  };
7334  // if bandwidth:
7335  if (cs.bbcBandwidthByIdx().contains(sensorIdx))
7336  ifBw = cs.bbcBandwidthByIdx()[sensorIdx];
7337  else
7338  {
7340  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7341  ": cannot find BBC bandwidth for the sensorIdx " + QString("").setNum(sensorIdx) +
7342  "; the tag is \"" + sensorTag + "\"");
7343  return "";
7344  };
7345  // if sideband:
7346  if (cSideBand.toLower() == 'u')
7347  ifSBnd = CSB_USB;
7348  else if (cSideBand.toLower() == 'l')
7349  ifSBnd = CSB_LSB;
7350  else if (cSideBand.toLower() == 'd')
7351  ifSBnd = CSB_DUAL;
7352  else
7353  {
7355  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7356  ": cannot guess sideband; the tag is \"" + sensorTag + "\"");
7357  return "";
7358  };
7359  };
7360  //
7361  //
7362  //
7363  // collect the current LO setup:
7364  if (cs.loFreqById().contains(loId))
7365  loFreq = cs.loFreqById().value(loId);
7366  else
7368  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7369  ": LO frequency for LO \"" + loId + "\" is not defined; the tag is: \"" +
7370  asciifyString(sensorTag) + "\"");
7371 
7372  if (cs.loSideBandById().contains(loId))
7373  loSBnd = cs.loSideBandById().value(loId);
7374  else
7376  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7377  ": LO sideband for LO \"" + loId + "\" is not defined; the tag is: \"" +
7378  asciifyString(sensorTag) + "\"");
7379  //
7380  //
7381  //
7382  //
7383  // generate the strings:
7384  double skyFrq;
7385  skyFrq = SgChannelSetup::calcSkyFreq(loFreq, ifFreq, ifBw, loSBnd, ifSBnd);
7386  sFreqSfx.sprintf("%08.1f-%08.1f:%05.1f", loFreq, ifFreq, ifBw);
7387  sPlrzSfx = polarization2Str(loPlrz);
7388  sLoSBndSfx = sideBand2Str(loSBnd);
7389  sIfSBndSfx = sideBand2Str(ifSBnd);
7390  //
7391  // ok.
7392 
7393  // set up channel key (for sorting):
7394  QString sensorKey("");
7395  sensorKey.sprintf("%08.1f-", skyFrq);
7396 //sensorKey = sFreqSfx + '-' + sPlrzSfx + '-' + sLoSBndSfx + '-' + sIfSBndSfx + '-' + loId + '-' + chanId;
7397  sensorKey += sPlrzSfx + '-' + loId + '-' + sLoSBndSfx + '-' + sIfSBndSfx + '-' + chanId + '-' + sFreqSfx;
7398 
7399  //
7400  // set up time-varying info:
7401  //
7402  // LO id:
7403  if (loId.size())
7404  {
7405  if (cs.loIdBySensorKey().contains(sensorKey))
7406  {
7407  // check:
7408  if (cs.loIdBySensorKey()[sensorKey] != loId)
7409  {
7411  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7412  ": got new LO ID \"" + loId + "\" for sensor key \"" + sensorKey +
7413  "\", the previous one is \"" + cs.loIdBySensorKey()[sensorKey] +
7414  "\"; the tag is \"" + asciifyString(sensorTag) + "\"");
7415  cs.loIdBySensorKey()[sensorKey] = loId;
7416  };
7417  }
7418  else
7419  cs.loIdBySensorKey()[sensorKey] = loId;
7420  };
7421  // LO freq:
7422  if (-1.0 < loFreq)
7423  {
7424  if (cs.loFreqBySensorKey().contains(sensorKey))
7425  {
7426  // check:
7427  if (cs.loFreqBySensorKey()[sensorKey] != loFreq)
7428  {
7430  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7431  ": got new LO frequency " +
7432  QString("").sprintf("%8.1f", loFreq) + " for sensor \"" +
7433  chanId + "\", with the sensor key \"" + sensorKey +
7434  "\", the previous one is " +
7435  QString("").sprintf("%8.1f", cs.loFreqBySensorKey()[sensorKey]) +
7436  "; the tag is \"" + asciifyString(sensorTag) + "\"");
7437  cs.loFreqBySensorKey()[sensorKey] = loFreq;
7438  };
7439  }
7440  else
7441  cs.loFreqBySensorKey()[sensorKey] = loFreq;
7442  };
7443  //
7444  // LO sideband:
7445  if (cs.loSideBandBySensorKey().contains(sensorKey))
7446  {
7447  // check:
7448  if (cs.loSideBandBySensorKey()[sensorKey] != loSBnd)
7449  {
7451  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7452  ": got new LO sideband " +
7453  sideBand2Str(loSBnd) + " for sensor \"" +
7454  chanId + "\", with the sensor key \"" + sensorKey +
7455  "\", the previous one is " +
7456  sideBand2Str(cs.loSideBandBySensorKey()[sensorKey]) +
7457  "; the tag is \"" + asciifyString(sensorTag) + "\"");
7458  cs.loSideBandBySensorKey()[sensorKey] = loSBnd;
7459  };
7460  }
7461  else
7462  cs.loSideBandBySensorKey()[sensorKey] = loSBnd;
7463  //
7464  // LO polarization:
7465  if (cs.loPolarizationBySensorKey().contains(sensorKey))
7466  {
7467  // check:
7468  if (cs.loPolarizationBySensorKey()[sensorKey] != loPlrz)
7469  {
7471  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7472  ": got new LO polarization " +
7473  polarization2Str(loPlrz) + " for sensor \"" +
7474  chanId + "\", with the sensor key \"" + sensorKey +
7475  "\", the previous one is " +
7476  polarization2Str(cs.loPolarizationBySensorKey()[sensorKey]) +
7477  "; the tag is \"" + asciifyString(sensorTag) + "\"");
7478  cs.loPolarizationBySensorKey()[sensorKey] = loPlrz;
7479  };
7480  }
7481  else
7482  cs.loPolarizationBySensorKey()[sensorKey] = loPlrz;
7483  //
7484  // IF frequency:
7485  if (-1.0 < ifFreq)
7486  {
7487  if (cs.ifFreqBySensorKey().contains(sensorKey))
7488  {
7489  // check:
7490  if (cs.ifFreqBySensorKey()[sensorKey] != ifFreq)
7491  {
7493  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7494  ": got new IF frequency " +
7495  QString("").sprintf("%8.1f", ifFreq) + " for sensor \"" +
7496  chanId + "\", with the sensor key \"" + sensorKey +
7497  "\", the previous one is " +
7498  QString("").sprintf("%8.1f", cs.ifFreqBySensorKey()[sensorKey]) +
7499  "; the tag is \"" + asciifyString(sensorTag) + "\"");
7500  cs.ifFreqBySensorKey()[sensorKey] = ifFreq;
7501  };
7502  }
7503  else
7504  cs.ifFreqBySensorKey()[sensorKey] = ifFreq;
7505  };
7506  // IF bandwidth:
7507  if (-1.0 < ifBw)
7508  {
7509  if (cs.ifBandwidthBySensorKey().contains(sensorKey))
7510  {
7511  // check:
7512  if (cs.ifBandwidthBySensorKey()[sensorKey] != ifBw)
7513  {
7515  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7516  ": got new IF bandwidth " +
7517  QString("").sprintf("%8.1f", ifBw) + " for sensor \"" +
7518  chanId + "\", with the sensor key \"" + sensorKey +
7519  "\", the previous one is " +
7520  QString("").sprintf("%8.1f", cs.ifBandwidthBySensorKey()[sensorKey]) +
7521  "; the tag is \"" + asciifyString(sensorTag) + "\"");
7522  cs.ifBandwidthBySensorKey()[sensorKey] = ifBw;
7523  };
7524  }
7525  else
7526  cs.ifBandwidthBySensorKey()[sensorKey] = ifBw;
7527  };
7528  //
7529  // IF id:
7530  if (cs.ifIdBySensorKey().contains(sensorKey))
7531  {
7532  // check:
7533  if (cs.ifIdBySensorKey()[sensorKey] != chanId)
7534  {
7536  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7537  ": got new ID, " +
7538  chanId + ", for the channel key \"" + sensorKey +
7539  "\", the previous one is " + cs.ifIdBySensorKey()[sensorKey] +
7540  "; the tag is \"" + asciifyString(sensorTag) + "\"");
7541  cs.ifIdBySensorKey()[sensorKey] = chanId;
7542  };
7543  }
7544  else
7545  cs.ifIdBySensorKey()[sensorKey] = chanId;
7546  //
7547  //
7548  // done with time varying setup
7549  //
7550  //
7551  // IF index:
7552  if (cs.ifIdxById().contains(chanId))
7553  {
7554  // check:
7555  if (cs.ifIdxById()[chanId] != sensorIdx)
7556  {
7558  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7559  ": got new value, " +
7560  QString("").setNum(sensorIdx) + ", for the channel id \"" + chanId +
7561  "\", the previous one is " +
7562  QString("").setNum(cs.ifIdxById()[chanId]) +
7563  "; the tag is \"" + asciifyString(sensorTag) + "\"");
7564  cs.ifIdxById()[chanId] = sensorIdx;
7565  };
7566  }
7567  else
7568  cs.ifIdxById()[chanId] = sensorIdx;
7569  //
7570  //
7571  // LO id:
7572 // if (!cs.loIdByIdx().contains(sensorIdx))
7573 // cs.loIdByIdx()[sensorIdx] = loId;
7574  //
7575  //
7576  if (ifSBnd != CSB_UNDEF)
7577  {
7578  if (cs.ifSideBandById().contains(chanId))
7579  {
7580  // check:
7581  if (cs.ifSideBandById()[chanId] != ifSBnd)
7582  {
7584  "::setupTpSensor(): station " + stationName_ + ", caller " + callerName +
7585  ": got new sideband, " +
7586  sideBand2Str(ifSBnd) + ", for the channel id \"" + chanId +
7587  "\", the previous one is " +
7588  sideBand2Str(cs.ifSideBandById()[chanId]) +
7589  "; the tag is \"" + asciifyString(sensorTag) + "\"");
7590  cs.ifSideBandById()[chanId] = ifSBnd;
7591  };
7592  }
7593  else
7594  cs.ifSideBandById()[chanId] = ifSBnd;
7595  };
7596  //
7597 
7598  return sensorKey;
7599 };
7600 
7601 
7602 
7603 //
7604 bool SgStnLogCollector::extractTpcontVgosReading(const QString& str, const QRegularExpression& reTpcont,
7605  SgMJD& t, QMap<QString, QVector<int> >& tPcont, const SgMJD& tAtTheBegin)
7606 // SgMJD& t, QMap<char*, int*>& tPcont, const SgMJD& tAtTheBegin)
7607 {
7608  bool isOk=false;
7609  int nOn, nOf;
7610  QRegularExpression reNoData("\\$+");
7611  QVector<int> v(2);
7612 
7613  //
7614  if (!extractEpoch(str, t))
7615  return false;
7616  if (t < tAtTheBegin)
7617  return false;
7618 
7619  QString tpcontStr(str.mid(reTpcont.match(str).capturedEnd(1)));
7620 
7621  if (!tpcontStr.size())
7622  {
7624  "::extractTpcontVgosReading(): station " + stationName_ +
7625  ": cannot extract tpcont data from \"" + asciifyString(str) + "\"");
7626 // ": cannot extract tpcont data from \"" + str + "\"");
7627  return isOk;
7628  };
7629 
7630  QStringList lst=tpcontStr.split(",");
7631  if (lst.size()%3)
7633  "::extractTpcontVgosReading(): station " + stationName_ +
7634  ": got odd number of tpcont readings: \"" + asciifyString(str) + "\"");
7635 // ": got odd number of tpcont readings: \"" + str + "\"");
7636 
7637  //2020.021.18:00:00.17#rdtcd#tpcont/ 00d0, 12501, 12325, 01d0, 16054, 15765, 02d0, 20774, 20410, 03d0, 24388, 23985, 04d0, 27599, 27153
7638  //2020.021.18:00:00.17#rdtcd#tpcont/ 05d0, 28085, 27647, 06d0, 29475, 29027, 07d0, 30963, 30479, 08d0, 29392, 28953, 09d0, 30078, 29643
7639  //2020.021.18:00:00.17#rdtcd#tpcont/ 10d0, 37494, 36960, 11d0, 42335, 41705, 12d0, 46499, 45802, 13d0, 51354, 50535, 14d0, 49839, 48925
7640  //2020.021.18:00:00.17#rdtcd#tpcont/ 15d0, 43153, 42272
7641  //2020.021.18:00:00.17#rdtcd#tpcont/ 00d1, 11542, 11379, 01d1, 13078, 12877, 02d1, 16776, 16491, 03d1, 22232, 21871, 04d1, 27568, 27119
7642  //2020.021.18:00:00.17#rdtcd#tpcont/ 05d1, 26698, 26274, 06d1, 26024, 25611, 07d1, 27530, 27137, 08d1, 33180, 32491, 09d1, 32567, 32122
7643  //2020.021.18:00:00.17#rdtcd#tpcont/ 10d1, 42659, 42099, 11d1, 46937, 46283, 12d1, 50407, 49687, 13d1, 56087, 55247, 14d1, 56042, 55150
7644  //2020.021.18:00:00.17#rdtcd#tpcont/ 15d1, 47024, 46233
7645 
7646  int numOfRecs=lst.size()/3;
7647  for (int i=0; i<numOfRecs; i++)
7648  {
7649  const QString &strIdx=lst.at(3*i);
7650  const QString &strValOn=lst.at(3*i + 1);
7651  const QString &strValOf=lst.at(3*i + 2);
7652  //
7653  if (strIdx.size() && strValOn.size() && strValOf.size())
7654  {
7655  if (reNoData.match(strValOn).hasMatch())
7656  {
7657  nOn = -1;
7658  isOk = true;
7659  }
7660  else
7661  nOn = strValOn.toInt(&isOk);
7662 
7663  if (isOk && reNoData.match(strValOf).hasMatch())
7664  {
7665  nOf = -1;
7666  isOk = true;
7667  }
7668  else
7669  nOf = strValOf.toInt(&isOk);
7670  //
7671  if (isOk)
7672  {
7673  QString sensorKey=setupTpSensor(strIdx, "extractTpcontVgosReading()");
7674  //
7675  v[0] = nOn;
7676  v[1] = nOf;
7677  if (sensorKey.size())
7678  tPcont.insert(sensorKey, QVector<int>(v));
7679  };
7680  }
7681  else
7682  {
7683  if (strIdx.size() == 0)
7685  "::extractTpcontVgosReading(): station " + stationName_ + ": chanKey #" + QString("").setNum(i) +
7686  " is empty of tpcont readings: \"" + asciifyString(str) + "\"");
7687 // " is empty of tpcont readings: \"" + str + "\"");
7688  if (strValOn.size())
7690  "::extractTpcontVgosReading(): station " + stationName_ + ": tpcalon #" + QString("").setNum(i) +
7691  " is empty of tpcont readings: \"" + asciifyString(str) + "\"");
7692 // " is empty of tpcont readings: \"" + str + "\"");
7693  if (strValOf.size())
7695  "::extractTpcontVgosReading(): station " + stationName_ + ": tpcaloff #" + QString("").setNum(i) +
7696  " is empty of tpcont readings: \"" + asciifyString(str) + "\"");
7697 // " is empty of tpcont readings: \"" + str + "\"");
7698  };
7699  };
7700 
7704  {
7706  "::extractTpcontVgosReading(): station " + stationName_ +
7707  ": got an unexpected \"bbc\" record; input: \"" + asciifyString(str) + "\"");
7709  };
7710 
7711  return isOk;
7712 };
7713 
7714 
7715 
7716 //
7717 bool SgStnLogCollector::extractPcalVgosReading(const QString& str, const QRegularExpression& rePcal,
7718  SgMJD& t, QMap<QString, float*>& pcal, const SgMJD& tAtTheBegin)
7719 {
7720  bool isOk=false;
7721  float dAmp, dPhs;
7722  int idx;
7723  QRegularExpression reNoData("\\$+");
7724 // SgVector v(2);
7725 
7726  //
7727  if (!extractEpoch(str, t))
7728  return false;
7729  if (t < tAtTheBegin)
7730  return false;
7731 
7732  QString pcalStr(str.mid(rePcal.match(str).capturedEnd(1)));
7733 
7734  if (!pcalStr.size())
7735  {
7737  "::extractPcalVgosReading(): station " + stationName_ +
7738  ": cannot extract tpcont data from \"" + asciifyString(str) + "\"");
7739 // ": cannot extract tpcont data from \"" + str + "\"");
7740  return isOk;
7741  };
7742 
7743  QStringList lst=pcalStr.split(",");
7744  if (lst.size()%3)
7746  "::extractPcalVgosReading(): station " + stationName_ +
7747  ": got odd number of tpcont readings: \"" + asciifyString(str) + "\"");
7748 // ": got odd number of tpcont readings: \"" + str + "\"");
7749 
7750  //2020.195.11:30:01.17#rdtca#pcal/ 1a0000, 8.686, -98.7, 1a0005, 78.913, 116.7, 1a0010, 8.729, 147.9, 1a0015, 81.273, 4.1
7751  //2020.195.11:30:01.17#rdtca#pcal/ 1a0020, 9.421, 37.5, 1a0025, 88.580, -105.5, 1a0030, 10.177, -72.2, 1a0035, 97.212, 144.1
7752  //2020.195.11:30:01.17#rdtca#pcal/ 1a0040, 11.646, 176.3, 1a0045, 89.248, 33.1, 1a0050, 10.577, 65.5, 1a0055, 93.330, -79.2
7753  //2020.195.11:30:01.17#rdtca#pcal/ 1a0060, 10.255, -47.4, 1a0065, 93.203, 169.1, 1a0070, 10.437, -155.9, 1a0075, 89.414, 59.5
7754  //2020.195.11:30:01.17#rdtca#pcal/ 1a0080, 10.014, 92.8, 1a0085, 84.492, -47.7, 1a0090, 9.561, -14.2, 1a0095, 82.770, -155.3
7755  //2020.195.11:30:01.17#rdtca#pcal/ 1a0100, 8.782, -120.1, 1a0105, 79.763, 101.6, 1a0110, 8.836, 137.8, 1a0115, 77.939, -3.8
7756  //2020.195.11:30:01.17#rdtca#pcal/ 1a0120, 8.740, 32.5, 1a0125, 73.421, -105.2, 1a0130, 8.134, -68.7, 1a0135, 74.094, 150.8
7757  //2020.195.11:30:01.17#rdtca#pcal/ 1a0140, 7.557, -168.7, 1a0145, 69.966, 50.6, 1a0150, 7.977, 88.8, 1a0155, 72.224, -54.9
7758  //2020.195.11:30:01.17#rdtca#pcal/ 1a0160, 8.275, -19.4, 1a0165, 74.537, -158.0, 1a0170, 8.204, -123.8, 1a0175, 72.798, 88.5
7759  //2020.195.11:30:01.17#rdtca#pcal/ 1a0180, 8.256, 131.2, 1a0185, 73.794, -6.5, 1a0190, 7.957, 28.8, 1a0195, 74.957, -109.7
7760  //2020.195.11:30:01.17#rdtca#pcal/ 1a0200, 8.315, -75.6, 1a0205, 73.965, 144.7, 1a0210, 8.324, 179.7, 1a0215, 74.379, 38.9
7761 
7762  int numOfRecs=lst.size()/3;
7763  for (int i=0; i<numOfRecs; i++)
7764  {
7765  const QString &strIdx=lst.at(3*i).simplified();
7766  const QString &strValAm=lst.at(3*i + 1);
7767  const QString &strValPh=lst.at(3*i + 2);
7768  QString chanId(strIdx.simplified().rightJustified(8, ' '));
7769 
7770  //
7771  if (strIdx.size() && strValAm.size() && strValPh.size())
7772  {
7773  if (reNoData.match(strValAm).hasMatch())
7774  {
7775  dAmp = -1.0;
7776  isOk = true;
7777  }
7778  else
7779  dAmp = strValAm.toFloat(&isOk);
7780 
7781  if (isOk && reNoData.match(strValPh).hasMatch())
7782  {
7783  dPhs = -1.0;
7784  isOk = true;
7785  }
7786  else
7787  dPhs = strValPh.toFloat(&isOk);
7788  //
7789  if (isOk)
7790  {
7791  QChar cPlrz(strIdx.at(0));
7792  QChar cBand(strIdx.at(1));
7793  int offset;
7794  if (cBand == 'a')
7795  offset = 0;
7796  else if (cBand == 'b')
7797  offset = 16;
7798  else if (cBand == 'c')
7799  offset = 32;
7800  else if (cBand == 'd')
7801  offset = 48;
7802  else
7803  offset =100;
7804 
7805  if (cPlrz == '0')
7807  else if (cPlrz == '1')
7809  else
7810  {
7813  "::extractPcalVgosReading(): station " + stationName_ +
7814  ": cannot figure out polarization from \"" + strIdx.at(strIdx.size() - 1) +
7815  "\"; input: \"" + asciifyString(str) + "\"");
7816  };
7817  //
7818  idx = strIdx.mid(2).toInt(&isOk);
7819  if (isOk)
7820  {
7821  idx += offset;
7822  //
7823  // set up channel key (for sorting):
7824  QString chanKey("");
7825  // simple yet
7826  chanKey = cBand + '-' + cPlrz + '-' + chanId;
7827  //
7828  if (logReadings_.channelSetup().pcalIdByKey().contains(chanKey))
7829  {
7830  // check:
7831  if (logReadings_.channelSetup().pcalIdByKey()[chanKey] != chanId)
7832  {
7834  "::extractPcalVgosReading(): station " + stationName_ + ": get new id, " +
7835  chanId + ", for the channel key \"" + chanKey +
7836  "\", the previous one is " +
7837  logReadings_.channelSetup().pcalIdByKey()[chanKey] +
7838  "; input: \"" + asciifyString(str) + "\"");
7839  logReadings_.channelSetup().pcalIdByKey()[chanKey] = chanId;
7840  };
7841  }
7842  else
7843  logReadings_.channelSetup().pcalIdByKey()[chanKey] = chanId;
7844  //
7845  float *f=new float[2];
7846  *f = dAmp;
7847  *(f+1) = dPhs;
7848 // pcal.insert(chanId, f);
7849  pcal.insert(logReadings_.channelSetup().pcalIdByKey()[chanKey], f);
7850 
7851  }
7852  else
7854  "::extractPcalVgosReading(): station " + stationName_ + ": cannot convert str \"" +
7855  strIdx.mid(2) + "\" to int; input: \"" + asciifyString(str) + "\"");
7856  };
7857  }
7858  else
7859  {
7860  if (strIdx.size() == 0)
7862  "::extractPcalVgosReading(): station " + stationName_ + ": sensorKey #" + QString("").setNum(i) +
7863  " is empty of tpcont readings: \"" + asciifyString(str) + "\"");
7864 // " is empty of tpcont readings: \"" + str + "\"");
7865  if (strValAm.size())
7867  "::extractPcalVgosReading(): station " + stationName_ + ": amplitude #" + QString("").setNum(i) +
7868  " is empty of tpcont readings: \"" + asciifyString(str) + "\"");
7869 // " is empty of tpcont readings: \"" + str + "\"");
7870  if (strValPh.size())
7872  "::extractPcalVgosReading(): station " + stationName_ + ": phase #" + QString("").setNum(i) +
7873  " is empty of tpcont readings: \"" + asciifyString(str) + "\"");
7874 // " is empty of tpcont readings: \"" + str + "\"");
7875  };
7876  };
7877  return isOk;
7878 };
7879 
7880 
7881 
7882 //
7884  const QRegularExpressionMatch& match, SgMJD& t, QString& sKey, float& dot2gps,
7885  const SgMJD& tAtTheBegin)
7886 {
7887  bool isOk=false;
7888  float f;
7889  //
7890  if (!extractEpoch(str, t))
7891  return false;
7892  if (t < tAtTheBegin)
7893  return false;
7894 
7895  sKey = match.captured(1);
7896 //QString cap2(match.captured(2));
7897  QString cap3(match.captured(2));
7898 
7899  f = cap3.toFloat(&isOk);
7900  if (isOk)
7901  dot2gps = f;
7902  else
7904  "::extractDot2xpsVgosReading(): station " + stationName_ + ": cannot convert \"" + cap3 +
7905  "\" to double; input: \"" + asciifyString(str) + "\"");
7906 
7907  return isOk;
7908 };
7909 
7910 
7911 
7912 
7913 
7914 //
7915 bool SgStnLogCollector::extractTraklReading(const QString& str, const QRegularExpressionMatch& match,
7916  SgMJD& t, SgTraklReading& tr, const SgMJD& tAtTheBegin)
7917 {
7918  bool isOk=false;
7919  double d;
7920  QString s("");
7921 
7922  if (!extractEpoch(str, t))
7923  return false;
7924  if (t < tAtTheBegin)
7925  return false;
7926 // 1 2 3 4 5 6 7
7927 //2020.203.18:21:45.11#trakl#[az 10.0149 el 50.0437 azv 0.00000000 elv 0.00000000 mjd 59051 s 66104 ms 980 ]
7928 
7929  tr.setT(t);
7930  //
7931  if ((s=match.captured(1)).size())
7932  {
7933  d = s.toDouble(&isOk);
7934  if (!isOk)
7936  "::extractTraklReading(): station " + stationName_ +
7937  ": cannot convert to double: \"" + s + "\"; input: \"" + asciifyString(str) + "\"");
7938  else
7939  tr.setAz(d);
7940  };
7941  if ((s=match.captured(2)).size())
7942  {
7943  d = s.toDouble(&isOk);
7944  if (!isOk)
7946  "::extractTraklReading(): station " + stationName_ +
7947  ": cannot convert to double: \"" + s + "\"; input: \"" + asciifyString(str) + "\"");
7948  else
7949  tr.setEl(d);
7950  };
7951  if ((s=match.captured(3)).size())
7952  {
7953  d = s.toDouble(&isOk);
7954  if (!isOk)
7956  "::extractTraklReading(): station " + stationName_ +
7957  ": cannot convert to double: \"" + s + "\"; input: \"" + asciifyString(str) + "\"");
7958  else
7959  tr.setAzv(d);
7960  };
7961  if ((s=match.captured(4)).size())
7962  {
7963  d = s.toDouble(&isOk);
7964  if (!isOk)
7966  "::extractTraklReading(): station " + stationName_ +
7967  ": cannot convert to double: \"" + s + "\"; input: \"" + asciifyString(str) + "\"");
7968  else
7969  tr.setElv(d);
7970  };
7971  return isOk;
7972 };
7973 
7974 
7975 
7976 //
7977 bool SgStnLogCollector::extractSefdReading(const QString& str, const QRegularExpressionMatch& match,
7978  SgMJD& t, QString& sensorId, QString& srcName, double& az, double& de, QVector<double>& vec,
7979  const SgMJD& tAtTheBegin)
7980 {
7981  bool isOk=false;
7982  double d;
7983  QString sensorTag(match.captured(4));
7984  QString s("");
7985 //QRegularExpression notATag("ia|ib|ic|id|ie|if|ig|ih");
7986  QRegularExpression notATag("i[A-Za-z0-9]");
7987 
7988  if (!extractEpoch(str, t))
7989  return false;
7990  if (t < tAtTheBegin)
7991  return false;
7992  if (notATag.match(sensorTag).hasMatch())
7993  return false;
7994 
7995 // 1 2 3 4 5 6 7 8 9 10 11 12
7996 //2020.034.17:11:35.51#onoff#VAL casa 295.4 63.4 001l 1 l 3464.40 0.9025 62.33 2139.2 58.787 0.93
7997 //2020.034.17:11:35.51#onoff#VAL casa 295.4 63.4 002l 1 l 3432.40 0.8950 63.19 2407.4 65.123 1.03
7998 
7999  srcName = match.captured(1);
8000  QString sensorKey=setupTpSensor(sensorTag, "extractSefdReading()");
8001  if (!sensorKey.size())
8002  return false;
8003 
8004 //sensorId = logReadings_.channelSetup().ifIdBySensorKey()[chanKey];
8005  sensorId = sensorKey;
8006 
8007  //
8008  if ((s=match.captured(2)).size())
8009  {
8010  d = s.toDouble(&isOk);
8011  if (!isOk)
8013  "::extractSefdReading(): station " + stationName_ +
8014  ": cannot convert to double: \"" + s + "\"; input: \"" + asciifyString(str) + "\"");
8015  else
8016  az = d;
8017  };
8018  //
8019  if ((s=match.captured(3)).size())
8020  {
8021  d = s.toDouble(&isOk);
8022  if (!isOk)
8024  "::extractSefdReading(): station " + stationName_ +
8025  ": cannot convert to double: \"" + s + "\"; input: \"" + asciifyString(str) + "\"");
8026  else
8027  de = d;
8028  };
8029  vec.resize(6);
8030  for (int i=0; i<6; i++)
8031  {
8032  if ((s=match.captured(7 + i)).size())
8033  {
8034  d = s.toDouble(&isOk);
8035  if (!isOk)
8037  "::extractSefdReading(): station " + stationName_ +
8038  ": cannot convert to double: \"" + s + "\"; input: \"" + asciifyString(str) + "\"");
8039  else
8040  vec[i] = d;
8041  };
8042  };
8043  return isOk;
8044 };
8045 
8046 
8047 
8048 //
8049 bool SgStnLogCollector::extractCableCalibration(const QString& str, const QRegularExpressionMatch& match,
8050  SgMJD& t, double& v)
8051 {
8052  if (!extractEpoch(str, t))
8053  return false;
8054 
8055  bool isOk=true;
8056  QString strCableVal(match.captured(2));
8057 
8058 
8059  if (strCableVal.endsWith('-'))
8060  strCableVal.chop(1);
8061  v = strCableVal.toDouble(&isOk);
8062  if (!isOk)
8064  "::extractCableCalibration(): failed to extract cable calibration value from \"" +
8065  strCableVal + "\"");
8066  else if (fabs(v) > 1.0e6) // is it enough?
8067  {
8068  v = 0.0;
8069  isOk = false;
8071  "::extractCableCalibration(): the exctracted value looks suspicious: \"" +
8072  strCableVal + "\", skipped");
8073  };
8074 // else
8075 // v /= 4.0e5;
8076  return isOk;
8077 };
8078 
8079 
8080 
8081 //
8083  const QRegularExpressionMatch& match, SgMJD& t, double& v, QString& source, QString& scan)
8084 {
8085  int nYear=0, nMonth=0, nDay=0, nHour=0, nMin=0;
8086  double dSecond=0.0, f=0.0;
8087  bool isOk=true;
8088 
8089 
8090  nYear = match.captured(1).toInt(&isOk);
8091  if (isOk)
8092  {
8093  nMonth = match.captured(2).toInt(&isOk);
8094  if (isOk)
8095  {
8096  nDay = match.captured(3).toInt(&isOk);
8097  if (isOk)
8098  {
8099  nHour = match.captured(4).toInt(&isOk);
8100  if (isOk)
8101  {
8102  nMin = match.captured(5).toInt(&isOk);
8103  if (isOk)
8104  {
8105  dSecond = match.captured(6).toDouble(&isOk);
8106  if (isOk)
8107  t.setUpEpoch(nYear, nMonth, nDay, nHour, nMin, dSecond);
8108  };
8109  };
8110  };
8111  };
8112  };
8113  if (!isOk)
8115  "::extractDataFromPcmtRecord(): failed to extract epoch from the string \"" + asciifyString(str) + "\"");
8116 // "::extractDataFromPcmtRecord(): failed to extract epoch from the string \"" + str + "\"");
8117  else
8118  {
8119  f = match.captured(7).toDouble(&isOk);
8120  if (isOk)
8121  {
8122  v = f;
8123  source = match.captured(8);
8124  if (match.lastCapturedIndex() >= 9)
8125  scan = match.captured(9);
8126  else
8127  std::cout << " --- no scan\n";
8128  }
8129  else
8131  "::extractDataFromPcmtRecord(): failed to extract cable cal value from the string \"" +
8132  asciifyString(str) + "\"");
8133 // str + "\"");
8134  };
8135  return isOk;
8136 };
8137 
8138 
8139 
8140 //
8142  const QRegularExpressionMatch& match, SgMJD& t, SgMeteoData& m)
8143 {
8144  int nYear=0, nMonth=0, nDay=0, nHour=0, nMin=0;
8145  double dSecond=0.0, f=0.0;
8146  bool isOk=true;
8147 
8148  nYear = match.captured(1).toInt(&isOk);
8149  if (isOk)
8150  {
8151  nMonth = match.captured(2).toInt(&isOk);
8152  if (isOk)
8153  {
8154  nDay = match.captured(3).toInt(&isOk);
8155  if (isOk)
8156  {
8157  nHour = match.captured(4).toInt(&isOk);
8158  if (isOk)
8159  {
8160  nMin = match.captured(5).toInt(&isOk);
8161  if (isOk)
8162  {
8163  dSecond = match.captured(6).toDouble(&isOk);
8164  if (isOk)
8165  t.setUpEpoch(nYear, nMonth, nDay, nHour, nMin, dSecond);
8166  };
8167  };
8168  };
8169  };
8170  };
8171  if (!isOk)
8173  "::extractDataFromMetRecord(): failed to extract epoch from the string \"" +
8174  asciifyString(str) + "\"");
8175 // "::extractDataFromMetRecord(): failed to extract epoch from the string \"" + str + "\"");
8176  else
8177  {
8178  f = match.captured(7).toDouble(&isOk);
8179  if (isOk)
8180  {
8181  m.setPressure(f);
8182  f = match.captured(8).toDouble(&isOk);
8183  if (isOk)
8184  {
8185  m.setTemperature(f);
8186  f = match.captured(9).toDouble(&isOk);
8187  if (isOk)
8188  m.setRelativeHumidity(f*0.01);
8189  else
8191  "::extractDataFromMetRecord(): failed to extract relative humidity from the string \"" +
8192  asciifyString(str) + "\"");
8193 // str + "\"");
8194  }
8195  else
8197  "::extractDataFromMetRecord(): failed to extract pressure from the string \"" +
8198  asciifyString(str) + "\"");
8199 // str + "\"");
8200  }
8201  else
8203  "::extractDataFromMetRecord(): failed to extract temperature from the string \"" +
8204  asciifyString(str) + "\"");
8205 // str + "\"");
8206  };
8207  return isOk;
8208 };
8209 
8210 
8211 
8212 //
8213 bool SgStnLogCollector::extractCableCalibrationSignByDiff(const QRegularExpressionMatch& match, int& v)
8214 {
8215  double d;
8216  bool isOk;
8217 
8218  QString strCableDiff(match.captured(2));
8219  QString strCableSign(match.captured(3));
8220 
8221  d = strCableDiff.toDouble(&isOk);
8222  if (isOk)
8223  {
8224  if (fabs(d) < 1.0e6) // is it enough?
8225  {
8226  if (strCableSign.contains("-"))
8227  v = -1;
8228  else if (strCableSign.contains("+"))
8229  v = 1;
8230  else
8232  "::extractCableCalibrationSignByDiff(): get unusable cable sign char sequence: \"" +
8233  strCableSign + "\"");
8234  }
8235  else
8236  {
8237  isOk = false;
8239  "::extractCableCalibrationSignByDiff(): the cable diff is too big: \"" + strCableDiff + "\"");
8240  };
8241  }
8242  else
8244  "::extractCableCalibrationSignByDiff(): cannot convert diff to double: \"" + strCableDiff + "\"");
8245  return isOk;
8246 };
8247 
8248 
8249 
8250 //
8251 bool SgStnLogCollector::checkRinexFile(const QString& fileName, const SgMJD& tStart,
8252  const SgMJD& tFinis, const QString& rinexStnName)
8253 {
8254  const QString eoh("END OF HEADER");
8255  QString path2Rinex("");
8256  QString str("");
8257  int idx=fileName.lastIndexOf("/");
8258  if (idx>-1)
8259  path2Rinex = fileName.left(idx);
8260 
8261  QDir dir(path2Rinex);
8262  QStringList nameFilters;
8263 // nameFilters << "sa01*0.??m";
8264  nameFilters << rinexStnName + "*.??m";
8265  QStringList nameList=dir.entryList(nameFilters,
8266  QDir::Files | QDir::Readable, QDir::Name | QDir::IgnoreCase);
8267  if (!nameList.size())
8268  {
8270  "::checkRinexFile(): no RINEX file found");
8271  return false;
8272  }
8273  else
8275  "::checkRinexFile(): processing RINEX files for the station " + stationName_);
8276 // 1 2 3 4
8277 //0123456789012345678901234567890123456789012345678901234567890123456789
8278 // 09 9 24 0 1 1 1000.0 22.4 76.7
8279 // 13 6 3 0 1 1 993.3 23.5 76.1
8280 // 18 2 15 0 0 0 1010.5 22.9 100.6 0.0 0.0 0.0 0.0
8281 // 18 5 14 0 0 0 1009.5 27.0 96.3-9999.9-9999.9-9999.9-9999.9
8282 // 18 5 14 0 1 0 1009.5 27.0 96.3-9999.9-9999.9-9999.9-9999.9
8283  QRegExp reData("\\s*(\\d{1,2})\\s+(\\d{1,2})\\s+(\\d{1,2})\\s+"
8284  "(\\d{1,2})\\s+(\\d{1,2})\\s+(\\d{1,2})\\s+"
8285  "(\\d{1,4}\\.\\d+)\\s+([+-\\.\\d]+)\\s+([+-]?[\\.\\d]+)(?:\\s+|$|-99)",
8286  Qt::CaseInsensitive);
8287  int nYr, nMn, nDy, nHr, nMi, nSc;
8288  double fPr, fTp, fRh;
8289  SgMeteoData m;
8290  bool isOk;
8291  logReadings_.meteoPars().clear();
8292  QFile f;
8293  double dP=0.0;
8294  //
8296  {
8299  "::checkRinexFile(): using offset of " + QString("").setNum(dP) + " mbar for atmospheric "
8300  "pressure of \"" + stationName_ + "\" station");
8301  };
8302  //
8303  for (int i=0; i<nameList.size(); i++)
8304  {
8305  const QString &fn=nameList.at(i);
8306 
8308  "::checkRinexFile(): processing " + fn + " file");
8309  str = "";
8310  idx = 0;
8311  f.setFileName(path2Rinex + "/" + fn);
8312  if (f.open(QFile::ReadOnly))
8313  {
8314  QTextStream s(&f);
8315  int count=0;
8316  while (!s.atEnd() && !str.contains(eoh))
8317  {
8318  str = s.readLine();
8319  idx++;
8320  };
8322  "::checkRinexFile(): skipped " + QString("").setNum(idx) + " strings");
8323  while (!s.atEnd())
8324  {
8325  nYr = nMn = nDy = nHr = nMi = nSc = 0;
8326  fPr = fTp = fRh = 0.0;
8327  str = s.readLine();
8328  if (reData.indexIn(str) != -1)
8329  {
8330  nYr = reData.cap(1).toInt(&isOk);
8331  if (isOk)
8332  {
8333  nMn = reData.cap(2).toInt(&isOk);
8334  if (isOk)
8335  {
8336  nDy = reData.cap(3).toInt(&isOk);
8337  if (isOk)
8338  {
8339  nHr = reData.cap(4).toInt(&isOk);
8340  if (isOk)
8341  {
8342  nMi = reData.cap(5).toInt(&isOk);
8343  if (isOk)
8344  {
8345  nSc = reData.cap(6).toInt(&isOk);
8346  if (isOk)
8347  {
8348  fPr = reData.cap(7).toDouble(&isOk);
8349  if (isOk)
8350  {
8351  fTp = reData.cap(8).toDouble(&isOk);
8352  if (isOk)
8353  {
8354  fRh = reData.cap(9).toDouble(&isOk);
8355  if (isOk)
8356  {
8357  SgMJD t(nYr, nMn, nDy, nHr, nMi, (double)nSc);
8358  if (tStart<=t && t<= tFinis)
8359  {
8360  m.setTemperature(fTp);
8361  m.setPressure(fPr + dP);
8362  if (fRh < 0.0)
8363  {
8365  "::checkRinexFile(): the extracted relative humidity looks "
8366  "suspicious: " + QString("").setNum(fRh) + "%; adjusted it to zero");
8367  m.setRelativeHumidity(0.0);
8368  }
8369  else if (100.0 < fRh)
8370  {
8372  "::checkRinexFile(): the extracted relative humidity looks "
8373  "suspicious: " + QString("").setNum(fRh) + "%; adjusted it to 100%");
8374  m.setRelativeHumidity(1.0);
8375  }
8376  else
8377  m.setRelativeHumidity(fRh*0.01);
8378  //
8379  SgMeteoReading *meteoRec=new SgMeteoReading(t, m);
8380  logReadings_.meteoPars() << meteoRec;
8381  count++;
8382  };
8383  idx++;
8384  }
8385  else
8387  "::checkRinexFile(): cannot convert relative humidity to double, "
8388  "string=\"" + reData.cap(9) + "\"");
8389  }
8390  else
8392  "::checkRinexFile(): cannot convert temperature to double, string=\"" +
8393  reData.cap(8) + "\"");
8394  }
8395  else
8397  "::checkRinexFile(): cannot convert pressure to double, string=\"" +
8398  reData.cap(7) + "\"");
8399  }
8400  else
8402  "::checkRinexFile(): cannot convert second to int, string=\"" +
8403  reData.cap(6) + "\"");
8404  }
8405  else
8407  "::checkRinexFile(): cannot convert minute to int, string=\"" +
8408  reData.cap(5) + "\"");
8409  }
8410  else
8412  "::checkRinexFile(): cannot convert hour to int, string=\"" + reData.cap(4) + "\"");
8413  }
8414  else
8416  "::checkRinexFile(): cannot convert day to int, string=\"" + reData.cap(3) + "\"");
8417  }
8418  else
8420  "::checkRinexFile(): cannot convert month to int, string=\"" + reData.cap(2) + "\"");
8421  }
8422  else
8424  "::checkRinexFile(): cannot convert year to int, string=\"" + reData.cap(1) + "\"");
8425  };
8426  };
8427  f.close();
8428  s.setDevice(NULL);
8430  "::checkRinexFile(): extracted " + QString("").setNum(count) + " meteo records from " +
8431  QString("").setNum(idx) + " strings of " + f.fileName() + " RINEX file");
8432  }
8433  else
8434  {
8436  "::checkRinexFile(): unable to read the file \"" + f.fileName() + "\"");
8437  return false;
8438  };
8439  };
8441  "::checkRinexFile(): collected " + QString("").setNum(logReadings_.meteoPars().size()) +
8442  " meteo records");
8443  return logReadings_.meteoPars().size()>0;
8444 };
8445 
8446 
8447 
8448 //
8450  bool createAntabFile, bool overwriteAntabFile, bool reportAllReadings)
8451 {
8452  // output of the raw data:
8454 
8455  // ANTAB:
8456  if (createAntabFile)
8458  useSkededChannelSetup_, overwriteAntabFile, reportAllReadings);
8459 
8460  // verify collected data:
8462  // put data into station data structures:
8464  {
8467  "::propagateData(): the cable calibration data for " + stn->getKey() + " are CDMS");
8468  }
8469  else if (hasCableRecord_ && hasCdmsRecord_)
8470  {
8472  "::propagateData(): both /cable/ and /CDMS/ commands were found for " + stn->getKey() +
8473  " in the log file");
8474  };
8475 
8476  return logReadings_.propagateData(stn);
8477 };
8478 
8479 
8480 
8481 //
8482 bool SgStnLogCollector::readDbbc3DumpFile(const QString& fileName)
8483 {
8484  QString str("");
8485  QFile f;
8486  QTextStream s;
8487  FILE *pipe;
8488  qint64 fileSize;
8489  int numOfReadStrs=0;
8490  bool reachedEndOfSession=false;
8491  QRegularExpressionMatch match;
8492  SgMJD t, lastReadTsys(tZero);
8493 
8494 
8495  QString sEpoch("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):([0-9\\.]+)\\s*UTC\\s*");
8496  QString sSep("\\s*,\\s*");
8497  QString sDbl("([0-9\\.+-]+)");
8498 
8499 
8500  //2020-07-20T17:00:00.379712 UTC: BBC002: 3448,32,agc,66,63,15202,15130,15298,15222,SEFDU: 10174.0 Jy,SEFDL: 9848.0 Jy
8501  QRegularExpression reBbc(sEpoch + ":\\s*BBC(\\d+):\\s*" + sDbl + sSep +
8502  "(\\d+)" + sSep + "(\\w+)" + sSep + "(\\d+)" + sSep + "(\\d+)" + sSep + "(\\d+)" + sSep +
8503  "(\\d+)" + sSep + "(\\d+)" + sSep + "(\\d+)" + sSep + "SEFDU:\\s*" + sDbl + "\\s*Jy" + sSep +
8504  "SEFDL:\\s*" + sDbl + "\\s*Jy.*");
8505 
8506  //2020.202.18:01:44.03/dbbc3/dbbc001/ 3480.400000,a,32,1,agc,79,84,15299,15290,14977,14972;
8507  //QRegularExpression reDbbc3Tp("/dbbc3/dbbc(\\d{3})/\\s*([0-9\\.+-]+),([^,]+),(\\d+),(\\d+),"
8508  // "(\\w+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+);.*");
8509 
8510  QString sensorId("");
8511  int nYr, nMn, nDy, nHr, nMi;
8512  double ifFrq, dSc;
8513  double bw;
8514  QString agc("");
8515  double bbcGainU, bbcGainL;
8516  double bbcTPUOn, bbcTPLOn, bbcTPUOff, bbcTPLOff;
8517  double bbcSEFDU, bbcSEFDL;
8518 
8519  bool isDataOn=false;
8520  bool isOnSource=false;
8521  SgOnSourceRecord *osRec=NULL;
8522  int onSourceIdx=0;
8523  int numOfOnSource;
8524 
8525  fileSize = QFileInfo(fileName).size();
8526 
8527  pipe = compressors.openFlt(fileName, f, s, FLTD_Input);
8528  if (s.device())
8529  {
8530  // clear previous TPC readings:
8531  for (int i=0; i<logReadings_.onSourceRecords().size(); i++)
8532  logReadings_.onSourceRecords()[i]->dbbc3Tps().clear();
8533  for (int i=0; i<logReadings_.dbbc3Tps().size(); i++)
8534  delete logReadings_.dbbc3Tps()[i];
8535  logReadings_.dbbc3Tps().clear();
8537  "::readDbbc3DumpFile(): station " + stationName_ +
8538  ": previously accumulated dbbc3 TP records were reset");
8539 
8540  if ((numOfOnSource=logReadings_.onSourceRecords().size()))
8541  osRec = logReadings_.onSourceRecords().first();
8542 
8543  bool have2reportNumOfStrings=10000000 < fileSize;
8544  while (!s.atEnd() && !reachedEndOfSession)
8545  {
8546  str = s.readLine();
8547  numOfReadStrs++;
8548 
8549 if (have2reportNumOfStrings && numOfReadStrs%200000 == 0)
8550 std::cout << " -- read " << numOfReadStrs/1000 << "K strings; file size: " << fileSize << "\n";
8551 
8552  agc = "";
8553 // bbcIdx = 0;
8554  nYr = nMn = nDy = nHr = nMi = 0;
8555  dSc = ifFrq = bw = bbcGainU = bbcGainL = bbcTPUOn =
8556  bbcTPLOn = bbcTPUOff = bbcTPLOff = bbcSEFDU = bbcSEFDL = 0.0;
8557 
8558  if ((match=reBbc.match(str)).hasMatch())
8559  {
8560  agc = match.captured(10);
8561  // they pass regexp, it is ok do not check for conversion success:
8562  nYr = match.captured( 1).toInt();
8563  nMn = match.captured( 2).toInt();
8564  nDy = match.captured( 3).toInt();
8565  nHr = match.captured( 4).toInt();
8566  nMi = match.captured( 5).toInt();
8567  dSc = match.captured( 6).toDouble();
8568  t.setUpEpoch(nYr, nMn, nDy, nHr, nMi, dSc);
8569  sensorId = match.captured(7).simplified().rightJustified(5, ' ');
8570 // bbcIdx = match.captured( 7).toInt();
8571  ifFrq = match.captured( 8).toDouble();
8572  bw = match.captured( 9).toDouble();
8573  bbcGainU = match.captured(11).toDouble();
8574  bbcGainL = match.captured(12).toDouble();
8575  bbcTPUOn = match.captured(13).toDouble();
8576  bbcTPLOn = match.captured(14).toDouble();
8577  bbcTPUOff = match.captured(15).toDouble();
8578  bbcTPLOff = match.captured(16).toDouble();
8579  bbcSEFDU = match.captured(17).toDouble();
8580  bbcSEFDL = match.captured(18).toDouble();
8581  //
8582  // find onSource record:
8583  while (onSourceIdx<numOfOnSource && (osRec=logReadings_.onSourceRecords()[onSourceIdx]) &&
8584  osRec->tFinis()<t)
8585  onSourceIdx++;
8586  if (osRec && osRec->tStart()<t)
8587  isOnSource = true;
8588  else
8589  isOnSource = false;
8590  //
8591  if (osRec && osRec->tDataOn()<t)
8592  isDataOn = true;
8593  else
8594  isDataOn = false;
8595  //
8596  SgDbbc3TpReading *tp=NULL;
8597  if (0.1/DAY2SEC < fabs(lastReadTsys - t))
8598  {
8599  tp = new SgDbbc3TpReading;
8600  tp->setT(t);
8601  tp->setOsRec(isOnSource?osRec:NULL);
8602  tp->setIsOnSource(isOnSource);
8603  tp->setIsDataOn(isDataOn);
8604  logReadings_.dbbc3Tps() << tp;
8605  if (osRec)
8606  osRec->dbbc3Tps() << tp;
8607  }
8608  else
8609  tp = logReadings_.dbbc3Tps().last();
8610  //
8611  tp->addRecord(sensorId, "", bw, agc, bbcGainU, bbcGainL, bbcTPUOff, bbcTPLOff,
8612  bbcTPUOn, bbcTPLOn, bbcSEFDU, bbcSEFDL);
8613  lastReadTsys = t;
8614  };
8615  };
8616 
8617  };
8618  compressors.closeFlt(pipe, f, s);
8619 
8620 
8622  "::readDbbc3DumpFile(): station " + stationName_ + ": " + QString("").setNum(numOfReadStrs) +
8623  " strings of the DBBC3 dump file \"" + fileName + "\" were read");
8625  "::readDbbc3DumpFile(): station " + stationName_ + ": collected " +
8626  QString("").setNum(logReadings_.dbbc3Tps().size()) + " dbbc3 TP records");
8627 
8628  return true;
8629 };
8630 
8631 /*=====================================================================================================*/
8632 
8633 
8634 
8635 
8636 
8637 
8638 
8639 /*=======================================================================================================
8640 *
8641 * SgVlbaLogCollector's METHODS:
8642 *
8643 *======================================================================================================*/
8644 //
8645 // static first:
8646 //
8648 {
8649  return "SgVlbaLogCollector";
8650 };
8651 
8652 
8653 
8654 // An empty constructor:
8656  logFileName_(""),
8657  readingsByKey_(),
8658  ivs2vlba_()
8659 {
8660  for (int i=0; i<NUM_OF_VLBA_ENTRIES; i++)
8662 };
8663 
8664 
8665 
8666 //
8667 // A destructor:
8669 {
8670  for (QMap<QString, SgStnLogReadings*>::iterator it=readingsByKey_.begin();
8671  it!=readingsByKey_.end(); ++it)
8672  delete it.value();
8673  readingsByKey_.clear();
8674 };
8675 
8676 
8677 
8678 //
8679 bool SgVlbaLogCollector::readLogFile(const QString& fileName, int nYear)
8680 {
8681  QString str("");
8682  QString key("");
8683  QFile f(fileName);
8684  QString stnPattern("([\\w]{2})");
8685  QString srcPattern("([\\d\\w+-]{2,8})");
8686  QString epcPattern("(\\d{3})(?:-|\\s+)(\\d{2}):(\\d{2}):(\\d{2})");
8687  QString dblPattern("([+-\\.\\d]+)");
8688 
8689  QRegExp rePulseCalInfo("PulseCal information for\\s+" + stnPattern + "\\s+",
8690  Qt::CaseInsensitive);
8691  QRegExp reScanCalInfo("Scan information for\\s+" + stnPattern + "\\s+",
8692  Qt::CaseInsensitive);
8693  QRegExp reWeatherInfo("Weather information for\\s+" + stnPattern + "\\s+",
8694  Qt::CaseInsensitive);
8695  QRegExp rePulseCalData
8696  (epcPattern + "\\s+'CC'\\s+" + dblPattern + "\\s+" + dblPattern,
8697  Qt::CaseInsensitive);
8698  QRegExp reScanCalData
8699  (srcPattern + "\\s+" + epcPattern + "\\s+" + epcPattern + "\\s+" +
8700  dblPattern + "\\s+" + dblPattern + "\\s+" + dblPattern,
8701  Qt::CaseInsensitive);
8702  QRegExp rePulseScanData
8703  ("!\\s+" + stnPattern + "\\s+([\\w\\d+-]+)\\s+" + srcPattern + "/(\\d+)\\s+" +
8704  epcPattern + "/" + epcPattern,
8705  Qt::CaseInsensitive);
8706  QRegExp reWeatherData
8707  (epcPattern + "\\s+" + dblPattern + "\\s+" + dblPattern + "\\s+" + dblPattern + "\\s+" +
8708  dblPattern + "\\s+" + dblPattern + "\\s+" + dblPattern + "\\s+" + dblPattern,
8709  Qt::CaseInsensitive);
8710 
8711  logFileName_ = fileName;
8712  SgStnLogReadings *reading=NULL;
8713  SgOnSourceRecord *osRec=NULL;
8714  SgMJD t, t_aux;
8715  bool have2read, isOk;
8716  double d;
8717  int m;
8718  //
8719  if (!f.exists())
8720  {
8722  "::readLogFile(): the log file " + fileName + " does not exist");
8723  return false;
8724  };
8725  //
8726  //
8728  "::readLogFile(): reading log file " + fileName);
8729  //
8730  have2read = true;
8731  if (f.open(QFile::ReadOnly))
8732  {
8733  QTextStream s(&f);
8734  while (!s.atEnd())
8735  {
8736  if (have2read)
8737  str = s.readLine();
8738  else
8739  have2read = true;
8740  //
8741  // pulse cal info:
8742  if (rePulseCalInfo.indexIn(str) != -1)
8743  {
8744  key = rePulseCalInfo.cap(1);
8745  //
8746  if (readingsByKey_.contains(key))
8747  reading = readingsByKey_[key];
8748  else
8749  readingsByKey_.insert(key, (reading=new SgStnLogReadings(key)));
8750  //
8751 // while (!s.atEnd() && !(str.contains(" information ") && !str.contains(key)))
8752  str = "";
8753  while (!s.atEnd() && !str.contains(" information "))
8754  {
8755  str = s.readLine();
8756  //
8757  //
8758  if (rePulseCalData.indexIn(str) != -1)
8759  {
8760  if (strs2mjd(nYear, rePulseCalData.cap(1), rePulseCalData.cap(2),
8761  rePulseCalData.cap(3), rePulseCalData.cap(4), t))
8762  {
8763  d = rePulseCalData.cap(5).toDouble(&isOk);
8764  if (isOk)
8765  reading->cableCals() << new SgCableCalReading(t, d*1.0e-12);
8766  else
8768  "::readLogFile(): failed to extract cable cal value from PulseCalData: \"" +
8769  str + "\"");
8770  }
8771  else
8773  "::readLogFile(): failed to extract epoch from PulseCalData: \"" + str + "\"");
8774  };
8775  if (rePulseScanData.indexIn(str) != -1)
8776  {
8777  m = rePulseScanData.cap(4).toInt(&isOk);
8778  if (isOk)
8779  {
8780  if (m != 999) // are others ok?
8781  {
8782  if (strs2mjd(nYear, rePulseScanData.cap(5), rePulseScanData.cap(6),
8783  rePulseScanData.cap(7), rePulseScanData.cap(8), t))
8784  {
8785  if (strs2mjd(nYear, rePulseScanData.cap(9), rePulseScanData.cap(10),
8786  rePulseScanData.cap(11), rePulseScanData.cap(12), t_aux))
8787  {
8788  osRec = new SgOnSourceRecord;
8789  osRec->setSourceName(rePulseScanData.cap(3).toUpper());
8790  osRec->setTstart(t);
8791  osRec->setTfinis(t_aux);
8792  // check for duplicates:
8793  if (reading->onSourceRecords().size()==0)
8794  reading->onSourceRecords() << osRec;
8795 // else if (*reading->onSourceRecords().last() != *osRec)
8796  else if (!reading->onSourceRecords().last()->isSameArgs(*osRec))
8797  reading->onSourceRecords() << osRec;
8798  else
8799  {
8801  "::readLogFile(): got a duplicate string of PulseScanData: \"" + str + "\"");
8802  delete osRec;
8803  };
8804  }
8805  else
8807  "::readLogFile(): failed to extract epoch_2 from PulseScanData: \"" + str + "\"");
8808  }
8809  else
8811  "::readLogFile(): failed to extract epoch_1 from PulseScanData: \"" + str + "\"");
8812  };
8813  }
8814  else
8816  "::readLogFile(): failed to extract qualifier value from PulseCalData: \"" + str + "\"");
8817  };
8818  };
8819  have2read = false;
8820  };
8821  //
8822  // scan info:
8823  /*
8824  if (reScanCalInfo.indexIn(str) != -1)
8825  {
8826  key = reScanCalInfo.cap(1);
8827  if (readingsByKey_.contains(key))
8828  reading = readingsByKey_[key];
8829  else
8830  {
8831  reading = new SgStnLogReadings;
8832  reading->setStationName(key);
8833  readingsByKey_.insert(key, reading);
8834  };
8835 
8836  while (!s.atEnd() && !(str.contains(" information ") && !str.contains(key)))
8837  {
8838  str = s.readLine();
8839  if (reScanCalData.indexIn(str) != -1)
8840  {
8841  ..*..
8842  };
8843  };
8844  have2read = false;
8845  };
8846  */
8847  //
8848  //
8849  // weather info:
8850  if (reWeatherInfo.indexIn(str) != -1)
8851  {
8852  key = reWeatherInfo.cap(1);
8853  //
8854  if (readingsByKey_.contains(key))
8855  reading = readingsByKey_[key];
8856  else
8857  readingsByKey_.insert(key, (reading=new SgStnLogReadings(key)));
8858  //
8859 // while (!s.atEnd() && !(str.contains(" information ") && !str.contains(key)))
8860  str = "";
8861  while (!s.atEnd() && !str.contains(" information "))
8862  {
8863  str = s.readLine();
8864  if (reWeatherData.indexIn(str) != -1)
8865  {
8866  if (strs2mjd(nYear, reWeatherData.cap(1), reWeatherData.cap(2),
8867  reWeatherData.cap(3), reWeatherData.cap(4), t))
8868  {
8869  double temp, press, dewpt;
8870  temp = reWeatherData.cap(5).toDouble(&isOk);
8871  if (isOk)
8872  {
8873  press = reWeatherData.cap(6).toDouble(&isOk);
8874  if (isOk)
8875  {
8876  dewpt = reWeatherData.cap(7).toDouble(&isOk);
8877  if (isOk)
8878  reading->meteoPars() << new
8879  SgMeteoReading(t, SgMeteoData(temp, press, SgMeteoData::dewPt2Rho(temp, dewpt)));
8880  else
8882  "::readLogFile(): failed to extract dew point from WeatherData: \"" + str + "\"");
8883  }
8884  else
8886  "::readLogFile(): failed to extract pressure from WeatherData: \"" + str + "\"");
8887  }
8888  else
8890  "::readLogFile(): failed to extract temperature from WeatherData: \"" + str + "\"");
8891  }
8892  else
8894  "::readLogFile(): failed to extract epoch from WeatherData: \"" + str + "\"");
8895  };
8896  };
8897  have2read = false;
8898  };
8899  };
8900  f.close();
8901  s.setDevice(NULL);
8902  };
8903 
8904  for (QMap<QString, SgStnLogReadings*>::iterator it=readingsByKey_.begin();
8905  it!=readingsByKey_.end(); ++it)
8906  {
8907  SgStnLogReadings *rd=it.value();
8908  rd->setCableSign(-1);
8909  rd->setCableCalAmbig(1.0e-9);
8910  rd->allocateCableReadings();
8911  };
8912  //
8914  "::readLogFile(): collected logs of " + QString("").setNum(readingsByKey_.size())+
8915  " stations from the log file");
8917  "::readLogFile(): parsing of the log file has been completed");
8918  //
8919  return true;
8920 };
8921 
8922 
8923 
8924 //
8925 bool SgVlbaLogCollector::strs2mjd(int nYear, const QString& sDay, const QString& sHr,
8926  const QString& sMin, const QString& sSec, SgMJD& t)
8927 {
8928  int dy, hr, mi, se;
8929  bool isOk;
8930  isOk = true;
8931 
8932  dy = sDay.toInt(&isOk);
8933  if (isOk)
8934  {
8935  hr = sHr.toInt(&isOk);
8936  if (isOk)
8937  {
8938  mi = sMin.toInt(&isOk);
8939  if (isOk)
8940  {
8941  se = sSec.toInt(&isOk);
8942  if (isOk)
8943  t.setUpEpoch(nYear, 0, dy, hr, mi, se);
8944  else
8946  "::strs2mjd(): failed to extract seconds from \"" + sSec + + "\"");
8947  }
8948  else
8950  "::strs2mjd(): failed to extract minutes from \"" + sMin + + "\"");
8951  }
8952  else
8954  "::strs2mjd(): failed to extract hours from \"" + sHr + + "\"");
8955  }
8956  else
8958  "::strs2mjd(): failed to extract days from \"" + sDay + "\"");
8959  return isOk;
8960 };
8961 
8962 
8963 
8964 //
8966 {
8967  if (isVlba(stn->getKey()))
8968  {
8969  QString vlbaKey=ivs2vlba_.value(stn->getKey());
8970  if (readingsByKey_.contains(vlbaKey))
8971  {
8972  SgStnLogReadings *logReadings=readingsByKey_.value(vlbaKey);
8973 
8974  // verify collected data:
8975  logReadings->verifyReadings(stn, NULL);
8976 
8977  // put data into station data structures:
8978  return logReadings->propagateData(stn);
8979  }
8980  else // VLBA station not found in the log file
8981  {
8983  "::propagateData(): cannot find VLBA station " + stn->getKey() + " (aka " + vlbaKey +
8984  ") in the log file");
8985  return false;
8986  };
8987  }
8988  else // not a VLBA station
8989  {
8991  "::propagateData(): cannot find a station " + stn->getKey() + " in the map of VLBA stations");
8992  return false;
8993  };
8994 };
8995 /*=====================================================================================================*/
8996 
8997 
8998 
8999 
9000 
9001 
9002 
9003 
9004 
9005 /*=====================================================================================================*/
9006 //
9007 // FRIENDS:
9008 //
9009 /*=====================================================================================================*/
9010 //
9011 
9012 
9013 
9014 
9015 /*=====================================================================================================*/
9016 //
9017 // aux functions:
9018 //
9019 //
9020 
9021 
9022 
9023 
9024 /*=====================================================================================================*/
9025 //
9026 // constants:
9027 //
9028 const QString SgStnLogReadings::sFiller_("n/a");
9029 const int SgStnLogReadings::nFiller_ = -999;
9030 const double SgStnLogReadings::dFiller_ = -99.9;
9031 
9032 
9033 int SgStnLogCollector::fsContentStartsAt_[] = {0, 10, 14, 20, 0, 0};
9034 
9035 
9037  { "BR", "CA", "EB", "FD", "GA", "GT", "HN", "JV", "KP", "LA", "MK", "NL", "OV", "PT", "SC" };
9039  { "BR-VLBA ", "CAMBRIDG", "EFLSBERG", "FD-VLBA ", "VLBA85_3", "GBT-VLBA", "HN-VLBA ",
9040  "JODRELL2", "KP-VLBA ", "LA-VLBA ", "MK-VLBA ", "NL-VLBA ", "OV-VLBA ", "PIETOWN ",
9041  "SC-VLBA " };
9042 
9043 
9044 
9045 
9046 
9047 
9048 /*=====================================================================================================*/
9049 
9050 
9051 
9052 
9053 QString asciifyString(const QString& str)
9054 {
9055  QString s("");
9056 //QRegularExpression rx("[\\x{00}-\\x{20}]");
9057  ushort n;
9058  for (int i=0; i<str.size(); i++)
9059  {
9060 // if (rx.match(str.at(i)).hasMatch())
9061  n = str.at(i).unicode();
9062  if (n<32 || 126<n)
9063  s += QString("").sprintf("\\0x%04X", n);
9064  else
9065  s += str.at(i);
9066  };
9067  return s;
9068 };
9069 
9070 
9071 
9072 
9073 
9074 
9075 
9076 
9077 
9078 
9079 
9080 
9081 
9082 
9083 
9084 
9085 /*=====================================================================================================*/
9086 
9087 
9088 
9089 
9090 
SgIoExtFilterHandler compressors
@ FLTD_Output
@ FLTD_Input
SgLogger * logger
Definition: SgLogger.cpp:231
const SgMJD tZero(1957, 10, 4)
#define DAY2SEC
radians to mas:
Definition: SgMathSupport.h:56
#define RAD2DEG
< radians to degrees:
Definition: SgMathSupport.h:32
QString asciifyString(const QString &str)
#define NUM_OF_VLBA_ENTRIES
@ AOD_CABLE_CAL
@ AOD_PCAL
@ AOD_CABLE_SIGN
@ AOD_DBBC3TP
@ AOD_FMTGPS
@ AOD_ALL
@ AOD_TPI
@ AOD_METEO
@ AOD_NOVEL
@ AOD_DATA_ON
@ AOD_SEFD
@ AOD_TSYS
SgVersion libraryVersion("SgLib", 0, 7, 5, "Tuscarora (rc1)", SgMJD(2022, 2, 18, 17, 34))
QString polarization2Str(SgChannelPolarization p)
Definition: SgVex.cpp:1127
QString sideBand2Str(SgChannelSideBand sb)
Definition: SgVex.cpp:1113
SgChannelPolarization
Definition: SgVex.h:57
@ CP_UNDEF
Definition: SgVex.h:58
@ CP_VerticalLP
Definition: SgVex.h:62
@ CP_RightCP
Definition: SgVex.h:59
@ CP_HorizontalLP
Definition: SgVex.h:61
@ CP_LeftCP
Definition: SgVex.h:60
SgChannelSideBand
Definition: SgVex.h:47
@ CSB_DUAL
Definition: SgVex.h:51
@ CSB_USB
Definition: SgVex.h:50
@ CSB_LSB
Definition: SgVex.h:49
@ CSB_UNDEF
Definition: SgVex.h:48
#define UNUSED
bool isAttr(uint a) const
Definition: SgAttribute.h:226
void addAttr(uint a)
Definition: SgAttribute.h:202
static const QString className()
void setV(double v)
void setOsRec(SgOnSourceRecord *os)
double getV() const
const SgMJD & getT() const
const SgOnSourceRecord * getOsRec() const
QMap< QString, double > & ifFreqBySensorKey()
QMap< QString, SgChannelSideBand > & ifSideBandById()
QMap< QString, int > & ifIdxById()
QMap< QString, QList< QString > > & origSensorIdById()
QMap< QString, SgChannelPolarization > loPolarizationById_
QMap< QString, SgChannelSideBand > & loSideBandById()
QMap< QString, SgChannelPolarization > & loPolarizationById()
QMap< QString, double > & ifBandwidthBySensorKey()
QMap< QString, SgChannelPolarization > & pcalPolarizationById()
QMap< QString, QString > loIdByCid_
QMap< int, double > & bbcBandwidthByIdx()
HwType getHwType() const
void setBackEndType(BackEndType tp)
QMap< QString, QString > & ifIdBySensorKey()
bool selfCheck(const QString &stnKey)
QMap< int, double > & bbcFreqByIdx()
QMap< QString, QString > & xpsIdByKey()
QMap< QString, double > & loFreqById()
QMap< QString, QString > ifIdBySensorKey_
QMap< QString, QString > & pcalIdByKey()
QMap< QString, int > ifIdxById_
static double calcSkyFreq(double loFreq, double bbcFreq, double width, SgChannelSideBand loSideBand, SgChannelSideBand ifSideBand)
QMap< QString, SgChannelSideBand > loSideBandById_
QMap< QString, QString > & loIdByCid()
QMap< int, QString > loIdByIdx_
static const QString className()
QMap< QString, SgChannelPolarization > & loPolarizationBySensorKey()
QMap< QString, QString > & loIdBySensorKey()
QMap< int, double > bbcFreqByIdx_
QMap< QString, double > loFreqById_
QMap< int, QString > & loIdByIdx()
QMap< QString, double > & loFreqBySensorKey()
BackEndType backEndType_
QMap< QString, double > loFreqBySensorKey_
QMap< QString, SgChannelPolarization > & ifPolarizationById()
QMap< int, double > & ifFreqByIdx()
BackEndType getBackEndType() const
QMap< int, double > bbcBandwidthByIdx_
QMap< QString, SgChannelSideBand > ifSideBandById_
QMap< QString, SgChannelSideBand > & loSideBandBySensorKey()
void setHwType(HwType tp)
const QString & getBandKey() const
const QList< SgChannelSideBand > & getSideBands() const
const QList< ChanCfg > & getChannelCfgs() const
const QString & getStnKey() const
QMap< QString, StnCfg > stnCfgByKey_
static const QString className()
bool parseSkdFile(const QString &fileName)
void addRecord(const QString &sensorId, const QString &boardId, double bw, const QString &agc, double gainU, double gainL, double tpOffU, double tpOffL, double tpOnU, double tpOnL, double sefdU, double sefdL)
void setOsRec(SgOnSourceRecord *os)
const SgOnSourceRecord * getOsRec() const
const SgMJD & getT() const
void setIsOnSource(bool isOnSource)
void setT(const SgMJD &t)
const QMap< QString, TpRecord > & getTpBySensor() const
void setIsDataOn(bool isDataOn)
void setT(const SgMJD &t)
const SgOnSourceRecord * getOsRec() const
bool addDot2gpsByBrd(const QString &key, float v)
const QMap< QString, float > & getDot2gpsByBrd() const
void setOsRec(SgOnSourceRecord *os)
const SgMJD & getT() const
const SgIoExternalFilter * lookupFilterByFileName(const QString &fileName)
static void closeFlt(FILE *&p, QFile &file, QTextStream &ts)
FILE * openFlt(const QString &fileName, QFile &file, QTextStream &ts, FilterDirection)
const QString & getDefaultExtension() const
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ IO_TXT
Definition: SgLogger.h:65
bool isEligible(LogLevel lvl, quint32 f) const
Definition: SgLogger.h:151
Definition: SgMJD.h:59
@ F_YYYYMMDDHHMMSSSS
Long verbose: Fri, the 2nd of Apr, 2010; 17hr 02min 43.6400sec.
Definition: SgMJD.h:67
@ F_Simple
Digits: 2010/04/02 17:02:43.6.
Definition: SgMJD.h:68
@ F_SOLVE_SPLFL_V3
Another spoolfile represenation of epoch: 2012.01.20-09:14:28.0.
Definition: SgMJD.h:76
@ F_SOLVE_SPLFL
That was used in ECC.dat files: 2010.04.02-17.02.
Definition: SgMJD.h:74
@ F_INTERNAL
Digits, date and time: 20100402.71.
Definition: SgMJD.h:72
QString toString(Format format=F_Verbose) const
Definition: SgMJD.cpp:1007
void setUpEpoch(int year, int month, int day, int hour, int min, double sec)
Definition: SgMJD.cpp:254
int calcYear() const
Definition: SgMJD.cpp:204
double getPressure() const
Definition: SgMeteoData.h:242
void setRelativeHumidity(double rho)
Definition: SgMeteoData.h:274
double getTemperature() const
Definition: SgMeteoData.h:234
void setTemperature(double t)
Definition: SgMeteoData.h:258
void setPressure(double p)
Definition: SgMeteoData.h:266
static double dewPt2Rho(double temperature, double dewPtTemperature)
Definition: SgMeteoData.cpp:39
double getRelativeHumidity() const
Definition: SgMeteoData.h:250
const SgMJD & getT() const
const SgOnSourceRecord * getOsRec() const
void setOsRec(SgOnSourceRecord *os)
static const QString className()
const SgMeteoData & getM() const
const QString & getKey() const
Definition: SgObjectInfo.h:319
QList< SgCableCalReading * > & cableCals()
QList< SgTsysReading * > & tSyses()
static const QString className()
const SgMJD & getTdataOn() const
const QString & getScanName() const
void setScanName(const QString &str)
const SgMJD & getTfinis() const
void setSourceName(const QString &str)
void setTfinis(const SgMJD &t)
QList< SgDbbc3TpReading * > & dbbc3Tps()
const QString & getSourceName() const
const SgMJD & getTstart() const
void setTstart(const SgMJD &t)
QList< SgMeteoReading * > & meteoPars()
const SgOnSourceRecord * getOsRec() const
void setT(const SgMJD &t)
void setOsRec(SgOnSourceRecord *os)
const QMap< QString, float * > & getPcal() const
static const QString className()
const SgMJD & getT() const
bool addPcals(const QMap< QString, float * > &pcals)
const SgMJD & getT() const
static const QString className()
bool addValByChanKey(const SgMJD &t, const QString &srcName, double az, double el, const QString &chanKey, const QVector< double > &val)
double getAz() const
QMap< QString, QVector< double > * > valByChanKey_
double getEl() const
const QMap< QString, QVector< double > * > & getValByChanKey() const
const QString & getSrcName() const
const QMap< QString, double > * rinexPressureOffsetByStn_
QString setupTpSensor(const QString &sensorTag, const QString &callerName)
const QMap< QString, QString > * rinexFileNameByStn_
static const QRegularExpression reMet_
FieldSystemEpochFormat fsFmt_
bool extractTraklReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, SgTraklReading &, const SgMJD &tAtTheBegin)
static const QString className()
bool extractTsysVgosReading(const QString &str, const QRegularExpression &reTsys, SgMJD &t, QMap< QString, float > &tSys, const SgMJD &tAtTheBegin)
static const QRegularExpression reFsOld_
bool extractBbcReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, const SgMJD &atEnd, SgChannelSetup &cs, const SgMJD &tFirst)
bool createAntabFile(const QString &stnKey, const QString &outputFileName, bool have2owrt, bool reportAllTsysData)
static const QRegularExpression rePcmt_
bool extractTsysReading(const QString &str, const QRegularExpression &reTsys, SgMJD &t, QMap< QString, float > &tSys, const SgMJD &tAtTheBegin)
bool extractDataFromMetRecord(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, SgMeteoData &m)
bool extractVciReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, const SgMJD &atEnd, SgChannelSetup &cs, const SgMJD &tFirst)
bool readDbbc3DumpFile(const QString &fileName)
const QMap< QString, int > * defaultCableSignByStn_
bool extractCableCalibration(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, double &v)
static int fsContentStartsAt_[]
bool extractCableCalibrationSignByDiff(const QRegularExpressionMatch &match, int &v)
bool propagateData(SgVlbiStationInfo *stn, bool createAntabFile, bool overwriteAntabFile, bool reportAllTsysData)
bool extractContent(const QString &str, QString &content)
bool extractVcReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, const SgMJD &atEnd, SgChannelSetup &cs, const SgMJD &tFirst)
SgChannelSkeded * channelSkeded_
bool extractPatchReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, const SgMJD &atEnd, SgChannelSetup &cs, const SgMJD &tFirst)
bool extractMeteoReading(const QString &str, const QRegularExpression &reMeteo, SgMJD &t, SgMeteoData &m, const int *oom)
FieldSystemEpochFormat guessFsFormat(const QString &str)
bool readLogFile(const QString &fileName, const QString &stnName, const SgMJD &tFirst, const SgMJD &tLast, const QString &orderOfMeteo)
bool extractChanSkyFrqReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, const SgMJD &atEnd, SgChannelSetup &cs, const SgMJD &tFirst)
bool extractDot2gpsVgosReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, QString &sKey, float &dot2gps, const SgMJD &tAtTheBegin)
bool extractEpoch(const QString &str, SgMJD &t)
bool extractLoReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, const SgMJD &atEnd, SgChannelSetup &cs, const SgMJD &tFirst)
bool extractDataFromPcmtRecord(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, double &v, QString &source, QString &scan)
static const QRegularExpression reFsNewest_
bool extractPcalVgosReading(const QString &str, const QRegularExpression &re, SgMJD &t, QMap< QString, float * > &pcal, const SgMJD &tAtTheBegin)
QMap< QString, Procedure * > procedureByName_
static const QRegularExpression reFsNew_
SgStnLogReadings logReadings_
bool checkRinexFile(const QString &fileName, const SgMJD &tStart, const SgMJD &tFinis, const QString &rinexStnName)
bool extractSefdReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, QString &sensorId, QString &srcName, double &az, double &de, QVector< double > &vec, const SgMJD &tAtTheBegin)
bool extractTpcontVgosReading(const QString &str, const QRegularExpression &reTpcont, SgMJD &t, QMap< QString, QVector< int > > &tPcont, const SgMJD &tAtTheBegin)
bool extractLoRxgReading(const QString &str, const QRegularExpressionMatch &match, SgMJD &t, const SgMJD &atEnd, SgChannelSetup &cs, const SgMJD &tFirst)
const QString & getRecorderInfo() const
QList< SgDbbc3TpReading * > & dbbc3Tps()
static const QString sFiller_
QList< SgTraklReading * > & trakls()
QList< SgDot2xpsReading * > dot2xpses_
QList< SgSefdReading * > sefds_
void export2antabFrqs_vgosSetup(QTextStream &s)
bool createAntabFile(const QString &inputLogFileName, const QString &outputFileName, const QString &stnKey, const SgChannelSkeded *channelSkeded, bool useSkededChannelSetup, bool have2overwrite, bool reportAllTsysData)
void export2antCalFrqs_vgosSetup(QTextStream &s)
QList< SgCableCalReading * > & cableCals()
void export2antabFrqs_skededSetup(QTextStream &s, const SgChannelSkeded::StnCfg &sCfg)
QList< SgTsysReading * > & tSyses()
bool createAntCalFile(const QString &inputLogFileName, const QString &outputFileName, const QString &stnKey, const SgChannelSkeded *channelSkeded, bool useSkededChannelSetup, bool have2overwrite, bool reportAllReadings, bool supressNonUsedSensors, int antcalOutputData, const QString &ext4compress, const QString &userCommand)
void interpolateMeteoParameters(SgVlbiAuxObservation *aux)
void setCableCalAmbig(double a)
void export2antabFrqs_nativeSetup(QTextStream &s)
QList< SgPcalReading * > pcals_
static const QString className()
QList< SgSefdReading * > & sefds()
QList< SgDbbc3TpReading * > dbbc3Tps_
void export2antabFrqs_missedSetup(QTextStream &s)
void setCableSign(int n)
static const double dFiller_
QList< SgCableCalReading * > cableCals_
bool compareChannelSetups(const SgChannelSkeded::StnCfg &sCfg)
void lookupScanName(SgOnSourceRecord *osRec, const QMap< QString, SgVlbiAuxObservation * > &auxObsByScan)
QList< SgMeteoReading * > & meteoPars()
QList< SgDot2xpsReading * > & dot2xpses()
void setRecorderInfo(const QString &info)
void setStationName(const QString &name)
void setBackEndInfo(const QString &info)
QList< SgOnSourceRecord * > & onSourceRecords()
QList< SgOnSourceRecord * > onSourceRecords_
QList< SgTraklReading * > trakls_
SgChannelSetup & channelSetup()
SgChannelSetup channelSetup_
const QString & getExperimentName() const
void setExperimentName(const QString &name)
QList< SgTsysReading * > tSyses_
QList< SgMeteoReading * > meteoPars_
const QString & getBackEndInfo() const
void export2antCalPcal_vgosSetup(QTextStream &s)
QList< SgCableCalReading * > & cableLongs()
void setFsVersionLabel(const QString &ver)
int getCableSign() const
QList< SgCableCalReading * > cableLongs_
void export2antCalFrqs_skededSetup(QTextStream &s, const SgChannelSkeded::StnCfg &sCfg)
bool compareChannelNumbers(const SgChannelSkeded::StnCfg &sCfg)
bool propagateData(SgVlbiStationInfo *stn)
void verifyReadings(SgVlbiStationInfo *stn, const QMap< QString, int > *defaultCableSignByStn)
static const int nFiller_
QList< SgPcalReading * > & pcals()
QMap< QString, SgOnSourceRecord * > recordByScan_
void setItType(InputType t)
void export2antCalFrqs_nativeSetup(QTextStream &s)
static const QString className()
void setT(const SgMJD &t)
void setElv(float elv)
float getEl() const
float getAz() const
void setAzv(float azv)
void setAz(float az)
void setEl(float el)
const SgMJD & getT() const
void setOsRec(SgOnSourceRecord *os)
void setT(const SgMJD &t)
static const QString className()
void addTsyses(const QMap< QString, float > &tsys)
void setIsOnSource(bool isOnSource)
const QMap< QString, float > & getTsys() const
QMap< QString, QVector< int > > & tpcont()
QList< SgTraklReading * > & trakls()
const SgOnSourceRecord * getOsRec() const
void setIsDataOn(bool isDataOn)
const SgMJD & getT() const
QMap< QString, QVector< int > > tpcont_
QMap< QString, float > & tsys()
const QMap< QString, QVector< int > > & getTpcont() const
QMap< QString, float > tsys_
void addTpconts(const QMap< QString, QVector< int > > &tpcont)
SgOnSourceRecord *& osRec()
void setElement(unsigned int i, double d)
Definition: SgVector.h:348
double getElement(unsigned int i) const
Definition: SgVector.h:362
QString name(NameFormat fmt=NF_Human) const
Definition: SgVersion.cpp:54
static const QString className()
bool readLogFile(const QString &fileName, int year)
bool strs2mjd(int nYear, const QString &sDay, const QString &sHr, const QString &sMin, const QString &sSec, SgMJD &t)
bool propagateData(SgVlbiStationInfo *stn)
static const QString ivsStationNames_[NUM_OF_VLBA_ENTRIES]
bool isVlba(const QString &key) const
static const QString vlbaStationCodes_[NUM_OF_VLBA_ENTRIES]
QMap< QString, QString > ivs2vlba_
QMap< QString, SgStnLogReadings * > readingsByKey_
void setTsyses(const SgVector &ts)
void setCableCalibration(double cable)
void setMeteoData(const SgMeteoData &meteo)
SgVlbiObservation * getOwner() const
SgVlbiSourceInfo * src()
const QString & getScanName() const
QMap< QString, SgVlbiObservable * > & observableByKey()
QMap< QString, SgVlbiAuxObservation * > * auxObservationByScanId()
QVector< QString > & tsysIfSideBands()
QVector< double > & tsysIfFreqs()
QVector< QString > & tsysIfIds()
QString name() const
@ Attr_HAS_CABLE_CAL
a station has cable calibration readings;
@ Attr_METEO_MODIFIED
a station has meteo parameters;
@ Attr_CABLE_CAL_MODIFIED
a station has cable calibration readings;
@ Attr_HAS_METEO
a station has meteo parameters;
@ Attr_CABLE_CAL_IS_CDMS
FS log file contains /CDMS/ readings instead of /cable/;.
void setCableCalMultiplierDBCal(double c)
QVector< QString > & tsysIfPolarizations()
SgVersion * driverVersion
Definition: l2aVersion.cpp:31