General Purpose Geodetic Library
SgVlbiBand.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is a part of Space Geodetic Library. The library is used by
4  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
5  * geodetic VLBI observations.
6  * Copyright (C) 2010-2020 Sergei Bolotin.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include <iostream>
24 #include <stdlib.h>
25 
26 #include <QtCore/QDataStream>
27 
28 
29 #include <SgLogger.h>
30 #include <SgTaskConfig.h>
31 #include <SgTaskManager.h>
32 #include <SgVlbiBand.h>
33 #include <SgVlbiObservable.h>
34 #include <SgVlbiObservation.h>
35 
36 
37 
38 /*=======================================================================================================
39 *
40 * SgVlbiBand's METHODS:
41 *
42 *======================================================================================================*/
43 // An empty constructor:
45  SgObjectInfo(-1, "_"),
46  observables_(),
47  history_(),
48  stationsByName_(),
49  baselinesByName_(),
50  sourcesByName_(),
51  stationsByIdx_(),
52  baselinesByIdx_(),
53  sourcesByIdx_(),
54  sampleRateByCount_(),
55  bitsPerSampleByCount_(),
56  recordMode_(""),
57  grdAmbigsBySpacing_(),
58  strGrdAmbigsStat_(""),
59  phdAmbigsBySpacing_(),
60  strPhdAmbigsStat_(""),
61  phCalOffset_1ByBln_(),
62  phCalOffset_2ByBln_()
63 {
64  frequency_ = 0.0;
65  tCreation_ = tZero;
66  inputFileName_ = "null";
68  correlatorType_ = "Mk0";
70  sampleRate_ = 0.0;
71  bitsPerSample_ = 0;
74 };
75 
76 
77 
78 // destructor:
80 {
81  stationsByIdx_.clear();
82  baselinesByIdx_.clear();
83  sourcesByIdx_.clear();
84  sampleRateByCount_.clear();
85  bitsPerSampleByCount_.clear();
86  grdAmbigsBySpacing_.clear();
87  phdAmbigsBySpacing_.clear();
88  phCalOffset_1ByBln_.clear();
89  phCalOffset_2ByBln_.clear();
90 
91  // clear maps:
92  for (QMap<QString, SgVlbiStationInfo*>::iterator it=stationsByName_.begin();
93  it != stationsByName_.end(); ++it)
94  delete it.value();
95  stationsByName_.clear();
96 
97  for (QMap<QString, SgVlbiBaselineInfo*>::iterator it=baselinesByName_.begin();
98  it != baselinesByName_.end(); ++it)
99  delete it.value();
100  baselinesByName_.clear();
101 
102  for (QMap<QString, SgVlbiSourceInfo*>::iterator it=sourcesByName_.begin();
103  it != sourcesByName_.end(); ++it)
104  delete it.value();
105  sourcesByName_.clear();
106 
107  // clear observations container:
108  observables_.clear();
109 };
110 
111 
112 
113 //
115 {
116  // attributes:
118  //
119  for (QMap<QString, SgVlbiStationInfo*>::iterator it=stationsByName_.begin();
120  it!=stationsByName_.end(); ++it)
121  it.value()->resetAllEditings();
122  for (QMap<QString, SgVlbiSourceInfo*>::iterator it=sourcesByName_.begin();
123  it!=sourcesByName_.end(); ++it)
124  it.value()->resetAllEditings();
125  for (QMap<QString, SgVlbiBaselineInfo*>::iterator it=baselinesByName_.begin();
126  it!=baselinesByName_.end(); ++it)
127  it.value()->resetAllEditings();
128  //
130 };
131 
132 
133 
134 //
136 {
137  s << getKey() << getAttributes() << getSigma2add(DT_DELAY);
138  if (s.status() != QDataStream::Ok)
139  {
141  ": saveIntermediateResults(): error writting data");
142  return false;
143  };
144  //
145  for (QMap<QString, SgVlbiStationInfo*>::const_iterator it=stationsByName_.begin();
146  it!=stationsByName_.end(); ++it)
147  if (s.status() == QDataStream::Ok)
148  {
149  s << it.value()->getKey(); // put a station name to check order
150  it.value()->clockBreaks().saveIntermediateResults(s);
151  }
152  else
153  {
155  ": saveIntermediateResults(): error writting clock break data: " + it.value()->getKey());
156  return false;
157  };
158  //
159  if (s.status() != QDataStream::Ok)
160  {
162  ": saveIntermediateResults(): error writting data");
163  return false;
164  };
165  return s.status() == QDataStream::Ok;
166 };
167 
168 
169 
170 //
172 {
173  QString key;
174  unsigned int attributes;
175  double sigma2add;
176  s >> key >> attributes >> sigma2add;
177  if (s.status() != QDataStream::Ok)
178  {
180  ": loadIntermediateResults(): error reading data: " +
181  (s.status()==QDataStream::ReadPastEnd?"read past end of the file":"read corrupt data"));
182  return false;
183  };
184  if (getKey() != key)
185  {
187  ": loadIntermediateResults(): error reading data: wrong order, key mismatch: got [" + key +
188  "], expected [" + getKey() + "]");
189  return false;
190  };
191 
192  for (QMap<QString, SgVlbiStationInfo*>::iterator it=stationsByName_.begin();
193  it!=stationsByName_.end(); ++it)
194  if (s.status() == QDataStream::Ok)
195  {
196  s >> key; // first, check the order:
197  if (it.value()->getKey() != key)
198  {
200  ": loadIntermediateResults(): error reading data: wrong order, key mismatch: got [" + key +
201  "], expected [" + it.value()->getKey() + "]");
202  return false;
203  }
204  if (!it.value()->clockBreaks().loadIntermediateResults(s))
205  {
207  ": loadIntermediateResults(): error reading data: clock break data for " +
208  it.value()->getKey());
209  return false;
210  }
211  }
212  else
213  {
215  ": loadIntermediateResults(): error writting clock break data for " + it.value()->getKey() +
216  ": " + (s.status()==QDataStream::ReadPastEnd?"read past end of the file":"read corrupt data"));
217  return false;
218  };
219  setAttributes(attributes);
220  setSigma2add(DT_DELAY, sigma2add);
221  //
222  return s.status()==QDataStream::Ok;
223 };
224 
225 
226 
227 //
229 {
230  QMap<QString, QMap<QString, int> >
231  numByScanIdBySrc;
232  QString str("");
233  bool isOk=true;
234  int numOfZCodes=0;
235  int num;
236  maxNumOfChannels_ = 0;
237  sampleRate_ = 0.0;
238  bitsPerSample_ = 0;
239  sampleRateByCount_.clear();
240  bitsPerSampleByCount_.clear();
241  grdAmbigsBySpacing_.clear();
242  phdAmbigsBySpacing_.clear();
243 
244  // set up "typical" group delay ambiguity spacing for the band:
245  for (int i=0; i<observables_.size(); i++)
246  {
250  if (maxNumOfChannels_ < o->getNumOfChannels())
252  if (o->getErrorCode() == "Z")
253  numOfZCodes++;
254  numByScanIdBySrc[o->owner()->src()->getKey()][o->owner()->getScanId()]++;
257  };
258  //
259  // set up the typical sample rate:
260  if (sampleRateByCount_.size() == 0) //?
262  "::selfCheck(): cannot find the sample rate for the " + getKey() + "-band");
263  else if (sampleRateByCount_.size() == 1)
264  {
265  sampleRate_ = sampleRateByCount_.begin().key();
267  "::selfCheck(): set up the sample rate to " + QString("").sprintf("%.2f", sampleRate_) +
268  " for the " + getKey() + "-band");
269  }
270  else
271  {
272  num = 0;
274  "::selfCheck(): found multiple values of the sample rate at the " + getKey() + "-band:");
275  for (QMap<double, int>::iterator it=sampleRateByCount_.begin(); it!=sampleRateByCount_.end(); ++it)
276  {
278  "::selfCheck(): " + QString("").sprintf("%.2f -> %d times", it.key(), it.value()));
279  if (it.value() > num)
280  {
281  num = it.value();
282  sampleRate_ = it.key();
283  };
284  };
286  "::selfCheck(): set up the typical sample rate to " + QString("").sprintf("%.2f", sampleRate_) +
287  " for the " + getKey() + "-band");
288  };
289  //
290  // set up the typical bits per sample:
291  if (bitsPerSampleByCount_.size() == 0) //?
293  "::selfCheck(): cannot find the bits per sample for the " + getKey() + "-band");
294  else if (bitsPerSampleByCount_.size() == 1)
295  {
296  bitsPerSample_ = bitsPerSampleByCount_.begin().key();
298  "::selfCheck(): set up the bits per sample to " + QString("").sprintf("%d", bitsPerSample_) +
299  " for the " + getKey() + "-band");
300  }
301  else
302  {
303  num = 0;
305  "::selfCheck(): found multiple values of the bits per sample at the " + getKey() + "-band:");
306  for (QMap<int, int>::iterator it=bitsPerSampleByCount_.begin(); it!=bitsPerSampleByCount_.end();
307  ++it)
308  {
310  "::selfCheck(): " + QString("").sprintf("%d -> %d times", it.key(), it.value()));
311  if (it.value() > num)
312  {
313  num = it.value();
314  bitsPerSample_ = it.key();
315  };
316  };
318  "::selfCheck(): set up the typical bits per sample to " +
319  QString("").sprintf("%d", bitsPerSample_) + " for the " + getKey() + "-band");
320  };
321  recordMode_.sprintf("NChan:%d Rbw:%.1f Bps:%d",
323 
325  "::selfCheck(): the record mode has been set to \"" + recordMode_ +
326  "\" for the " + getKey() + "-band:");
327 
328  //
329  //
330  num = 0;
331  // group delay:
332  for (QMap<double, int>::iterator it=grdAmbigsBySpacing_.begin(); it!=grdAmbigsBySpacing_.end(); ++it)
333  {
334  if (it.value() > num)
335  {
336  num = it.value();
337  typicalGrdAmbigSpacing_ = it.key();
338  };
339  };
340  if (grdAmbigsBySpacing_.size() == 1)
341  strGrdAmbigsStat_.sprintf("%.1f", grdAmbigsBySpacing_.begin().key()*1.0e9);
342  else
343  {
344  strGrdAmbigsStat_ = "";
345  num = observables_.size();
346  for (QMap<double, int>::iterator it=grdAmbigsBySpacing_.begin(); it!=grdAmbigsBySpacing_.end(); ++it)
347  strGrdAmbigsStat_ += QString("").sprintf("%.1f (%.1f%%), ", it.key()*1.0e9, it.value()*100.0/num);
349  };
350  //
351  // phase delay:
352  num = 0;
353  for (QMap<double, int>::iterator it=phdAmbigsBySpacing_.begin(); it!=phdAmbigsBySpacing_.end(); ++it)
354  {
355  if (it.value() > num)
356  {
357  num = it.value();
358  typicalPhdAmbigSpacing_ = it.key();
359  };
360  };
361  if (phdAmbigsBySpacing_.size() == 1)
362  strPhdAmbigsStat_.sprintf("%.3f", phdAmbigsBySpacing_.begin().key()*1.0e9);
363  else
364  {
365  strPhdAmbigsStat_ = "";
366  num = observables_.size();
367  for (QMap<double, int>::iterator it=phdAmbigsBySpacing_.begin(); it!=phdAmbigsBySpacing_.end(); ++it)
368  strPhdAmbigsStat_ += QString("").sprintf("%.3f (%.1f%%), ", it.key()*1.0e9, it.value()*100.0/num);
370  };
371  //
372  //
373  if (typicalGrdAmbigSpacing_ > 0.0)
374  {
377  "::selfCheck(): the typical ambig.spacing for the " + getKey() + "-band was set to " +
378  QString("").sprintf("%.2fns", typicalGrdAmbigSpacing_*1.0e9));
379  }
380  else
381  {
384  "::selfCheck(): set up of the typical ambig.spacing for the " + getKey() + "-band failed");
385  };
386  // adjust error codes: Z code was added by the import procedure
387  // if all codes are "Z", that is an old DSN session, remove them:
388  if (numOfZCodes == observables_.size() && !isAttr(Attr_HAS_AMBIGS))
389  {
390  for (int i=0; i<observables_.size(); i++)
391  observables_.at(i)->setErrorCode(" ");
393  "::selfCheck(): looks like an old DSN session, the error codes have been cleared");
394  };
395  //
396  // baselines:
397  for (BaselinesByName_it it=baselinesByName_.begin(); it!=baselinesByName_.end(); ++it)
398  isOk = isOk && it.value()->selfCheck();
399  //
400  // sources:
401  for (SourcesByName_it it=sourcesByName_.begin(); it!=sourcesByName_.end(); ++it)
402  {
403  SgVlbiSourceInfo *si=it.value();
404  if (numByScanIdBySrc.contains(si->getKey()))
405  si->setTotalScanNum(numByScanIdBySrc.value(si->getKey()).size());
406  else
407  {
408  str = si->getKey();
409  // the source have no any observations on the primary band, remove it from the maps:
410  --it;
411  sourcesByName_.remove(str);
412  delete si;
414  "::selfCheck(): the source \"" + str + "\" has no any good observations in the primary band"
415  ", it was removed from the " + getKey() + "-band too");
416  };
417  };
419  "::selfCheck(): numbers of scans per a source were calculated", true);
420  //
421  return isOk;
422 };
423 /*=====================================================================================================*/
424 
425 
426 
427 
428 /*=====================================================================================================*/
SgLogger * logger
Definition: SgLogger.cpp:231
const SgMJD tZero(1957, 10, 4)
QMap< QString, SgVlbiBaselineInfo * >::iterator BaselinesByName_it
QMap< QString, SgVlbiSourceInfo * >::iterator SourcesByName_it
@ DT_DELAY
Definition: SgWrmsable.h:44
bool isAttr(uint a) const
Definition: SgAttribute.h:226
void setAttributes(unsigned int a)
Definition: SgAttribute.h:191
unsigned int getAttributes() const
Definition: SgAttribute.h:183
void delAttr(uint a)
Definition: SgAttribute.h:210
void addAttr(uint a)
Definition: SgAttribute.h:202
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ IO_BIN
Definition: SgLogger.h:64
@ PREPROC
Definition: SgLogger.h:98
void resetAllEditings()
Definition: SgObjectInfo.h:595
double getSigma2add(DataType) const
Definition: SgObjectInfo.h:367
const QString & getKey() const
Definition: SgObjectInfo.h:319
void setSigma2add(DataType dType, double d)
Definition: SgObjectInfo.h:471
QString strPhdAmbigsStat_
Definition: SgVlbiBand.h:264
QMap< int, SgVlbiBaselineInfo * > baselinesByIdx_
Definition: SgVlbiBand.h:246
int maxNumOfChannels_
Definition: SgVlbiBand.h:249
void resetAllEditings()
Definition: SgVlbiBand.cpp:114
int bitsPerSample_
Definition: SgVlbiBand.h:251
QMap< int, SgVlbiStationInfo * > stationsByIdx_
Definition: SgVlbiBand.h:245
QMap< QString, SgVector * > phCalOffset_2ByBln_
Definition: SgVlbiBand.h:267
double sampleRate_
Definition: SgVlbiBand.h:250
bool selfCheck()
Definition: SgVlbiBand.cpp:228
double frequency_
Definition: SgVlbiBand.h:232
QMap< int, int > bitsPerSampleByCount_
Definition: SgVlbiBand.h:253
bool saveIntermediateResults(QDataStream &) const
Definition: SgVlbiBand.cpp:135
QString strGrdAmbigsStat_
Definition: SgVlbiBand.h:260
double typicalGrdAmbigSpacing_
Definition: SgVlbiBand.h:259
QMap< QString, SgVlbiBaselineInfo * > baselinesByName_
Definition: SgVlbiBand.h:242
QMap< QString, SgVlbiStationInfo * > stationsByName_
Definition: SgVlbiBand.h:241
QString recordMode_
Definition: SgVlbiBand.h:254
QMap< QString, SgVector * > phCalOffset_1ByBln_
Definition: SgVlbiBand.h:266
QMap< double, int > sampleRateByCount_
Definition: SgVlbiBand.h:252
QList< SgVlbiObservable * > observables_
Definition: SgVlbiBand.h:234
int inputFileVersion_
Definition: SgVlbiBand.h:238
SgMJD tCreation_
Definition: SgVlbiBand.h:236
QString inputFileName_
Definition: SgVlbiBand.h:237
QMap< int, SgVlbiSourceInfo * > sourcesByIdx_
Definition: SgVlbiBand.h:247
QMap< double, int > grdAmbigsBySpacing_
Definition: SgVlbiBand.h:258
QMap< double, int > phdAmbigsBySpacing_
Definition: SgVlbiBand.h:262
bool loadIntermediateResults(QDataStream &)
Definition: SgVlbiBand.cpp:171
const QString className() const
Definition: SgVlbiBand.h:453
QString correlatorType_
Definition: SgVlbiBand.h:239
@ Attr_HAS_AMBIGS
the band contains group delays and ambiguities;
Definition: SgVlbiBand.h:62
@ Attr_NOT_VALID
omit these data;
Definition: SgVlbiBand.h:59
QMap< QString, SgVlbiSourceInfo * > sourcesByName_
Definition: SgVlbiBand.h:243
double typicalPhdAmbigSpacing_
Definition: SgVlbiBand.h:263
double getAmbiguitySpacing() const
double getSampleRate() const
int getNumOfChannels() const
const QString & getErrorCode() const
SgVlbiObservation * owner()
SgVlbiMeasurement & phDelay()
int getBitsPerSample() const
SgVlbiMeasurement & grDelay()
SgVlbiSourceInfo * src()
const QString & getScanId() const
void setTotalScanNum(int n)