General Purpose Geodetic Library
SgVlbiSessionUtilities.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 <SgVlbiSession.h>
27 
28 
29 #if QT_VERSION >= 0x050000
30 # include <QtWidgets/QMessageBox>
31 #else
32 # include <QtGui/QMessageBox>
33 #endif
34 
35 
36 #include <QtCore/QTextStream>
37 #include <QtCore/QFile>
38 
39 
40 #include <SgCubicSpline.h>
41 #include <SgEstimator.h>
42 #include <SgLogger.h>
44 #include <SgSolutionReporter.h>
45 #include <SgTaskManager.h>
46 #include <SgVector.h>
47 #include <SgVlbiBand.h>
48 #include <SgVlbiObservation.h>
49 
50 
51 #define LOCAL_DEBUG
52 
53 
54 
55 
56 // sorts obs by residuals:
58 
59 
60 
61 /*=======================================================================================================
62 *
63 * METHODS:
64 *
65 *======================================================================================================*/
66 //
68 {
69  bool stnPosRead, stnVelRead, srcPosRead, srcSmRead, axsOfsRead, hiFyEopRead,
70  stnGrdRead, extErpRead;
71  QString path2efaStnPos(config_->evaluatePath2(path2APrioriFiles_,
73  QString path2efaStnVel(config_->evaluatePath2(path2APrioriFiles_,
75  QString path2efaSrcPos(config_->evaluatePath2(path2APrioriFiles_,
77  QString path2efaSrcSsm(config_->evaluatePath2(path2APrioriFiles_,
79  QString path2efaAxsOfs(config_->evaluatePath2(path2APrioriFiles_,
81  QString path2efaHiFyEop(config_->evaluatePath2(path2APrioriFiles_,
83  QString path2efaStnGrd(config_->evaluatePath2(path2APrioriFiles_,
85  QString path2extErp(config_->evaluatePath2(path2APrioriFiles_,
87 
88  stnPosRead = stnVelRead = srcPosRead = srcSmRead = axsOfsRead = hiFyEopRead = stnGrdRead =
89  extErpRead = false;
90 
91  hiFyEopRead = (0<apHiFyEop_.getFileName().size() && apHiFyEop_.isOk());
92  // check for others too:
93 
94 
95 
96 
97  //
98  // read external sites position file:
99  if (path2efaStnPos != apStationPositions_.getFileName())
100  {
101  apStationPositions_.readFile(path2efaStnPos);
102  stnPosRead = true;
104  "::collectAPriories(): load from the file " + apStationPositions_.getFileName() +
105  QString("").sprintf(" %d", apStationPositions_.size()) + " records of a priori sites positions");
106  };
107  // read external sites velocities file:
108  if (path2efaStnVel != apStationVelocities_.getFileName())
109  {
110  apStationVelocities_.readFile(path2efaStnVel);
111  stnVelRead = true;
113  "::collectAPriories(): load from the file " + apStationVelocities_.getFileName() +
114  QString("").sprintf(" %d", apStationVelocities_.size()) + " records of a priori sites velocities");
115  };
116  // read external source positions file:
117  if (path2efaSrcPos != apSourcePositions_.getFileName())
118  {
119  apSourcePositions_.readFile(path2efaSrcPos);
120  srcPosRead = true;
122  "::collectAPriories(): load from the file " + apSourcePositions_.getFileName() +
123  QString("").sprintf(" %d", apSourcePositions_.size()) + " records of a priori sources positions");
124  };
125  // read external source ssm file:
126  if (path2efaSrcSsm != apSourceStrModel_.getFileName())
127  {
128  apSourceStrModel_.readFile(path2efaSrcSsm);
129  srcSmRead = true;
131  "::collectAPriories(): load from the file " + apSourceStrModel_.getFileName() +
132  QString("").sprintf(" %d", apSourceStrModel_.size()) + " records of source structure model");
133  };
134  // read external axis offsets file:
135  if (path2efaAxsOfs != apAxisOffsets_.getFileName())
136  {
137  apAxisOffsets_.readFile(path2efaAxsOfs);
138  axsOfsRead = true;
140  "::collectAPriories(): load from the file " + apAxisOffsets_.getFileName() +
141  QString("").sprintf(" %d", apAxisOffsets_.size()) + " records of a priori axis offsets");
142  };
143  // read external high frequency ERP file:
144  if (path2efaHiFyEop != apHiFyEop_.getFileName())
145  {
146  apHiFyEop_.readFile(path2efaHiFyEop);
147  hiFyEopRead = true;
149  "::collectAPriories(): load from the file " + apHiFyEop_.getFileName() + " model of hi frequency EOP");
150  };
151  // read external mean sites gradients file:
152  if (path2efaStnGrd != apStationGradients_.getFileName())
153  {
154  apStationGradients_.readFile(path2efaStnGrd);
155  stnGrdRead = true;
157  "::collectAPriories(): load from the file " + apStationGradients_.getFileName() +
158  QString("").sprintf(" %d", apStationGradients_.size()) +
159  " records of a priori mean sites gradients");
160  };
161  // read external ERP file:
163  path2extErp != externalErpFile_.getFileName())
164  {
166  extErpRead = true;
168  "::collectAPriories(): read " + QString("").setNum(numOfPts4ErpInterpolation_) +
169  " records from the external a priori ERP file " + externalErpFile_.getFileName() +
170  "; mean epoch: " + tMean_.toString());
171  };
172  // End of reading external files.
174  "::collectAPriories(): files with external a priori were read", true);
175 
176  // Update info:
177  //
178  // first, check stations:
179  SgAPrioriRec *apRec=NULL;
180  for (StationsByName_it it=stationsByName_.begin(); it!=stationsByName_.end(); ++it)
181  {
182  SgVlbiStationInfo *si=it.value();
183  // process coordinates and velocities:
184  if (apStationPositions_.size() && apStationVelocities_.size() && (stnPosRead || stnVelRead))
185  {
187  if (apRec)
188  {
190  si->setR_ea(Sg3dVector(apRec->at(0).getDvalue("0"), apRec->at(0).getDvalue("1"),
191  apRec->at(0).getDvalue("2")));
193  "::collectAPriories(): set up external a priori coords for station " +
194  si->getKey() + "; the diff is " +
195  QString("").sprintf("%.1f mm", (si->getR() - si->getR_ea()).module()*1.0e3) +
196  "; tSince: " + apRec->getTsince().toString());
197  }
198  else
199  {
202  "::collectAPriories(): cannot find station " + si->getKey() +
203  " in the list of a priori coordinates");
204  si->setR_ea(si->getR());
205  };
207  if (apRec)
208  si->setV_ea(Sg3dVector(apRec->at(0).getDvalue("0"), apRec->at(0).getDvalue("1"),
209  apRec->at(0).getDvalue("2")));
210  else
211  {
214  "::collectAPriories(): cannot find station " + si->getKey() +
215  " in the list of a priori velocities");
216  si->setV_ea(v3Zero);
217  };
218  };
219  // process external axis offsets:
220  if (apAxisOffsets_.size() && axsOfsRead)
221  {
222  if ((apRec=apAxisOffsets_.lookupApRecord(si->getKey())))
223  {
225  // set up a posteriori value:
226  si->setAxisOffset_ea(apRec->at(0).getDvalue("1")); // from estimation
228  "::collectAPriories(): set an external a priori axis offset for station " +
229  si->getKey() + "; the diff is " +
230  QString("").sprintf("%.1f mm", (si->getAxisOffset() - si->getAxisOffset_ea())*1.0e3));
231  // check the value from the database and the "a priori" column (==0):
232  if (fabs(si->getAxisOffset() - apRec->at(0).getDvalue("0")) > 1.0e-4)
234  "::collectAPriories(): a priori axis offset for station " + si->getKey() +
235  QString("").sprintf(" has different value in the database (%.1f mm) and "
236  "the external file (%.1f mm)", si->getAxisOffset()*1.0e3, apRec->at(0).getDvalue("0")*1.0e3));
237  }
238  else
239  {
242  "::collectAPriories(): cannot find station " + si->getKey() +
243  " in the list of a priori axis offsets");
244  si->setAxisOffset_ea(si->getAxisOffset());
245  };
246  };
247  // process external mean sites gradients:
248  if (apStationGradients_.size() && stnGrdRead)
249  {
250  if ((apRec=apStationGradients_.lookupApRecord(si->getKey())))
251  {
252  // set up a priori values:
253  si->setGradNorth(apRec->at(0).getDvalue("0"));
254  si->setGradEast (apRec->at(0).getDvalue("1"));
256  "::collectAPriories(): a priori gradients " + QString("").sprintf("(%6.2f and %6.1f mm)",
257  si->getGradNorth()*1000.0, si->getGradEast()*1000.0) +
258  " have been set up for station " + si->getKey());
259  }
260  else
262  "::collectAPriories(): cannot find station " + si->getKey() +
263  " in the list of a priori mean site gradients");
264  };
265  // end of station loop
266  };
268  "::collectAPriories(): the stations were done", true);
269  //
270  // then sources:
271  if ( (apSourcePositions_.size() && srcPosRead) ||
272 // (apSourceStrModel_.size() && srcSmRead)
273  srcSmRead )
274  {
275  for (SourcesByName_it it=sourcesByName_.begin(); it!=sourcesByName_.end(); ++it)
276  {
277  SgVlbiSourceInfo *si=it.value();
278  // positions:
279  if ((apRec=apSourcePositions_.lookupApRecord(si->getKey())))
280  {
282  si->setRA_ea(apRec->at(0).getDvalue("0"));
283  si->setDN_ea(apRec->at(0).getDvalue("1"));
284  si->setAprioriComments(apRec->getComments());
286  si->getRA_ea(), si->getDN_ea()));
288  "::collectAPriories(): set up external a priori coords for source " + si->getKey() +
289  "; the diff is " + QString("").sprintf("%.3f mas",
290  si->getAl2ExtA()*RAD2MAS));
291  }
292  else
293  {
296  "::collectAPriories(): cannot find source " + si->getKey() +
297  " in the list of a priori coordinates");
299  si->setRA_ea(si->getRA());
300  si->setDN_ea(si->getDN());
301  si->setAprioriComments("");
302  si->setAl2ExtA(0.0);
303  };
304  // SSM:
305  // clear the existing model:
306  if (si->sModel().size())
307  si->clearSrcStructPoints();
308  if ((apRec=apSourceStrModel_.lookupApRecord(si->getKey(), tStart_)))
309  {
310  for (int i=0; i<apRec->size(); i++)
311  {
312  double x, y, k, b;
313  bool er, ek, eb;
314  x = y = k = b = 0.0;
315  er = ek = eb = false;
316  x = apRec->at(i).getDvalue("MP_X");
317  y = apRec->at(i).getDvalue("MP_Y");
318  k = apRec->at(i).getDvalue("MP_K");
319  b = apRec->at(i).getDvalue("MP_B");
320  er= apRec->at(i).getBvalue("MP_ER");
321  ek= apRec->at(i).getBvalue("MP_EK");
322  eb= apRec->at(i).getBvalue("MP_EB");
323 /*
324  if (fabs(x) < 1.0e-6 && fabs(y) < 1.0e-6)
325  logger->write(SgLogger::WRN, SgLogger::IO_TXT | SgLogger::FLY_BY, className() +
326  "::collectAPriories(): cannot add SSM for the source \"" + si->getKey() +
327  "\": x and y are zeros");
328  else if (!(0.0 < k && k < 1.0))
329  logger->write(SgLogger::WRN, SgLogger::IO_TXT | SgLogger::FLY_BY, className() +
330  "::collectAPriories(): cannot add SSM for the source \"" + si->getKey() +
331  "\": k is out of range");
332  else
333 */
334  // check for usable values; a user can turn off a model if k==0:
335  if ((1.0e-6 < fabs(x) || 1.0e-6 < fabs(y)) && 0.0 < k && k < 1.0)
336  si->addSrcStructPoint(k, b, x/RAD2MAS, y/RAD2MAS, ek, eb, er);
337  };
339  "::collectAPriories(): found " + QString("").setNum(apRec->size()) +
340  "-component multipoint SS model for the source \"" + si->getKey() + "\"");
341  }
342  else
343  {
344 // logger->write(SgLogger::WRN, SgLogger::IO_TXT | SgLogger::FLY_BY, className() +
345 // "::collectAPriories(): cannot find source " + si->getKey() +
346 // " in the list of SSM");
347  };
348  };
349  };
351  "::collectAPriories(): the sources were done", true);
352 
353 
354  // ERP:
355  // if (extErpRead && externalErpFile_.isOk())
358  {
361  "::collectAPriories(): ERP were prepared for interpolation", true);
362  }
363  else
365  "::collectAPriories(): cannot make ERP interpolation: data are not provided", true);
366 
367  // and individual observations:
368  QString str;
369  double dT, t;
370  dT = (getLeapSeconds() + 32.184)/DAY2SEC;
371  for (int iObs=0; iObs<observations_.size(); iObs++)
372  {
373  SgVlbiObservation *obs=observations_.at(iObs);
374  double dUt, dPx, dPy, dCx, dCy;
375  double ut0i, px0i, py0i;
376  double ut0e, px0e, py0e;
377  double cx0e, cy0e;
378  double r;
379  dUt = dPx = dPy = dCx = dCy = 0.0;
380  t = obs->toDouble() + dT;
381  //
382  // external HiFrequency ERP model:
383  if (hiFyEopRead)
384  {
385  apHiFyEop_.calcCorrections(*obs+dT, dUt, dPx, dPy);
386  dUt /= 1.0e6*DAY2SEC;
387  dPx /= 1.0e3*RAD2MAS;
388  dPy /= 1.0e3*RAD2MAS;
389  /*
390  obs->setAprioriUt1HfContrib(dUt);
391  obs->setAprioriPxHfContrib(dPx);
392  obs->setAprioriPyHfContrib(dPy);
393  */
394  obs->setExtDelayHiFyPxy((obs->getDdel_dPx()*dPx + obs->getDdel_dPy()*dPy));
395  obs->setExtDelayHiFyUt1( obs->getDdel_dUT1()*dUt );
396  obs->setExtRateHiFyPxy ((obs->getDrat_dPx()*dPx + obs->getDrat_dPy()*dPy));
397  obs->setExtRateHiFyUt1 ( obs->getDrat_dUT1()*dUt );
398  // make it SOLVE-compatible:
399  obs->setAprioriUt1HfContrib(0.0);
400  obs->setAprioriPxHfContrib(0.0);
401  obs->setAprioriPyHfContrib(0.0);
402  }
403  else
404  {
405 std::cout << " -- no HF calculated\n";
406  /*
407  // need to add a priori HF from database too:
408  // ... later ...
409  obs->setAprioriUt1HfContrib(dUt);
410  obs->setAprioriPxHfContrib(dPx);
411  obs->setAprioriPyHfContrib(dPy);
412  */
413  obs->setExtDelayHiFyPxy(0.0);
414  obs->setExtDelayHiFyUt1(0.0);
415  obs->setExtRateHiFyPxy (0.0);
416  obs->setExtRateHiFyUt1 (0.0);
417  };
418  //
419  obs->setAprioriUt1HfContrib(dUt);
420  obs->setAprioriPxHfContrib(dPx);
421  obs->setAprioriPyHfContrib(dPy);
422  //
423  // external ERP a priori:
425  {
431 
432  ut0i = innerUt1Interpolator_->spline(t, 0, r)/DAY2SEC;
433  px0i = innerPxyInterpolator_->spline(t, 0, r)/RAD2MAS;
434  py0i = innerPxyInterpolator_->spline(t, 1, r)/RAD2MAS;
435  //
436  dUt = ut0e - ut0i;
437  dPx = px0e - px0i;
438  dPy = py0e - py0i;
439  dCx = cx0e;
440  dCy = cy0e;
441  //
443  {
444  obs->setExtDelayErp(obs->getDdel_dUT1()*dUt +
445  obs->getDdel_dPx() *dPx + obs->getDdel_dPy() *dPy +
446  obs->getDdel_dCipX()*dCx + obs->getDdel_dCipY()*dCy);
447  obs->setExtRateErp (obs->getDrat_dUT1()*dUt +
448  obs->getDrat_dPx() *dPx + obs->getDrat_dPy() *dPy +
449  obs->getDrat_dCipX()*dCx + obs->getDrat_dCipY()*dCy);
450  obs->setAprioriUt1LfContrib(ut0e);
451  obs->setAprioriPxLfContrib(px0e);
452  obs->setAprioriPyLfContrib(py0e);
453  obs->setAprioriCxLfContrib(cx0e);
454  obs->setAprioriCyLfContrib(cy0e);
455  }
456  else
457  {
458  obs->setExtDelayErp(0.0);
459  obs->setExtRateErp (0.0);
460  obs->setAprioriUt1LfContrib(ut0i);
461  obs->setAprioriPxLfContrib(px0i);
462  obs->setAprioriPyLfContrib(py0i);
463  };
464  }
465  else
466  {
467  obs->setExtDelayErp(0.0);
468  obs->setExtRateErp (0.0);
470  {
471  ut0i = innerUt1Interpolator_->spline(t, 0, r)/DAY2SEC;
472  obs->setAprioriUt1LfContrib(ut0i);
473  };
475  {
476  px0i = innerPxyInterpolator_->spline(t, 0, r)/RAD2MAS;
477  py0i = innerPxyInterpolator_->spline(t, 1, r)/RAD2MAS;
478  obs->setAprioriPxLfContrib(px0i);
479  obs->setAprioriPyLfContrib(py0i);
480  };
481  };
482  };
483  if (hiFyEopRead)
485  "::collectAPriories(): the observations have been updated with external model "
486  "of high frequency EOP variations");
488  "::collectAPriories(): the observations were done", true);
489 };
490 
491 
492 
493 //
495  double& vUt1, double& rUt1,
496  double& vPx, double& rPx, double& vPy, double& rPy,
497  double& vCx, double& rCx, double& vCy, double& rCy)
498 {
499  vUt1 = rUt1 = vPx = rPx = vPy = rPy = vCx = rCx = vCy = rCy = 0.0;
500  double dT, t;
501  dT = (getLeapSeconds() + 32.184)/DAY2SEC;
502  t = epoch.toDouble() + dT;
503 
505  {
511  }
512  else
513  {
514  vUt1= innerUt1Interpolator_->spline(t, 0, rUt1);
515  vPx = innerPxyInterpolator_->spline(t, 0, rPx );
516  vPy = innerPxyInterpolator_->spline(t, 1, rPy );
517  };
518  vUt1/= DAY2SEC;
519  rUt1/= DAY2SEC;
520  vPx /= RAD2MAS;
521  rPx /= RAD2MAS;
522  vPy /= RAD2MAS;
523  rPy /= RAD2MAS;
524  vCx /= RAD2MAS;
525  rCx /= RAD2MAS;
526  vCy /= RAD2MAS;
527  rCy /= RAD2MAS;
529  "::getAprioriErp(): the ERP apriori for the epoch " + (epoch + dT).toString() + " are:");
531  "::getAprioriErp(): ut1: " +
532  QString("").sprintf("%12.6fms %12.6fms/d", vUt1*1.0e3*DAY2SEC, rUt1*1.0e3*DAY2SEC));
534  "::getAprioriErp(): p_x: " +
535  QString("").sprintf("%12.6fmas %12.6fmas/d", vPx*RAD2MAS, rPx*RAD2MAS));
537  "::getAprioriErp(): p_y: " +
538  QString("").sprintf("%12.6fmas %12.6fmas/d", vPy*RAD2MAS, rPy*RAD2MAS));
540  "::getAprioriErp(): CIP_x: " +
541  QString("").sprintf("%12.6fmas %12.6fmas/d", vCx*RAD2MAS, rCx*RAD2MAS));
543  "::getAprioriErp(): CIP_y: " +
544  QString("").sprintf("%12.6fmas %12.6fmas/d", vCy*RAD2MAS, rCy*RAD2MAS));
545 };
546 
547 
548 
549 //
551 {
553  if (path2file != externalWeights_.getFileName())
554  externalWeights_.readFile(path2file);
555 };
556 
557 
558 
559 //
561 {
562 
566  delete innerUt1Interpolator_;
568  delete innerPxyInterpolator_;
570  innerUt1Interpolator_ = NULL;
571  innerPxyInterpolator_ = NULL;
572 
573 
574  if (externalErpFile_.isOk())
578 
579  // feed the interpolators:
581  "::prepare4ErpInterpolation(): the spliners were created", true);
582  int n;
583  //
584  // UT1:
585  n = args4Ut1Interpolation_->n();
586  for (int i=0; i<n; i++)
587  {
590  };
591  // Polar motion:
592  n = args4PxyInterpolation_->n();
593  for (int i=0; i<n; i++)
594  {
598  };
600  "::prepare4ErpInterpolation(): the inner interpolator has been fed", true);
601 
602  if (externalErpFile_.isOk())
603  {
604  double utOffset = 0.0;
607  {
608  utOffset = getLeapSeconds();
610  "::prepare4ErpInterpolation(): UT1-UTC will be adjusted by " + QString("").setNum(utOffset) +
611  " secs to get TAI", true);
612  };
613  // External table, UT1 and PM are in one file:
614  n = externalErpFile_.argument()->n();
615  for (int i=0; i<n; i++)
616  {
630  {
637  };
638  };
640  "::prepare4ErpInterpolation(): the outer interpolator has been fed", true);
641  //
643  {
645  "::prepare4ErpInterpolation(): database and external file UT1 types mismatch!"
646  " Trying to adjust, however, it was not tested.");
647  // mimic SOLVE's flybymap.f behavior:
650 
651  for (unsigned int i=0; i<innerUt1Interpolator_->argument().n(); i++)
652  innerUt1Interpolator_->table()(i, 0) -=
654  for (unsigned int i=0; i<externalErpInterpolator_->argument().n(); i++)
658  "::prepare4ErpInterpolation(): the UT1type has been adjusted", true);
659  };
661  "::prepare4ErpInterpolation(): the UT1type was checked", true);
662  };
663  //
664 
667  if (externalErpFile_.isOk())
670  "::prepare4ErpInterpolation(): the spliners were prepared", true);
671 
674 
675  /*
676  for (int i=0; i<innerUt1Interpolator_->numOfRecords(); i++)
677  {
678  QString str;
679  str.sprintf("%2d %14.6f %14.6f",
680  i, innerUt1Interpolator_->argument().getElement(i),
681  innerUt1Interpolator_->table().getElement(i, 0));
682  std::cout << qPrintable(str) << "\n";
683  };
684  std::cout << "PM table of interpolation from the database:\n";
685  for (int i=0; i<innerPxyInterpolator_->numOfRecords(); i++)
686  {
687  QString str;
688  str.sprintf("%2d %14.6f %14.6f %14.6f",
689  i, innerPxyInterpolator_->argument().getElement(i),
690  innerPxyInterpolator_->table().getElement(i, 0),
691  innerPxyInterpolator_->table().getElement(i, 1));
692  std::cout << qPrintable(str) << "\n";
693  };
694  std::cout << "ERP table of interpolation from the external file:\n";
695  for (int i=0; i<externalErpInterpolator_->numOfRecords(); i++)
696  {
697  QString str;
698  str.sprintf("%2d %14.6f %14.6f %14.6f %14.6f",
699  i, externalErpInterpolator_->argument().getElement(i),
700  externalErpInterpolator_->table().getElement(i, SgExternalErpFile::UT1_IDX),
701  externalErpInterpolator_->table().getElement(i, SgExternalErpFile::PMX_IDX),
702  externalErpInterpolator_->table().getElement(i, SgExternalErpFile::PMY_IDX));
703  std::cout << qPrintable(str) << "\n";
704  };
705  */
706 };
707 
708 
709 
710 //
712 {
713  int numOfCorrected=0;
714  // mimic SOLVE:
715  if (!(config_->getUseGoodQualityCodeAtStartup() /* && primaryBand_->getInputFileVersion()<4 */))
716  return numOfCorrected;
717 
718  QString primeBandKey=primaryBand_->getKey();
719  for (int i=0; i<observations_.size(); i++)
720  {
721  SgVlbiObservation *obs=observations_.at(i);
722  for (QMap<QString, SgVlbiObservable*>::iterator it=obs->observableByKey().begin();
723  it!=obs->observableByKey().end(); ++it)
724  {
725  SgVlbiObservable *o=it.value();
726  if (true)
727  {
728  //
729  // turn off any obs with QC<config_->getGoodQualityCodeAtStartup()
732  {
734  numOfCorrected++;
735  };
736  //
737  }
738  else // old version:
739  {
740  if (o->getBandKey()==primeBandKey && obs->isEligible(config_) &&
742  {
744  numOfCorrected++;
745  };
746  };
747  };
748  };
750  "::suppressNotSoGoodObs(): " + QString("").setNum(numOfCorrected) +
751  " observation" + (numOfCorrected==1?" was":"s were") +
752  " deselected due to not sufficiently high Quality Code, " +
753  QString("").setNum(config_->getGoodQualityCodeAtStartup()), true);
754  //
755  return numOfCorrected;
756 };
757 
758 
759 
760 //
762 {
763  if (!(config_ && parametersDescriptor_))
764  return;
765 
767  "::doPostReadActions_old(): post read actions initiated for the session " + getName(), true);
768 
769  // save pointers:
770  SgTaskConfig *config_saved = config_;
771  SgParametersDescriptor *parametersDescriptor_saved = parametersDescriptor_;
772 
773  config_ = new SgTaskConfig;
774  *config_ = *config_saved;
776  *parametersDescriptor_ = *parametersDescriptor_saved;
777 
779  //
780  //
782  //
783  if (config_->getDoIonoCorrection4SBD() && bands().size()>1)
784  {
786  "::doPostReadActions_old(): evaluating ionospheric corrections for single band delays", true);
788  };
789  //
791  {
793  "::doPostReadActions_old(): running clock break detections, early stage", true);
795  };
796  //
798  {
800  "::doPostReadActions_old(): elimination of outliers, early stage", true);
802  };
803  //
804  // restore pointers:
805  delete config_;
806  delete parametersDescriptor_;
807  config_ = config_saved;
808  parametersDescriptor_ = parametersDescriptor_saved;
809 };
810 
811 
812 
813 //
814 void SgVlbiSession::process(bool haveProcessAllBands, bool interactWithGui)
815 {
816  if (!(config_ && parametersDescriptor_))
817  {
819  "::process(): called in nonappropriate form: config of parametersDescriptor is NULL, ignoring");
820  return;
821  };
822 
823  bool hasArc, hasStc;
824  hasArc = hasStc = false;
825  for (int i=0; i<parametersDescriptor_->num(); i++)
826  {
829  hasArc = true;
831  hasStc = true;
832  };
833  if (hasArc && hasStc)
834  {
835  QMessageBox::warning(NULL, "Cannot estimate", "The software is unable to estimate a combination of "
836  "arc or piece-wise parameters and stochastic parameters. Latter releases will do it. Sorry for "
837  "unconvenience");
839  "::process(): cannot estimate arc or pwl AND stochastic parameters in one solution");
840  return;
841  };
842 
843 
844  SgTask *task = new SgTask("Internal run manager for the session " + getName());
845  QList<SgObservation*> *obsList = NULL;
846 
847  // config_->setPath2APrioriFiles(path2APrioriFiles_);
848  task->setConfig(*config_);
849  task->addSession((SgVlbiSessionInfo*)this, this);
851 
852  //
853  QString path2efa;
854  bool have2reloadEfas(false);
857  have2reloadEfas = true;
860  have2reloadEfas = true;
861 
864  have2reloadEfas = true;
867  have2reloadEfas = true;
870  have2reloadEfas = true;
872  if (path2efa != apHiFyEop_.getFileName() && config_->getUseExtAPrioriHiFyErp())
873  have2reloadEfas = true;
876  have2reloadEfas = true;
879  have2reloadEfas = true;
880  //
881 // if (have2reloadEfas || lastProcessedConfig_.getIsSolveCompatible() != config_->getIsSolveCompatible())
882 // if (lastProcessedConfig_ != *config_)
883  if (have2reloadEfas ||
892  )
893  {
896  {
897  // recalc geodetic coordinates:
898  for (StationsByName_it it=stationsByName_.begin(); it!=stationsByName_.end(); ++it)
899  it.value()->recalcRLF(config_->getIsSolveCompatible());
900  // do something else:
901 
902  };
903  };
904  //
905  // check for a file with external weights, if necessary -- read it and update weights.
907  {
909  if (externalWeights_.isOk())
910  {
911  zerofySigma2add();
913  }
914  else
915  {
916  // zerofySigma2add();
918  "::process(): reading an external weights file failed, no weights were applied");
919  };
920  };
921 
923 
924  obsList = (QList<SgObservation*>*) &observations_;
925  QString bandKey=bands_.at(config_->getActiveBandIdx())->getKey();
927  "::process(): starting analysis of the " + bandKey + "-band");
928 
929  for (int i=0; i<observations_.size(); i++)
930  {
931  SgVlbiObservation *obs=observations_.at(i);
932  obs->setupActiveObservable(bandKey);
934  };
935 
936  // set up the manager:
937  mgr->setObservations(obsList);
938  mgr->currentSessionInfo() = (SgVlbiSessionInfo*)this;
939  mgr->currentSession() = this;
940 
941  // GUI:
947  mgr->setHave2InteractWithGui(interactWithGui);
948  // mgr->setHave2InteractWithGui(false);
949 
950  // run it:
951  mgr->prepare4Run();
952  mgr->run(haveProcessAllBands);
953  if (reporter_)
954  reporter_->absorbInfo(mgr);
955  mgr->finisRun();
956 
957  delete task;
958  task = NULL;
959  delete mgr;
960  mgr = NULL;
961  // save the config:
963 };
964 
965 
966 
967 //
969 {
970  for (StationsByName_it it_s=stationsByName_.begin(); it_s!=stationsByName_.end(); ++it_s)
971  {
972  SgVlbiStationInfo *si=it_s.value();
973  //
974  bool isOk=false;
975  for (BaselinesByName_it it_b=baselinesByName_.begin(); it_b!=baselinesByName_.end(); ++it_b)
976  {
977  QString st1Name, st2Name;
978  SgVlbiBaselineInfo *bi=it_b.value();
979  st1Name = bi->getKey().left(8);
980  st2Name = bi->getKey().right(8);
981  if ((si->getKey() == st1Name || si->getKey() == st2Name) &&
983  isOk = true;
984  };
985  if (!isOk)
986  {
989  "::checkExcludedStations(): all baselines of the station " + si->getKey() +
990  " are deselected, the station is turned off too");
991  };
992  };
993 };
994 
995 
996 
997 //
999 {
1000 
1001 
1002 
1003 };
1004 
1005 
1006 //
1007 //
1008 //
1009 
1010 
1011 
1012 //
1013 //
1014 //
1015 //
1016 // ------------------------ clock break related procedures:
1017 //
1018 //
1020  SgVlbiBand* band, double& cbShift, double& cbSigma)
1021 {
1022  // collect the observations for the station:
1023  QList<SgVlbiBaselineInfo*> baselines;
1024  BaselinesByName_it baselineItr=band->baselinesByName().begin();
1025  for (int iBaseline=0; baselineItr!=band->baselinesByName().end(); ++baselineItr, iBaseline++)
1026  {
1027  SgVlbiBaselineInfo* baselineInfo=baselineItr.value();
1028  if ( baselineInfo &&
1029  !baselineInfo->isAttr(SgVlbiBaselineInfo::Attr_NOT_VALID) &&
1030  baselineInfo->getKey().contains(stn->getKey()) )
1031  {
1032  // determine how many points on both sides of the break:
1033  int numOnLeft=0, numOnRight=0;
1034  QList<SgVlbiObservable*> *observables=&baselineInfo->observables();
1035  for (int idx=0; idx<observables->size(); idx++)
1036  {
1037  if (observables->at(idx)->epoch()<=tBreak)
1038  numOnLeft++;
1039  else
1040  numOnRight++;
1041  };
1042  if (numOnLeft>2 && numOnRight>2)
1043  baselines.append(baselineInfo);
1044  };
1045  };
1046  if (!baselines.size()) // complain and return
1047  {
1049  "::calculateClockBreakParameter(): cannot evaluate clock break parameters: num of baselines==0");
1050  return;
1051  }
1052  else
1054  "::calculateClockBreakParameter(): collected " + QString("").setNum(baselines.size()) +
1055  " baselines for the station " + stn->getKey());
1056 
1057  int nZ=0;
1058  for (int iBaseline=0; iBaseline<baselines.size(); iBaseline++)
1059  {
1060  SgVlbiBaselineInfo *baselineInfo=baselines.at(iBaseline);
1061  QList<SgVlbiObservable*> *observables=&baselineInfo->observables();
1062  for (int idx=0; idx<observables->size(); idx++)
1063  nZ++;
1064  };
1065 
1066  SgEstimator *estimator=new SgEstimator(config_);
1067  QList<SgParameter*> *localParameters=new QList<SgParameter*>;
1068  // create parameters list:
1069  SgParameter *pC, *pAi, *pBi;
1070  pC = new SgParameter("Shift");
1071  pC->setSigmaAPriori(1.0e+8);
1072  localParameters->append(pC);
1073  for (int iBaseline=0; iBaseline<baselines.size(); iBaseline++)
1074  {
1075  SgVlbiBaselineInfo *baselineInfo=baselines.at(iBaseline);
1076  pAi = new SgParameter("A_" + QString("").sprintf("%03d_(", iBaseline) +
1077  baselineInfo->getKey() + ")");
1078  pBi = new SgParameter("B_" + QString("").sprintf("%03d_(", iBaseline) +
1079  baselineInfo->getKey() + ")");
1080  pAi->setSigmaAPriori(1.0e+8);
1081  pBi->setSigmaAPriori(1.0e+8);
1082  localParameters->append(pAi);
1083  localParameters->append(pBi);
1084  };
1085  estimator->addParametersList(localParameters);
1086 // estimator->setListP(stochasticParameters);
1087  estimator->prepare2Run(nZ + 10, tStart_, tFinis_, tRefer_);
1088  // feed the estimator:
1089  double res, sig, sign;
1090  SgVector vO_C(1), vSigma(1);
1091  double dsSB=0.1E-9; // 0.1ns
1092  double dsGR=5.E-12; // 5ps
1093  for (int iBaseline=0; iBaseline<baselines.size(); iBaseline++)
1094  {
1095  SgVlbiBaselineInfo *baselineInfo=baselines.at(iBaseline);
1096  sign = -1.0;
1097  if (baselineInfo->getKey().indexOf(stn->getKey())>0) // the second station
1098  sign = 1.0;
1099  pAi = localParameters->at(2*iBaseline + 1);
1100  pBi = localParameters->at(2*iBaseline + 2);
1101  QList<SgVlbiObservable*> *observables=&baselineInfo->observables();
1102  for (int idx=0; idx<observables->size(); idx++)
1103  {
1104  SgVlbiObservable *o=observables->at(idx);
1107  {
1108  res = m->getResidual();
1109  sig = m->sigma2Apply() + dsGR;
1111  sig += dsSB;
1112  if (o->epoch()<=tBreak)
1113  pC->setD(0.0);
1114  else
1115  pC->setD(1.0E-9*sign);
1116  pAi->setD(1.0E-9);
1117  pBi->setD(1.0E-9*(o->epoch() - tBreak));
1118  vO_C.setElement (0, res);
1119  vSigma.setElement(0, sig);
1120  estimator->processObs(o->epoch(), vO_C, vSigma);
1121  };
1122  };
1123  };
1124  estimator->finisRun();
1125  cbShift = pC->getSolution()*1.0E-9;
1126  cbSigma = pC->getSigma()*1.0E-9;
1127  //
1128  for (int i=0; i<localParameters->size(); i++)
1129  delete localParameters->at(i);
1130  delete localParameters;
1131  localParameters = NULL;
1132  delete estimator;
1133 };
1134 
1135 
1136 
1137 //
1139 {
1140  if (!band || !agents.size())
1141  return;
1142 
1143  // first, pick up baselines with clock breaks:
1144  QList<SgVlbiBaselineInfo*> baselines;
1145  QMap<QString, SgVlbiBaselineInfo*>
1147  BaselinesByName_it it=band->baselinesByName().begin();
1148  int nZ=0;
1149  for (int iBaseline=0; it!=band->baselinesByName().end(); ++it, iBaseline++)
1150  {
1151  SgVlbiBaselineInfo *blInfo=it.value();
1152  if (blInfo && !blInfo->isAttr(SgVlbiBaselineInfo::Attr_NOT_VALID))
1153  {
1154  for (int idxAgent=0; idxAgent<agents.size(); idxAgent++)
1155  {
1156  SgClockBreakAgent *agent=agents.at(idxAgent);
1157  if (agent->stn_ && blInfo->getKey().contains(agent->stn_->getKey()))
1158  {
1160  "::calculateClockBreaksParameters(): gathering info for CB on " + agent->epoch_.toString() +
1161  " at " + agent->stn_->getKey() + "; baseline " + blInfo->getKey());
1162  // determine how many points on both sides of the break:
1163  int numOnLeft=0, numOnRight=0;
1164  QList<SgVlbiObservable*> *observables=&blInfo->observables();
1165  for (int idx=0; idx<observables->size(); idx++)
1166  {
1167  if (observables->at(idx)->owner()->isAttr(SgVlbiObservation::Attr_PROCESSED) &&
1168  observables->at(idx)->epoch() < agent->epoch_)
1169  numOnLeft++;
1170  else if (observables->at(idx)->owner()->isAttr(SgVlbiObservation::Attr_PROCESSED) &&
1171  agent->epoch_ < observables->at(idx)->epoch())
1172  numOnRight++;
1173  };
1174  if (numOnLeft>2 && numOnRight>2)
1175  {
1176  if (!baselinesByName.contains(blInfo->getKey()))
1177  {
1178  baselines.append(blInfo);
1179  baselinesByName.insert(blInfo->getKey(), blInfo);
1180  };
1181  nZ += numOnLeft + numOnRight;
1182  };
1183  };
1184  };
1185  };
1186  };
1187  baselinesByName.clear();
1188  if (!baselines.size()) // complain and return
1189  {
1191  "::calculateClockBreaksParameters(): cannot evaluate clock break parameters: num of baselines==0");
1192  return;
1193  }
1194  else
1196  "::calculateClockBreaksParameters(): collect " + QString("").setNum(baselines.size()) +
1197  " baselines for clock breaks evaluation");
1198 
1199  // prepare the estimator:
1200  SgEstimator *estimator=new SgEstimator(config_);
1201  QList<SgParameter*> *localParameters=new QList<SgParameter*>;
1202  // create parameters list:
1203  for (int idxAgent=0; idxAgent<agents.size(); idxAgent++)
1204  {
1205  SgClockBreakAgent *agent=agents.at(idxAgent);
1206  agent->pC_ = new SgParameter("Shift at " + agent->stn_->getKey() +
1207  QString("").sprintf("_%03d", idxAgent));
1208  agent->pC_->setSigmaAPriori(1.0e+8);
1209  localParameters->append(agent->pC_);
1210  };
1211  SgParameter *pAi;
1212  QMap< QString, QList<SgParameter*> >
1213  parametersByBaseline;
1214  for (int iBaseline=0; iBaseline<baselines.size(); iBaseline++)
1215  {
1216  SgVlbiBaselineInfo *baselineInfo=baselines.at(iBaseline);
1217  int nOrder=2;
1218  SgVlbiStationInfo *si;
1219  QList<SgParameter*> parList;
1220  si = baselineInfo->stn_1(stationsByName_);
1221  if (si && si->getClocksModelOrder()>nOrder)
1222  nOrder = si->getClocksModelOrder();
1223  si = baselineInfo->stn_2(stationsByName_);
1224  if (si && si->getClocksModelOrder()>nOrder)
1225  nOrder = si->getClocksModelOrder();
1226  for (int idxP=0; idxP<nOrder; idxP++)
1227  {
1228  pAi = new SgParameter("A_" + QString("").sprintf("%02d_%03d_(", idxP, iBaseline) +
1229  baselineInfo->getKey() + ")");
1230  pAi->setSigmaAPriori(1.0e+8);
1231  localParameters->append(pAi);
1232  parList.append(pAi);
1233  };
1234  parametersByBaseline.insert(baselineInfo->getKey(), parList);
1235  };
1236  // set up the estimator:
1237  estimator->addParametersList(localParameters);
1238  estimator->prepare2Run(nZ + 10, tStart_, tFinis_, tRefer_);
1239  // feed the estimator:
1240  double res, sig, sign;
1241  SgVector vO_C(1), vSigma(1);
1242  for (int iBaseline=0; iBaseline<baselines.size(); iBaseline++)
1243  {
1244  SgVlbiBaselineInfo *blInfo=baselines.at(iBaseline);
1245  const QList<SgParameter*> &parList=parametersByBaseline.value(blInfo->getKey());
1246  QList<SgVlbiObservable*> *observables=&blInfo->observables();
1247  for (int idx=0; idx<observables->size(); idx++)
1248  {
1249  SgVlbiObservable *o=observables->at(idx);
1252  {
1253  res = m->getResidual();
1254  sig = m->sigma2Apply();
1255  // clock breaks parameters:
1256  for (int idxAgent=0; idxAgent<agents.size(); idxAgent++)
1257  {
1258  SgClockBreakAgent *agent=agents.at(idxAgent);
1259  SgParameter *pC=agent->pC_;
1260  sign = -1.0;
1261  if (blInfo->getKey().indexOf(agent->stn_->getKey()) > 0) // the second station
1262  sign = 1.0;
1263  if (o->epoch() <= agent->epoch_)
1264  pC->setD(0.0);
1265  else
1266  pC->setD(1.0E-9*sign);
1267  };
1268  // baselines:
1269  double d(1.0), dt(o->epoch() - tRefer_);
1270  for (int idxP=0; idxP<parList.size(); idxP++)
1271  {
1272  pAi = parList.at(idxP);
1273  pAi->setD(1.0E-9*d);
1274  d *= dt;
1275  };
1276  vO_C.setElement (0, res);
1277  vSigma.setElement(0, sig);
1278  estimator->processObs(o->epoch(), vO_C, vSigma);
1279  };
1280  };
1281  };
1282  // make solution:
1283  estimator->finisRun();
1284  // pick up the solved values:
1285  for (int idxAgent=0; idxAgent<agents.size(); idxAgent++)
1286  {
1287  SgClockBreakAgent *agent=agents.at(idxAgent);
1288  SgParameter *pC=agent->pC_;
1289  agent->shift_ = pC->getSolution()*1.0E-9;
1290  agent->sigma_ = pC->getSigma()*1.0E-9;
1291  };
1292  //
1293  for (int i=0; i<localParameters->size(); i++)
1294  delete localParameters->at(i);
1295  delete localParameters;
1296  localParameters = NULL;
1297  delete estimator;
1298 };
1299 
1300 
1301 
1302 //
1303 bool SgVlbiSession::detectClockBreaks_mode1(SgVlbiBand* band, QString& stnName, SgMJD& tBreak)
1304 {
1305  BaselinesByName candidates;
1306  tBreak = tZero;
1307  // now, we are working with SBD only:
1308  BaselinesByName_it itBaselineInfo=band->baselinesByName().begin();
1309  for (int iBaseline=0; itBaselineInfo!=band->baselinesByName().end(); ++itBaselineInfo, iBaseline++)
1310  {
1311  SgVlbiBaselineInfo *baselineInfo=itBaselineInfo.value();
1312  if (baselineInfo && !baselineInfo->isAttr(SgVlbiBaselineInfo::Attr_NOT_VALID))
1313  {
1314  baselineInfo->calculateClockF1(config_);
1315  baselineInfo->evaluateCBIndicator();
1316  SgClockBreakIndicator *cbi = baselineInfo->cbIndicator();
1317  if (cbi && 100.0*(cbi->totWrms_ - cbi->minWrms_)/cbi->totWrms_>40.0 &&
1318  cbi->numOnLeft_ > 0 && cbi->numOnRight_ > 0)
1319  {
1320  candidates.insert(baselineInfo->getKey(), baselineInfo);
1321  /*
1322  std::cout << qPrintable(baselineInfo->getKey()) << ": value "
1323  << 100.0*(cbi->totWrms_ - cbi->minWrms_)/cbi->totWrms_ << "% at "
1324  << qPrintable(cbi->epoch_.toString())
1325  << "; num on the left wing " << cbi->numOnLeft_
1326  << "; num on the right wing " << cbi->numOnRight_ << "\n";
1327  */
1328  };
1329  };
1330  };
1331  if (!candidates.size())
1332  return false;
1333  // get maximum (absolute):
1334  double maxConsumed=0.0;
1335  SgVlbiBaselineInfo *blBreak=NULL;
1336  QString blName, stnName_1, stnName_2;
1337  BaselinesByName_it iBli=candidates.begin();
1338  for (; iBli!=candidates.end(); ++iBli)
1339  if (maxConsumed < iBli.value()->cbIndicator()->totWrms_ - iBli.value()->cbIndicator()->minWrms_)
1340  {
1341  maxConsumed = iBli.value()->cbIndicator()->totWrms_ - iBli.value()->cbIndicator()->minWrms_;
1342  blName = iBli.key();
1343  tBreak = iBli.value()->cbIndicator()->epoch_;
1344  };
1345  if (band->baselinesByName().contains(blName))
1346  blBreak = band->baselinesByName().value(blName);
1347  else
1348  {
1349  // complain:
1351  "::detectClockBreaks(): baseline name " + blName +
1352  " is not in band's baselinesByName_ container");
1353  return false;
1354  };
1355  SgVlbiObservable *obs=blBreak->observables().at(0);
1356  stnName_1 = obs->stn_1()->getKey();
1357  stnName_2 = obs->stn_2()->getKey();
1358  /*
1359  std::cout << "Determined: " << qPrintable(blBreak->getKey()) << " with components "
1360  << qPrintable(stnName_1) << " and " << qPrintable(stnName_2)
1361  << " from " << candidates.size() << " candidates\n";
1362  */
1363  //
1364  // ok, now what we've got: blBreak == baseline info with a clock break
1365  // blName == it's name
1366  // stnName_1 == name of the first station and
1367  // stnName_2 == name of the second station at the baseline.
1368  //
1369  // evaluate frequencies:
1370  QMap<QString, int> numByName;
1371  iBli = candidates.begin();
1372  for (; iBli!=candidates.end(); ++iBli)
1373  if (iBli.key().contains(stnName_1) || iBli.key().contains(stnName_2))
1374  {
1375  SgVlbiObservable *obs=iBli.value()->observables().at(0);
1377  numByName[obs->stn_1()->getKey()]++;
1379  numByName[obs->stn_2()->getKey()]++;
1380  };
1381  // get maximum:
1382  QMap<QString, int>::iterator iAux=numByName.begin();
1383  int minN=iAux.value(), maxN=iAux.value();
1384  stnName = iAux.key();
1385  for (; iAux!=numByName.end(); ++iAux)
1386  {
1387  int n=iAux.value();
1388  if (minN>n)
1389  minN = n;
1390  if (maxN<n)
1391  {
1392  maxN = n;
1393  stnName = iAux.key();
1394  };
1395  // std::cout << " ... " << qPrintable(iAux.key()) << ": " << iAux.value() << " ... \n";
1396  };
1397  // determine proper station and epoch:
1398  if (maxN!=minN || (baselinesByName_.size()==1 && maxN==1 && minN==1))
1399  {
1400  if (stationsByName().contains(stnName))
1401  {
1402  // stnBreak = stationsByName().value(stnName);
1403  // std::cout << "The break station is: " << qPrintable(stnName) << "\n";
1404  // adjust break epoch:
1405  iBli = candidates.begin();
1406  for (; iBli!=candidates.end(); ++iBli)
1407  if (iBli.key().contains(stnName) &&
1408  iBli.value()->cbIndicator()->tOnLeft_ <= tBreak && // ensure that it is the same break
1409  tBreak <= iBli.value()->cbIndicator()->tOnRight_)
1410  {
1411  if (tBreak < iBli.value()->cbIndicator()->epoch_)
1412  {
1413  tBreak = iBli.value()->cbIndicator()->epoch_;
1414  // std::cout << " processing " << qPrintable(iBli.key()) << ", epoch: "
1415  // << qPrintable(tBreak.toString()) << "\n";
1416  };
1417  };
1418  // std::cout << "The break epoch is: " << qPrintable(tBreak.toString()) << "\n";
1419  return true;
1420  }
1421  else
1423  "::detectClockBreaks(): stnName " + stnName + " is not in stationsByName() container");
1424  }
1425  else
1427  "::detectClockBreaks(): impossible to guess the station name: maxN==minN==" +
1428  QString("").setNum(maxN));
1429  return false;
1430 };
1431 
1432 
1433 
1434 //
1435 void SgVlbiSession::checkBandForClockBreaks(int bandIdx, bool have2AdjustResiduals)
1436 {
1437  // check:
1438  if (bandIdx<0 || bandIdx>bands_.size()-1)
1439  return;
1440  SgVlbiBand *band=bands_.at(bandIdx);
1441  if (!band)
1442  {
1444  "::checkBandForClockBreaks(): got wrong band (=NULL) for the band index " +
1445  QString("").setNum(bandIdx));
1446  return;
1447  };
1448  // proceed:
1450  "::checkBandForClockBreaks(): processing observations from " + band->getKey() + "-band", true);
1451  QString stnName("");
1452  SgMJD tBreak(tZero);
1453  int limit=5, idx=0, bandIdxSaved;
1454  bandIdxSaved = config_->getActiveBandIdx();
1455  config_->setActiveBandIdx(bandIdx);
1456  while (detectClockBreaks_mode1(band, stnName, tBreak) && idx<limit)
1457  {
1459  "::checkBandForClockBreaks(): detected clock break #" + QString("").setNum(idx) + " at " +
1460  stnName + " on " + tBreak.toString(), true);
1461  idx++;
1462  // process the clock break:
1463  // determine parameters of the break:
1464  SgVlbiStationInfo *stnBreak=stationsByName().value(stnName);
1465  double shift, sigma;
1466  calculateClockBreakParameter(tBreak, stnBreak, band, shift, sigma);
1468  shift = round(1.0E9*shift); // round to ns
1471  shift = round(1.0E12*shift)*1.0E-3; // round to ps
1472  sigma *= 1.0E9;
1473  if (fabs(shift) > 3.0*sigma) // 3sigma threshold (otherwise, do it by hands):
1474  {
1475  //
1476  // ok, let user know
1478  "::checkBandForClockBreaks(): detected clock break at " + stnBreak->getKey() +
1479  " station on " + tBreak.toString() + "; shift on " +
1480  QString("").sprintf("%.4f ns", shift), true);
1481  // adjust station information concerning the clock break:
1482  correctClockBreak(band, stnBreak, tBreak, shift, sigma, have2AdjustResiduals);
1483  };
1484  // recalculate residuals:
1485  process(true, false);
1486  };
1487  config_->setActiveBandIdx(bandIdxSaved);
1488 };
1489 
1490 
1491 
1492 //
1494 {
1496  "::detectAndProcessClockBreaks(): clock break detection procedure initiated", true);
1497  // evaluate residuals:
1498  process(true, false);
1499  // run through all bands:
1500  for (int iBand=0; iBand<numberOfBands(); iBand++)
1501  checkBandForClockBreaks(iBand, false);
1502 };
1503 
1504 
1505 
1506 //
1508  const SgMJD& tBreak, double shift, double sigma, bool have2AdjustResiduals, bool have2Complain)
1509 {
1510  //
1511  // check for clock reference station, SOLVE will not tolerate it:
1512  if (have2Complain &&
1513  stationsByName().value(stnInfo->getKey())->isAttr(SgVlbiStationInfo::Attr_REFERENCE_CLOCKS) &&
1514  QMessageBox::warning(NULL, "A clock break is at a reference clock station",
1515  "A clock break has occured at clocks of a reference clock station.\n"
1516  "It is suggested to assign a reference clock station attribute to another station "
1517  "and reprocess data.\n"
1518  "Continue anyway?",
1519  QMessageBox::Yes | QMessageBox::No, QMessageBox::No)==QMessageBox::No)
1520  {
1521  return;
1522  };
1523  //
1524  //
1525  SgVlbiStationInfo *stn2Correct=NULL;
1527  stn2Correct = stnInfo;
1528  else
1529  stn2Correct = band->stationsByName().value(stnInfo->getKey());
1530 
1531  //check for existing clock breaks:
1532  SgParameterBreak *clockBreak=NULL;
1533  if (stn2Correct->clockBreaks().size())
1534  for (int i=0; i<stn2Correct->clockBreaks().size(); i++)
1535  if (fabs(*(stn2Correct->clockBreaks().at(i)) - tBreak) < 5.5E-6) // 0.4752 sec
1536  clockBreak = stn2Correct->clockBreaks().at(i);
1537  if (clockBreak) // update existing clock break:
1538  {
1539  clockBreak->setA0(config_->getUseDynamicClockBreaks()? 0.0 : (clockBreak->getA0()+shift));
1540  clockBreak->setS0(sigma);
1542  "::processClockBreakMarks(): the clock break at " + stn2Correct->getKey() +
1543  " station on " + tBreak.toString() + "; has been updated to " +
1544  QString("").sprintf("%.4f ns", clockBreak->getA0()));
1545  }
1546  else // create a new clock break:
1547  {
1548  clockBreak = new SgParameterBreak(tBreak + 5.0E-6, config_->getUseDynamicClockBreaks()?0.0:shift);
1549  clockBreak->setS0(sigma);
1550  if (stn2Correct->clockBreaks().addBreak(clockBreak))
1552  "::processClockBreakMarks(): the new break has been appended to the model");
1553  else
1555  "::processClockBreakMarks(): adding new clock break at " + stn2Correct->getKey() +
1556  " station on " + tBreak.toString() + " failed");
1557  };
1558  //
1559  //
1562  //
1563  //
1564  // at last, update residuals for all bands and redraw plots:
1565  if (have2AdjustResiduals)
1566  for (int iBand=0; iBand<numberOfBands(); iBand++)
1567  {
1568  SgVlbiBand* band=bands_.at(iBand);
1569  for (int iObs=0; iObs<band->observables().size(); iObs++)
1570  {
1571  SgVlbiObservable *o=band->observables().at(iObs);
1572  if (o->epoch()>tBreak+5.0E-6 && o->owner()->baseline()->getKey().contains(stn2Correct->getKey()))
1573  {
1574  if (o->owner()->baseline()->getKey().indexOf(stn2Correct->getKey()) == 0)
1575  {
1576  o->sbDelay().setResidual(o->sbDelay().getResidual() + shift*1.0E-9);
1577  o->grDelay().setResidual(o->grDelay().getResidual() + shift*1.0E-9);
1578  }
1579  else
1580  {
1581  o->sbDelay().setResidual(o->sbDelay().getResidual() - shift*1.0E-9);
1582  o->grDelay().setResidual(o->grDelay().getResidual() - shift*1.0E-9);
1583  }
1584  };
1585  };
1586  };
1587 };
1588 // -------------------------- end of "clock break" procedures.
1589 //
1590 //
1591 //
1592 
1593 
1594 
1595 //
1596 //
1597 //
1598 // -------------------------- dealing with outliers:
1599 //
1600 //
1602 {
1603  for (int iBand=0; iBand<numberOfBands(); iBand++)
1604  eliminateOutliersSimpleMode(iBand, 200, 5.0);
1605 };
1606 
1607 
1608 
1609 //
1610 void SgVlbiSession::eliminateOutliersSimpleMode(int bandIdx, int maxNumOfPasses, double threshold,
1611  double upperLimit)
1612 {
1613  if (bandIdx<0 || bandIdx>bands_.size()-1)
1614  return;
1615  SgVlbiBand *band = bands_.at(bandIdx);
1616  if (!band)
1617  {
1619  "::eliminateOutliersSimpleMode(): got wrong band (=NULL) for the band index " +
1620  QString("").setNum(bandIdx));
1621  return;
1622  };
1623  int numOfEliminated, numOfPasses;
1624  int bandIdxSaved;
1625  bool hasBeenModified;
1626  bool need2check4absValue=upperLimit>0.0;
1627 // double sumW, sumOC, sigma, res, sig;
1628  double sigma;
1629  uint flag;
1630  QList<SgVlbiObservable*> elluminated;
1631  numOfEliminated = 0;
1632  numOfPasses = 0;
1633  hasBeenModified = true;
1634  bandIdxSaved = config_->getActiveBandIdx();
1635  config_->setActiveBandIdx(bandIdx);
1639  while (hasBeenModified && (numOfPasses<maxNumOfPasses))
1640  {
1641  if (numOfPasses>0)
1642  process(true, false);
1643  sigma = band->wrms(DT_DELAY);
1644  hasBeenModified = false;
1645  for (int idx=0; idx<band->observables().size(); idx++)
1646  {
1647  SgVlbiObservable *o=band->observables().at(idx);
1650  {
1651  if (fabs(m->getResidual()) > threshold*sigma ||
1652  (need2check4absValue && fabs(m->getResidual()) > upperLimit) )
1653  {
1654  o->owner()->addAttr(flag);
1656  hasBeenModified = true;
1657  numOfEliminated++;
1658  elluminated << o;
1659  };
1660  };
1661  };
1662  numOfPasses++;
1663  };
1665  "::eliminateOutliersSimpleMode(): eliminated " + QString("").setNum(numOfEliminated) +
1666  (config_->getUseDelayType()==SgTaskConfig::VD_SB_DELAY?" SbDelay":" GrDelay") +
1667  " observables from the " + band->getKey() + "-band in " + QString("").setNum(numOfPasses) +
1668  " passes, the threshold is " + QString("").setNum(threshold));
1669  if (elluminated.size())
1670  {
1672  "::eliminateOutliersSimpleMode(): the eliminated observations are:");
1673  for (int i=0; i<elluminated.size(); i++)
1674  {
1675  SgVlbiObservable *o=elluminated.at(i);
1677  logger->write(SgLogger::INF, SgLogger::PREPROC, className() + "::eliminateOutliersSimpleMode(): # " +
1678  QString("").setNum(o->getMediaIdx()) + " " +
1679  o->epoch().toString(SgMJD::F_Simple) + " " +
1680  o->getBaseline()->getKey() + " @ " + o->getSrc()->getKey() + " residual " +
1681  QString("").sprintf("%.3f +/- %.3f (ns) | %.3f with QC %d",
1682  m->getResidual()*1.0e9,
1683  m->getSigma()*1.0e9,
1684  m->getResidualNorm(), o->getQualityFactor()));
1685  };
1686  elluminated.clear();
1687  };
1688  config_->setActiveBandIdx(bandIdxSaved);
1689 };
1690 
1691 
1692 
1693 //
1694 void SgVlbiSession::eliminateLargeOutliers(int bandIdx, int maxNumOfPasses, double wrmsRatio)
1695 {
1696  if (bandIdx<0 || bandIdx>bands_.size()-1)
1697  return;
1698  SgVlbiBand *band = bands_.at(bandIdx);
1699  if (!band)
1700  {
1702  "::eliminateLargeOutliers(): got wrong band (=NULL) for the band index " +
1703  QString("").setNum(bandIdx));
1704  return;
1705  };
1706  int numOfPasses;
1707  int bandIdxSaved;
1708  bool hasBeenModified;
1709  double sigma, prevSigma, residMax;
1710  uint flag;
1711  QList<SgVlbiObservable*> elliminated;
1712  numOfPasses = 0;
1713  hasBeenModified = true;
1714  bandIdxSaved = config_->getActiveBandIdx();
1715  config_->setActiveBandIdx(bandIdx);
1719  //
1720  prevSigma = band->wrms(DT_DELAY);
1721  //
1723  "::eliminateLargeOutliers(): start of the procedure");
1724  while (hasBeenModified &&
1725  (numOfPasses < maxNumOfPasses) &&
1726  (8 < band->numProcessed(DT_DELAY)))
1727  // (numOfParameters_ < band->numProcessed(DT_DELAY) + 2))
1728  {
1729  SgVlbiObservable *testedObs=NULL;
1730  residMax = 0.0;
1731  hasBeenModified = false;
1732  // first, find a largest residual:
1733  for (int idx=0; idx<band->observables().size(); idx++)
1734  {
1735  SgVlbiObservable *o=band->observables().at(idx);
1738  {
1739  if (residMax < fabs(m->getResidualNorm()))
1740  {
1741  residMax = fabs(m->getResidualNorm());
1742  testedObs= o;
1743  };
1744  };
1745  };
1746  if (testedObs)
1747  {
1749  "::eliminateLargeOutliers(): found a candidate: " + testedObs->strId() + " with norm.resid= " +
1750  QString("").sprintf("%10.4f", residMax));
1751  // deselect it:
1752  testedObs->owner()->addAttr(flag);
1754  // and make a new solution:
1755  process(true, false);
1756  sigma = band->wrms(DT_DELAY);
1757  // check how it was improved:
1758  //std::cout << " ++ wrmsRatio=" << wrmsRatio << " prevSigma=" << prevSigma
1759  //<< " sigma=" << sigma << " prevSigma/sigma=" << prevSigma/sigma << "\n";
1760  if (wrmsRatio < prevSigma/sigma)
1761  {
1762  hasBeenModified = true;
1763  elliminated << testedObs;
1764  prevSigma = sigma;
1766  "::eliminateLargeOutliers(): the obs is removed");
1767  }
1768  else // restore the obs:
1769  {
1770  testedObs->owner()->delAttr(flag);
1771  process(true, false);
1773  "::eliminateLargeOutliers(): the obs is ok");
1774  };
1775  }
1776  else
1778  "::eliminateLargeOutliers(): the observable is NULL");
1779  numOfPasses++;
1780  };
1781  //
1783  "::eliminateLargeOutliers(): eliminated " + QString("").setNum(elliminated.size()) +
1784  (config_->getUseDelayType()==SgTaskConfig::VD_SB_DELAY?" SbDelay":" GrDelay") +
1785  " observables from the " + band->getKey() + "-band in " + QString("").setNum(numOfPasses) +
1786  " passes");
1787  if (elliminated.size())
1788  {
1790  "::eliminateLargeOutliers(): the eliminated observations are:");
1791  for (int i=0; i<elliminated.size(); i++)
1792  {
1793  SgVlbiObservable *o=elliminated.at(i);
1796  "::eliminateLargeOutliers(): # " +
1797  QString("").setNum(o->getMediaIdx()) + " " +
1798  o->epoch().toString(SgMJD::F_Simple) + " " +
1799  o->getBaseline()->getKey() + " @ " + o->getSrc()->getKey() + " residual " +
1800  QString("").sprintf("%.3f +/- %.3f (ns) | %.3f with QC %d",
1801  m->getResidual()*1.0e9,
1802  m->getSigma()*1.0e9,
1803  m->getResidualNorm(), o->getQualityFactor()));
1804  };
1805  elliminated.clear();
1806  };
1807  config_->setActiveBandIdx(bandIdxSaved);
1808 };
1809 
1810 
1811 
1812 
1813 //
1815 {
1816  if (bandIdx<0 || bandIdx>bands_.size()-1)
1817  return 0;
1818  SgVlbiBand *band = bands_.at(bandIdx);
1819  if (!band)
1820  {
1822  "::eliminateOutliers(): got wrong band (=NULL) for the band index " +
1823  QString("").setNum(bandIdx));
1824  return 0;
1825  };
1826  double threshold;
1827  int numOfEliminated, numOfPasses, maxNumOfPasses;
1828  int bandIdxSaved;
1829  bool hasBeenModified;
1830  uint flag;
1831  bool wasMeddledIntoWc=false;
1832  QList<SgVlbiObservable*> elluminated;
1833  //
1835  {
1837  wasMeddledIntoWc = true;
1838  };
1839  //
1840  maxNumOfPasses = config_->getOpIterationsLimit();
1841  threshold = config_->getOpThreshold();
1842  numOfEliminated = 0;
1843  numOfPasses = 0;
1844  hasBeenModified = true;
1845  bandIdxSaved = config_->getActiveBandIdx();
1846  config_->setActiveBandIdx(bandIdx);
1848 
1849  // GUI:
1851  (*longOperationStart_)(numOfPasses, maxNumOfPasses, "");
1852 
1855  while (hasBeenModified && (numOfPasses<maxNumOfPasses))
1856  {
1857  if (numOfPasses>0)
1858  process(false, false);
1859  QList<SgVlbiObservable*> outlierCandidates;
1860  for (int idx=0; idx<band->observables().size(); idx++)
1861  {
1862  SgVlbiObservable *o=band->observables().at(idx);
1865  fabs(m->getResidualNorm()) > threshold)
1866  outlierCandidates << o;
1867  };
1868  // ok, there are outliers
1869  if (outlierCandidates.size())
1870  {
1871  qSort(outlierCandidates.begin(), outlierCandidates.end(), normResidSortingOrderLessThan);
1872  // determine how much outliers should be removed:
1873  double max=fabs(outlierCandidates.first()->activeDelay()->getResidualNorm());
1874  if (outlierCandidates.size()>2 && max>2.0*threshold)
1875  {
1876 #ifdef LOCAL_DEBUG
1877  std::cout << " MODE: cluster\n";
1878 #endif
1879  while (fabs(outlierCandidates.last()->activeDelay()->getResidualNorm())<max-0.5*threshold &&
1880  outlierCandidates.size()>1)
1881  outlierCandidates.removeLast();
1882  }
1883  else // otherwise, eliminate only the largest outlier:
1884  {
1885 #ifdef LOCAL_DEBUG
1886  std::cout << " MODE: the largest one\n";
1887 #endif
1888  SgVlbiObservable *o=outlierCandidates.at(0);
1889  outlierCandidates.clear();
1890  outlierCandidates << o;
1891  };
1892 
1893 #ifdef LOCAL_DEBUG
1894  std::cout << "Pass # " << numOfPasses << " (" << maxNumOfPasses << ") "
1895  << "observations to be excluded:\n";
1896 #endif
1897  for (int idx=0; idx<outlierCandidates.size(); idx++)
1898  {
1899  SgVlbiObservable *o=outlierCandidates.at(idx);
1900  o->owner()->addAttr(flag);
1902  numOfEliminated++;
1903  elluminated << o;
1904 #ifdef LOCAL_DEBUG
1905  std::cout << "obs# " << o->owner()->getMediaIdx() << ": (" << qPrintable(o->epoch().toString())
1906  << ") " << qPrintable(o->baseline()->getKey() + " @" + o->src()->getKey())
1907  << " " << o->activeDelay()->getResidualNorm() << "\n";
1908 #endif
1909  };
1910  numOfPasses++;
1911  hasBeenModified = true;
1912  // GUI part:
1914  {
1916  (*longOperationMessage_)("Processing outliers: pass " +
1917  QString("").setNum(numOfPasses) + " from " + QString("").setNum(maxNumOfPasses));
1919  (*longOperationProgress_)(numOfPasses);
1920  };
1921  //
1922  }
1923  else
1924  {
1925  hasBeenModified = false;
1926 #ifdef LOCAL_DEBUG
1927  std::cout << "the size is 0\n";
1928 #endif
1929  };
1930  outlierCandidates.clear();
1931  };
1932 
1933 #ifdef LOCAL_DEBUG
1934  if (numOfPasses==maxNumOfPasses)
1935  std::cout << "reached max passing number (" << numOfPasses << ")\n";
1936 #endif
1937 
1938  //
1940  "::eliminateOutliers(): eliminated " + QString("").setNum(numOfEliminated) +
1941  " observables from " + band->getKey() + "-band in " + QString("").setNum(numOfPasses) +
1942  " passes with the threshold " + QString("").setNum(threshold));
1943  if (elluminated.size())
1944  {
1946  "::eliminateOutliers(): the eliminated observations are:");
1947  for (int i=0; i<elluminated.size(); i++)
1948  {
1949  SgVlbiObservable *o=elluminated.at(i);
1951  logger->write(SgLogger::INF, SgLogger::PREPROC, className() + "::eliminateOutliers(): # " +
1952  QString("").setNum(o->getMediaIdx()) + " " +
1953  o->epoch().toString(SgMJD::F_Simple) + " " +
1954  o->getBaseline()->getKey() + " @ " + o->getSrc()->getKey() + " residual " +
1955  QString("").sprintf("%.3f +/- %.3f (ns) | %.3f with QC %d",
1956  m->getResidual()*1.0e9,
1957  m->getSigma()*1.0e9,
1958  m->getResidualNorm(), o->getQualityFactor()));
1959  };
1960  elluminated.clear();
1961  };
1962  //
1963  // restore config:
1964  config_->setActiveBandIdx(bandIdxSaved);
1965  if (wasMeddledIntoWc)
1969  (*longOperationStop_)();
1972  return numOfEliminated;
1973 };
1974 
1975 
1976 
1977 //
1979 {
1980  if (bandIdx<0 || bandIdx>bands_.size()-1)
1981  return 0;
1982  SgVlbiBand *band=bands_.at(bandIdx);
1983  if (!band)
1984  {
1986  "::restoreOutliers(): got wrong band (=NULL) for the band index " +
1987  QString("").setNum(bandIdx));
1988  return 0;
1989  };
1990  double threshold;
1991  int numOfRestored, numOfPasses, maxNumOfPasses;
1992  int bandIdxSaved;
1993  bool hasBeenModified;
1994  uint flag;
1995  bool wasMeddledIntoWc=false;
1997  {
1999  wasMeddledIntoWc = true;
2000  };
2001  //
2002  maxNumOfPasses = config_->getOpIterationsLimit();
2003  threshold = config_->getOpThreshold();
2004  numOfRestored = 0;
2005  numOfPasses = 0;
2006  hasBeenModified = true;
2007  bandIdxSaved = config_->getActiveBandIdx();
2008  config_->setActiveBandIdx(bandIdx);
2012  while (hasBeenModified && (numOfPasses<maxNumOfPasses))
2013  {
2014  if (numOfPasses > 0)
2015  process(false, false);
2016  QList<SgVlbiObservable*> outlierCandidates;
2017  for (int idx=0; idx<band->observables().size(); idx++)
2018  {
2019  SgVlbiObservable *o=band->observables().at(idx);
2022  o->owner()->isAttr(flag) &&
2023  o->isUsable() &&
2024  m)
2025  if (fabs(m->getResidualNorm()) < threshold)
2026  outlierCandidates << o;
2027  };
2028  // ok, there are outliers
2029  if (outlierCandidates.size())
2030  {
2031  qSort(outlierCandidates.begin(), outlierCandidates.end(), normResidSortingOrderLessThan);
2032  // determine how much outliers should be removed:
2033  double max, min;
2034  max = fabs(outlierCandidates.first()->activeDelay()->getResidualNorm());
2035  min = fabs(outlierCandidates.last ()->activeDelay()->getResidualNorm());
2036  if (outlierCandidates.size()>2 && min<1.0)
2037  {
2038 #ifdef LOCAL_DEBUG
2039  std::cout << " MODE: cluster-bottom\n";
2040 #endif
2041  while (fabs(outlierCandidates.first()->activeDelay()->getResidualNorm())>1.0 &&
2042  outlierCandidates.size()>1)
2043  outlierCandidates.removeFirst();
2044  }
2045  else if (outlierCandidates.size()>2 && max>1.0) // here the outliers are in the range
2046  // from sigma to sigma*threshold, so we will
2047  // include them all -- sigma will not get lower,
2048  // there is no sense to recalculate the solution
2049  {
2050 #ifdef LOCAL_DEBUG
2051  std::cout << " MODE: cluster-top\n";
2052 #endif
2053  }
2054  else // otherwise, eliminate only the largest outlier:
2055  {
2056 #ifdef LOCAL_DEBUG
2057  std::cout << " MODE: the smallest one\n";
2058 #endif
2059  SgVlbiObservable *o=outlierCandidates.last();
2060  outlierCandidates.clear();
2061  outlierCandidates << o;
2062  };
2063 #ifdef LOCAL_DEBUG
2064  std::cout << "Pass # " << numOfPasses << " (" << maxNumOfPasses << ") "
2065  << "observation to be restored:\n";
2066 #endif
2067  for (int idx=0; idx<outlierCandidates.size(); idx++)
2068  {
2069  SgVlbiObservable *o=outlierCandidates.at(idx);
2070  o->owner()->delAttr(flag);
2071  numOfRestored++;
2072 #ifdef LOCAL_DEBUG
2073  std::cout << "obs# " << o->owner()->getMediaIdx() << ": (" << qPrintable(o->epoch().toString())
2074  << ") " << qPrintable(o->baseline()->getKey() + " @" + o->src()->getKey())
2075  << " " << o->activeDelay()->getResidualNorm() << "\n";
2076 #endif
2077  };
2078  numOfPasses++;
2079  hasBeenModified = true;
2080  }
2081  else
2082  {
2083  hasBeenModified = false;
2084 #ifdef LOCAL_DEBUG
2085  std::cout << "the size is 0\n";
2086 #endif
2087  };
2088  outlierCandidates.clear();
2089  };
2090 
2091 #ifdef LOCAL_DEBUG
2092  if (numOfPasses==maxNumOfPasses)
2093  std::cout << "reached max passing number (" << numOfPasses << ")\n";
2094 #endif
2095 
2097  "::restoreOutliers(): restored " + QString("").setNum(numOfRestored) +
2098  " observables from " + band->getKey() + "-band in " + QString("").setNum(numOfPasses) +
2099  " passes with the threshold " + QString("").setNum(threshold));
2100  // restore config:
2101  config_->setActiveBandIdx(bandIdxSaved);
2102  if (wasMeddledIntoWc)
2104  hasOutlierRestoratioRun_ = true;
2107  return numOfRestored;
2108 };
2109 
2110 
2111 
2112 
2113 //
2114 //
2115 //
2116 //
2117 // -------------------------- ambiguity resolving part:
2118 //
2120 {
2121  if (bandIdx<0 || bandIdx>bands_.size()-1)
2122  return;
2123  SgVlbiBand *band=bands_.at(bandIdx);
2124  if (!band)
2125  {
2127  "::scanBaselines4GrDelayAmbiguities(): got wrong band (=NULL) for the band index " +
2128  QString("").setNum(bandIdx));
2129  return;
2130  };
2131  for (int i=0; i<observations_.size(); i++)
2132  {
2133  SgVlbiObservation *obs=observations_.at(i);
2134  //obs->setupActiveObservable(bandKey);
2136  };
2137 
2138  bool noTriange=band->stationsByName().size()<3;
2139  //
2140  BaselinesByName_it itBaselineInfo=band->baselinesByName().begin();
2141  for (; itBaselineInfo!=band->baselinesByName().end(); ++itBaselineInfo)
2142  {
2143  SgVlbiBaselineInfo *baselineInfo=itBaselineInfo.value();
2144  if (isInUse(baselineInfo))
2145  {
2146  baselineInfo->scan4Ambiguities();
2147  baselineInfo->evaluateMeanGrDelResiduals();
2148  if (noTriange)
2149  baselineInfo->setGrdAmbiguities2min();
2150  };
2151  };
2152 
2153  // no any closed triangle:
2154  if (noTriange)
2155  {
2157  return;
2158  };
2159 
2160  resolveGrAmbigTriangles(bandIdx);
2161 
2162  //
2164 };
2165 
2166 
2167 
2168 //
2170 {
2171  SgVlbiBand *band=bands_.at(bandIdx);
2172  SgVlbiStationInfo *refStation=NULL, *station=NULL;
2173  int m;
2174  //
2175  // session's map:
2176  m = 0;
2177  for (StationsByName_it it=stationsByName_.begin(); it!=stationsByName_.end(); ++it)
2178  {
2179  SgVlbiStationInfo *stn=it.value();
2181  refStation = stn;
2182  if (m < stn->numProcessed(DT_DELAY))
2183  {
2184  m = stn->numProcessed(DT_DELAY);
2185  station = stn;
2186  };
2187  }
2188  // if the atribute not set yet, choose the reference station that has max observations:
2189  if (!refStation)
2190  {
2191  if (station)
2192  {
2193  refStation = station;
2195  "::resolveGrAmbigTriangles(): cannot find the reference clock station, picked " +
2196  refStation->getKey() + " as the reference one");
2197  }
2198  else
2199  {
2201  "::resolveGrAmbigTriangles(): unable to determine the reference clock station");
2202  return;
2203  };
2204  }
2205  else
2207  "::resolveGrAmbigTriangles(): found " + refStation->getKey() + " as the reference clock station");
2208 
2209  //
2210  // create a list of stations and a list of baselines; the elements of the lists are
2211  // pointers, so no time consuming copies required
2212  QList<SgVlbiStationInfo*> stations;
2213  QList<SgVlbiBaselineInfo*> baselines;
2214  //
2215  //
2216  //StationsByName_it itStationInfo=band->stationsByName().begin();
2217  for (StationsByName_it it=band->stationsByName().begin(); it!=band->stationsByName().end(); ++it)
2218  if (isInUse(it.value()))
2219  stations.append(it.value());
2220  //
2221  for (BaselinesByName_it it=band->baselinesByName().begin(); it!=band->baselinesByName().end(); ++it)
2222  if (isInUse(it.value()))
2223  baselines.append(it.value());
2224  //
2225  int numOfStations=stations.size();
2226  int numOfBaselines=baselines.size();
2227 
2228  SgEstimator *estimator=new SgEstimator(config_);
2229  QList<SgParameter*> *localParameters=new QList<SgParameter*>;
2230  // create parameters list:
2231  SgParameter *pN;
2232  for (int iBaseline=0; iBaseline<numOfBaselines; iBaseline++)
2233  {
2234  SgVlbiBaselineInfo *baselineInfo=baselines.at(iBaseline);
2235  pN = new SgParameter("N_" + QString("").sprintf("%03d_(", iBaseline) +
2236  baselineInfo->getKey() + ")");
2237  pN->setSigmaAPriori(1.0e+8);
2238  baselineInfo->pAux() = pN;
2239  localParameters->append(pN);
2240  };
2241  estimator->addParametersList(localParameters);
2242  estimator->prepare2Run(numOfStations*(numOfStations-1)*(numOfStations-2)/2/3 + 10,
2243  tStart_, tFinis_, tRefer_);
2244  // make constraints:
2245  // first, figure out the reference station:
2246  // lookup session's map for a reference station:
2247  // apply constraints:
2248  for (int i=0; i<numOfBaselines; i++)
2249  {
2250  SgVlbiBaselineInfo *bl=baselines.at(i);
2251  if (bl->getKey().contains(refStation->getKey() + ":") ||
2252  bl->getKey().contains(":" + refStation->getKey()) )
2253  {
2254  bl->pAux()->setD(1.0);
2255  estimator->processConstraint(0.0, 1.0e-13);
2256  };
2257  };
2258  // feed the estimator:
2259  double b, sig;
2260  SgVector vO_C(1), vSigma(1);
2261  SgVlbiBaselineInfo *biIJ, *biIK, *biJK;
2262  SgVlbiStationInfo *stI, *stJ, *stK;
2263  QString blName;
2264  SgMJD t=getTMean();
2265  for (int i=0; i<numOfStations; i++)
2266  {
2267  stI = stations.at(i);
2268  for (int j=i+1; j<numOfStations; j++)
2269  {
2270  stJ = stations.at(j);
2271  biIJ = NULL;
2272  // set up ij-th baseline:
2273  blName = stI->getKey() + ":" + stJ->getKey();
2274  if (band->baselinesByName().contains(blName))
2275  {
2276  biIJ = band->baselinesByName().value(blName);
2277  biIJ->setAuxSign( 1.0);
2278  }
2279  else
2280  {
2281  blName = stJ->getKey() + ":" + stI->getKey();
2282  if (band->baselinesByName().contains(blName))
2283  {
2284  biIJ = band->baselinesByName().value(blName);
2285  biIJ->setAuxSign(-1.0);
2286  };
2287  };
2288  for (int k=j+1; k<numOfStations; k++)
2289  {
2290  stK = stations.at(k);
2291  biIK = NULL;
2292  biJK = NULL;
2293  // set up ik-th baseline:
2294  blName = stI->getKey() + ":" + stK->getKey();
2295  if (band->baselinesByName().contains(blName))
2296  {
2297  biIK = band->baselinesByName().value(blName);
2298  biIK->setAuxSign( 1.0);
2299  }
2300  else
2301  {
2302  blName = stK->getKey() + ":" + stI->getKey();
2303  if (band->baselinesByName().contains(blName))
2304  {
2305  biIK = band->baselinesByName().value(blName);
2306  biIK->setAuxSign(-1.0);
2307  };
2308  };
2309  // set up jk-th baseline:
2310  blName = stJ->getKey() + ":" + stK->getKey();
2311  if (band->baselinesByName().contains(blName))
2312  {
2313  biJK = band->baselinesByName().value(blName);
2314  biJK->setAuxSign( 1.0);
2315  }
2316  else
2317  {
2318  blName = stK->getKey() + ":" + stJ->getKey();
2319  if (band->baselinesByName().contains(blName))
2320  {
2321  biJK = band->baselinesByName().value(blName);
2322  biJK->setAuxSign(-1.0);
2323  };
2324  };
2325  // process the triangle:
2326  if (isInUse(stI) && isInUse(stJ) && isInUse(stK) &&
2327  isInUse(biIJ) && isInUse(biIK) && isInUse(biJK))
2328  {
2329  b = biIK->getMeanGrDelResiduals()*biIK->getAuxSign() -
2330  biIJ->getMeanGrDelResiduals()*biIJ->getAuxSign() -
2331  biJK->getMeanGrDelResiduals()*biJK->getAuxSign();
2332  sig = sqrt(
2336 // biIJ->pAux()->setD( biIJ->getMaxGrdAmbigSpacing()*biIJ->getAuxSign());
2337 // biIK->pAux()->setD(-biIK->getMaxGrdAmbigSpacing()*biIK->getAuxSign());
2338 // biJK->pAux()->setD( biJK->getMaxGrdAmbigSpacing()*biJK->getAuxSign());
2339  biIJ->pAux()->setD(
2341  biIK->pAux()->setD(
2343  biJK->pAux()->setD(
2345 
2346  vO_C.setElement (0, b);
2347  vSigma.setElement(0, sig);
2348  estimator->processObs(t, vO_C, vSigma);
2349  };
2350  };
2351  };
2352  };
2353  estimator->finisRun();
2354  // adjust ambiguities at the baselines:
2355  for (int iBaseline=0; iBaseline<numOfBaselines; iBaseline++)
2356  {
2357  SgVlbiBaselineInfo *baselineInfo=baselines.at(iBaseline);
2358  int deltaN=rint(baselineInfo->pAux()->getSolution());
2359  baselineInfo->shiftAmbiguities(deltaN);
2360  // std::cout << qPrintable(baselineInfo->getKey()) << ": "
2361  // << baselineInfo->pAux()->getSolution() << " +/ " << baselineInfo->pAux()->getSigma()
2362  // << "\n";
2363  };
2364  //
2365  stations.clear();
2366  baselines.clear();
2367  //
2368  for (int i=0; i<localParameters->size(); i++)
2369  delete localParameters->at(i);
2370  delete localParameters;
2371  localParameters = NULL;
2372  delete estimator;
2373 };
2374 
2375 
2376 
2377 //
2379 {
2380  // if the session was not processed yet or was analyzed at another analysis center,
2381  // we are going to process it. Otherwise (i.e., it was already analyzed by us) just
2382  // to read data and display it.
2383  //
2385  {
2387  "::need2runAutomaticDataProcessing(): this session is not processed yet");
2388  return true;
2389  };
2390 
2391  const SgVlbiHistory& history=primaryBand_->history();
2392  int ver, verOfExactAcFullName, verOfAcFullName, verOfAcAbbrevName;
2393  int verOfDomainName;
2394 
2395  if (history.size()<3) // nothing to check
2396  {
2398  "::need2runAutomaticDataProcessing(): the history too short");
2399  return true;
2400  };
2401  //
2402  if (!reporter_ || !reporter_->identities())
2403  {
2405  "::need2runAutomaticDataProcessing(): the reporter is not exists yet");
2406  return true; // nowhere to get clues
2407  };
2408  //
2410  QString str("");
2411  QStringList ambigNames, fullNameElements, abbrevNameElements;
2412  ambigNames << "Authority" << "Center" << "Centre" << "Centro" << "Institute" << "National"
2413  << "Observatory" << "Observatoire" << "Technology" << "University";
2414 
2415  str = "(?:";
2416  for (int i=0; i<ambigNames.size()-1; i++)
2417  str += ambigNames.at(i) + "|";
2418  str += ambigNames.at(ambigNames.size()-1) + ")";
2419 
2420  QRegExp rxF(str), rxA, rxM;
2421  rxF.setCaseSensitivity(Qt::CaseInsensitive);
2422  rxA.setCaseSensitivity(Qt::CaseInsensitive);
2423  rxM.setCaseSensitivity(Qt::CaseInsensitive);
2424 
2425  // to serch for a full ac name or part of it:
2426  fullNameElements = ids->getAcFullName().split(QRegExp("\\W+"), QString::SkipEmptyParts);
2427  str = "(?:";
2428  for (int i=0; i<fullNameElements.size(); i++)
2429  if (!fullNameElements.at(i).contains(rxF))
2430  str += fullNameElements.at(i) + "|";
2431  if (str[str.size()-1] == QChar('|'))
2432  str[str.size()-1] = QChar(')');
2433  rxF.setPattern(str);
2434 
2435  // to serch for an abbreviated ac name or part of it:
2436  abbrevNameElements = ids->getAcAbbrevName().split(QRegExp("\\W+"), QString::SkipEmptyParts);
2437  str = "(?:";
2438  for (int i=0; i<abbrevNameElements.size(); i++)
2439  str += abbrevNameElements.at(i) + "|";
2440  if (str[str.size()-1] == QChar('|'))
2441  str[str.size()-1] = QChar(')');
2442  rxA.setPattern(str);
2443 
2444  // to serch for our domain name:
2445  str = ids->getUserEmailAddress();
2446  QString domainName("");
2447 
2448  rxM.setPattern("\\s*([A-Za-z0-9_]+)@([A-Za-z0-9_]+\\.[A-Za-z0-9_]+)");
2449 
2450  if (ids->getUserEmailAddress().indexOf(rxM) != -1)
2451  domainName = rxM.cap(2);
2452 
2453  ver = history.last()->getVersion() - 1;
2454  verOfExactAcFullName = verOfAcFullName = verOfAcAbbrevName = verOfDomainName = -1;
2455  for (int i=0; i<history.size(); i++)
2456  {
2457  const QString& st=history.at(i)->getText();
2458  int v=history.at(i)->getVersion();
2459  if (st.contains(ids->getAcFullName(), Qt::CaseInsensitive))
2460  verOfExactAcFullName = v;
2461  if (st.contains(rxF))
2462  verOfAcFullName = v;
2463  if (st.contains(rxA))
2464  verOfAcAbbrevName = v;
2465  if (domainName.size()>0 && st.contains(domainName, Qt::CaseInsensitive))
2466  verOfDomainName = v;
2467  };
2468  //
2469  if (verOfAcFullName == -1)
2470  {
2472  "::need2runAutomaticDataProcessing(): cannot find AC full name (" +
2473  ids->getAcFullName() + ") in the history");
2474  return true;
2475  };
2476  if (verOfAcAbbrevName == -1)
2477  {
2479  "::need2runAutomaticDataProcessing(): cannot find AC abbreviated name, " + ids->getAcAbbrevName() +
2480  ", in the history");
2481  return true;
2482  };
2483  //
2484  //
2485  // definitely, it is ours:
2486  if (verOfExactAcFullName == ver)
2487  {
2489  "::need2runAutomaticDataProcessing(): we know this session, found exact full AC name");
2490  return false;
2491  };
2492  if (domainName.size()>0 && verOfDomainName==ver)
2493  {
2495  "::need2runAutomaticDataProcessing(): we know this session, found contact info from our domain");
2496  return false;
2497  };
2498  //
2499  //
2500  if (verOfAcFullName < ver || verOfAcAbbrevName < ver)
2501  {
2503  "::need2runAutomaticDataProcessing(): found fingerprints (" +
2504  QString("").sprintf("%d,%d", verOfAcFullName, verOfAcAbbrevName) +
2505  ") but not for the last version (" + QString("").sprintf("%d", ver) + ")");
2506  return true;
2507  };
2508  //
2509  // perhaps:
2511  "::need2runAutomaticDataProcessing(): the session looks familiar");
2512  return false;
2513 };
2514 
2515 
2516 
2517 //
2519 {
2520  bool has=false;
2521  for (StationsByName_it it=stationsByName_.begin(); it!=stationsByName_.end(); ++it)
2522  {
2523  SgVlbiStationInfo *stn=it.value();
2525  has = true;
2526  };
2527  return has;
2528 };
2529 
2530 
2531 
2532 //
2534 {
2535  bool has=false;
2536  for (StationsByName_it it=stationsByName_.begin(); it!=stationsByName_.end(); ++it)
2537  {
2538  SgVlbiStationInfo *stn=it.value();
2539  if (isInUse(stn) &&
2542  has = true;
2543  };
2544  return has;
2545 };
2546 
2547 
2548 
2549 //
2550 bool SgVlbiSession::writeUserData2File(const QString& fileName)
2551 {
2552  bool isOk=false;
2553  QString str("");
2554  //
2555  QFile f(fileName);
2556  if (!f.open(QIODevice::WriteOnly))
2557  {
2559  "::writeUserData2File(): error opening output file \"" + f.fileName() + "\"");
2560  return isOk;
2561  };
2562  //
2563  SgMJD prevT(tZero);
2564  QMap<QString, QString> hasReported;
2565  // make output:
2566  QTextStream ts(&f);
2567 
2568  ts << "#\n"
2569  << "#YYY MM DD HH MM SS Station_ _ScanID_ Elevation SlntHDel SlntWDel ___partial___ "
2570  << "SlntHRte SlntWRte ___partial___\n"
2571  << "#\n";
2572 
2573  for (int i=0; i<observations_.size(); i++)
2574  {
2575  SgVlbiObservation *obs=observations_.at(i);
2576  SgVlbiAuxObservation *auxObs_1=obs->auxObs_1(), *auxObs_2=obs->auxObs_2();
2577 
2578 // YY MM DD HH MM SS.S station scan_name
2579 // slant_delay partial_slant_delay slant_delay_rate partial_slant_delay_rate
2580  if (prevT < *obs)
2581  {
2582  hasReported.clear();
2583  prevT = *obs;
2584  };
2585  if (auxObs_1 && auxObs_2)
2586  {
2587  if (!hasReported.contains(obs->stn_1()->getKey()))
2588  {
2589  str.sprintf("%s %8s %10s %9.6f %10.2f %8.2f %15.6e %10.2f %8.2f %15.6e",
2590  qPrintable(obs->toString(SgMJD::F_Simple).replace(QRegExp("[:/]"), " ")),
2591  qPrintable(obs->stn_1()->getKey()),
2592  qPrintable(obs->getScanName()),
2593  auxObs_1->getElevationAngle()*RAD2DEG,
2594  1.0e12*auxObs_1->getSlantDelayH(),
2595  1.0e12*auxObs_1->getSlantDelayW(),
2596  auxObs_1->getPartDelayW(),
2597  1.0e15*auxObs_1->getSlantRateH(),
2598  1.0e15*auxObs_1->getSlantRateW(),
2599  auxObs_1->getPartRateW()
2600  );
2601  ts << str << "\n";
2602  hasReported.insert(obs->stn_1()->getKey(), "1");
2603  };
2604  if (!hasReported.contains(obs->stn_2()->getKey()))
2605  {
2606  str.sprintf("%s %8s %10s %9.6f %10.2f %8.2f %15.6e %10.2f %8.2f %15.6e",
2607  qPrintable(obs->toString(SgMJD::F_Simple).replace(QRegExp("[:/]"), " ")),
2608  qPrintable(obs->stn_2()->getKey()),
2609  qPrintable(obs->getScanName()),
2610  auxObs_2->getElevationAngle()*RAD2DEG,
2611  1.0e12*auxObs_2->getSlantDelayH(),
2612  1.0e12*auxObs_2->getSlantDelayW(),
2613  auxObs_2->getPartDelayW(),
2614  1.0e15*auxObs_2->getSlantRateH(),
2615  1.0e15*auxObs_2->getSlantRateW(),
2616  auxObs_2->getPartRateW()
2617  );
2618  ts << str << "\n";
2619  hasReported.insert(obs->stn_2()->getKey(), "2");
2620  };
2621  };
2622  };
2623  ts.setDevice(NULL);
2624  f.close();
2625  return true;
2626 };
2627 /*=====================================================================================================*/
2628 
2629 
2630 
2631 
2632 
2633 
2634 /*=====================================================================================================*/
2635 //
2636 // FRIENDS:
2637 //
2638 /*=====================================================================================================*/
2639 //
2640 
2641 
2642 
2643 /*=====================================================================================================*/
2644 //
2645 // aux functions:
2646 //
2648 {
2649  return
2650  fabs(o1->activeDelay()->getResidualNorm()) > fabs(o2->activeDelay()->getResidualNorm());
2651 };
2652 
2653 
2654 
2655 //
2656 void evaluatePCal4GrpDelay(SgVector& pCalByChan, const SgVector& rFreqByChan, int numOfChannels,
2657  double& pCal4GrpDelay, double& pCalSigma4GrpDelay,
2658  int obsIdx, const SgMJD& epoch,
2659  const QString& sourceName, const QString& baselineName)
2660 {
2661  int numOfActualChannels = rFreqByChan.n();
2662  while (rFreqByChan.getElement(numOfActualChannels-1)==0.0)
2663  numOfActualChannels--;
2664 
2665  if (numOfChannels != numOfActualChannels)
2667  QString("").sprintf("evaluatePCal4GrpDelay(): number of actual channels (%d) is not equal"
2668  "to the declared number (%d), for the Obs#%d, %s @%s, on ",
2669  numOfActualChannels, numOfChannels, obsIdx, qPrintable(sourceName), qPrintable(baselineName))
2670  + epoch.toString());
2671 
2672  if (!numOfActualChannels)
2673  {
2675  QString("").sprintf("evaluatePCal4GrpDelay(): number of actual channels is zero, "
2676  "nothing to do, for the Obs#%d, %s @%s, on ",
2677  obsIdx, qPrintable(sourceName), qPrintable(baselineName)) + epoch.toString());
2678  return;
2679  };
2680  if (numOfActualChannels==1)
2681  {
2683  QString("").sprintf("evaluatePCal4GrpDelay(): only one actual channel, "
2684  "nothing to do, for the Obs#%d, %s @%s, on ",
2685  obsIdx, qPrintable(sourceName), qPrintable(baselineName)) + epoch.toString());
2686  return;
2687  };
2688 
2689  for (int i=0; i<numOfActualChannels; i++)
2690  pCalByChan.setElement(i, fmod(pCalByChan.getElement(i), 360.0));
2691 
2692  for (int i=0; i<numOfActualChannels; i++)
2693  pCalByChan.setElement(i, pCalByChan.getElement(i) - pCalByChan.getElement(0));
2694 
2695  for (int i=0; i<numOfActualChannels; i++)
2696  {
2697  while (pCalByChan.getElement(i) > 180.0)
2698  pCalByChan.setElement(i, pCalByChan.getElement(i) - 360.0);
2699  while (pCalByChan.getElement(i) < -180.0)
2700  pCalByChan.setElement(i, pCalByChan.getElement(i) + 360.0);
2701  };
2702  // now the phases are in cycles:
2703  for (int i=0; i<numOfActualChannels; i++)
2704  pCalByChan.setElement(i, pCalByChan.getElement(i)/360.0);
2705 
2706  for (int j=0; j<2; j++)
2707  for (int i=0; i<numOfActualChannels-1; i++)
2708  {
2709  if (pCalByChan.getElement(i+1) - pCalByChan.getElement(i) > 0.5)
2710  pCalByChan.setElement(i+1, pCalByChan.getElement(i+1) - 1.0);
2711  if (pCalByChan.getElement(i+1) - pCalByChan.getElement(i) < -0.5)
2712  pCalByChan.setElement(i+1, pCalByChan.getElement(i+1) + 1.0);
2713  };
2714 
2715  // estimate the slope:
2716  double weight=1.0;
2717  double sum=0.0, sumX=0.0, sumY=0.0;
2718  double sumXY=0.0, sumX2=0.0, sumY2=0.0;
2719  double a=0.0, b=0.0, /*sigmaA=0.0,*/ sigmaB=0.0;
2720  for (int i=0; i<numOfActualChannels; i++)
2721  {
2722  sum += weight;
2723  sumX += weight*rFreqByChan.getElement(i);
2724  sumY += weight* pCalByChan.getElement(i);
2725  sumXY+= weight*rFreqByChan.getElement(i)* pCalByChan.getElement(i);
2726  sumX2+= weight*rFreqByChan.getElement(i)*rFreqByChan.getElement(i);
2727  sumY2+= weight* pCalByChan.getElement(i)* pCalByChan.getElement(i);
2728  };
2729  double delta = sum*sumX2 - sumX*sumX;
2730  a = (sumX2*sumY - sumX*sumXY)/delta;
2731  b = (sumXY*sum - sumX*sumY )/delta;
2732  double varnc;
2733  if (numOfActualChannels>2)
2734  {
2735  varnc = (sumY2 + a*a*sum + b*b*sumX2 - 2.0*(a*sumY + b*sumXY - a*b*sumX))/(numOfActualChannels - 2);
2736  // sigmaA = sqrt(varnc*sumX2/delta);
2737  sigmaB = sqrt(varnc*sum /delta);
2738  }
2739  else
2740  {
2741  // sigmaA = 0.0;
2742  sigmaB = 0.0;
2743  };
2744 
2745  pCal4GrpDelay = b*1.0e6;
2746  pCalSigma4GrpDelay = sigmaB*1.0e6;
2747  return;
2748 };
2749 
2750 
2751 
2752 
2753 
2754 
2755 
2756 //
2757 // Evaluating the ionospherie effective frequencies for group delay, phase delay and
2758 // group rate observables. The code is from "mk5/progs/solve/sdbh/ionfr.f" file.
2759 // utils/db2vgosDB/do_freq.f
2760 // utils/db2vgosDB/do_freq_merge.f
2761 //
2763  // input:
2764  const SgVector& numOfAccPeriodsByChan_USB, const SgVector& numOfAccPeriodsByChan_LSB,
2765  const SgVector& refFreqByChan, const SgVector& fringeAmplitudeByChan,
2766  const SgVector& numOfSamplesByChan_USB, const SgVector& numOfSamplesByChan_LSB,
2767  double sampleRate, double refFreq, int numOfChannels,
2768  // output:
2769  double& effFreq4GR, double& effFreq4PH, double& effFreq4RT,
2770  // info about the observation (for Log's purposes) and equalWeightsFlag:
2771  const QString& oId, bool useEqualWeights)
2772 {
2773  // set up nominal values:
2774  effFreq4GR = effFreq4PH = effFreq4RT = refFreq;
2775 
2776  // first, check the declared number of channels:
2777  int numOfActualChannels=refFreqByChan.n();
2778  while (numOfActualChannels && refFreqByChan.getElement(numOfActualChannels-1)==0.0)
2779  numOfActualChannels--;
2780 
2781  if (numOfChannels != numOfActualChannels)
2783  QString("").sprintf("evaluateEffectiveFreqs_old(): number of actual channels (%d) is not equal"
2784  "to the declared number (%d) for obs ", numOfActualChannels, numOfChannels) + oId);
2785  if (numOfActualChannels == 0)
2786  {
2788  "evaluateEffectiveFreqs_old(): number of actual channels is zero, nothing to do for obs " + oId);
2789  return;
2790  };
2791  if (numOfActualChannels == 1)
2792  {
2794  "evaluateEffectiveFreqs_old(): only one actual channel, nothing to do for obs " + oId);
2795  return;
2796  };
2797 
2798  int numOfGoodChannels=0;
2799  int numOfGoodAccPeriods=0;
2800  bool hasBadAmplitude=false;
2801  bool hasSequenceBug=true;
2802  bool areSampleNumsUsable=false;
2803  bool areAllFreqsSame=false;
2804  double minFrq, maxFrq, d;
2805  minFrq = maxFrq = refFreqByChan.getElement(0);
2806  // check the channels set up:
2807  for (int i=0; i<numOfActualChannels; i++)
2808  {
2809  // fringe amplitudes:
2810  if (fringeAmplitudeByChan.getElement(i)<0.0 || fringeAmplitudeByChan.getElement(i)>1.0)
2811  hasBadAmplitude = true; // at least one value are bad (ionfr.f: BAD_CHAN)
2812  //
2813  if ((numOfAccPeriodsByChan_USB.getElement(i) + numOfAccPeriodsByChan_LSB.getElement(i))*
2814  fringeAmplitudeByChan.getElement(i) > 1.0E-8)
2815  numOfGoodChannels++;
2816  //
2817  if (numOfAccPeriodsByChan_USB.getElement(i) + numOfAccPeriodsByChan_LSB.getElement(i) > 0.0)
2818  numOfGoodAccPeriods++;
2819  //
2820  if (i>0 && numOfAccPeriodsByChan_LSB.getElement(i)-1 != numOfAccPeriodsByChan_LSB.getElement(i-1))
2821  hasSequenceBug = false;
2822  //
2823  if (numOfSamplesByChan_USB.getElement(i)!=0.0 || numOfSamplesByChan_LSB.getElement(i)!=0.0)
2824  areSampleNumsUsable = true;
2825  //
2826  if (refFreqByChan.getElement(i) > maxFrq)
2827  maxFrq = refFreqByChan.getElement(i);
2828  //
2829  if (refFreqByChan.getElement(i) < minFrq)
2830  minFrq = refFreqByChan.getElement(i);
2831  };
2832  if (maxFrq-minFrq < 0.001) // MHz
2833  areAllFreqsSame = true;
2834 
2835  if (areAllFreqsSame) // complain, return
2836  {
2838  "evaluateEffectiveFreqs_old(): all frequencies are the same, nothing to do for obs " + oId);
2839  return;
2840  };
2841 
2842  if (numOfActualChannels!=numOfGoodChannels || numOfActualChannels!=numOfGoodAccPeriods)// just complain
2844  QString("").sprintf("evaluateEffectiveFreqs_old(): the numbers of actual channels (%d), "
2845  "good channels (%d) and good accumulated periods (%d) are not the same "
2846  "for obs ", numOfActualChannels, numOfGoodChannels, numOfGoodAccPeriods) + oId);
2847 
2848  SgVector weightByChan(numOfActualChannels);
2849  // from John's ionfr.f:
2850  SgVector weightByChan_USB(numOfActualChannels);
2851  SgVector weightByChan_LSB(numOfActualChannels);
2852  //
2853  if (numOfGoodChannels<2 || numOfGoodAccPeriods<2 || hasSequenceBug || hasBadAmplitude)
2854  for (int i=0; i<numOfActualChannels; i++)
2855  {
2856  weightByChan.setElement (i, 1.0);
2857  weightByChan_USB.setElement(i, 0.0);
2858  weightByChan_LSB.setElement(i, 1.0);
2859  }
2860  else if (!areSampleNumsUsable)
2861  for (int i=0; i<numOfActualChannels; i++)
2862  {
2863  d = 1.0;
2864  if (!useEqualWeights)
2865  d = (numOfAccPeriodsByChan_USB.getElement(i) + numOfAccPeriodsByChan_LSB.getElement(i))
2866  *fringeAmplitudeByChan.getElement(i);
2867  weightByChan.setElement(i, d);
2868  weightByChan_USB.setElement(i, numOfAccPeriodsByChan_USB.getElement(i));
2869  weightByChan_LSB.setElement(i, numOfAccPeriodsByChan_LSB.getElement(i));
2870  }
2871  else
2872  for (int i=0; i<numOfActualChannels; i++)
2873  {
2874  d = 1.0;
2875  if (!useEqualWeights)
2876  d = (numOfSamplesByChan_USB.getElement(i) + numOfSamplesByChan_LSB.getElement(i))
2877  *fringeAmplitudeByChan.getElement(i)/sampleRate;
2878  weightByChan.setElement(i, d);
2879  weightByChan_USB.setElement(i, numOfSamplesByChan_USB.getElement(i));
2880  weightByChan_LSB.setElement(i, numOfSamplesByChan_LSB.getElement(i));
2881  };
2882 
2883  // make sums:
2884  double sumWei=0.0;
2885  double sumFr1=0.0;
2886  double sumFr2=0.0;
2887  double sumFq2=0.0;
2888  double sumFri=0.0;
2889  double sumDfi=0.0;
2890  //
2891  double halfBw=sampleRate/4.0/1.0e6;
2892  double df, frq_i;
2893  //
2894  for (int i=0; i<numOfActualChannels; i++)
2895  {
2896  frq_i = refFreqByChan.getElement(i);
2897  // new way:
2898  if (weightByChan_USB.getElement(i)>0.0 && weightByChan_LSB.getElement(i)<1.0E-3)
2899  frq_i = refFreqByChan.getElement(i) - halfBw;
2900  else if (weightByChan_USB.getElement(i)<1.0E-3 && weightByChan_LSB.getElement(i)>0.0)
2901  frq_i = refFreqByChan.getElement(i) + halfBw;
2902  //
2903  df = frq_i - refFreq;
2904  sumWei += weightByChan.getElement(i);
2905  sumFr1 += weightByChan.getElement(i)*df;
2906  sumFr2 += weightByChan.getElement(i)*df*df;
2907  sumFq2 += weightByChan.getElement(i)*frq_i*frq_i;
2908  sumFri += weightByChan.getElement(i)/frq_i;
2909  sumDfi += weightByChan.getElement(i)*df/frq_i;
2910  };
2911  double da=sumWei*sumFr2 - sumFr1*sumFr1;
2912  double db=sumFri*sumFr1 - sumDfi*sumWei;
2913  double dc=sumFri*sumFr2 - sumDfi*sumFr1;
2914 
2915  effFreq4GR = (fabs(db)>1.0E-10)?sqrt(da/db):refFreq;
2916  effFreq4PH = (fabs(dc)>1.0E-10)?sqrt(refFreq*da/dc):refFreq;
2917  effFreq4RT = sqrt(sumFq2/sumWei);
2918 
2919  return;
2920 };
2921 
2922 
2923 
2924 
2925 //
2926 // Evaluating the ionospherie effective frequencies for group delay, phase delay and
2927 // group rate observables. The code is from "mk5/progs/solve/sdbh/ionfr.f" file.
2928 // utils/db2vgosDB/do_freq.f
2929 // utils/db2vgosDB/do_freq_merge.f
2930 //
2932  // input:
2933  const SgVector& numOfAccPeriodsByChan_USB, const SgVector& numOfAccPeriodsByChan_LSB,
2934  const SgVector& refFreqByChan, const SgVector& fringeAmplitudeByChan,
2935  const SgVector& numOfSamplesByChan_USB, const SgVector& numOfSamplesByChan_LSB,
2936  double sampleRate, double refFreq, int numOfChannels,
2937  // output:
2938  double& effFreq4GR, double& effFreq4PH, double& effFreq4RT,
2939  // type of a correlator:
2940  const QString& correlatorType,
2941  // info about the observation (for Log's purposes) and equalWeightsFlag:
2942  const QString& oId, bool useEqualWeights)
2943 {
2944 /*
2945 std::cout << "ObsId: " << qPrintable(oId) << "\n";
2946 std::cout << "sampleRate= " << sampleRate << " refFreq=" << refFreq << " numOfChannels=" << numOfChannels << "\n";
2947 std::cout << "numOfAccPeriodsByChan_USB= " << numOfAccPeriodsByChan_USB << " numOfAccPeriodsByChan_LSB=" << numOfAccPeriodsByChan_LSB << "\n";
2948 std::cout << "refFreqByChan= " << refFreqByChan << " fringeAmplitudeByChan=" << fringeAmplitudeByChan << "\n";
2949 std::cout << "numOfSamplesByChan_USB= " << numOfSamplesByChan_USB << " numOfSamplesByChan_LSB=" << numOfSamplesByChan_LSB << "\n\n";
2950 */
2951  // set up nominal values:
2952  effFreq4GR = effFreq4PH = effFreq4RT = refFreq;
2953  //
2954  // first, check the declared number of channels:
2955  int numOfActualChannels=refFreqByChan.n();
2956  while (numOfActualChannels && fabs(refFreqByChan.getElement(numOfActualChannels-1))<1.0e-6)
2957  numOfActualChannels--;
2958 
2959 
2960  if (numOfActualChannels == 0)
2961  {
2963  "evaluateEffectiveFreqs(): number of actual channels is zero, nothing to do for the obs " + oId);
2964  return;
2965  };
2966  if (numOfActualChannels == 1)
2967  {
2969  "evaluateEffectiveFreqs(): only one actual channel, nothing to do for the obs " + oId);
2970  return;
2971  };
2972  //
2973  if (!(correlatorType.contains("GSI", Qt::CaseInsensitive) ||
2974  correlatorType.contains("K5", Qt::CaseInsensitive)) &&
2975  numOfChannels != numOfActualChannels)
2977  QString("").sprintf("evaluateEffectiveFreqs(): number of actual channels (%d) is not equal"
2978  "to the declared number (%d) for the obs ", numOfActualChannels, numOfChannels) + oId);
2979  //
2980  //
2981  int numOfGoodChannels=0;
2982  int numOfGoodAccPeriods=0;
2983  bool hasBadAmplitude=false;
2984  bool hasSequenceBug=true;
2985  bool areSampleNumsUsable=false;
2986  bool areAllFreqsSame=false;
2987  double minFrq, maxFrq;
2988  minFrq = maxFrq = refFreqByChan.getElement(0);
2989  // check the channels set up:
2990  for (int i=0; i<numOfActualChannels; i++)
2991  {
2992  // fringe amplitudes:
2993  if (fringeAmplitudeByChan.getElement(i)<0.0 || fringeAmplitudeByChan.getElement(i)>1.0)
2994  hasBadAmplitude = true; // at least one value are bad (ionfr.f: BAD_CHAN)
2995  //
2996  if ((numOfAccPeriodsByChan_USB.getElement(i) + numOfAccPeriodsByChan_LSB.getElement(i))*
2997  fringeAmplitudeByChan.getElement(i) > 1.0E-8)
2998  numOfGoodChannels++;
2999  //
3000  if (numOfAccPeriodsByChan_USB.getElement(i) + numOfAccPeriodsByChan_LSB.getElement(i) > 0.0)
3001  numOfGoodAccPeriods++;
3002  //
3003  if (i>0 && numOfAccPeriodsByChan_LSB.getElement(i)-1 != numOfAccPeriodsByChan_LSB.getElement(i-1))
3004  hasSequenceBug = false;
3005  //
3006  if (numOfSamplesByChan_USB.getElement(i)>=1.0 || numOfSamplesByChan_LSB.getElement(i)>=1.0)
3007  areSampleNumsUsable = true;
3008  //
3009  if (refFreqByChan.getElement(i) > maxFrq)
3010  maxFrq = refFreqByChan.getElement(i);
3011  //
3012  if (refFreqByChan.getElement(i) < minFrq)
3013  minFrq = refFreqByChan.getElement(i);
3014  //
3015  };
3016 
3017  if (maxFrq-minFrq < 0.001) // MHz
3018  areAllFreqsSame = true;
3019 
3020  if (areAllFreqsSame) // complain, return
3021  {
3023  "evaluateEffectiveFreqs(): all frequencies are the same, nothing to do for obs " + oId);
3024  return;
3025  };
3026 
3027  if (!(correlatorType.contains("GSI", Qt::CaseInsensitive) ||
3028  correlatorType.contains("K5", Qt::CaseInsensitive)) &&
3029  (numOfActualChannels!=numOfGoodChannels || numOfActualChannels!=numOfGoodAccPeriods)) // complain
3031  QString("").sprintf("evaluateEffectiveFreqs(): the numbers of actual channels (%d), "
3032  "good channels (%d) and good accumulated periods (%d) are not the same "
3033  "for obs ", numOfActualChannels, numOfGoodChannels, numOfGoodAccPeriods) + oId);
3034  if (hasBadAmplitude) // just complain
3036  "evaluateEffectiveFreqs(): bad amplitudes are detected for the obs " + oId);
3037  if (hasSequenceBug) // just complain
3039  "evaluateEffectiveFreqs(): the sequence bug is detected for the obs " + oId);
3040 
3041 
3042  SgVector noAP_USB(numOfActualChannels);
3043  SgVector noAP_LSB(numOfActualChannels);
3044  for (int i=0; i<numOfActualChannels; i++)
3045  {
3046  if (useEqualWeights)
3047  {
3048  if (numOfSamplesByChan_USB.getElement(i) > 0.0)
3049  noAP_USB.setElement(i, 1.0);
3050  else
3051  noAP_USB.setElement(i, 0.0);
3052  if (numOfSamplesByChan_LSB.getElement(i) > 0.0)
3053  noAP_LSB.setElement(i, 1.0);
3054  else
3055  noAP_LSB.setElement(i, 0.0);
3056  }
3057  else if (areSampleNumsUsable)
3058  {
3059  noAP_USB.setElement(i, numOfSamplesByChan_USB.getElement(i));
3060  noAP_LSB.setElement(i, numOfSamplesByChan_LSB.getElement(i));
3061  }
3062  else
3063  {
3064  noAP_USB.setElement(i, numOfAccPeriodsByChan_USB.getElement(i));
3065  noAP_LSB.setElement(i, numOfAccPeriodsByChan_LSB.getElement(i));
3066  };
3067  };
3068 
3069  // make sums:
3070  double sumWei=0.0;
3071  double sumFr1=0.0;
3072  double sumFr2=0.0;
3073  double sumFq2=0.0;
3074  double sumFri=0.0;
3075  double sumDfi=0.0;
3076  //
3077  double halfBw=sampleRate/4.0/1.0e6;
3078  double df, frq_i, wei2, weiUSB, weiLSB;
3079 
3080  // old way:
3081  if (false)
3082  {
3083  for (int i=0; i<numOfActualChannels; i++)
3084  {
3085  frq_i = refFreqByChan.getElement(i);
3086  df = frq_i - refFreq;
3087  if (!useEqualWeights)
3088  {
3089  if (!areSampleNumsUsable)
3090  wei2 = (noAP_USB.getElement(i) + noAP_LSB.getElement(i))*fringeAmplitudeByChan.getElement(i);
3091  else
3092  wei2 = (numOfSamplesByChan_USB.getElement(i) + numOfSamplesByChan_LSB.getElement(i))
3093  *fringeAmplitudeByChan.getElement(i);
3094  }
3095  else
3096  wei2 = 1.0;
3097  //
3098  sumWei += wei2;
3099  sumFr1 += wei2*df;
3100  sumFr2 += wei2*df*df;
3101  sumFq2 += wei2*frq_i*frq_i;
3102  sumFri += wei2/frq_i;
3103  sumDfi += wei2*df/frq_i;
3104  };
3105  }
3106  // new way:
3107  else
3108  {
3109  for (int i=0; i<numOfActualChannels; i++)
3110  {
3111  frq_i = refFreqByChan.getElement(i);
3112  //
3113  if (!useEqualWeights)
3114  {
3115  if (!areSampleNumsUsable)
3116  {
3117  weiUSB = noAP_USB.getElement(i);
3118  weiLSB = noAP_LSB.getElement(i);
3119  }
3120  else
3121  {
3122  weiUSB = numOfSamplesByChan_USB.getElement(i);
3123  weiLSB = numOfSamplesByChan_LSB.getElement(i);
3124  };
3125  wei2 = (weiUSB + weiLSB)*fringeAmplitudeByChan.getElement(i);
3126  if (weiUSB>0.0 && weiLSB>0.0) // nothing to do
3127  {
3128  }
3129  else if (weiUSB > 0.0)
3130  frq_i -= halfBw;
3131 // frq_i += halfBw; // <-- to reproduce the confuse with USB/LSB
3132  else if (weiLSB > 0.0)
3133  frq_i += halfBw;
3134 // frq_i -= halfBw; // <-- to reproduce the confuse with USB/LSB
3135  }
3136  else
3137  wei2 = 1.0;
3138 
3139  df = frq_i - refFreq;
3140 
3141  sumWei += wei2;
3142  sumFr1 += wei2*df;
3143  sumFr2 += wei2*df*df;
3144  sumFq2 += wei2*frq_i*frq_i;
3145  sumFri += wei2/frq_i;
3146  sumDfi += wei2*df/frq_i;
3147  };
3148  };
3149  //
3150  double da=sumWei*sumFr2 - sumFr1*sumFr1;
3151  double db=sumFri*sumFr1 - sumWei*sumDfi;
3152  double dc=sumFri*sumFr2 - sumFr1*sumDfi;
3153 
3154  effFreq4GR = (fabs(db)<1.0E-12)?refFreq:sqrt(da/db);
3155  effFreq4PH = (fabs(dc)<1.0E-12)?refFreq:sqrt(refFreq*da/dc);
3156  effFreq4RT = (sumWei<1.0E-16)?refFreq:sqrt(sumFq2/sumWei);
3157 
3158  // complain:
3159  if (fabs(db)<1.0E-12)
3161  "evaluateEffectiveFreqs(): suspicious channel setup (fabs(db)<1.0E-12) for the obs " + oId);
3162  if (fabs(dc)<1.0E-12)
3164  "evaluateEffectiveFreqs(): suspicious channel setup (fabs(dc)<1.0E-12) for the obs " + oId);
3165  if (sumWei<1.0E-16)
3167  "evaluateEffectiveFreqs(): suspicious channel setup (sumWei<1.0E-16) for the obs " + oId);
3168 
3169  return;
3170 };
3171 /*=====================================================================================================*/
3172 
3173 
3174 
3175 /*=====================================================================================================*/
const Sg3dVector v3Zero(0.0, 0.0, 0.0)
SgLogger * logger
Definition: SgLogger.cpp:231
const SgMJD tZero(1957, 10, 4)
#define RAD2MAS
radians to ms:
Definition: SgMathSupport.h:60
#define DAY2SEC
radians to mas:
Definition: SgMathSupport.h:56
#define RAD2DEG
< radians to degrees:
Definition: SgMathSupport.h:32
QMap< QString, SgVlbiBaselineInfo * >::iterator BaselinesByName_it
QMap< QString, SgVlbiBaselineInfo * > BaselinesByName
bool normResidSortingOrderLessThan(SgVlbiObservable *, SgVlbiObservable *)
void evaluateEffectiveFreqs_old_version(const SgVector &numOfAccPeriodsByChan_USB, const SgVector &numOfAccPeriodsByChan_LSB, const SgVector &refFreqByChan, const SgVector &fringeAmplitudeByChan, const SgVector &numOfSamplesByChan_USB, const SgVector &numOfSamplesByChan_LSB, double sampleRate, double refFreq, int numOfChannels, double &effFreq4GR, double &effFreq4PH, double &effFreq4RT, const QString &oId, bool useEqualWeights)
void evaluateEffectiveFreqs(const SgVector &numOfAccPeriodsByChan_USB, const SgVector &numOfAccPeriodsByChan_LSB, const SgVector &refFreqByChan, const SgVector &fringeAmplitudeByChan, const SgVector &numOfSamplesByChan_USB, const SgVector &numOfSamplesByChan_LSB, double sampleRate, double refFreq, int numOfChannels, double &effFreq4GR, double &effFreq4PH, double &effFreq4RT, const QString &correlatorType, const QString &oId, bool useEqualWeights)
void evaluatePCal4GrpDelay(SgVector &pCalByChan, const SgVector &rFreqByChan, int numOfChannels, double &pCal4GrpDelay, double &pCalSigma4GrpDelay, int obsIdx, const SgMJD &epoch, const QString &sourceName, const QString &baselineName)
QMap< QString, SgVlbiSourceInfo * >::iterator SourcesByName_it
QMap< QString, SgVlbiStationInfo * >::iterator StationsByName_it
@ DT_DELAY
Definition: SgWrmsable.h:44
const QString & getComments() const
const SgMJD & getTsince() const
const QString & getFileName() const
SgAPrioriRec * lookupApRecord(const QString &, const SgMJD &=tZero)
bool readFile(const QString &fileName, DataType=DT_UNDEF)
bool isAttr(uint a) const
Definition: SgAttribute.h:226
void delAttr(uint a)
Definition: SgAttribute.h:210
void addAttr(uint a)
Definition: SgAttribute.h:202
bool addBreak(const SgMJD &t, double a0=0.0, double a1=0.0, double a2=0.0, bool isDynamic=false)
SgParameter * pC_
Definition: SgVlbiSession.h:68
SgVlbiStationInfo * stn_
Definition: SgVlbiSession.h:65
void prepare4Spline()
bool isOk() const
SgMatrix & table()
double spline(double arg, int nColumn, double &r)
SgVector & argument()
void addParametersList(QList< SgParameter * > *, bool=false)
void prepare2Run(int numOfExpectedObs, const SgMJD &, const SgMJD &, const SgMJD &)
void processConstraint(double o_c, double sigma)
void processObs(const SgMJD &t, const SgVector &o_c, const SgVector &sigma)
SgTidalUt1::UT1TideContentType ut1Type() const
InputEopType inputEopType() const
const QString & getFileName() const
bool readFile(const QString &, const SgMJD &, int numOfPoints)
bool readFile(const QString &)
const QString & getFileName() const
void setupExternalWeights(BaselinesByName &)
const QString & getAcAbbrevName() const
Definition: SgIdentities.h:247
const QString & getUserEmailAddress() const
Definition: SgIdentities.h:223
const QString & getAcFullName() const
Definition: SgIdentities.h:239
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ IO_TXT
Definition: SgLogger.h:65
@ REPORT
Definition: SgLogger.h:95
@ PREPROC
Definition: SgLogger.h:98
@ FLY_BY
Definition: SgLogger.h:85
Definition: SgMJD.h:59
@ F_Simple
Digits: 2010/04/02 17:02:43.6.
Definition: SgMJD.h:68
QString toString(Format format=F_Verbose) const
Definition: SgMJD.cpp:1007
double toDouble() const
Definition: SgMJD.h:533
void setElement(unsigned int i, unsigned int j, double d)
Definition: SgMatrix.h:402
double getElement(unsigned int i, unsigned int j) const
Definition: SgMatrix.h:385
bool readFile(const QString &)
const QString & getFileName() const
void calcCorrections(const SgMJD &, double &dUt1, double &dPx, double &dPy)
double getDversion() const
Definition: SgModelsInfo.h:114
const QString & getKey() const
Definition: SgObjectInfo.h:319
int numProcessed(DataType dType) const
Definition: SgObjectInfo.h:351
double wrms(DataType) const
Definition: SgObjectInfo.h:567
virtual int getMediaIdx() const
@ Attr_NOT_VALID
omit the observation;
Definition: SgObservation.h:78
@ Attr_PROCESSED
the observation has been processed;
Definition: SgObservation.h:79
void setS0(double a)
Definition: SgBreakModel.h:443
double getA0() const
Definition: SgBreakModel.h:363
void setA0(double a)
Definition: SgBreakModel.h:419
@ Attr_DYNAMIC
parameters supposed to be estimated during the common solution;
Definition: SgBreakModel.h:60
double getSolution() const
Definition: SgParameter.h:435
double getSigma() const
Definition: SgParameter.h:443
void setSigmaAPriori(double v)
Definition: SgParameter.h:619
SgParameterCfg::PMode getMode(int i) const
void setD(double d)
Definition: SgPartial.h:347
void absorbInfo(SgTaskManager *)
SgIdentities * identities()
const QString & getExtAPrioriSitesVelocitiesFileName() const
bool getDoIonoCorrection4SBD() const
Definition: SgTaskConfig.h:881
const QString & getExtWeightsFileName() const
Definition: SgTaskConfig.h:953
bool getUseExtAPrioriSitesVelocities() const
void setDoWeightCorrection(bool)
bool getUseExtAPrioriSourceSsm() const
bool getUseExtAPrioriHiFyErp() const
bool getUseExtAPrioriSitesPositions() const
bool getUseExtAPrioriErp() const
bool getIsSolveCompatible() const
Definition: SgTaskConfig.h:897
VlbiDelayType getUseDelayType() const
Definition: SgTaskConfig.h:857
bool getDoWeightCorrection() const
Definition: SgTaskConfig.h:889
bool getUseExtAPrioriMeanGradients() const
bool getDoClockBreakDetectionMode1() const
int getGoodQualityCodeAtStartup() const
Definition: SgTaskConfig.h:841
const QString & getExtAPrioriSitesPositionsFileName() const
const QString & getExtAPrioriHiFyErpFileName() const
static QString evaluatePath2(const QString &dir2, const QString &path2)
bool getUseExternalWeights() const
Definition: SgTaskConfig.h:921
void setActiveBandIdx(int)
bool getUseExtAPrioriSourcesPositions() const
bool getHave2ApplyUt1OceanTideHFContrib() const
Definition: SgTaskConfig.h:372
bool getHave2ApplyPxyOceanTideHFContrib() const
Definition: SgTaskConfig.h:373
bool getDoOutliersEliminationMode1() const
bool getUseExtAPrioriAxisOffsets() const
bool getUseDynamicClockBreaks() const
Definition: SgTaskConfig.h:905
int getOpIterationsLimit() const
Definition: SgTaskConfig.h:985
const QString & getExtAPrioriMeanGradientsFileName() const
const QString & getExtAPrioriSourcesPositionsFileName() const
double getOpThreshold() const
Definition: SgTaskConfig.h:977
void setUseDelayType(VlbiDelayType)
bool getUseGoodQualityCodeAtStartup() const
Definition: SgTaskConfig.h:849
const QString & getExtAPrioriAxisOffsetsFileName() const
int getActiveBandIdx() const
Definition: SgTaskConfig.h:873
bool getOpHave2SuppressWeightCorrection() const
Definition: SgTaskConfig.h:993
const QString & getExtAPrioriErpFileName() const
const QString & getExtAPrioriSourceSsmFileName() const
void setLongOperationStart(void(*operation)(int, int, const QString &))
SgVlbiSessionInfo *& currentSessionInfo()
Definition: SgTaskManager.h:85
void setLongOperationMessage(void(*operation)(const QString &))
void setLongOperationStop(void(*operation)())
void setObservations(QList< SgObservation * > *)
virtual void run(bool=true)
void setHave2InteractWithGui(bool have2)
void setLongOperationShowStats(void(*operation)(const QString &label, int numTot, int numPrc, double wrms, double chi2))
virtual bool prepare4Run()
SgVlbiSession *& currentSession()
Definition: SgTaskManager.h:89
void setLongOperationProgress(void(*operation)(int))
virtual void finisRun()
Definition: SgTask.h:59
void setConfig(const SgTaskConfig &)
Definition: SgTask.h:259
void addSession(SgVlbiSessionInfo *, SgVlbiSession *)
Definition: SgTask.cpp:69
void setParameters(const SgParametersDescriptor &)
Definition: SgTask.h:267
double calc(const SgMJD &)
Definition: SgTidalUt1.cpp:119
unsigned int n() const
Definition: SgVector.h:327
void setElement(unsigned int i, double d)
Definition: SgVector.h:348
double getElement(unsigned int i) const
Definition: SgVector.h:362
double getElevationAngle() const
QMap< QString, SgVlbiBaselineInfo * > & baselinesByName()
Definition: SgVlbiBand.h:376
QMap< QString, SgVlbiStationInfo * > & stationsByName()
Definition: SgVlbiBand.h:368
QList< SgVlbiObservable * > & observables()
Definition: SgVlbiBand.h:288
SgVlbiHistory & history()
Definition: SgVlbiBand.h:360
SgVlbiStationInfo * stn_2(QMap< QString, SgVlbiStationInfo * >) const
@ Attr_NOT_VALID
omit the baseline;
SgParameter *& pAux()
SgVlbiStationInfo * stn_1(QMap< QString, SgVlbiStationInfo * >) const
double getMeanGrDelResiduals() const
QList< SgVlbiObservable * > & observables()
void calculateClockF1(SgTaskConfig *)
double getTypicalAmbigSpacing(SgTaskConfig::VlbiDelayType type) const
SgClockBreakIndicator * cbIndicator()
double getMeanGrDelResidualsSigma() const
void setAuxSign(double s)
double getAuxSign() const
void shiftAmbiguities(int deltaN)
double sigma2Apply() const
void setResidual(double)
double getSigma() const
double getResidual() const
double getResidualNorm() const
bool isUsable() const
const SgMJD & epoch() const
int getQualityFactor() const
SgVlbiStationInfo *& stn_2()
SgVlbiStationInfo *& stn_1()
SgVlbiObservation * owner()
SgVlbiSourceInfo * getSrc() const
QString strId() const
SgVlbiSourceInfo *& src()
const QString & getBandKey() const
SgVlbiBaselineInfo * getBaseline() const
SgVlbiBaselineInfo *& baseline()
SgVlbiMeasurement * activeDelay()
SgVlbiMeasurement & grDelay()
SgVlbiMeasurement & sbDelay()
int getMediaIdx() const
double getDrat_dCipY() const
@ Attr_SBD_NOT_VALID
omit the observation if single band delay is analysed;
void setExtRateErp(double v)
SgVlbiStationInfo * stn_1()
SgVlbiAuxObservation * auxObs_2()
void setAprioriCxLfContrib(double v)
void setExtDelayHiFyUt1(double v)
void setAprioriUt1HfContrib(double v)
void setupActiveMeasurement(const SgTaskConfig *)
SgVlbiBaselineInfo * baseline()
double getDdel_dPy() const
void setAprioriCyLfContrib(double v)
double getDrat_dPx() const
void setupActiveObservable(const QString &)
void setAprioriPyLfContrib(double v)
void setExtRateHiFyUt1(double v)
double getDrat_dCipX() const
void setExtDelayErp(double v)
SgVlbiStationInfo * stn_2()
double getDdel_dCipY() const
void setAprioriPyHfContrib(double v)
double getDrat_dUT1() const
void setAprioriUt1LfContrib(double v)
void setExtRateHiFyPxy(double v)
const QString & getScanName() const
void setAprioriPxLfContrib(double v)
void setExtDelayHiFyPxy(double v)
void setAprioriPxHfContrib(double v)
double getDdel_dPx() const
double getDrat_dPy() const
QMap< QString, SgVlbiObservable * > & observableByKey()
double getDdel_dUT1() const
virtual bool isEligible(const SgTaskConfig *)
SgVlbiAuxObservation * auxObs_1()
double getDdel_dCipX() const
const QString & getName() const
@ Attr_FF_OUTLIERS_PROCESSED
outliers have been processed;
@ Attr_FF_AMBIGS_RESOLVED
ambiguities have been resolved;
@ Attr_HAS_IONO_CORR
the theoretical values are available;
@ Attr_HAS_WEIGHTS
the theoretical values are available;
SgMJD tFinis_
last epoch of the observations;
SgMJD tMean_
mean epoch of the observations;
const SgMJD & getTMean() const
SgMJD tStart_
first epoch of the observations;
SgAPriories apStationGradients_
void(* longOperationStart_)(int minStep, int maxStep, const QString &message)
int numberOfBands() const
StationsByName stationsByName_
bool writeUserData2File(const QString &fileName)
QList< SgVlbiBand * > & bands()
void resolveGrAmbigTriangles(int bandIdx)
QList< SgVlbiBand * > bands_
SgTidalUt1::UT1TideContentType tabsUt1Type_
void calculateIonoCorrections(const SgTaskConfig *)
SgVector * args4PxyInterpolation_
SgAPriories apStationVelocities_
int restoreOutliers(int bandIdx)
void(* longOperationProgress_)(int step)
double getLeapSeconds()
SgTaskConfig lastProcessedConfig_
QMap< QString, SgVlbiStationInfo * > & stationsByName()
SgAPriories apAxisOffsets_
QList< SgVlbiObservation * > observations_
SgAPriories apSourceStrModel_
SgAPriories apStationPositions_
SgSolutionReporter * reporter_
bool detectClockBreaks_mode1(SgVlbiBand *, QString &, SgMJD &)
void(* longOperationStop_)()
bool hasOutlierRestoratioRun_
void process(bool haveProcessAllBands, bool interactWithGui)
SgAPriories apSourcePositions_
SgCubicSpline * externalErpInterpolator_
bool isInUse(SgVlbiBaselineInfo *)
void scanBaselines4GrDelayAmbiguities(int bandIdx)
SgExternalEopFile externalErpFile_
SgModelsInfo calcInfo_
SgExternalWeights externalWeights_
void(* longOperationMessage_)(const QString &message)
bool hasPxyInterpolation_
void eliminateLargeOutliers(int bandIdx, int maxNumOfPasses, double wrmsRatio)
void correctClockBreak(SgVlbiBand *, SgVlbiStationInfo *, const SgMJD &, double, double, bool, bool=true)
SgCubicSpline * innerUt1Interpolator_
void getAprioriErp(const SgMJD &t, double &vUt1, double &rUt1, double &vPx, double &rPx, double &vPy, double &rPy, double &vCx, double &rCx, double &vCy, double &rCy)
void calculateClockBreaksParameters(QList< SgClockBreakAgent * > &, SgVlbiBand *)
BaselinesByName baselinesByName_
void calculateClockBreakParameter(const SgMJD &, SgVlbiStationInfo *, SgVlbiBand *, double &, double &)
bool hasUt1Interpolation_
SgParametersDescriptor * parametersDescriptor_
QString path2APrioriFiles_
SgVlbiBand * primaryBand_
int eliminateOutliers(int bandIdx)
void eliminateOutliersSimpleMode(int bandIdx, int maxNumOfPasses, double threshold, double=0.0)
bool hasOutlierEliminationRun_
static QString className()
SgVector * args4Ut1Interpolation_
SgMatrix * tabs4Ut1Interpolation_
void(* longOperationShowStats_)(const QString &label, int numTot, int numPrc, double wrms, double chi2)
bool have2InteractWithGui_
int numOfPts4ErpInterpolation_
SourcesByName sourcesByName_
bool isAble2InterpolateErp_
void checkBandForClockBreaks(int, bool)
SgCubicSpline * innerPxyInterpolator_
QMap< QString, SgVlbiBaselineInfo * > & baselinesByName()
SgTaskConfig * config_
SgMatrix * tabs4PxyInterpolation_
SgModelEop_JMG_96_hf apHiFyEop_
double getDN_ea() const
void addSrcStructPoint(double k, double b, double x, double y, bool estK=false, bool estB=false, bool estR=false)
double getRA_ea() const
void setAprioriComments(const QString &str)
void setDN_ea(double dn)
double getAl2ExtA() const
double getRA() const
void setRA_ea(double ra)
QList< StructModelMp > & sModel()
void setAl2ExtA(double l)
double getDN() const
static double arcLength(double ra_1, double dn_1, double ra_2, double dn_2)
@ Attr_HAS_A_PRIORI_POS
indicates that the source has a priori position;
double getGradNorth() const
double getAxisOffset() const
void setV_ea(const Sg3dVector &v)
double getGradEast() const
@ Attr_NOT_VALID
omit the station;
@ Attr_CONSTRAIN_COO
constrain station position in estimation;
@ Attr_REFERENCE_CLOCKS
the clocks are the reference ones;
@ Attr_HAS_A_PRIORI_AXO
indicates that the station has a priori axis offset;
@ Attr_ESTIMATE_COO
estimate station position;
@ Attr_HAS_A_PRIORI_POS
indicates that the station has a priori r and v;
void setGradNorth(double v)
void setAxisOffset_ea(double v)
const Sg3dVector & getR()
double getAxisOffset_ea() const
const Sg3dVector & getR_ea()
SgBreakModel & clockBreaks()
int getClocksModelOrder() const
void setR_ea(const Sg3dVector &r)
void setGradEast(double v)