General Purpose Geodetic Library
SgSolutionReporter.cpp
Go to the documentation of this file.
1 
2 /*
3  *
4  * This file is a part of Space Geodetic Library. The library is used by
5  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
6  * geodetic VLBI observations.
7  * Copyright (C) 2010-2020 Sergei Bolotin.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23 
24 #include <iostream>
25 #include <stdlib.h>
26 
27 #include <QtCore/QDateTime>
28 #include <QtCore/QDir>
29 #include <QtCore/QFile>
30 #include <QtCore/QList>
31 #include <QtCore/QMap>
32 
33 
34 
35 #include <SgSolutionReporter.h>
36 
37 
38 #include <Sg3dMatrixR.h>
39 #include <SgArcStorage.h>
40 #include <SgConstants.h>
41 #include <SgEstimator.h>
42 #include <SgIdentities.h>
43 #include <SgLogger.h>
44 #include <SgMathSupport.h>
45 #include <SgPwlStorage.h>
46 #include <SgPwlStorageBSplineL.h>
47 #include <SgPwlStorageBSplineQ.h>
48 #include <SgPwlStorageIncRates.h>
49 #include <SgTaskManager.h>
50 #include <SgVersion.h>
51 #include <SgVlbiBand.h>
52 #include <SgVlbiNetworkId.h>
53 #include <SgVlbiObservation.h>
54 #include <SgVlbiSession.h>
55 
56 
57 
59 
60 void calcLhv(const Sg3dVector& r1, const Sg3dVector& dr1, const Sg3dVector& r2, const Sg3dVector& dr2,
61  const SgMatrix& r, Sg3dVector& lhv, Sg3dVector& lhvSigma, double& length, double& lengthSigma);
62 void calcLhv(const Sg3dVector& r1, const Sg3dVector& r2, const Sg3dVector& db,
63  const SgMatrix& r, Sg3dVector& lhv, Sg3dVector& lhvSigma, double& length, double& lengthSigma);
64 
65 
66 
67 static const QString srcChars[] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
68  "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
69 static const int numOfSrcChars = sizeof(srcChars)/sizeof(QString);
70 
71 
72 
73 /*=======================================================================================================
74 *
75 * METHODS:
76 *
77 *======================================================================================================*/
78 //
79 // static first:
81 {
82  return "SgSolutionReporter";
83 };
84 
85 
86 
87 //
89  activeBandKey_(""),
90  identities_(id),
91  runEpoch_(tZero),
92  creationEpoch_(tZero),
93  reportID_("?"),
94  solutionTypeName_("N/A"),
95  path2APrioriFiles_("NONE"),
96  stcSolutions_(),
97  parByName_(),
98  stcParByName_(),
99  pwlByName_(),
100  arcByName_(),
101  usedSources_(),
102  skippedSources_(),
103  userComents_(),
104  erpTref_(tZero)
105 {
106  setSession(session);
107  activeBand_ = NULL;
108  PxAll_ = NULL;
109  condNumber_ = 0.0;
115 
117 };
118 
119 
120 
121 // A destructor:
123 {
124  session_ = NULL;
125  config_ = NULL;
126  parametersDescriptor_ = NULL;
127  activeBand_ = NULL;
128  if (PxAll_)
129  {
130  delete PxAll_;
131  PxAll_ = NULL;
132  };
133  numOfUnknowns_ = 0;
134  numOfObservations_ = 0;
135  numOfConstraints_ = 0;
136  freeResources();
137  usedSources_.clear();
138  skippedSources_.clear();
139  userComents_.clear();
140 };
141 
142 
143 
144 //
146 {
147  if ((session_=session))
148  {
151  session_->setReporter(this);
152  }
153  else
154  {
155  config_ = NULL;
156  parametersDescriptor_ = NULL;
157  };
158 };
159 
160 
161 
162 //
164 {
165  if (PxAll_)
166  {
167  delete PxAll_;
168  PxAll_ = NULL;
169  };
170 
171  parByName_.clear();
172  pwlByName_.clear();
173  arcByName_.clear();
174  stcParByName_.clear();
175 
176  for (int i=0; i<parList_.size(); i++)
177  delete parList_.at(i);
178  parList_.clear();
179 
180  for (int i=0; i<allParList_.size(); i++)
181  delete allParList_.at(i);
182  allParList_.clear();
183 
184  for (int i=0; i<pwlList_.size(); i++)
185  delete pwlList_.at(i);
186  pwlList_.clear();
187 
188  for (int i=0; i<arcList_.size(); i++)
189  delete arcList_.at(i);
190  arcList_.clear();
191 
192  for (QMap<QString, SgEstimator::StochasticSolutionCarrier>::iterator it=stcSolutions_.begin();
193  it!=stcSolutions_.end(); ++it)
194  {
196  &stcSC=it.value();
197  for (int i=0; i<stcSC.list_->size(); i++)
198  delete stcSC.list_->at(i);
199  stcSC.list_->clear();
200  delete stcSC.list_;
201  delete stcSC.P_;
202  delete stcSC.x_;
203  stcSC.list_ = NULL;
204  stcSC.x_ = NULL;
205  stcSC.P_ = NULL;
206  };
207  stcSolutions_.clear();
208 };
209 
210 
211 
212 //
214 {
215  bool useDelays=config_->getUseDelayType()!=SgTaskConfig::VD_NONE;
216  bool useRates=config_->getUseRateType()!=SgTaskConfig::VR_NONE;
217  QString str("");
218  // later, add deleting of objects here
219  freeResources();
220 
221  numOfUnknowns_ = 0;
222  numOfObservations_ = 0;
223  numOfConstraints_ = 0;
224  condNumber_ = 0.0;
225 
228 
229  // "Single band X-band";
230  // "Group delay X-band";
231  switch (config_->getUseDelayType())
232  {
234  solutionTypeName_ = "No data ";
235  break;
237  solutionTypeName_ = "Single band ";
238  break;
240  solutionTypeName_ = "Group delay ";
241  break;
243  solutionTypeName_ = "Phase delay ";
244  break;
245  };
246  if (useDelays && useRates)
247  solutionTypeName_ += "and delay rates ";
248  else if (useRates)
249  solutionTypeName_ += "Delay rates ";
250  //
252  {
253  str = "";
254  for (int i=0; i<session_->bands().size(); i++)
255  str += session_->bands().at(i)->getKey() + "/";
256  str.chop(1);
257  solutionTypeName_ += str + " combination";
258  }
259  else
260  solutionTypeName_ += activeBandKey_ + "-band";
261 
262  // evaluate normalized residuals per object:
263  // baselines:
264  QMap<QString, SgVlbiBaselineInfo*>::iterator itb;
265  for (itb=activeBand_->baselinesByName().begin(); itb!=activeBand_->baselinesByName().end(); ++itb)
266  {
267  double sum1(0.0), sum2(0.0), sumNRD(0.0), sumNRD_plus_15(0.0);
268  double ro, sig4NRD2, sig4NRD2_plus_15;
269  int num(0);
270  SgVlbiBaselineInfo *bi=itb.value();
271  for (int i=0; i<bi->observables().size(); i++)
272  {
273  SgVlbiObservable *o=bi->observables().at(i);
276  {
277  ro = m->getResidual();
278  sig4NRD2 = m->sigma2Apply()*m->sigma2Apply();
279  sig4NRD2_plus_15 = sig4NRD2 -
280  m->getSigma2add()*m->getSigma2add() +
281  15.0*15.0*1.0e-24;
282  sumNRD += ro*ro/sig4NRD2;
283  sumNRD_plus_15 += ro*ro/sig4NRD2_plus_15;
284  sum1 += m->getResidualNorm();
285  sum2 += m->getResidualNorm()*m->getResidualNorm();
286  num++;
287  };
288  };
289  if (num > 1)
290  {
291  bi->setNormedResid(DT_DELAY, sqrt((sum2 - sum1*sum1/num)/num));
292  bi->setSFF_NrmRes(DT_DELAY, sqrt(sumNRD/num));
293  bi->setSFF_NrmRes_plus_15(DT_DELAY, sqrt(sumNRD_plus_15/num));
294  }
295  else if (num == 1)
296  {
297  bi->setNormedResid(DT_DELAY, 1.0);
298  bi->setSFF_NrmRes(DT_DELAY, sqrt(sumNRD));
299  bi->setSFF_NrmRes_plus_15(DT_DELAY, sqrt(sumNRD_plus_15));
300  };
301  };
302  // sources and stations (they have not their own lists of observations [yet]):
303  QMap< QString, QList<SgVlbiObservation*> > obsBySrcNames;
304  QMap< QString, QList<SgVlbiObservation*> > obsByStnNames;
305  for (int i=0; i<session_->observations().size(); i++)
306  {
308  SgVlbiObservable *o=obs->activeObs();
310  {
311  obsBySrcNames[o->src()->getKey()] << obs;
312  obsByStnNames[o->stn_1()->getKey()] << obs;
313  obsByStnNames[o->stn_2()->getKey()] << obs;
314  };
315  };
316  QMap< QString, QList<SgVlbiObservation*> >::iterator its;
317  for (its=obsBySrcNames.begin(); its!=obsBySrcNames.end(); ++its)
318  {
319  SgVlbiSourceInfo *si=activeBand_->sourcesByName().find(its.key()).value();
320  QList<SgVlbiObservation*> &obsList=its.value();
321  double sum1(0.0), sum2(0.0), sumNRD(0.0), sumNRD_plus_15(0.0), ro, sig4NRD2, sig4NRD2_plus_15;
322  int num(0);
323  for (int i=0; i<obsList.size(); i++)
324  {
325  SgVlbiObservation *obs=obsList.at(i);
326  if (obs->activeObs() && obs->activeObs()->activeDelay())
327  {
329  ro = m->getResidual();
330  sig4NRD2 = m->sigma2Apply()*m->sigma2Apply();
331  sig4NRD2_plus_15 = sig4NRD2 - m->getSigma2add()*m->getSigma2add() + 15.0*15.0*1.0e-24;
332  sumNRD += ro*ro/sig4NRD2;
333  sumNRD_plus_15 += ro*ro/sig4NRD2_plus_15;
334  sum1 += obs->getNormalizedDelayResidual();
336  num++;
337  };
338  };
339  if (num > 1)
340  {
341  si->setNormedResid(DT_DELAY, sqrt((sum2 - sum1*sum1/num)/num));
342  si->setSFF_NrmRes(DT_DELAY, sqrt(sumNRD/num));
343  si->setSFF_NrmRes_plus_15(DT_DELAY, sqrt(sumNRD_plus_15/num));
344  }
345  else if (num == 1)
346  {
347  si->setNormedResid(DT_DELAY, 1.0);
348  si->setSFF_NrmRes(DT_DELAY, sqrt(sumNRD));
349  si->setSFF_NrmRes_plus_15(DT_DELAY, sqrt(sumNRD_plus_15));
350  }
351  else
352  {
353  si->setNormedResid(DT_DELAY, 0.0);
354  si->setSFF_NrmRes(DT_DELAY, 0.0);
356  };
357  };
358  for (its=obsByStnNames.begin(); its!=obsByStnNames.end(); ++its)
359  {
360  SgVlbiStationInfo *si=activeBand_->stationsByName().find(its.key()).value();
361  QList<SgVlbiObservation*> &obsList=its.value();
362  double sum1(0.0), sum2(0.0), sumNRD(0.0), sumNRD_plus_15(0.0), ro, sig4NRD2, sig4NRD2_plus_15;
363  int num(0);
364  for (int i=0; i<obsList.size(); i++)
365  {
366  SgVlbiObservation *obs=obsList.at(i);
367  if (obs->activeObs() && obs->activeObs()->activeDelay())
368  {
370  ro = m->getResidual();
371  sig4NRD2 = m->sigma2Apply()*m->sigma2Apply();
372  sig4NRD2_plus_15 = sig4NRD2 - m->getSigma2add()*m->getSigma2add() + 15.0*15.0*1.0e-24;
373  sumNRD += ro*ro/sig4NRD2;
374  sumNRD_plus_15 += ro*ro/sig4NRD2_plus_15;
375 
376  sum1 += obs->getNormalizedDelayResidual();
378  num++;
379  };
380  };
381  if (num > 1)
382  {
383  si->setNormedResid(DT_DELAY, sqrt((sum2 - sum1*sum1/num)/num));
384  si->setSFF_NrmRes(DT_DELAY, sqrt(sumNRD/num));
385  si->setSFF_NrmRes_plus_15(DT_DELAY, sqrt(sumNRD_plus_15/num));
386  }
387  else if (num == 1)
388  {
389  si->setNormedResid(DT_DELAY, 1.0);
390  si->setSFF_NrmRes(DT_DELAY, sqrt(sumNRD));
391  si->setSFF_NrmRes_plus_15(DT_DELAY, sqrt(sumNRD_plus_15));
392  }
393  else
394  {
395  si->setNormedResid(DT_DELAY, 0.0);
396  si->setSFF_NrmRes(DT_DELAY, 0.0);
398  };
399  };
400  // make a copy of saved parameters (will use them later):
401  SgEstimator *estimator=NULL;
402  if (mgr && (estimator=mgr->estimator()))
403  {
405  for (int i=0; i<xAll->size(); i++)
406  {
407  SgParameter *p=new SgParameter(*xAll->at(i));
408  allParList_.append(p);
409  if (!xAll->at(i)->isAttr(SgParameter::Attr_IS_SPECIAL))
410  {
411  p = new SgParameter(*xAll->at(i));
412  parList_.append(p);
413  parByName_.insert(p->getName(), p);
414  };
415  };
416  QList<SgPwlStorage*> *pwlList=estimator->pwlStorage();
417  for (int i=0; i<pwlList->size(); i++)
418  {
419  SgPwlStorage *pwl;
420  switch (config_->getPwlMode())
421  {
422  default:
424  pwl = new SgPwlStorageBSplineL;
425  break;
427  pwl = new SgPwlStorageBSplineQ;
428  break;
430  pwl = new SgPwlStorageIncRates;
431  break;
432  };
433  *pwl = *pwlList->at(i);
434  pwlList_.append(pwl);
435  pwlByName_.insert(pwl->getPOrig()->getName(), pwl);
436  };
437  QList<SgArcStorage*> *arcList=estimator->arcStorage();
438  for (int i=0; i<arcList->size(); i++)
439  {
440  SgArcStorage *arc=new SgArcStorage;
441  *arc = *arcList->at(i);
442  arcList_.append(arc);
443  arcByName_.insert(arc->getPOrig()->getName(), arc);
444  };
445  PxAll_ = new SgSymMatrix(*estimator->mPall());
446  condNumber_ = estimator->maxConditionNumber();
447  };
448  //
449  //
450  // stochastic parameters:
451  const QMap<QString, SgEstimator::StochasticSolutionCarrier> stcs=estimator->stcSolutions();
452  for (QMap<QString, SgEstimator::StochasticSolutionCarrier>::const_iterator it=stcs.begin();
453  it!=stcs.end(); ++it)
454  {
456  &stcSC=it.value();
458  carrier;
459  QString timeTag(stcSC.epoch_.toString(SgMJD::F_INTERNAL));
460  // put the solution in the container:
461  carrier.epoch_ = stcSC.epoch_;
462  carrier.list_ = new QList<SgParameter*>();
463  for (int i=0; i<stcSC.list_->size(); i++)
464  {
465  SgParameter *par=NULL, *p=stcSC.list_->at(i);
466  if (p->getNumObs())
467  {
468  carrier.list_->append((par=new SgParameter(*p)));
469  (stcParByName_[par->getName()])[timeTag] = par;
470  };
471  };
472  carrier.x_ = new SgVector(*stcSC.x_);
473  carrier.P_ = new SgSymMatrix(*stcSC.P_);
474  stcSolutions_.insert(timeTag, carrier);
475  };
476  //
477  //
482 };
483 
484 
485 
486 //
488 {
489  if (parByName_.contains(p->getName()))
490  {
491  *p = *parByName_[p->getName()];
492  }
493  else if (pwlByName_.contains(p->getName()))
494  {
495  *p = *pwlByName_[p->getName()]->getPOrig();
496  }
497  else if (arcByName_.contains(p->getName()))
498  {
499  *p = *arcByName_[p->getName()]->getPOrig();
500  }
501  else if (stcParByName_.contains(p->getName()))
502  {
503  *p = **stcParByName_[p->getName()].begin();
504  }
505  else
506  {
507 // std::cout << "Parameter " << qPrintable(p->getName()) << " was not estimated\n";
508  };
509 };
510 
511 
512 
513 //
515 {
516  //
517  // stations:
518  StationsByName_it it_st;
519  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
520  {
521  SgVlbiStationInfo *si = it_st.value();
522  for (int i=0; i<si->getClocksModelOrder(); i++)
523  lookupParameter(si->pClocks(i));
524  for (int i=0; i<si->clockBreaks().size(); i++)
525  {
526  lookupParameter(si->clockBreaks().at(i)->pA0());
527  lookupParameter(si->clockBreaks().at(i)->pA1());
528  lookupParameter(si->clockBreaks().at(i)->pA2());
529  };
531  lookupParameter(si->pAtmGradN());
532  lookupParameter(si->pAtmGradE());
533  lookupParameter(si->pRx());
534  lookupParameter(si->pRy());
535  lookupParameter(si->pRz());
537  };
538  //
539  // sources:
540  SourcesByName_it it_so;
541  for (it_so=session_->sourcesByName().begin(); it_so!=session_->sourcesByName().end(); ++it_so)
542  {
543  SgVlbiSourceInfo *si = it_so.value();
544  lookupParameter(si->pRA());
545  lookupParameter(si->pDN());
546  };
547  //
548  // baselines:
549  BaselinesByName_it it_bl;
550  for (it_bl=session_->baselinesByName().begin(); it_bl!=session_->baselinesByName().end(); ++it_bl)
551  {
552  SgVlbiBaselineInfo *bi = it_bl.value();
553  lookupParameter(bi->pClock());
554  lookupParameter(bi->pBx());
555  lookupParameter(bi->pBy());
556  lookupParameter(bi->pBz());
557  };
558  //
559  // EOP:
568 };
569 
570 
571 
572 //
574 {
580 
581  if (erpTref_ == tZero)
582  {
583  erpTref_ = session_->tRefer();
585  "::evaluateUsedErpApriori2(): the ERP reference time has been adjusted to " + erpTref_.toString());
586  };
591 };
592 
593 
594 
595 
596 //
598 {
599  if (erpTref_ == tZero)
600  {
601  erpTref_ = session_->tRefer();
603  "::evaluateUsedErpApriori(): the ERP reference time has been adjusted to " + erpTref_.toString());
604  };
605  bool isNormalSession;
606  SgVlbiObservation *obs;
607  int num;
613 
614  SgEstimator *est_ut=new SgEstimator(config_);
615  SgEstimator *est_px=new SgEstimator(config_);
616  SgEstimator *est_py=new SgEstimator(config_);
617  SgEstimator *est_cx=new SgEstimator(config_);
618  SgEstimator *est_cy=new SgEstimator(config_);
624  SgParameter *pA_ut, *pB_ut, *pC_ut, *pD_ut;
625  SgParameter *pA_px, *pB_px, *pC_px, *pD_px;
626  SgParameter *pA_py, *pB_py, *pC_py, *pD_py;
627  SgParameter *pA_cx, *pB_cx, *pC_cx, *pD_cx;
628  SgParameter *pA_cy, *pB_cy, *pC_cy, *pD_cy;
629  isNormalSession = 16.0/24.0 <= (session_->getTFinis() - session_->getTStart());
630  // UT1:
631  prs_ut->append((pA_ut=new SgParameter("UT1, 0-term (ms )")));
632  prs_ut->append((pB_ut=new SgParameter("UT1, 1-term (ms/d )")));
633  // Px:
634  prs_px->append((pA_px=new SgParameter("PMx, 0-term (mas )")));
635  prs_px->append((pB_px=new SgParameter("PMx, 1-term (mas/d )")));
636  // Py:
637  prs_py->append((pA_py=new SgParameter("PMy, 0-term (mas )")));
638  prs_py->append((pB_py=new SgParameter("PMy, 1-term (mas/d )")));
639  // CIPx:
640  prs_cx->append((pA_cx=new SgParameter("CIPx, 0-term (mas )")));
641  prs_cx->append((pB_cx=new SgParameter("CIPx, 1-term (mas/d )")));
642  // CIPy:
643  prs_cy->append((pA_cy=new SgParameter("CIPy, 0-term (mas )")));
644  prs_cy->append((pB_cy=new SgParameter("CIPy, 1-term (mas/d )")));
645  //
646  if (isNormalSession)
647  {
648  prs_ut->append((pC_ut=new SgParameter("UT1, 2-term (ms/d/d)")));
649  prs_ut->append((pD_ut=new SgParameter("UT1, 3-term (ms/d/d)")));
650  prs_px->append((pC_px=new SgParameter("PMx, 2-term (mas/d/d)")));
651  prs_px->append((pD_px=new SgParameter("PMx, 3-term (mas/d/d)")));
652  prs_py->append((pC_py=new SgParameter("PMy, 2-term (mas/d/d)")));
653  prs_py->append((pD_py=new SgParameter("PMy, 3-term (mas/d/d)")));
654  prs_cx->append((pC_cx=new SgParameter("CIPx, 2-term (mas/d/d)")));
655  prs_cx->append((pD_cx=new SgParameter("CIPx, 3-term (mas/d/d)")));
656  prs_cy->append((pC_cy=new SgParameter("CIPy, 2-term (mas/d/d)")));
657  prs_cy->append((pD_cy=new SgParameter("CIPy, 3-term (mas/d/d)")));
658  }
659  for (int i=0; i<prs_ut->size(); i++)
660  {
661  SgParameter *p=prs_ut->at(i);
662  p->setSigmaAPriori(1.0e+8);
663  p->setScale(1.0e3*DAY2SEC);
665  };
666  for (int i=0; i<prs_px->size(); i++)
667  {
668  SgParameter *p=prs_px->at(i);
669  p->setSigmaAPriori(1.0e+8);
670  p->setScale(1.0e3*RAD2SEC);
672  };
673  for (int i=0; i<prs_py->size(); i++)
674  {
675  SgParameter *p=prs_py->at(i);
676  p->setSigmaAPriori(1.0e+8);
677  p->setScale(1.0e3*RAD2SEC);
679  };
680  for (int i=0; i<prs_cx->size(); i++)
681  {
682  SgParameter *p=prs_cx->at(i);
683  p->setSigmaAPriori(1.0e+8);
684  p->setScale(1.0e3*RAD2SEC);
686  };
687  for (int i=0; i<prs_cy->size(); i++)
688  {
689  SgParameter *p=prs_cy->at(i);
690  p->setSigmaAPriori(1.0e+8);
691  p->setScale(1.0e3*RAD2SEC);
693  };
694  //
695  est_ut->addParametersList(prs_ut);
696  est_px->addParametersList(prs_px);
697  est_py->addParametersList(prs_py);
698  est_cx->addParametersList(prs_cx);
699  est_cy->addParametersList(prs_cy);
700  est_ut->prepare2Run(session_->observations().size()+10,
702  est_px->prepare2Run(session_->observations().size()+10,
704  est_py->prepare2Run(session_->observations().size()+10,
706  est_cx->prepare2Run(session_->observations().size()+10,
708  est_cy->prepare2Run(session_->observations().size()+10,
710  //
711  // feed the estimators:
712  double sig, dT, dt, dt2, dt3;
713  double dsSB=0.1E-9; // 0.1ns
714  double dsGR=2.E-12; // 2ps
715  SgVector vO_C(1), vSigma(1);
716  SgMJD t0(erpTref_);
717  num = 0;
718  dT = (session_->getLeapSeconds() + 32.184)/DAY2SEC;
719  for (int i=0; i<session_->observations().size(); i++)
720  {
721  obs = session_->observations().at(i);
722  SgVlbiMeasurement *m=obs->activeObs()?obs->activeObs()->activeDelay():NULL;
724  {
725  sig = m->sigma2Apply() + dsGR;
727  sig += dsSB;
728  vSigma.setElement(0, sig);
729 
730  dt = (*obs - t0) + dT;
731  dt2 = dt*dt;
732  dt3 = dt2*dt;
733  //
734  pA_ut->setD(1.0);
735  pB_ut->setD(dt);
736 
737  pA_px->setD(1.0);
738  pB_px->setD(dt);
739 
740  pA_py->setD(1.0);
741  pB_py->setD(dt);
742 
743  pA_cx->setD(1.0);
744  pB_cx->setD(dt);
745 
746  pA_cy->setD(1.0);
747  pB_cy->setD(dt);
748 
749  if (isNormalSession)
750  {
751  pC_ut->setD(dt2);
752  pD_ut->setD(dt3);
753  pC_px->setD(dt2);
754  pD_px->setD(dt3);
755  pC_py->setD(dt2);
756  pD_py->setD(dt3);
757  pC_cx->setD(dt2);
758  pD_cx->setD(dt3);
759  pC_cy->setD(dt2);
760  pD_cy->setD(dt3);
761  };
762  //
763  vO_C.setElement (0, obs->aPrioriUt1());
764  est_ut->processObs(*obs, vO_C, vSigma);
765  //
766  vO_C.setElement (0, obs->aPrioriPx());
767  est_px->processObs(*obs, vO_C, vSigma);
768  //
769  vO_C.setElement (0, obs->aPrioriPy());
770  est_py->processObs(*obs, vO_C, vSigma);
771  //
772  vO_C.setElement (0, obs->aPrioriCipX());
773  est_cx->processObs(*obs, vO_C, vSigma);
774  //
775  vO_C.setElement (0, obs->aPrioriCipY());
776  est_cy->processObs(*obs, vO_C, vSigma);
777  num++;
778  };
779  };
780  est_ut->finisRun();
781  est_px->finisRun();
782  est_py->finisRun();
783  est_cx->finisRun();
784  est_cy->finisRun();
785  //
786  erp_ut1_0_ = pA_ut->getSolution();
787  erp_ut1_1_ = pB_ut->getSolution();
788  //
789  erp_pmx_0_ = pA_px->getSolution();
790  erp_pmx_1_ = pB_px->getSolution();
791  //
792  erp_pmy_0_ = pA_py->getSolution();
793  erp_pmy_1_ = pB_py->getSolution();
794  //
795  eop_cix_0_ = pA_cx->getSolution();
796  eop_cix_1_ = pB_cx->getSolution();
797  //
798  eop_ciy_0_ = pA_cy->getSolution();
799  eop_ciy_1_ = pB_cy->getSolution();
800  //
801  if (isNormalSession)
802  {
803  erp_ut1_2_ = pC_ut->getSolution();
804  erp_ut1_3_ = pD_ut->getSolution();
805  erp_pmx_2_ = pC_px->getSolution();
806  erp_pmx_3_ = pD_px->getSolution();
807  erp_pmy_2_ = pC_py->getSolution();
808  erp_pmy_3_ = pD_py->getSolution();
809  eop_cix_2_ = pC_cx->getSolution();
810  eop_cix_3_ = pD_cx->getSolution();
811  eop_ciy_2_ = pC_cy->getSolution();
812  eop_ciy_3_ = pD_cy->getSolution();
813  };
814  //
815  for (int i=0; i<prs_ut->size(); i++)
816  delete prs_ut->at(i);
817  for (int i=0; i<prs_px->size(); i++)
818  delete prs_px->at(i);
819  for (int i=0; i<prs_py->size(); i++)
820  delete prs_py->at(i);
821  for (int i=0; i<prs_cx->size(); i++)
822  delete prs_cx->at(i);
823  for (int i=0; i<prs_cy->size(); i++)
824  delete prs_cy->at(i);
825  delete prs_ut;
826  delete prs_px;
827  delete prs_py;
828  delete prs_cx;
829  delete prs_cy;
830  //
831  delete est_ut;
832  delete est_px;
833  delete est_py;
834  delete est_cx;
835  delete est_cy;
836 };
837 
838 
839 
840 //
842 {
843  if (!PxAll_)
844  {
846  "::calculateConditionNumber(): PxAll is NULL");
847  return;
848  };
849  if (PxAll_->n()<1)
850  {
852  "::calculateConditionNumber(): the dimenstion of PxAll is less than unity, nothing to calculate");
853  condNumber_ = -1.0;
854  return;
855  };
856  if (PxAll_->n()==1)
857  {
859  "::calculateConditionNumber(): the dimenstion of PxAll is unity, nothing to calculate");
860  condNumber_ = 1.0;
861  return;
862  };
863  //
864  SgMatrix *mP;
865  SgVector *u;
866  int n;
867  double s, betta, gamma;
868  //
869  n = PxAll_->n();
870  mP = new SgMatrix(n, n);
871  u = new SgVector(n);
872  for (int i=0; i<n; i++)
873  for (int j=0; j<n; j++)
874  mP->setElement(i, j, PxAll_->getElement(i, j));
875 
876  for (int l=0; l<n; l++)
877  {
878  s = 0.0;
879  for (int i=l; i<n; i++)
880  s += mP->getElement(i, l)*mP->getElement(i, l);
881  s = - signum(mP->getElement(l, l))*sqrt(s);
882  u->setElement(l, mP->getElement(l, l) - s);
883  for (int i=l+1; i<n; i++)
884  u->setElement(i, mP->getElement(i, l));
885  mP->setElement(l, l, s);
886  betta = 1.0/(s*u->getElement(l));
887  for (int j=l+1; j<n; j++)
888  {
889  s = 0.0;
890  for (int i=l; i<n; i++)
891  s += u->getElement(i)*mP->getElement(i, j);
892  gamma = betta*s;
893  for (int i=l+1; i<n; i++)
894  mP->setElement(i, j, mP->getElement(i, j) + gamma*u->getElement(i));
895  };
896  };
897  // end of householdering
898 
899 
900  for (int i=0; i<n; i++)
901  u->setElement(i, sqrt(PxAll_->getElement(i, i)));
902  // diagonals of P are eigenvalues.
903  double minEv, maxEv;
904  minEv = maxEv = u->getElement(0);
905  for (int i=0; i<n; i++)
906  {
907 std::cout << i << ": " << u->getElement(i) << "\n";
908  if (u->getElement(i) < minEv)
909  minEv = u->getElement(i);
910  if (u->getElement(i) > maxEv)
911  maxEv = u->getElement(i);
912  };
913 std::cout << "max eigenvalue= " << maxEv << ", min eigenvalue= " << minEv
914  << "condition number= " << (condNumber_=(minEv!=0.0?maxEv/minEv:-1.0))
915  << "\n";
916 
917  delete mP;
918  delete u;
919 };
920 
921 
922 
923 //
924 void SgSolutionReporter::report2spoolFile(const QString& path, const QString& path2obsStatus,
925  const QString& fileName, bool isNeedResidualsOutput)
926 {
927  if (PxAll_ == NULL)
928  {
930  "::report2spoolFile(): an attempt to create a report without a solution");
931  return;
932  };
933 
935  if (runEpoch_==tZero)
937 
938  QFile f(path + "/" + fileName);
939  QString auxFname("");
940  if (!f.open(QIODevice::WriteOnly))
941  {
943  "::report2spoolFile(): error opening output file: " + path + "/" + fileName);
944  return;
945  };
947  ap = config_->apByNetId().contains(session_->getNetworkID()) ?
949 
951  synchronizeInfo();
952 // calculateConditionNumber();
953 
954  bool hasEop(false);
956  {
958  hasEop = true;
959  };
961  {
963  hasEop = true;
964  };
966  {
968  hasEop = true;
969  };
971  {
973  hasEop = true;
974  };
976  {
977  erpTref_ = session_->pUT1()->getTMean();
978  hasEop = true;
979  };
981  {
983  hasEop = true;
984  };
985  if (hasEop)
987 
988  //
989  //
990  QTextStream ts(&f);
991  // make output:
992  // the header:
994  // the fly-byes:
996  if (isNeedResidualsOutput)
998  // meteo statistics:
1000  // general statistics:
1002  // per baseline statistics:
1004  // per source statistics:
1006  // per station statistics:
1008  // a priori and "flybies":
1010  // results of estimation process:
1012  // baseline variations:
1014  // close the file:
1015  ts.setDevice(NULL);
1016  f.close();
1017  //
1019  {
1021  {
1022  if (reportAtmo(path, auxFname = "ATMO" + identities_.getUserDefaultInitials()))
1024  "::report2spoolFile(): the estimated zenith delays PWL-parameters have been saved "
1025  "in the file: " + path + "/" + auxFname);
1026  else
1028  "::report2spoolFile(): saving of the estimated zenith delays PWL-parameters failed");
1029  };
1030  //
1032  {
1033  if (reportCloc(path, auxFname = "CLOC" + identities_.getUserDefaultInitials()))
1035  "::report2spoolFile(): the estimated clock PWL-parameters have been saved "
1036  "in the file: " + path + "/" + auxFname);
1037  else
1039  "::report2spoolFile(): saving of the estimated clock PWL-parameters failed");
1040  };
1041  //
1042  if (ap.doReportNotUsedData_)
1043  {
1044  if (reportNotUsedObs(path2obsStatus,
1045  auxFname = "nuSolve_unused_observations_" + identities_.getUserDefaultInitials()))
1047  "::report2spoolFile(): the not used observations have been saved "
1048  "in the file: " + path2obsStatus + "/" + auxFname);
1049  else
1051  "::report2spoolFile(): saving of the not used observations failed");
1052  };
1053  };
1054  //
1055  //
1057  {
1058  if (reportPall(path, auxFname = "PALL" + identities_.getUserDefaultInitials()))
1060  "::report2spoolFile(): the covariance matrix has been saved "
1061  "in the file: " + path + "/" + auxFname);
1062  else
1064  "::report2spoolFile(): saving of the covariance matrix failed");
1065  };
1066  //
1067  //
1069 };
1070 
1071 
1072 
1073 //
1074 void SgSolutionReporter::report2aposterioriFiles(const QString& path, const QString& fileNameBase)
1075 {
1076  if (PxAll_ == NULL)
1077  {
1079  "::report2aposterioriFiles(): an attempt to create a report without a solution");
1080  return;
1081  };
1082  //
1084  if (runEpoch_==tZero)
1086  //
1088  synchronizeInfo();
1089  //
1090  bool hasEop(false);
1092  {
1094  hasEop = true;
1095  };
1097  {
1099  hasEop = true;
1100  };
1102  {
1104  hasEop = true;
1105  };
1107  {
1109  hasEop = true;
1110  };
1112  {
1113  erpTref_ = session_->pUT1()->getTMean();
1114  hasEop = true;
1115  };
1117  {
1119  hasEop = true;
1120  };
1121  if (hasEop)
1123  //
1124  //
1125  if (reportSources_Output4AposterioriFiles(path, fileNameBase))
1127  "::report2aposterioriFiles(): a file with a posteriori positions "
1128  "of radio sources has been created");
1129  else
1131  "::report2aposterioriFiles(): creating a file with a posteriori positions "
1132  "of radio sources failed");
1133 
1134  if (reportStations_Output4AposterioriFiles(path, fileNameBase))
1136  "::report2aposterioriFiles(): files with a posteriori positions "
1137  "of stations have been created");
1138  else
1140  "::report2aposterioriFiles(): creating files with a posteriori positions "
1141  "of stations failed");
1142  //
1144 };
1145 
1146 
1147 
1148 //
1150  const QString& fileNameBase)
1151 {
1153  {
1155  "::reportSources_Output4AposterioriFiles(): nothing to export, "
1156  "source positions were not estimated");
1157  return false;
1158  };
1159  //
1160  // collect statistics:
1161  if (!usedSources_.size())
1162  {
1163  for (QMap<QString, SgVlbiSourceInfo*>::iterator it=session_->sourcesByName().begin();
1164  it!=session_->sourcesByName().end(); ++it)
1165  {
1166  SgVlbiSourceInfo *si=it.value();
1168  usedSources_.append(si);
1169  };
1170  // sort in RA order:
1172  };
1173  //
1174  //
1175  QFile f(path + "/" + fileNameBase + ".src");
1176  if (!f.open(QIODevice::WriteOnly))
1177  {
1179  "::reportSources_Output4AposterioriFiles(): error opening output file: " + path +
1180  "/" + f.fileName() + " for writing source a posteriori positions");
1181  return false;
1182  };
1183  QString str("");
1184  QTextStream ts(&f);
1185  // make output:
1186  ts << "$$ Source flyby mod file from local solution of " << session_->getName() << " session\n";
1187  ts << "$$ " << usedSources_.size() << " total sources\n$$\n";
1188 
1189  for (int i=0; i<usedSources_.size(); i++)
1190  {
1191  SgVlbiSourceInfo *si=usedSources_.at(i);
1192  if (si->pRA()->isAttr(SgParameter::Attr_IS_SOLVED) &&
1194  {
1195  double vRA, vDN;
1198  vRA+= si->pRA()->getSolution();
1199  vDN+= si->pDN()->getSolution();
1200  //
1201  //
1202  str.sprintf("#-> %-8s %s %s %.6f %.6f %d %.6f",
1203  qPrintable(si->getKey()),
1204  qPrintable(si->ra2String(vRA)),
1205  qPrintable(si->dn2String(vDN, true)),
1206  si->pRA()->getSigma()*RAD2MS,
1207  si->pDN()->getSigma()*RAD2MAS,
1208  si->pRA()->getNumObs(),
1209  si->pRA()->getTMean().toDouble()
1210  );
1211  ts << str << "\n";
1212  str.sprintf(" %-8s %s %s %s",
1213  qPrintable(si->getKey()),
1214  qPrintable(si->ra2String(vRA)),
1215  qPrintable(si->dn2String(vDN, true)),
1216  qPrintable(si->getAprioriComments())
1217  );
1218  ts << str << "\n";
1219  };
1220  };
1221  // close the file:
1222  ts.setDevice(NULL);
1223  f.close();
1225  "::reportSources_Output4AposterioriFiles(): sources a posteriori positions were stored "
1226  "in file \"" + path + "/" + f.fileName() + "\"");
1227  return true;
1228 };
1229 
1230 
1231 
1232 //
1234  const QString& fileNameBase)
1235 {
1236  // coords:
1237  QFile f(path + "/" + fileNameBase + ".sit");
1238  if (!f.open(QIODevice::WriteOnly))
1239  {
1241  "::reportStations_Output4AposterioriFiles(): error opening output file: " + path +
1242  "/" + f.fileName() + " for writing station a posteriori positions");
1243  return false;
1244  };
1245  QString sTsince("-- -- --");
1246  QString sT0("------");
1247  if (session_->observations().size() > 0)
1248  {
1249  int nYear, nMonth, nDay, nHour, nMin;
1250  double dSec;
1251  SgMJD::MJD_reverse(session_->observations().at(0)->getDate(),
1252  session_->observations().at(0)->getTime(), nYear, nMonth, nDay, nHour, nMin, dSec);
1253  sTsince.sprintf("%02d %02d %02d", nYear%100, nMonth, nDay);
1254 
1256  session_->getApStationVelocities().getT0().getTime(), nYear, nMonth, nDay, nHour, nMin, dSec);
1257  sT0.sprintf("%02d%02d%02d", nYear%100, nMonth, nDay);
1258  };
1259  //
1260  QString str("");
1261  QTextStream ts(&f);
1262  // make output:
1263  ts
1264  << "$$ This file was produced by " << libraryVersion.name() << "\n"
1265  << "$$ From analysis of " << session_->getName() << " database.\n"
1266  << "$$\n"
1267  << "$$\n"
1268  << "$$ VLBI Site positions\n"
1269  << "$$ positions: x (m) y (m) z (m)\n";
1270 
1271  for (StationsByName_it it_st=session_->stationsByName().begin();
1272  it_st!=session_->stationsByName().end(); ++it_st)
1273  {
1274  SgVlbiStationInfo *si=it_st.value();
1276  {
1277  // coordinates:
1278  if (si->pRx()->isAttr(SgParameter::Attr_IS_SOLVED) &&
1281  {
1282  Sg3dVector dr(si->pRx()->getSolution(), si->pRy()->getSolution(),
1283  si->pRz()->getSolution());
1284  Sg3dVector r(si->getR());
1286  r = si->getR_ea();
1287  r += dr;
1288  str.sprintf(" %-8s %14.6f %14.6f %14.6f ",
1289  qPrintable(si->getKey()), r.at(X_AXIS), r.at(Y_AXIS), r.at(Z_AXIS));
1290  ts << str << sTsince << "\n";
1291  };
1292  };
1293  };
1294  // close the file:
1295  ts.setDevice(NULL);
1296  f.close();
1298  "::reportStations_Output4AposterioriFiles(): stations a posteriori coordinates were stored "
1299  "in file \"" + path + "/" + f.fileName() + "\"");
1300  //
1301  // vels:
1303  {
1305  "::reportStations_Output4AposterioriFiles(): external velocities were not used");
1306  return true;
1307  };
1308  //
1309  f.setFileName(path + "/" + fileNameBase + ".vel");
1310  if (!f.open(QIODevice::WriteOnly))
1311  {
1313  "::reportStations_Output4AposterioriFiles(): error opening output file: " + path +
1314  "/" + f.fileName() + " for writing station a posteriori velocities");
1315  return false;
1316  };
1317  ts.setDevice(&f);
1318  // make output:
1319  ts
1320  << sT0 << "\n"
1321  << "$$ This file was produced by " << libraryVersion.name() << "\n"
1322  << "$$ From analysis of " << session_->getName() << " database.\n"
1323  << "$$\n"
1324  << "$$\n"
1325  << "$$ velocities: x (mm/yr) y (mm/yr) z (mm/yr)\n"
1326  << "$$\n";
1327 
1328  for (StationsByName_it it_st=session_->stationsByName().begin();
1329  it_st!=session_->stationsByName().end(); ++it_st)
1330  {
1331  SgVlbiStationInfo *si=it_st.value();
1333  {
1334  // coordinates:
1335  if (si->pRx()->isAttr(SgParameter::Attr_IS_SOLVED) &&
1338  {
1339  Sg3dVector v(si->getV_ea()*1.0e3*365.242198781250);
1340  str.sprintf(" %-8s %8.1f %8.1f %8.1f",
1341  qPrintable(si->getKey()), v.at(X_AXIS), v.at(Y_AXIS), v.at(Z_AXIS));
1342 
1343  ts << str << "\n";
1344  };
1345  };
1346  };
1347  // close the file:
1348  ts.setDevice(NULL);
1349  f.close();
1351  "::reportStations_Output4AposterioriFiles(): stations velocities were stored "
1352  "in file \"" + path + "/" + f.fileName() + "\"");
1353  return true;
1354 };
1355 
1356 
1357 
1358 //
1360 {
1361  int nYear, nMonth, nDay, nHour, nMin;
1362  double dSec;
1363  QString str(""), dbName("");
1364 
1366  nYear, nMonth, nDay, nHour, nMin, dSec);
1367 
1368  QDateTime dt(QDate(nYear, nMonth, nDay), QTime(nHour, nMin, (int)(dSec)));
1369  QDateTime dtUTC(dt.toUTC());
1370 
1371  reportID_.sprintf("%2d%03d-%02d%02d",
1372  dtUTC.date().year() - (dtUTC.date().year()/100)*100,
1373  dtUTC.date().dayOfYear(),
1374  dtUTC.time().hour(),
1375  dtUTC.time().minute());
1376  ts << "1Run " << reportID_ << "\n";
1377 
1379  nYear, nMonth, nDay, nHour, nMin, dSec);
1380 
1381  str.sprintf(" Analysis center: %3s -- %s",
1382  qPrintable(identities_.getAcAbbName()), qPrintable(identities_.getAcFullName()));
1383  ts << str << "\n";
1384 
1385  str.sprintf(" Analyst: %s ( %s )",
1386  qPrintable(identities_.getUserName()), qPrintable(identities_.getUserEmailAddress()));
1387  ts << str << "\n";
1388 
1389  str.sprintf(" Machine: %s %s %s %s",
1390  qPrintable(identities_.getMachineNodeName()), qPrintable(identities_.getMachineMachineName()),
1391  qPrintable(identities_.getMachineSysName()), qPrintable(identities_.getMachineRelease()));
1392  ts << str << "\n";
1393 
1394  str.sprintf(" Executables: %s",
1395  qPrintable(identities_.getExecDir()));
1396  ts << str << "\n";
1397 
1398  str.sprintf(" Solve initials: %2s",
1399  qPrintable(identities_.getUserDefaultInitials()));
1400  ts << str << "\n";
1401  ts << " Spool format: " << libraryVersion.name() << "\n";
1402 
1403  str.sprintf(" Local time: %04d.%02d.%02d-%02d:%02d:%02d",
1404  nYear, nMonth, nDay, nHour, nMin, (int)dSec);
1405  ts << str << "\n";
1406 
1407  str.sprintf(" Correlator type: %s",
1408  qPrintable(activeBand_->getCorrelatorType()));
1409  ts << str << "\n";
1410  ts << " Mark-3 db_name:" << "\n\n" ;
1411 
1412  dbName = session_->getName();
1413  if (dbName.at(0) == '$')
1414  dbName.remove(0, 1);
1415  if (session_->bands().size() == 2)
1416  dbName = dbName.mid(0, 7) + activeBand_->getKey() + session_->getNetworkSuffix();
1417 
1418  str.sprintf(" Data base $%9s Ver%3d",
1419 // qPrintable(session_->getName()), session_->primaryBand()->getInputFileVersion());
1420 // qPrintable(session_->getName()), activeBand_->getInputFileVersion());
1421  qPrintable(dbName), activeBand_->getInputFileVersion());
1422  ts << str << "\n\n";
1423 
1424  str.sprintf(" Matrix Condition Number =%24.15E",
1425  condNumber_);
1426  ts << str << "\n\n";
1427 
1428  // should be replaced with actual info later:
1429  ts << " Listing_Options: CRES_EMULATION NO BASELINES NO MINIMUM NO" << "\n"
1430  << " Listing_Options: MAPPED_EOP_OUTPUT NO SEG_OUTPUT NO APRIORI_ZENDEL NO" << "\n"
1431  << " Listing_Options: NRD_TABLE YES CHI_TABLE NO SRC_STAT PRE2004 SEG_STYLE PRE2005" << "\n";
1432  ts << " SgLib release : " <<
1433  qPrintable(libraryVersion.getReleaseEpoch().toString(SgMJD::F_Date)) << "\n\n";
1434 
1435  if (userComents_.size())
1436  {
1437  ts << " User comments:" << "\n";
1438  for (int i=0; i<userComents_.size(); i++)
1439  ts << " " << identities_.getUserDefaultInitials() << ": " << userComents_.at(i) << "\n";
1440  ts << "\n";
1441  };
1442 };
1443 
1444 
1445 
1446 //
1448 {
1449  ts << " Flyby Station Cals: DB Station Cals: | DB Non-station Cals: "
1450  << "| Atmosphere Partial:\n"
1451  << " ------------------------------------------------------------------------------"
1452  << "--------------------\n";
1453 
1454  QString str;
1455  QList<QString> listOfContributions;
1456  int numOfStrings, idxStr, idxContr;
1457  StationsByName_it it;
1458 
1460  listOfContributions << "Pol Tide";
1462  listOfContributions << "WobXCont";
1464  listOfContributions << "WobYCont";
1466  listOfContributions << "EarthTid";
1468  listOfContributions << "Ocean";
1470  listOfContributions << "UT1Ortho";
1472  listOfContributions << "XpYpOrth";
1473  //
1474  if (session_->calcInfo().getDversion()<11.0)
1475  {
1477  listOfContributions << "PxyNutat";
1478  }
1479  else
1480  {
1482  listOfContributions << "XpYpLib";
1484  listOfContributions << "UT1Libra";
1485  };
1486  //
1488  listOfContributions << "FeedCorr";
1490  listOfContributions << "TiltRmvr";
1492  listOfContributions << "OPTLCont";
1494  listOfContributions << "OldOcean";
1496  listOfContributions << "OldPTide";
1497 
1498 
1499  // determine how the ionosphere corrections were applied:
1500  QString sIono("SION");
1502  sIono = "GION";
1504  sIono = "PION";
1505  QMap<QString, int> gionByName;
1506  QString sIonos[3]={"", sIono, ""};
1507  sIonos[2] = sIono + "/no" + sIono;
1508  //
1509  for (StationsByName_it it=session_->stationsByName().begin();
1510  it!=session_->stationsByName().end(); ++it)
1511  {
1512  QString stName=it.value()->getKey();
1513  for (BaselinesByName_it jt=session_->baselinesByName().begin();
1514  jt!=session_->baselinesByName().end(); ++jt)
1515  {
1516  SgVlbiBaselineInfo *bln=jt.value();
1518  {
1519  QString blName=bln->getKey();
1520  if (blName.contains(stName + ":") || blName.contains(":" + stName))
1521  {
1522  int nVal(0);
1527  nVal = 1;
1528  if (!gionByName.contains(stName))
1529  gionByName.insert(stName, nVal);
1530  else if (gionByName.value(stName)!=2 && gionByName.value(stName)!=nVal)
1531  gionByName[stName] = 2;
1532  };
1533  };
1534  };
1535  };
1536  // fill default value for not used objects:
1537  for (StationsByName_it it=session_->stationsByName().begin();
1538  it!=session_->stationsByName().end(); ++it)
1539  if (!gionByName.contains(it.value()->getKey()))
1540  gionByName.insert(it.value()->getKey(), 0);
1541  //
1542  numOfStrings = std::max(session_->stationsByName().size(), listOfContributions.size());
1543  idxStr = idxContr = 0;
1544  it = session_->stationsByName().begin();
1545  while (idxStr<numOfStrings)
1546  {
1547  if (it!=session_->stationsByName().end())
1548  {
1549  SgVlbiStationInfo *si=it.value();
1550  str.sprintf(" %-8s:NMFDRFLY %-8s %-11s ",
1551  qPrintable(si->getKey()),
1553  qPrintable(sIonos[gionByName[si->getKey()]])
1554 // session_->isAttr(SgVlbiSessionInfo::Attr_FF_ION_C_CALCULATED)?"GION":" "
1555  );
1556  ++it;
1557  }
1558  else
1559  str = " ";
1560  ts << str;
1561  if (idxContr<listOfContributions.size())
1562  {
1563  str.sprintf("| %-8s |",
1564  qPrintable(listOfContributions.at(idxContr)));
1565  idxContr++;
1566  }
1567  else
1568  str = "| |";
1569  ts << str;
1570  if (idxStr==0)
1571  ts << " NMFWTFLY \n";
1572  else
1573  ts << " \n";
1574  idxStr++;
1575  };
1576 
1577  ts << " ----------------------------------------------------------------------------"
1578  << "----------------------\n";
1579  str.sprintf(" CALC Version: %.2f ", //SOLVE release: ????.??.?? SOLVE revision: ????.??.?? ",
1581  ts << str << qPrintable(libraryVersion.name()) << "\n\n";
1582  // << " Fast_mode: ??? Fast_cov: ??? \n\n";
1583 
1584 //QString primaryBandKey = session_->primaryBand()->getKey(), auxBandKey, s2;
1585  QString auxBandKey, s2;
1586  for (int i=0; i<session_->bands().size(); i++)
1587  {
1588  auxBandKey = session_->bands().at(i)->getKey();
1589  if (auxBandKey != activeBandKey_)
1590  {
1591  s2 = session_->getName();
1592  str.sprintf(" %10s %2d NOT IN SOLUTION",
1593  qPrintable(s2.replace(s2.size()-2, 1, auxBandKey)),
1594  session_->bands().at(i)->getInputFileVersion());
1595  ts << str << "\n";
1596  };
1597  };
1598  ts << "\n";
1599 };
1600 
1601 
1602 
1603 //
1605 {
1606  QString str(""), useChar1(""), useChar2(""), sQcOb("");
1607  QString sVal("");
1608  QString oppBandKey("");
1609  double dSnrOb, dDelay;
1610  bool isMultipleBand;
1611  isMultipleBand = session_->bands().size() > 1;
1612  for (int i=0; i<session_->bands().size(); i++)
1613  if (session_->bands().at(i)->getKey() != activeBandKey_)
1614  oppBandKey = session_->bands().at(i)->getKey();
1615  //
1616 
1617  ts << "1Residuals from Run " << reportID_ << "\n";
1618  ts << " Baseline Source Date Time Obs del Del res "
1619  << "Del er. Obs rate Rate res R.err elev azim frq2-rat QC XS"
1620  << " SNR / SNS_S Tau_obs_x #AmbX Tau_obs_s #AmbS Tau_apriori_clo "
1621  << "Tau_theoretical Tau_est_contrb Rate_obs_x Rate_obs_s"
1622  << " Rate_apriori_clock Rate_theoretical Rate_estim_contrib Eff. Dur. "
1623  << "Res_gr_del_X Res_gr_del_S Gr_Spc_X Gr_Spc_S USR Ampltude Phase Obsind DS "
1624  << "Delay_residual\n";
1625  ts << " ps ps ps"
1626  << " fs/s fs/s fs/s deg deg deg deg seconds"
1627  << " seconds seconds seconds seconds"
1628  << " d/l d/l d/l d/l d/l"
1629  << " sec sec sec ns ns "
1630  << "d/l d/l rad seconds\n";
1631 
1632  for (int idx=0; idx<session_->observations().size(); idx++)
1633  {
1634  SgVlbiObservation *obs=session_->observations().at(idx);
1635  SgVlbiObservable *o=obs?obs->activeObs():NULL;
1636  SgVlbiObservable *o_ob=NULL;
1637  SgVlbiAuxObservation *aux_1=NULL, *aux_2=NULL;
1638  aux_1 = obs?obs->auxObs_1():NULL;
1639  aux_2 = obs?obs->auxObs_2():NULL;
1640 
1641  double delay_clock=0.0, rate_clock=0.0;
1642 
1643  if (o && aux_1 && aux_2)
1644  {
1645  if (obs->observableByKey().contains(oppBandKey))
1646  o_ob = obs->observableByKey().value(oppBandKey);
1647  else
1648  o_ob = NULL;
1650  {
1651  useChar1 = " ";
1652  useChar2 = " ";
1653  }
1654  else
1655  {
1656  useChar1 = ">";
1657  // no or bad opposite-band observable:
1658  if (isMultipleBand &&
1659  (o_ob==NULL || (o_ob->getQualityFactor() < config_->getQualityCodeThreshold())))
1660  useChar2 = "I";
1661  // bad quality of the active band observable:
1663  useChar2 = "F";
1664  // everything else:
1665  else
1666  useChar2 = "H";
1667  };
1668  if (o_ob)
1669  {
1670  sQcOb.sprintf("%2d", o_ob->getQualityFactor());
1671  dSnrOb = o_ob->getSnr();
1672  }
1673  else
1674  {
1675  sQcOb = " ";
1676  dSnrOb = -1.0;
1677  };
1678 // dGrDelay = o->grDelay().getValue() + o->grDelay().ambiguity();
1679  dDelay = o->activeDelay()->getValue() + o->activeDelay()->ambiguity();
1680  // mimic FORTRAN's deficiency of data representation:
1681  if (dDelay<=-1.0 || dDelay>=10.0)
1682  sVal = "**************";
1683  else
1684  sVal.sprintf("%#14.0f", dDelay*1.0e12);
1685 
1686  str.sprintf("%7d%1s %8s/%8s %8s %s %s%#8.0f %1s %#6.0f%#14.0f%#8.0f %1s %#6.0f"
1687  "%4d%4d%4d%4d %9.6f %2d/%2s %6.1f / %6.1f"
1688  " %17.13f %5d %17.13f %5d"
1689  " %16.13f %16.13f %17.13f"
1690  " %20.12e %20.12e %20.12e %20.12e %20.12e @@ "
1691  " %9.4f %17.8e %17.8e %9.4f %9.4f %3d %10.7f %9.5f %6d %24.12e"
1692  //
1693  ,
1694  o->getMediaIdx() + 1,
1695  qPrintable(useChar1),
1696  qPrintable(obs->stn_1()->getKey()),
1697  qPrintable(obs->stn_2()->getKey()),
1698  qPrintable(obs->src()->getKey()),
1699  qPrintable(obs->toString(SgMJD::F_SOLVE_SPLFL_V2)),
1700  // delay:
1701  qPrintable(sVal),
1702  o->activeDelay()->getResidual()*1.0e12,
1703  qPrintable(useChar2),
1704  o->activeDelay()->sigma2Apply()*1.0e12,
1705  // delay rate:
1706  o->phDRate().getValue()*1.0e15,
1707  o->phDRate().getResidual()*1.0e15,
1708  qPrintable(useChar2),
1709  o->phDRate().getSigma()*1.0e15,
1710  //
1711  (int)round(aux_1->getElevationAngle()*RAD2DEG),
1712  (int)round(aux_2->getElevationAngle()*RAD2DEG),
1713  (int)round(aux_1->getAzimuthAngle()*RAD2DEG),
1714  (int)round(aux_2->getAzimuthAngle()*RAD2DEG),
1715  o->activeDelay()->getQ2() + 1.0,
1716  o->getQualityFactor(),
1717  qPrintable(sQcOb),
1718  o->getSnr(),
1719  dSnrOb,
1720 
1721  o->grDelay().getValue(),
1723  o_ob?o_ob->grDelay().getValue():0.0,
1724  o_ob?o_ob->grDelay().getNumOfAmbiguities():0,
1725 
1726  delay_clock,
1727  obs->theoDelay(),
1728  obs->sumAX_4delay(),
1729  // e:
1730  o->phDRate().getValue(),
1731  o_ob?o_ob->phDRate().getValue():0.0,
1732  rate_clock,
1733  obs->theoRate(),
1734  obs->sumAX_4rate(),
1735  // @@
1736  o->getEffIntegrationTime(),
1737  o->grDelay().getResidual(),
1738  o_ob?o->grDelay().getResidual():0.0,
1739  o->grDelay().getAmbiguitySpacing()*1.0e9,
1740  o_ob?o->grDelay().getAmbiguitySpacing()*1.0e9:-1,
1741  1,
1742  o->getCorrCoeff(),
1743  o->getTotalPhase(),
1744  obs->getMediaIdx() + 1,
1745  o->activeDelay()->getResidual()
1746  );
1747 
1748 
1749 // Tau_obs_x #AmbX Tau_obs_s #AmbS Tau_apriori_clo Tau_theoretical Tau_est_contrb Rate_obs_x
1750 // Rate_obs_s Rate_apriori_clock Rate_theoretical Rate_estim_contrib Eff. Dur. Res_gr_del_X Res_gr_del_S Gr_Spc_X Gr_Spc_S
1751 // USR Ampltude Phase Obsind DS Delay_residual
1752 
1753 
1754 
1755 
1756 // 1> KOKEE /WETTZELL 3C371 2014.11.18-18:30:31.0 -9421890080. -295. F 125. 834105517. -119. F 245. 19 50 21 329 1.076813 0/ 9 5.5 / 14.8
1757 // 2 KOKEE /WETTZELL 0529+483 2014.11.18-18:33:47.0 -5983218674. 66. 72. -1626992487. 8. 37. 15 32 317 51 1.076494 9/ 9 9.6 / 20.2
1758 //
1759 // mk5_merge_v03/progs/solve/cres/secnd.f:
1760 // WRITE ( 23, 120 ) IOBS, IDLT, ISITN_CHR(ISITE(1)), &
1761 // & ISITN_CHR(ISITE(2)), ISTRN_CHR(ISTAR), STR_DATE(1:21), &
1762 // & FOBS*1.D3, DOC*1.D3, IPUNC, DOERR*1.D3, &
1763 // & ROBS*1.D3, ROC*1.D3, IPUNC, RERR*1.D3, &
1764 // & IPELV, IPAZ, COEF_IONO, LQUAL_CHR, LQUALXS_CHR, &
1765 // & SNR, SNR_S
1766 //
1767 // 120 FORMAT ( I7, A1, 1X, A8, "/", A8, 1X, A, 1X, A, 1X, &
1768 // & 2(F14.0, F8.0, 1X, A1, 1X, F6.0), 4I4, 2X, F9.6, &
1769 // & 1X, A2, '/', A2, 1X, F6.1, ' / ', F6.1 )
1770 // 120 FORMAT (
1771 // I7, IOBS
1772 // A1, 1X, IDLT
1773 // A8, "/", ISITN_CHR(ISITE(1)),
1774 // A8, 1X, ISITN_CHR(ISITE(2))
1775 // A, 1X, ISTRN_CHR(ISTAR)
1776 // A, 1X, STR_DATE(1:21),
1777 // 2(F14.0, F8.0, 1X, A1, 1X, F6.0),
1778 //==FOBS*1.D3, DOC*1.D3, IPUNC, DOERR*1.D3,
1779 //==ROBS*1.D3, ROC*1.D3, IPUNC, RERR*1.D3,
1780 // 4I4, 2X, IPELV IPAZ arrays?
1781 // F9.6, 1X, COEF_IONO,
1782 // A2, '/', LQUAL_CHR
1783 // A2, 1X, LQUALXS_CHR
1784 // F6.1, ' / ', SNR
1785 // F6.1 SNR_S
1786  ts << qPrintable(str) << "\n";
1787  };
1788  };
1789 
1790  ts << "\n";
1791 };
1792 
1793 
1794 
1795 //
1797 {
1798  QString str(""), useChar1(""), useChar2(""), sQcOb("");
1799  QString sVal("");
1800  QString oppBandKey("");
1801  double dSnrOb, dDelay;
1802  bool isMultipleBand;
1803  isMultipleBand = session_->bands().size() > 1;
1804  for (int i=0; i<session_->bands().size(); i++)
1805  if (session_->bands().at(i)->getKey() != activeBandKey_)
1806  oppBandKey = session_->bands().at(i)->getKey();
1807  //
1808  //
1809  ts << "1Residuals from Run " << reportID_ << "\n";
1810  ts << " Baseline Source Date Time Obs del Del res Del err"
1811  << " Obs rate Rate res Rate err elev frq2-rat QC XS SNR / SNS_S\n"
1812  << " ps ps ps"
1813  << " fs/s fs/s fs/s deg\n";
1814  for (int idx=0; idx<session_->observations().size(); idx++)
1815  {
1816  SgVlbiObservation *obs=session_->observations().at(idx);
1817  SgVlbiObservable *o=obs?obs->activeObs():NULL;
1818  SgVlbiObservable *o_ob=NULL;
1819  SgVlbiAuxObservation *aux_1=NULL, *aux_2=NULL;
1820  aux_1 = obs?obs->auxObs_1():NULL;
1821  aux_2 = obs?obs->auxObs_2():NULL;
1822  if (o && aux_1 && aux_2)
1823  {
1824  if (obs->observableByKey().contains(oppBandKey))
1825  o_ob = obs->observableByKey().value(oppBandKey);
1826  else
1827  o_ob = NULL;
1829  {
1830  useChar1 = " ";
1831  useChar2 = " ";
1832  }
1833  else
1834  {
1835  useChar1 = ">";
1836  // no or bad opposite-band observable:
1837  if (isMultipleBand &&
1838  (o_ob==NULL || (o_ob->getQualityFactor() < config_->getQualityCodeThreshold())))
1839  useChar2 = "I";
1840  // bad quality of the active band observable:
1842  useChar2 = "F";
1843  // everything else:
1844  else
1845  useChar2 = "H";
1846  };
1847  if (o_ob)
1848  {
1849  sQcOb.sprintf("%2d", o_ob->getQualityFactor());
1850  dSnrOb = o_ob->getSnr();
1851  }
1852  else
1853  {
1854  sQcOb = " ";
1855  dSnrOb = -1.0;
1856  };
1857 // dGrDelay = o->grDelay().getValue() + o->grDelay().ambiguity();
1858  dDelay = o->activeDelay()->getValue() + o->activeDelay()->ambiguity();
1859  // mimic FORTRAN's deficiency of data representation:
1860  if (dDelay<=-1.0 || dDelay>=10.0)
1861  sVal = "**************";
1862  else
1863  sVal.sprintf("%#14.0f", dDelay*1.0e12);
1864 
1865  str.sprintf("%7d%1s %8s/%8s %8s %s %s%#8.0f %1s %#6.0f%#14.0f%#8.0f %1s %#6.0f"
1866  "%4d%4d%4d%4d %9.6f %2d/%2s %6.1f / %6.1f",
1867  o->getMediaIdx() + 1, qPrintable(useChar1),
1868  qPrintable(obs->stn_1()->getKey()),
1869  qPrintable(obs->stn_2()->getKey()),
1870  qPrintable(obs->src()->getKey()),
1871  qPrintable(obs->toString(SgMJD::F_SOLVE_SPLFL_V2)),
1872  // delay:
1873  qPrintable(sVal),
1874  o->activeDelay()->getResidual()*1.0e12,
1875  qPrintable(useChar2),
1876  o->activeDelay()->sigma2Apply()*1.0e12,
1877  // delay rate:
1878  o->phDRate().getValue()*1.0e15,
1879  o->phDRate().getResidual()*1.0e15,
1880  qPrintable(useChar2),
1881  o->phDRate().getSigma()*1.0e15,
1882  //
1883  (int)round(aux_1->getElevationAngle()*RAD2DEG),
1884  (int)round(aux_2->getElevationAngle()*RAD2DEG),
1885  (int)round(aux_1->getAzimuthAngle()*RAD2DEG),
1886  (int)round(aux_2->getAzimuthAngle()*RAD2DEG),
1887  o->activeDelay()->getQ2() + 1.0,
1888  o->getQualityFactor(), qPrintable(sQcOb),
1889  o->getSnr(), dSnrOb
1890  );
1891 // 1> KOKEE /WETTZELL 3C371 2014.11.18-18:30:31.0 -9421890080. -295. F 125. 834105517. -119. F 245. 19 50 21 329 1.076813 0/ 9 5.5 / 14.8
1892 // 2 KOKEE /WETTZELL 0529+483 2014.11.18-18:33:47.0 -5983218674. 66. 72. -1626992487. 8. 37. 15 32 317 51 1.076494 9/ 9 9.6 / 20.2
1893 //
1894 // mk5_merge_v03/progs/solve/cres/secnd.f:
1895 // WRITE ( 23, 120 ) IOBS, IDLT, ISITN_CHR(ISITE(1)), &
1896 // & ISITN_CHR(ISITE(2)), ISTRN_CHR(ISTAR), STR_DATE(1:21), &
1897 // & FOBS*1.D3, DOC*1.D3, IPUNC, DOERR*1.D3, &
1898 // & ROBS*1.D3, ROC*1.D3, IPUNC, RERR*1.D3, &
1899 // & IPELV, IPAZ, COEF_IONO, LQUAL_CHR, LQUALXS_CHR, &
1900 // & SNR, SNR_S
1901 //
1902 // 120 FORMAT ( I7, A1, 1X, A8, "/", A8, 1X, A, 1X, A, 1X, &
1903 // & 2(F14.0, F8.0, 1X, A1, 1X, F6.0), 4I4, 2X, F9.6, &
1904 // & 1X, A2, '/', A2, 1X, F6.1, ' / ', F6.1 )
1905 // 120 FORMAT (
1906 // I7, IOBS
1907 // A1, 1X, IDLT
1908 // A8, "/", ISITN_CHR(ISITE(1)),
1909 // A8, 1X, ISITN_CHR(ISITE(2))
1910 // A, 1X, ISTRN_CHR(ISTAR)
1911 // A, 1X, STR_DATE(1:21),
1912 // 2(F14.0, F8.0, 1X, A1, 1X, F6.0),
1913 //==FOBS*1.D3, DOC*1.D3, IPUNC, DOERR*1.D3,
1914 //==ROBS*1.D3, ROC*1.D3, IPUNC, RERR*1.D3,
1915 // 4I4, 2X, IPELV IPAZ arrays?
1916 // F9.6, 1X, COEF_IONO,
1917 // A2, '/', LQUAL_CHR
1918 // A2, 1X, LQUALXS_CHR
1919 // F6.1, ' / ', SNR
1920 // F6.1 SNR_S
1921  ts << qPrintable(str) << "\n";
1922  };
1923  };
1924 
1925  ts << "\n";
1926 };
1927 
1928 
1929 
1930 //
1932 {
1933  ts << " Met Statistics:\n"
1934  << " Temperature Pressure Humidity\n"
1935  <<" Station average rms average rms average rms\n";
1936 
1937  QString str;
1938  StationsByName_it it;
1939  it=session_->stationsByName().begin();
1940 
1941  for (it=session_->stationsByName().begin(); it!=session_->stationsByName().end(); ++it)
1942  {
1943  SgVlbiStationInfo *si=it.value();
1944  str.sprintf(" %-8s MET",
1945  qPrintable(si->getKey()));
1946  ts << str;
1947 
1948  int num;
1949  double sumT_1, sumT_2, sumP_1, sumP_2, sumH_1, sumH_2;
1950  double rmsT, rmsP, rmsH, d;
1951  sumT_1 = sumT_2 = sumP_1 = sumP_2 = sumH_1 = sumH_2 = 0.0;
1952  rmsT = rmsP = rmsH = 0.0;
1953  num = 0;
1954 // QMap<SgMJD, SgVlbiAuxObservation*>::iterator jt;
1955 // for (jt=si->auxObservationByEpoch()->begin(); jt!=si->auxObservationByEpoch()->end(); ++jt)
1956  QMap<QString, SgVlbiAuxObservation*>::iterator jt;
1957  for (jt=si->auxObservationByScanId()->begin(); jt!=si->auxObservationByScanId()->end(); ++jt)
1958  {
1959  SgVlbiAuxObservation *auxObs=jt.value();
1961  {
1962  double t, p, h;
1963  t = auxObs->getMeteoData().getTemperature();
1964  p = auxObs->getMeteoData().getPressure();
1965  h = auxObs->getMeteoData().getRelativeHumidity()*100.0;
1966  sumT_1 += t;
1967  sumT_2 += t*t;
1968  sumP_1 += p;
1969  sumP_2 += p*p;
1970  sumH_1 += h;
1971  sumH_2 += h*h;
1972  num++;
1973  };
1974  };
1975  if (num>0)
1976  {
1977  d = sumT_2 - sumT_1*sumT_1/num;
1978  if (d<=0.0 && fabs(d)/sumT_2<1.0e-12)
1979  rmsT = 0.0;
1980  else
1981  rmsT = sqrt(d/num);
1982  d = sumP_2 - sumP_1*sumP_1/num;
1983  if (d<=0.0 && fabs(d)/sumP_2<1.0e-12)
1984  rmsP = 0.0;
1985  else
1986  rmsP = sqrt(d/num);
1987  d = sumH_2 - sumH_1*sumH_1/num;
1988  if (d<=0.0 && fabs(d)/sumH_2<1.0e-12)
1989  rmsH = 0.0;
1990  else
1991  rmsH = sqrt(d/num);
1992  str.sprintf(" %6.1f %6.1f %6.1f %6.1f%8.1f %7.1f",
1993  sumT_1/num, rmsT, sumP_1/num, rmsP, sumH_1/num, rmsH);
1994  }
1995  else
1996  str = " -999.0 0.0 -999.0 0.0-99900.0 0.0";
1997  ts << str << "\n";
1998  };
1999  ts << "\n";
2000 };
2001 
2002 
2003 
2004 //
2006 {
2007  const int qCodeLimit(config_->getQualityCodeThreshold());
2008  QString str;
2009  int numRecObs, numRec59Obs, numProcdObs, num;
2010  int nYear, nMonth, nDay, nHour, nMin;
2011  int numOfBands;
2012  double dSec, fInterval;
2013  int numProcRateObs;
2014  double rmsDelay(0.0), nrmsDelay(0.0), chi2Delay(0.0);
2015  double rmsRate(0.0), nrmsRate(0.0), chi2Rate(0.0);
2016  double nrmsCombined(0.0), chi2Combined(0.0);
2017  double sum1d, sum2d;
2018  double sum1r, sum2r;
2019  SgMJD t(session_->getTStart());
2021  numOfBands = session_->bands().size();
2022 
2023 //pBand = session_->primaryBand();
2024  SgMJD::MJD_reverse(t.getDate(), t.getTime(), nYear, nMonth, nDay, nHour, nMin, dSec);
2025  fInterval = session_->getTFinis() - t;
2026 
2027  numProcdObs = activeBand_->numProcessed(dType);
2028  numRecObs = numProcRateObs = numRec59Obs = 0;
2029  numRecObs = session_->primaryBand()->numUsable(DT_DELAY);
2030  // clear "num of recoverable obs" per object values:
2031  /*
2032  for (StationsByName_it it=activeBand_->stationsByName().begin();
2033  it!=activeBand_->stationsByName().end(); ++it)
2034  it.value()->setNumUsable(DT_DELAY, 0);
2035  for (BaselinesByName_it it=activeBand_->baselinesByName().begin();
2036  it!=activeBand_->baselinesByName().end(); ++it)
2037  it.value()->setNumUsable(DT_DELAY, 0);
2038  for (SourcesByName_it it=activeBand_->sourcesByName().begin();
2039  it!=activeBand_->sourcesByName().end(); ++it)
2040  it.value()->setNumUsable(DT_DELAY, 0);
2041  */
2042  for (int i=0; i<session_->observations().size(); i++)
2043  {
2044  SgVlbiObservation *obs=session_->observations().at(i);
2045  bool isOk=obs->observableByKey().size()==numOfBands;
2046  bool isOk59=obs->observableByKey().size()==numOfBands;
2047 
2048  for (QMap<QString, SgVlbiObservable*>::iterator it=obs->observableByKey().begin();
2049  it!=obs->observableByKey().end(); ++it)
2050  {
2051  int qCode=it.value()->getQualityFactor();
2052  isOk = isOk && qCode>=qCodeLimit;
2053  isOk59 = isOk59 && qCode>=5;
2054  };
2055 /*
2056  if (isOk)
2057  {
2058  numRecObs++;
2059  int idx;
2060  idx = obs->getStation1Idx();
2061  if (activeBand_->stationsByIdx().contains(idx))
2062  activeBand_->stationsByIdx().find(idx).value()->incNumUsable(DT_DELAY);
2063 
2064  idx = obs->getStation2Idx();
2065  if (activeBand_->stationsByIdx().contains(idx))
2066  activeBand_->stationsByIdx().find(idx).value()->incNumUsable(DT_DELAY);
2067 
2068  idx = obs->getSourceIdx();
2069  if (activeBand_->sourcesByIdx().contains(idx))
2070  activeBand_->sourcesByIdx().find(idx).value()->incNumUsable(DT_DELAY);
2071 
2072  idx = obs->getBaselineIdx();
2073  if (activeBand_->baselinesByIdx().contains(idx))
2074  activeBand_->baselinesByIdx().find(idx).value()->incNumUsable(DT_DELAY);
2075  };
2076 */
2077  if (isOk59)
2078  numRec59Obs++;
2079  };
2080  sum1r = sum2r = sum1d = sum2d = 0.0;
2081  num = 0;
2082  for (int i=0; i<session_->observations().size(); i++)
2083  {
2084  SgVlbiObservation *obs=session_->observations().at(i);
2086  {
2087  sum1d += obs->getNormalizedDelayResidual();
2089  sum1r += obs->getNormalizedRateResidual();
2091  num++;
2092  };
2093  };
2094  if (num != numProcdObs)
2095  std::cout << "num != numProcdObs: " << num << " vs " << numProcdObs << "\n";
2096  rmsDelay = activeBand_->wrms(dType)*1.0E12;
2097  nrmsDelay = sqrt((sum2d - sum1d*sum1d/num)/num);
2098 //chi2Delay = activeBand_->chi2(dType)/session_->getNumOfDOF();
2099  chi2Delay = activeBand_->reducedChi2(dType);
2100 
2102  {
2103  numProcRateObs = activeBand_->numProcessed(DT_RATE);
2104  rmsRate = activeBand_->wrms(DT_RATE)*1.0e15;
2105  nrmsRate = sqrt((sum2r - sum1r*sum1r/num)/num);
2106 // chi2Rate = activeBand_->chi2(DT_RATE)/dof;
2107  chi2Rate = activeBand_->reducedChi2(DT_RATE);
2108  };
2109 
2110  str.sprintf(" Run %10s %7d Observation Pairs Available ",
2111  qPrintable(reportID_), session_->observations().size());
2112  ts << str << "\n";
2113 
2114  str.sprintf(" Session started on: %14.6f %04d.%02d.%02d %02d:%02d:%06.3f UTC",
2115  t.toDouble() + 2400000.5,
2116  nYear, nMonth, nDay, nHour, nMin, dSec);
2117  ts << str << "\n";
2118 
2119  nDay = (int)trunc(fInterval);
2120  fInterval = fInterval - nDay;
2121 
2122  fInterval *= DAY2SEC;
2123  nHour = (int)(fInterval/3600.0);
2124  nMin = (int)((fInterval - 3600.0*nHour)/60.0);
2125  dSec = fInterval - 3600.0*nHour - 60.0*nMin;
2126  str.sprintf(" Actual duration: %9.3f sec %02d %02d:%02d:%06.3f sec",
2127  fInterval + nDay*DAY2SEC, nDay, nHour, nMin, dSec);
2128  ts << str << "\n";
2129 
2130  str.sprintf(" Solution type: %-17s ",
2131  qPrintable(solutionTypeName_));
2132  ts << str << "\n\n";
2133 
2134  ts <<
2135  " Data Type Number of Weighted RMS Normalized RMS Chi Square" << "\n"
2136  " Observations Residual Residual (precis)" << "\n"
2137  " Used" << "\n"
2138  " " << "\n";
2139 
2140  str.sprintf(" Delay %8d %18.3f ps %17.2f %12.4f",
2141  numProcdObs, rmsDelay, nrmsDelay, chi2Delay);
2142  ts << str << "\n";
2143 
2144  str.sprintf(" Rate %8d %18g fs/s %15.2f %12.4f",
2145  numProcRateObs, rmsRate, nrmsRate, chi2Rate);
2146  ts << str << "\n";
2147 
2148  str.sprintf("Combined %8d %15.2f %12.4f",
2149  0, nrmsCombined, chi2Combined);
2150  ts << str << "\n";
2151 
2152  ts << "----------------------------------------------------------------------- \n";
2153  // << " CRES mode: ?????? \n"
2154  // << " Suppression method in use: ????????????? \n";
2155 
2156  str.sprintf(" Used quality_code_limit: %3d ",
2157  qCodeLimit);
2158  ts << str << "\n";
2159 
2160  str.sprintf(" Number of potentially recoverable observations: %8d ",
2161  numRecObs);
2162  ts << str << "\n";
2163 
2164  str.sprintf(" Number of potentially good observations with QC 5-9:%7d ",
2165  numRec59Obs);
2166  ts << str << "\n";
2167 
2168  str.sprintf(" Number of used observations: %8d (%6.2f%%) ",
2169  numProcdObs, numProcdObs*100.0/numRecObs);
2170  ts << str << "\n";
2171 
2172  str.sprintf(" Number of suppressed observations: %8d (%6.2f%%) ",
2173  (numRecObs - numProcdObs), (numRecObs - numProcdObs)*100.0/numRecObs);
2174  ts << str << "\n";
2175 
2176  ts << "----------------------------------------------------------------------- \n\n\n\n";
2177 };
2178 
2179 
2180 
2181 //
2183 {
2184  QString str;
2185  // print a header:
2186  ts
2187  << " Baseline Statistics\n"
2188  << " Baseline # W.Obs W.RMS Del N.R.D. N.R.D. W.RMS Rate N.R.R. "
2189  << "D.RW R.RW \n"
2190  << " used/recov ps standard ( 15ps+i) fs/s "
2191  << "ps fs/s \n\n";
2192 
2193  // colect a list of "supressed" stations:
2194  QMap<QString, SgVlbiStationInfo*> skippedStationsByName;
2195  QMap<QString, SgVlbiStationInfo*>::iterator itSi;
2196  for (itSi=session_->stationsByName().begin(); itSi!=session_->stationsByName().end(); ++itSi)
2197  {
2198  SgVlbiStationInfo *si=itSi.value();
2200  skippedStationsByName.insert(si->getKey(), si);
2201  };
2202  // report baselines' statistics:
2203  QList<SgVlbiBaselineInfo*> skippedBaselines;
2204  QMap<QString, SgVlbiBaselineInfo*>::iterator it;
2205  for (it=activeBand_->baselinesByName().begin(); it!=activeBand_->baselinesByName().end(); ++it)
2206  {
2207  SgVlbiBaselineInfo *bi=it.value();
2208  QString biName=bi->getKey();
2209  QString st1Name=biName.left(8);
2210  QString st2Name=biName.right(8);
2212  !skippedStationsByName.contains(st1Name) &&
2213  !skippedStationsByName.contains(st2Name) )
2214  {
2215 // 1 2 3 4 5 6 7 8 9 10
2216 //01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
2217 // HOBART12-KATH12M 967/ 1004 37 0.97 1.38 202 5.40 29 0
2218 // HOBART12-YARRA12M 947/ 982 42 0.97 1.52 227 5.19 36 0
2219 // KATH12M -YARRA12M 1009/ 1029 32 0.95 1.24 216 4.74 26 0
2220 
2221  str.sprintf(" %-17s%5d/%5d%8.1f %9.2f %9.2f %7.1f %10.2f%7.1f%7.1f",
2222  qPrintable(biName.replace(8, 1, "-")),
2224  bi->wrms(DT_DELAY)*1.0E12,
2225 
2226 // bi->getNrmRes(),
2227  bi->getSFF_NrmRes(DT_DELAY),
2229 // 0.0, // nrd (15ps+i) ?
2230  bi->wrms(DT_RATE)*1.0E15, // wrms rate
2231  bi->getSFF_NrmRes(DT_RATE), // nrr
2232  bi->getSigma2add(DT_DELAY)*1.0E12,
2233  bi->getSigma2add(DT_RATE )*1.0E15 // rate's sigma2add
2234  );
2235  ts << str << "\n";
2236  }
2237  else
2238  skippedBaselines.append(bi);
2239  };
2240  ts << "\n\n";
2241 
2242  if (skippedBaselines.size())
2243  {
2244  ts << " Not included: \n\n";
2245  for (int i=0; i<skippedBaselines.size(); i++)
2246  {
2247  SgVlbiBaselineInfo *bi=skippedBaselines.at(i);
2248  QString biName=bi->getKey();
2249  str.sprintf(" %-17s%5d/%5d deselected",
2250  qPrintable(biName.replace(8, 1, "-")),
2252  ts << str << "\n";
2253  };
2254  ts << "\n\n";
2255  };
2256  // clear aux stuff:
2257  skippedStationsByName.clear();
2258  skippedBaselines.clear();
2259 };
2260 
2261 
2262 
2263 //
2265 {
2266  QString str;
2267  // print a header:
2268  ts
2269  << " Source Statistics \n"
2270  << " Source # W.Obs W.RMS Del N.R.D. N.R.D. W.RMS Rate N.R.R. \n"
2271  << " ps standard ( 15ps) fs/s \n \n";
2272 
2273  usedSources_.clear();
2274  skippedSources_.clear();
2275  QMap<QString, SgVlbiSourceInfo*>::iterator it;
2276  for (it=activeBand_->sourcesByName().begin(); it!=activeBand_->sourcesByName().end(); ++it)
2277  {
2278  SgVlbiSourceInfo *si=it.value();
2280  usedSources_.append(si);
2281  else
2282  skippedSources_.append(si);
2283  };
2284  // sort in RA order:
2287  // report sources' statistics:
2288  for (int i=0; i<usedSources_.size(); i++)
2289  {
2290  // 0059+581 A 58/ 60 655 0.33 29.76 195 0.77
2291  SgVlbiSourceInfo *si=usedSources_.at(i);
2292  str.sprintf(" %12s %1s %5d/%5d%8.1f %9.2f %8.2f %7.1f %10.2f",
2293  qPrintable(si->getKey()), qPrintable(srcChars[i % numOfSrcChars]),
2294  si->numProcessed(DT_DELAY), si->numUsable(DT_DELAY),// numbers of observations, processed and total
2295  si->wrms(DT_DELAY)*1.0E12, // WRMS delay
2296  si->getSFF_NrmRes(DT_DELAY), // nomalized residuals
2297  si->getSFF_NrmRes_plus_15(DT_DELAY), // nomalized residuals with fixed aux. weight
2298  si->wrms(DT_RATE)*1.0E15, // wrms rate
2299  si->getSFF_NrmRes(DT_RATE) // nrr
2300  );
2301  ts << str << "\n";
2302  };
2303  ts << "\n\n";
2304 
2305  if (skippedSources_.size())
2306  {
2307  ts << " Not included: \n\n";
2308  for (int i=0; i<skippedSources_.size(); i++)
2309  {
2311  str.sprintf(" %-10s%5d/%5d deselected",
2312  qPrintable(si->getKey()),
2314  ts << str << "\n";
2315  };
2316  ts << "\n\n";
2317  };
2318  //
2319  // at the end, collect stats from session level:
2320  usedSources_.clear();
2321  skippedSources_.clear();
2322  for (it=session_->sourcesByName().begin(); it!=session_->sourcesByName().end(); ++it)
2323  {
2324  SgVlbiSourceInfo *si=it.value();
2326  usedSources_.append(si);
2327  else
2328  skippedSources_.append(si);
2329  };
2330  // sort in RA order:
2333 };
2334 
2335 
2336 
2337 //
2339 {
2340  QString str;
2341  // print a header:
2342  ts
2343  << " Station Statistics \n"
2344  << " Station # W.Obs W.RMS Del N.R.D. N.R.D. W.RMS Rate N.R.R. \n"
2345  << " ps standard ( 15ps) fs/s \n \n";
2346 
2347 //pBand = session_->primaryBand();
2348  // report stations' statistics:
2349  QList<SgVlbiStationInfo*> skippedStations;
2350  QMap<QString, SgVlbiStationInfo*>::iterator it;
2351  for (it=activeBand_->stationsByName().begin(); it!=activeBand_->stationsByName().end(); ++it)
2352  {
2353  SgVlbiStationInfo *si=it.value();
2355  {
2356  str.sprintf(" %12s %5d/%5d%8.1f %9.2f %8.2f %7.1f %10.2f",
2357  qPrintable(si->getKey()),
2359  si->wrms(DT_DELAY)*1.0E12,
2360 // si->getNrmRes(),
2361  si->getSFF_NrmRes(DT_DELAY),
2363 // 0.0, // nrd (15ps+i) ?
2364  si->wrms(DT_RATE)*1.0E15, // wrms rate
2365  si->getSFF_NrmRes(DT_RATE) // nrr
2366  );
2367  ts << str << "\n";
2368  }
2369  else
2370  skippedStations.append(si);
2371  };
2372  ts << "\n\n";
2373 
2374  if (skippedStations.size())
2375  {
2376  ts << " Not included: \n\n";
2377  for (int i=0; i<skippedStations.size(); i++)
2378  {
2379  SgVlbiStationInfo *si=skippedStations.at(i);
2380  str.sprintf(" %-10s%5d/%5d deselected",
2381  qPrintable(si->getKey()),
2383  ts << str << "\n";
2384  };
2385  ts << "\n\n";
2386  };
2387  // clear aux stuff:
2388  skippedStations.clear();
2389 };
2390 
2391 
2392 
2393 //
2395 {
2396  QString path2AF;
2397  if (path2APrioriFiles_.at(0)=='/')
2398  path2AF = path2APrioriFiles_;
2399  else
2400  path2AF = identities_.getCurrentDir() + "/" + path2APrioriFiles_;
2401 
2402  ts
2403  << " *** Flyby Status ***\n\n"
2404  << " directory: " << qPrintable(path2AF) << "\n\n"
2405  << "Station Source Nutation Nutation Earth Earth Station "
2406  << "Pressure EOP Intp. EOP Intp. High Freq Axis \n"
2407  << "Positions Positions Model Time Rotation Rotation Velocity "
2408  << "Loading Smoothing Smoothing EOP Offset \n"
2409  << " Series Series Interpol. Model "
2410  << " CALC Mod File Model Mod File \n"
2411  << "--------- --------- --------- --------- --------- --------- --------- "
2412  << "--------- --------- --------- --------- ---------\n";
2413  // Station Positions
2414  ts << qPrintable((config_->getUseExtAPrioriSitesPositions() ?
2415  config_->getExtAPrioriSitesPositionsFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2416  // Source Positions
2417  ts << qPrintable((config_->getUseExtAPrioriSourcesPositions() ?
2418  config_->getExtAPrioriSourcesPositionsFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2419  // Nutation Model
2420  ts << qPrintable(QString("NONE").leftJustified(9, ' ', true)) << " ";
2421  // Nutation Time Series
2422  ts << qPrintable(QString("NONE").leftJustified(9, ' ', true)) << " ";
2423  // Earth Rotation Series
2424  ts << qPrintable((config_->getUseExtAPrioriErp() ?
2425  config_->getExtAPrioriErpFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2426  // Earth Rotation Interpol.
2427  ts << qPrintable((config_->getUseExtAPrioriErp() ?
2428  QString("C. Spline") : "NONE").leftJustified(9, ' ', true)) << " ";
2429  // Station Velocity Model
2430  ts << qPrintable((config_->getUseExtAPrioriSitesVelocities() ?
2431  config_->getExtAPrioriSitesVelocitiesFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2432  // Pressure Loading
2433  ts << qPrintable(QString("NONE").leftJustified(9, ' ', true)) << " ";
2434  // EOP Intp. Smoothing CALC
2435  ts << qPrintable(QString("NO_ZONAL").leftJustified(9, ' ', true)) << " ";
2436  // EOP Intp. Smoothing Mod File
2437  ts << qPrintable(QString("N/A").leftJustified(9, ' ', true)) << " ";
2438  // High Freq EOP Model
2439  ts << qPrintable((config_->getUseExtAPrioriHiFyErp() ?
2440  config_->getExtAPrioriHiFyErpFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2441  // Axis Offset Mod File
2442  ts << qPrintable((config_->getUseExtAPrioriAxisOffsets() ?
2443  config_->getExtAPrioriAxisOffsetsFileName() : "NONE").leftJustified(9, ' ', true)) << " \n\n";
2444  //
2445  ts << "Site Plate Map: " << qPrintable(path2AF) << "/sitpl.dat \n\n";
2446 };
2447 
2448 
2449 
2450 //
2452 {
2453  static const double clcScaleVals[10] =
2454  {1.0e09, 1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0,
2455  1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0};
2456  static const QString clcScaleNames[10] =
2457  {"ns ", "D-14 ", "D-14/day ", "D-14/day ", "D-14/day^2",
2458  "D-14/day^3", "D-14/day^4", "D-14/day^5", "D-14/day^6", "D-14/day^7"};
2459 
2460  QString str;
2461  int idx;
2462  SgPwlStorage *pwl=NULL;
2463  double chi;
2465 
2466 // if (session_->primaryBand()->getChi2()>0.0)
2467 // chi = sqrt(session_->primaryBand()->getChi2()/session_->primaryBand()->getNumOfDOF());
2468  if (activeBand_->chi2(dType) > 0.0)
2469 // chi = sqrt(activeBand_->chi2(dType)/session_->getNumOfDOF());
2470  chi = sqrt(activeBand_->reducedChi2(dType));
2471  else
2472  chi = 1.0; // do not scale at all
2473  // SgArcStorage *arc=NULL;
2474 
2475  ts
2476  << " Parameter adjustments for run " << qPrintable(reportID_)
2477  << " User=" << qPrintable(identities_.getUserDefaultInitials()) << "\n"
2478  << " Reference epoch for polynomial models: "
2479  << qPrintable(session_->tRefer().toString(SgMJD::F_SOLVE_SPLFL_SHORT)) << "\n"
2480  << " Parameter"
2481  << " Adjustment a-sigma m-sigma\n";
2482 
2483  StationsByName_it it_st;
2484  // reference clocks:
2485  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
2486  {
2487  SgVlbiStationInfo *si=it_st.value();
2490  {
2491  SgMJD t=*si->auxObservationByScanId()->begin().value();
2492  // WESTFORD CLCK 12/06/21 18:29 Reference
2493  str.sprintf(" %8s CLCK %s Reference",
2494  qPrintable(si->getKey()),
2495  qPrintable(t.toString(SgMJD::F_SOLVE_SPLFL_SHORT)));
2496  ts << str << "\n";
2497  };
2498  };
2499 
2500  idx = 1;
2501  // stations:
2502  Sg3dMatrixR W(EAST), V(NORTH);
2503  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
2504  {
2505  SgVlbiStationInfo *si=it_st.value();
2507  {
2508  // coordinates:
2510  {
2511  double cXY, cXZ, cYZ;
2512  double latitude, longitude, height;
2513  Sg3dVector r, rs;
2514  Sg3dVector r_apriori(si->getR());
2515  Sg3dMatrix m3M;
2516  SgMJD t(si->pRx()->getTMean());
2518  r_apriori = si->getR_ea() + si->getV_ea()*(t - session_->getApStationVelocities().getT0());
2519 
2520  SgVlbiStationInfo::calcRLF(latitude, longitude, height, r_apriori,
2522  m3M = W(-latitude)*V(longitude);
2523 
2524  // covariances (i.e., rho_{1,2}*sigma_1*sigma_2):
2525  cXY = PxAll_->getElement(si->pRx()->getIdx(), si->pRy()->getIdx());
2526  cXZ = PxAll_->getElement(si->pRx()->getIdx(), si->pRz()->getIdx());
2527  cYZ = PxAll_->getElement(si->pRy()->getIdx(), si->pRz()->getIdx());
2528 
2529  // evaluate displacement in VEN:
2530  r = m3M*Sg3dVector(si->pRx()->getSolution(), si->pRy()->getSolution(), si->pRz()->getSolution());
2531  // evaluate std. deviations:
2532  rs(VERTICAL) = sqrt(
2533  m3M.at(VERTICAL, X_AXIS)*m3M.at(VERTICAL, X_AXIS)*si->pRx()->getSigma()*si->pRx()->getSigma() +
2534  m3M.at(VERTICAL, Y_AXIS)*m3M.at(VERTICAL, Y_AXIS)*si->pRy()->getSigma()*si->pRy()->getSigma() +
2535  m3M.at(VERTICAL, Z_AXIS)*m3M.at(VERTICAL, Z_AXIS)*si->pRz()->getSigma()*si->pRz()->getSigma() +
2536  2.0*(m3M.at(VERTICAL, X_AXIS)*m3M.at(VERTICAL, Y_AXIS)*cXY +
2537  m3M.at(VERTICAL, X_AXIS)*m3M.at(VERTICAL, Z_AXIS)*cXZ +
2538  m3M.at(VERTICAL, Y_AXIS)*m3M.at(VERTICAL, Z_AXIS)*cYZ
2539  )
2540  );
2541  rs(EAST) = sqrt(
2542  m3M.at(EAST, X_AXIS)*m3M.at(EAST, X_AXIS)*si->pRx()->getSigma()*si->pRx()->getSigma() +
2543  m3M.at(EAST, Y_AXIS)*m3M.at(EAST, Y_AXIS)*si->pRy()->getSigma()*si->pRy()->getSigma() +
2544  m3M.at(EAST, Z_AXIS)*m3M.at(EAST, Z_AXIS)*si->pRz()->getSigma()*si->pRz()->getSigma() +
2545  2.0*(m3M.at(EAST, X_AXIS)*m3M.at(EAST, Y_AXIS)*cXY +
2546  m3M.at(EAST, X_AXIS)*m3M.at(EAST, Z_AXIS)*cXZ +
2547  m3M.at(EAST, Y_AXIS)*m3M.at(EAST, Z_AXIS)*cYZ
2548  )
2549  );
2550  rs(NORTH) = sqrt(
2551  m3M.at(NORTH, X_AXIS)*m3M.at(NORTH, X_AXIS)*si->pRx()->getSigma()*si->pRx()->getSigma() +
2552  m3M.at(NORTH, Y_AXIS)*m3M.at(NORTH, Y_AXIS)*si->pRy()->getSigma()*si->pRy()->getSigma() +
2553  m3M.at(NORTH, Z_AXIS)*m3M.at(NORTH, Z_AXIS)*si->pRz()->getSigma()*si->pRz()->getSigma() +
2554  2.0*(m3M.at(NORTH, X_AXIS)*m3M.at(NORTH, Y_AXIS)*cXY +
2555  m3M.at(NORTH, X_AXIS)*m3M.at(NORTH, Z_AXIS)*cXZ +
2556  m3M.at(NORTH, Y_AXIS)*m3M.at(NORTH, Z_AXIS)*cYZ
2557  )
2558  );
2559 
2560  ts << "Station positions are for epoch: "
2561  << qPrintable(si->pRx()->getTMean().toString(SgMJD::F_SOLVE_SPLFL)) << "\n";
2562  str.sprintf("%5d. %-8s %04d %4s X Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2563  idx, qPrintable(si->getKey()), si->getCdpNumber(), qPrintable(si->getTectonicPlateName()),
2564  (r_apriori.at(X_AXIS) + si->pRx()->getSolution())*1000.0,
2565  si->pRx()->getSolution()*1000.0,
2566  si->pRx()->getSigma()*1000.0,
2567  si->pRx()->getSigma()*1000.0*chi );
2568  ts << str << "\n";
2569  idx++;
2570 
2571  str.sprintf("%5d. %-8s %04d %4s Y Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2572  idx, qPrintable(si->getKey()), si->getCdpNumber(), qPrintable(si->getTectonicPlateName()),
2573  (r_apriori.at(Y_AXIS) + si->pRy()->getSolution())*1000.0,
2574  si->pRy()->getSolution()*1000.0,
2575  si->pRy()->getSigma()*1000.0,
2576  si->pRy()->getSigma()*1000.0*chi );
2577  ts << str << "\n";
2578  idx++;
2579 
2580  str.sprintf("%5d. %-8s %04d %4s Z Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2581  idx, qPrintable(si->getKey()), si->getCdpNumber(), qPrintable(si->getTectonicPlateName()),
2582  (r_apriori.at(Z_AXIS) + si->pRz()->getSolution())*1000.0,
2583  si->pRz()->getSolution()*1000.0,
2584  si->pRz()->getSigma()*1000.0,
2585  si->pRz()->getSigma()*1000.0*chi );
2586  ts << str << "\n";
2587  idx++;
2588 
2589  // the same but in VEN:
2590  str.sprintf(" %-8s %04d U Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2591  qPrintable(si->getKey()), si->getCdpNumber(),
2592  r.at(VERTICAL)*1000.0,
2593  r.at(VERTICAL)*1000.0,
2594  rs.at(VERTICAL)*1000.0,
2595  rs.at(VERTICAL)*1000.0*chi);
2596  ts << str << "\n";
2597  str.sprintf(" %-8s %04d E Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2598  qPrintable(si->getKey()), si->getCdpNumber(),
2599  r.at(EAST)*1000.0,
2600  r.at(EAST)*1000.0,
2601  rs.at(EAST)*1000.0,
2602  rs.at(EAST)*1000.0*chi);
2603  ts << str << "\n";
2604  str.sprintf(" %-8s %04d N Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2605  qPrintable(si->getKey()), si->getCdpNumber(),
2606  r.at(NORTH)*1000.0,
2607  r.at(NORTH)*1000.0,
2608  rs.at(NORTH)*1000.0,
2609  rs.at(NORTH)*1000.0*chi);
2610  ts << str << "\n";
2611  };
2612  // axis offset:
2614  {
2615  double vAxisOffset, sAxisOffset;
2617  vAxisOffset+= si->pAxisOffset()->getSolution();
2618  sAxisOffset = si->pAxisOffset()->getSigma();
2619 
2620  str.sprintf("%5d. %-8s Axis Offset %24.2f mm %14.3f mm %18.3f mm %18.3f mm",
2621  idx,
2622  qPrintable(si->getKey()),
2623  vAxisOffset*1.0e3,
2624  si->pAxisOffset()->getSolution()*1.0e3,
2625  sAxisOffset*1.0e3,
2626  sAxisOffset*1.0e3*chi );
2627  ts << str << "\n";
2628  idx++;
2629  };
2630  //
2631  // clocks:
2632  SgMJD t=*si->auxObservationByScanId()->begin().value();
2633  if (si->pClock0()->getPMode() != SgParameterCfg::PM_NONE)
2634  {
2635  int nPwl, nLoc, nMax;
2636  double *dVal, *dSig;
2637  pwl = pwlByName_.contains(si->pClock0()->getName())?
2638  pwlByName_.find(si->pClock0()->getName()).value():NULL;
2639  nPwl = pwl?pwl->getNumOfPolynomials():0;
2640  nLoc = si->getClocksModelOrder();
2641  nMax = std::max(nPwl, nLoc);
2642  dVal = new double[nMax];
2643  dSig = new double[nMax];
2644  for (int i=0; i<nMax; i++)
2645  dVal[i] = dSig[i] = 0.0;
2646  for (int i=0; i<nLoc; i++)
2647  {
2648  dVal[i] = si->getEstClockModel(i);
2649  dSig[i] = si->getEstClockModelSigma(i);
2650  };
2651  for (int i=0; i<nPwl; i++)
2652  {
2653  dVal[i]+= pwl->getP_Ai(i)->getSolution();
2654  dSig[i] = pwl->getP_Ai(i)->getSigma();
2655  };
2656  for (int i=0; i<nMax; i++)
2657  {
2658  str.sprintf("%5d. %-8s CL %1d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2659  idx, qPrintable(si->getKey()), i,
2660  qPrintable(t.toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2661  dVal[i]*clcScaleVals[i], qPrintable(clcScaleNames[i]),
2662  dSig[i]*clcScaleVals[i], qPrintable(clcScaleNames[i]),
2663  dSig[i]*clcScaleVals[i]*chi, qPrintable(clcScaleNames[i]));
2664  ts << str << "\n";
2665  idx++;
2666  };
2667  delete[] dVal;
2668  delete[] dSig;
2669  // adjust index for pwl/arc parameters (clocks):
2670  if (pwlByName_.contains(si->pClock0()->getName()))
2671  idx += pwlByName_.find(si->pClock0()->getName()).value()->getNumOfNodes();
2672  else if (arcByName_.contains(si->pClock0()->getName()))
2673  idx += arcByName_.find(si->pClock0()->getName()).value()->getNum();
2674  };
2675  if (si->clockBreaks().size())
2676  {
2677  si->clockBreaks().sortEvents();
2678  for (int j=0; j<si->clockBreaks().size(); j++)
2679  {
2680  SgParameterBreak *pb=si->clockBreaks().at(j);
2682  {
2683  if (pb->pA0())
2684  {
2685 // 219. SVETLOE BR 0 15/07/31 07:19 3.006 ns 0.022 ns 0.022 ns
2686  str.sprintf("%5d. %-8s BR %1d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2687  idx, qPrintable(si->getKey()), 0,
2688  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2689  pb->pA0()->getSolution()*clcScaleVals[0], qPrintable(clcScaleNames[0]),
2690  pb->pA0()->getSigma()*clcScaleVals[0], qPrintable(clcScaleNames[0]),
2691  pb->pA0()->getSigma()*clcScaleVals[0]*chi, qPrintable(clcScaleNames[0]));
2692  ts << str << "\n";
2693  idx++;
2694  };
2695  if (pb->pA1() && si->getClocksModelOrder()>1)
2696  {
2697 // 220. SVETLOE BR 1 15/07/31 07:19 -2.092 D-14 1.794 D-14 1.816 D-14
2698  str.sprintf("%5d. %-8s BR %1d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2699  idx, qPrintable(si->getKey()), 1,
2700  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2701  pb->pA1()->getSolution()*clcScaleVals[1], qPrintable(clcScaleNames[1]),
2702  pb->pA1()->getSigma()*clcScaleVals[1], qPrintable(clcScaleNames[1]),
2703  pb->pA1()->getSigma()*clcScaleVals[1]*chi, qPrintable(clcScaleNames[1]));
2704  ts << str << "\n";
2705  idx++;
2706  };
2707  if (pb->pA2() && si->getClocksModelOrder()>2)
2708  {
2709 // 221. SVETLOE BR 2 15/07/31 07:19 -2.186 D-14/day 4.439 D-14/day 4.494 D-14/day
2710  str.sprintf("%5d. %-8s BR %1d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2711  idx, qPrintable(si->getKey()), 2,
2712  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2713  pb->pA2()->getSolution()*clcScaleVals[2], qPrintable(clcScaleNames[2]),
2714  pb->pA2()->getSigma()*clcScaleVals[2], qPrintable(clcScaleNames[2]),
2715  pb->pA2()->getSigma()*clcScaleVals[2]*chi, qPrintable(clcScaleNames[2]));
2716  ts << str << "\n";
2717  idx++;
2718  };
2719  }
2720  else
2721  {
2722 //
2723 // 390. YARRA12M BR 0 14/11/13 23:44 0.472 ns 0.075 ns 0.075 ns
2724 //
2725  str.sprintf(" %-8s BR 0 %s #%3d band=* %15.3f ns %15.3f ns %18.3f ns",
2726  qPrintable(si->getKey()),
2727  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)), j,
2728  pb->getA0(),
2729  pb->getS0(),
2730  pb->getS0()*chi);
2731  ts << str << "\n";
2732  };
2733  };
2734  };
2735  // band-dependent breaks:
2736  for (int i=0; i<session_->bands().size(); i++)
2737  {
2738  SgVlbiBand *band=session_->bands().at(i);
2739  if (band->stationsByName().contains(si->getKey()))
2740  {
2741  SgVlbiStationInfo *sib=band->stationsByName().value(si->getKey());
2742  if (sib->clockBreaks().size())
2743  {
2744  sib->clockBreaks().sortEvents();
2745  for (int j=0; j<sib->clockBreaks().size(); j++)
2746  {
2747  SgParameterBreak *pb=sib->clockBreaks().at(j);
2748  str.sprintf(" %-8s BR 0 %s #%3d band=%s %15.3f ns %15.3f ns %18.3f ns",
2749  qPrintable(sib->getKey()),
2750  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)), j, qPrintable(band->getKey()),
2751  pb->getA0(),
2752  pb->getS0(),
2753  pb->getS0()*chi);
2754  ts << str << "\n";
2755  };
2756  };
2757  }
2758  else
2760  "::reportEstimationBlock_Output4Spoolfile(): cannot find station " + si->getKey() +
2761  " in the " + band->getKey() + "-band");
2762  };
2763  // zenith delay:
2764  // adjust index for pwl/arc parameters (zenith delay):
2765  if (pwlByName_.contains(si->pZenithDelay()->getName()))
2766  {
2767  pwl = pwlByName_.find(si->pZenithDelay()->getName()).value();
2768  for (int i=0; i<pwl->getNumOfPolynomials(); i++)
2769  {
2770  str.sprintf("%5d. %-8s AT %d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2771  idx, qPrintable(si->getKey()), i,
2772  qPrintable(pwl->tStart().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2773  (i==0 ? pwl->getP_Ai(i)->getSolution() + si->getEstWetZenithDelay() :
2774  pwl->getP_Ai(i)->getSolution() )/vLight*1.0e12, "ps ",
2775  pwl->getP_Ai(i)->getSigma()/vLight*1.0e12, "ps ",
2776  pwl->getP_Ai(i)->getSigma()/vLight*1.0e12*chi, "ps");
2777  ts << str << "\n";
2778  idx++;
2779  };
2780  str.sprintf(" %-8s Atm %s Avg: %9.3f ps Rms: %11.3f ps Tot_Rms: %11.3f ps",
2781  qPrintable(si->getKey()),
2782  qPrintable(
2783  pwl->tMean()
2784  // si->pZenithDelay()->getTMean()
2786  pwl->calcMean()/vLight*1.0e12,
2787  pwl->calcWRMS()/vLight*1.0e12,
2788  pwl->calcWRMS()/vLight*1.0e12*chi);
2789  ts << str << "\n";
2790  idx += pwl->getNumOfNodes();
2791  }
2792  else if (arcByName_.contains(si->pZenithDelay()->getName()))
2793  idx += arcByName_.find(si->pZenithDelay()->getName()).value()->getNum();
2795  {
2796  str.sprintf("%5d. %-8s AT 0 %s %20.3f %-s %10.3f %-s %10.3f %-s",
2797  idx, qPrintable(si->getKey()),
2798  qPrintable(t.toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2799  si->pZenithDelay()->getSolution()/vLight*1.0e12, "ps ",
2800  si->pZenithDelay()->getSigma()/vLight*1.0e12, "ps ",
2801  si->pZenithDelay()->getSigma()/vLight*1.0e12*chi, "ps");
2802  ts << str << "\n";
2803  idx++;
2804  };
2805  //
2806  // adjust index for pwl/arc parameters (gradients):
2807  if (pwlByName_.contains(si->pAtmGradN()->getName()))
2808  {
2809  pwl = pwlByName_.find(si->pAtmGradN()->getName()).value();
2810  if (pwl->getNumOfSegments()==1)
2811  {
2812  SgPwlStorage *pwlGrdN, *pwlGrdE;
2813  pwlGrdN = pwl;
2814  pwlGrdE = pwlByName_.find(si->pAtmGradE()->getName()).value();
2815  // gradient north, left:
2816  str.sprintf("%5d. %-8s NG %s %20.3f %-s %10.3f %-s %10.3f %-s",
2817  idx, qPrintable(si->getKey()),
2818  qPrintable(pwlGrdN->tStart().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2819  pwlGrdN->getP_Bi(0)->getSolution()*1.0e3, "mm ",
2820  pwlGrdN->getP_Bi(0)->getSigma()*1.0e3, "mm ",
2821  pwlGrdN->getP_Bi(0)->getSigma()*1.0e3*chi,"mm ");
2822  ts << str << "\n";
2823  idx++;
2824  // gradient east, left:
2825  str.sprintf("%5d. %-8s EG %s %20.3f %-s %10.3f %-s %10.3f %-s",
2826  idx, qPrintable(si->getKey()),
2827  qPrintable(pwlGrdE->tStart().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2828  pwlGrdE->getP_Bi(0)->getSolution()*1.0e3, "mm ",
2829  pwlGrdE->getP_Bi(0)->getSigma()*1.0e3, "mm ",
2830  pwlGrdE->getP_Bi(0)->getSigma()*1.0e3*chi,"mm ");
2831  ts << str << "\n";
2832  idx++;
2833  // gradient north, right:
2834  str.sprintf("%5d. %-8s NG %s %20.3f %-s %10.3f %-s %10.3f %-s",
2835  idx, qPrintable(si->getKey()),
2836  qPrintable(pwlGrdN->tFinis().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2837  pwlGrdN->getP_Bi(1)->getSolution()*1.0e3, "mm ",
2838  pwlGrdN->getP_Bi(1)->getSigma()*1.0e3, "mm ",
2839  pwlGrdN->getP_Bi(1)->getSigma()*1.0e3*chi,"mm ");
2840  ts << str << "\n";
2841  idx++;
2842  // gradient east, right:
2843  str.sprintf("%5d. %-8s EG %s %20.3f %-s %10.3f %-s %10.3f %-s",
2844  idx, qPrintable(si->getKey()),
2845  qPrintable(pwlGrdE->tFinis().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2846  pwlGrdE->getP_Bi(1)->getSolution()*1.0e3, "mm ",
2847  pwlGrdE->getP_Bi(1)->getSigma()*1.0e3, "mm ",
2848  pwlGrdE->getP_Bi(1)->getSigma()*1.0e3*chi,"mm ");
2849  ts << str << "\n";
2850  idx++;
2851  }
2852  else // report in the same way as zenith delays:
2853  {
2854  str.sprintf(" %-8s NGr %s Avg: %9.3f ps Rms: %11.3f ps Tot_Rms: %11.3f ps",
2855  qPrintable(si->getKey()),
2856 // qPrintable(si->pAtmGradN()->getTMean().toString(SgMJD::F_SOLVE_SPLFL_LONG)),
2857  qPrintable(pwl->tMean().toString(SgMJD::F_SOLVE_SPLFL_LONG)),
2858  pwl->calcMean()/vLight*1.0e12,
2859  pwl->calcWRMS()/vLight*1.0e12,
2860  pwl->calcWRMS()/vLight*1.0e12*chi);
2861  ts << str << "\n";
2862  idx += pwl->getNumOfNodes() + pwl->getNumOfPolynomials();
2863  pwl = pwlByName_.find(si->pAtmGradE()->getName()).value();
2864  str.sprintf(" %-8s EGr %s Avg: %9.3f ps Rms: %11.3f ps Tot_Rms: %11.3f ps",
2865  qPrintable(si->getKey()),
2866  qPrintable(pwl->tMean().toString(SgMJD::F_SOLVE_SPLFL_LONG)),
2867 // qPrintable(si->pAtmGradN()->getTMean().toString(SgMJD::F_SOLVE_SPLFL_LONG)),
2868  pwl->calcMean()/vLight*1.0e12,
2869  pwl->calcWRMS()/vLight*1.0e12,
2870  pwl->calcWRMS()/vLight*1.0e12*chi);
2871  ts << str << "\n";
2872  idx += pwl->getNumOfNodes() + pwl->getNumOfPolynomials();
2873  };
2874  }
2875  else
2876  {
2877  if (arcByName_.contains(si->pAtmGradN()->getName()))
2878  idx += arcByName_.find(si->pAtmGradN()->getName()).value()->getNum();
2879  if (arcByName_.contains(si->pAtmGradE()->getName()))
2880  idx += arcByName_.find(si->pAtmGradE()->getName()).value()->getNum();
2881  };
2882  ts << "\n";
2883  };
2884  };
2885  //
2886  //
2888  {
2889  for (int i=0; i<usedSources_.size(); i++)
2890  {
2891  SgVlbiSourceInfo *si=usedSources_.at(i);
2892  if (si->pRA()->isAttr(SgParameter::Attr_IS_SOLVED) &&
2894  {
2895  double vRA, vDN;
2896  double d;
2899  vRA+= si->pRA()->getSolution();
2900  vDN+= si->pDN()->getSolution();
2901  //
2902  // RA:
2903  str.sprintf("%5d.%s %-8s RT. ASC. %s %11.4f m-asec %10.4f m-asec %10.4f"
2904  " m-asec",
2905  idx,
2906  qPrintable(srcChars[i % numOfSrcChars]),
2907  qPrintable(si->getKey()),
2908  qPrintable(si->ra2String(vRA)),
2909  si->pRA()->getSolution()*RAD2MAS,
2910  si->pRA()->getSigma()*RAD2MAS,
2911  si->pRA()->getSigma()*RAD2MAS*chi
2912  );
2913  ts << str << "\n";
2914  str.sprintf(" CORRECTION %20.7f\n SCALED SIGMA %20.7f",
2915  si->pRA()->getSolution()*RAD2SEC/15.0,
2916  si->pRA()->getSigma()*RAD2SEC/15.0*chi
2917  );
2918  ts << str << "\n";
2919  ts << "\n";
2920  idx++;
2921 
2922  // DN:
2923  str.sprintf("%5d.%s %-8s DEC. %s %16.4f m-asec %15.4f m-asec %15.4f m-asec",
2924  idx,
2925  qPrintable(srcChars[i % numOfSrcChars]),
2926  qPrintable(si->getKey()),
2927  qPrintable(si->dn2String(vDN)),
2928  si->pDN()->getSolution()*RAD2MAS,
2929  si->pDN()->getSigma()*RAD2MAS,
2930  si->pDN()->getSigma()*RAD2MAS*chi
2931  );
2932  ts << str << "\n";
2933  str.sprintf(" CORRECTION %20.7f\n SCALED SIGMA %20.7f",
2934  si->pDN()->getSolution()*RAD2SEC,
2935  si->pDN()->getSigma()*RAD2SEC*chi
2936  );
2937  ts << str << "\n";
2938  ts << "\n";
2939  idx++;
2940  //
2941  // correlation:
2942  // covariances (i.e., rho_{1,2}*sigma_1*sigma_2):
2943  d = PxAll_->getElement(si->pRA()->getIdx(), si->pDN()->getIdx());
2944  if (si->pRA()->getSigma()>0.0 && si->pDN()->getSigma()>0.0)
2945  str.sprintf(" %-8s CORRELATION %10.4f Reference date: 2000.01.01-12:00:00",
2946  qPrintable(si->getKey()),
2947  d/(si->pRA()->getSigma()*si->pDN()->getSigma())
2948  );
2949  else
2950  str.sprintf(" %-8s CORRELATION ------- Reference date: 2000.01.01-12:00:00",
2951  qPrintable(si->getKey()));
2952  ts << str << "\n";
2953  };
2954  };
2955  };
2956  //
2957  // stations again:
2958  //
2959  // zenith delays:
2960  int idxAux, sum;
2962  {
2963  idxAux = 1;
2964  sum = 0;
2965  ts << " Atmosphere Constraint Statistics\n";
2966  double d, ovrl_rms, ovrl_rel, ovrl_trace;
2967  double scale=1.0e12/vLight/24.0;
2968  ovrl_rms = ovrl_trace = ovrl_rel = 0.0;
2969  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
2970  {
2971  SgVlbiStationInfo *si = it_st.value();
2972  if (pwlByName_.contains(si->pZenithDelay()->getName()))
2973  {
2974  pwl = pwlByName_.find(si->pZenithDelay()->getName()).value();
2975 // pwl->calcMeansResids4Sfo(d, v_sig);
2976  d = pwl->calcRateRms4Sfo();
2977 // double sigmaAPriori=pwl->getP_Bi(0)->getSigmaAPriori(); // actual
2978  double sigmaAPriori=pwl->getPOrig()->getSigmaAPriori(); // nominal
2979  ovrl_rms += d;
2980  ovrl_rel += d/sigmaAPriori/sigmaAPriori;
2981  d = sqrt(d/pwl->getNumOfNodes());
2982  ovrl_trace += pwl->trace();
2983  str.sprintf("%3d. %-8s Input %6.2f ps/h RMS %6.2f ps/h NRMS %5.2f share %4.2f count %3d",
2984  idxAux, qPrintable(si->getKey()),
2985  pwl->getPOrig()->getSigmaAPriori()*scale,
2986  d*scale,
2987  d/sigmaAPriori,
2988  pwl->getNumOfNodes()>0?pwl->trace()/pwl->getNumOfNodes():0.0,
2989  pwl->getNumOfNodes());
2990  ts << str << "\n";
2991  idxAux++;
2992  sum += pwl->getNumOfNodes();
2993  };
2994  };
2995  ovrl_rms = sqrt(ovrl_rms/sum);
2996  ovrl_rel = sqrt(ovrl_rel/sum);
2997  str.sprintf(" Overall RMS %6.2f ps/h NRMS %5.2f share %4.2f count %3d",
2998  ovrl_rms*scale,
2999  ovrl_rel,
3000  ovrl_trace/sum,
3001  sum);
3002  ts << str << "\n\n";
3003  };
3004  // clocks:
3006  {
3007  double d, ovrl_rms, ovrl_rel, ovrl_trace;
3008  double scale=1.0e14/86400.0;
3009  ovrl_rms = ovrl_trace = ovrl_rel = 0.0;
3010  idxAux = 1;
3011  sum = 0;
3012  ts << " Clock Constraint Statistics\n";
3013  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3014  {
3015  SgVlbiStationInfo *si = it_st.value();
3016  if (pwlByName_.contains(si->pClock0()->getName()))
3017  {
3018  pwl = pwlByName_.find(si->pClock0()->getName()).value();
3019 // pwl->calcMeansResids4Sfo(d, v_sig);
3020  d = pwl->calcRateRms4Sfo();
3021 // double sigmaAPriori=pwl->getP_Bi(0)->getSigmaAPriori(); // actual
3022  double sigmaAPriori=pwl->getPOrig()->getSigmaAPriori(); // nominal
3023  ovrl_rms += d;
3024  ovrl_rel += d/sigmaAPriori/sigmaAPriori;
3025  d = sqrt(d/pwl->getNumOfNodes());
3026  ovrl_trace += pwl->trace();
3027  str.sprintf("%3d. %-8s Input %6.2f D-14 RMS %6.2f D-14 NRMS %5.2f share %4.2f count %3d",
3028  idxAux, qPrintable(si->getKey()),
3029  pwl->getPOrig()->getSigmaAPriori()*scale,
3030  d*scale,
3031  d/sigmaAPriori,
3032  pwl->getNumOfNodes()>0?pwl->trace()/pwl->getNumOfNodes():0.0,
3033  pwl->getNumOfNodes());
3034  ts << str << "\n";
3035  idxAux++;
3036  sum += pwl->getNumOfNodes();
3037  };
3038  };
3039  ovrl_rms = sqrt(ovrl_rms/sum);
3040  ovrl_rel = sqrt(ovrl_rel/sum);
3041  str.sprintf(" Overall RMS %6.2f D-14 NRMS %5.2f share %4.2f count %3d",
3042  ovrl_rms*scale,
3043  ovrl_rel,
3044  ovrl_trace/sum,
3045  sum);
3046  ts << str << "\n\n";
3047  };
3048  //
3049  // EOPs:
3050  SgParameter *p, *p4erp=NULL;
3051  bool isErpAdjusted(false);
3052  double dUt1=0.0, dPmx=0.0, dPmy=0.0;
3053  double rUt1=0.0, rPmx=0.0, rPmy=0.0;
3054  double sigUt1=0.0, sigPmx=0.0, sigPmy=0.0;
3055  double aprUt1=0.0, aprPmx=0.0, aprPmy=0.0, dt, dd;
3056  double aprCipX=0.0, aprCipY=0.0;
3057  //
3058  // corrections to polar motion, x:
3059  p = session_->pPolusX();
3060  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3061  {
3062  dt = p->getTMean() - erpTref_;
3063  aprPmx = erp_pmx_0_ + erp_pmx_1_*dt + erp_pmx_2_*dt*dt + erp_pmx_3_*dt*dt*dt;
3064  dd = 0.0;
3066  dd = session_->pPolusXRate()->getSolution()*dt;
3067  str.sprintf("%5d. X Wobble 0, %s %12.4f masec %10.2f microasec %10.2f microasec %10.2f microasec",
3068  idx,
3069  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3070  (aprPmx + p->getSolution() + dd)*RAD2SEC*1.0e3,
3071  p->getSolution()*RAD2SEC*1.0e6,
3072  p->getSigma()* RAD2SEC*1.0e6,
3073  p->getSigma()* RAD2SEC*1.0e6*chi
3074  );
3075  ts << str << "\n";
3076  idx++;
3077  isErpAdjusted = true;
3078  p4erp = p;
3079  dPmx = p->getSolution();
3080  sigPmx= p->getSigma();
3081  };
3082  // corrections to polar-x motion rate:
3083  p = session_->pPolusXRate();
3084  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3085  {
3086  dt = p->getTMean() - erpTref_;
3087  str.sprintf("%5d. X Wobble 1, %s %12.4f mas/d %10.2f microas/d %10.2f microas/d %10.2f microas/d",
3088  idx,
3089  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3090  (erp_pmx_1_ + 2.0*erp_pmx_2_*dt + 3.0*erp_pmx_3_*dt*dt + p->getSolution())*RAD2SEC*1.0e3,
3091  p->getSolution()*RAD2SEC*1.0e6,
3092  p->getSigma()* RAD2SEC*1.0e6,
3093  p->getSigma()* RAD2SEC*1.0e6*chi
3094  );
3095  ts << str << "\n";
3096  idx++;
3097  isErpAdjusted = true;
3098  rPmx = p->getSolution();
3099  p4erp = p;
3100  };
3101  //
3102  // corrections to polar-y motion:
3103  p = session_->pPolusY();
3104  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3105  {
3106  dt = p->getTMean() - erpTref_;
3107  aprPmy = erp_pmy_0_ + erp_pmy_1_*dt + erp_pmy_2_*dt*dt + erp_pmy_3_*dt*dt*dt;
3108  dd = 0.0;
3110  dd = session_->pPolusYRate()->getSolution()*dt;
3111  str.sprintf("%5d. Y Wobble 0, %s %12.4f masec %10.2f microasec %10.2f microasec %10.2f microasec",
3112  idx,
3113  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3114  (aprPmy + p->getSolution() + dd)*RAD2SEC*1.0e3,
3115  p->getSolution()*RAD2SEC*1.0e6,
3116  p->getSigma()* RAD2SEC*1.0e6,
3117  p->getSigma()* RAD2SEC*1.0e6*chi
3118  );
3119  ts << str << "\n";
3120  idx++;
3121  isErpAdjusted = true;
3122  p4erp = p;
3123  dPmy = p->getSolution();
3124  sigPmy= p->getSigma();
3125  };
3126  // corrections to polar-y motion rate:
3127  p = session_->pPolusYRate();
3128  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3129  {
3130  dt = p->getTMean() - erpTref_;
3131  str.sprintf("%5d. Y Wobble 1, %s %12.4f mas/d %10.2f microas/d %10.2f microas/d %10.2f microas/d",
3132  idx,
3133  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3134  (erp_pmy_1_ + 2.0*erp_pmy_2_*dt + 3.0*erp_pmy_3_*dt*dt + p->getSolution())*RAD2SEC*1.0e3,
3135  p->getSolution()*RAD2SEC*1.0e6,
3136  p->getSigma()* RAD2SEC*1.0e6,
3137  p->getSigma()* RAD2SEC*1.0e6*chi
3138  );
3139  ts << str << "\n";
3140  idx++;
3141  isErpAdjusted = true;
3142  rPmy = p->getSolution();
3143  p4erp = p;
3144  };
3145  //
3146  // corrections to UT1:
3147  p = session_->pUT1();
3148  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3149  {
3150  dt = p->getTMean() - erpTref_;
3151  aprUt1 = erp_ut1_0_ + erp_ut1_1_*dt + erp_ut1_2_*dt*dt + erp_ut1_3_*dt*dt*dt;
3152  dd = 0.0;
3154  dd = session_->pUT1Rate()->getSolution()*dt;
3155  str.sprintf("%5d. UT1-TAI 0, %s %12.4f msec %10.2f microsec %11.2f microsec %11.2f microsec",
3156  idx,
3157  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3158  (aprUt1 + p->getSolution() + dd)*DAY2SEC*1.0e3,
3159  p->getSolution()*DAY2SEC*1.0e6,
3160  p->getSigma()* DAY2SEC*1.0e6,
3161  p->getSigma()* DAY2SEC*1.0e6*chi);
3162  ts << str << "\n";
3163  idx++;
3164  isErpAdjusted = true;
3165  p4erp = p;
3166  dUt1 = p->getSolution();
3167  sigUt1= p->getSigma();
3168  //
3169  dUt1Value_ = aprUt1 + p->getSolution() + dd;
3171  dUt1StdDev_ = p->getSigma();
3172  //
3173  };
3174  // corrections to UT1 rate:
3175  p = session_->pUT1Rate();
3176  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3177  {
3178  dt = p->getTMean() - erpTref_;
3179  // progs/solve/adjst/a2jst_segeop.f ?
3180  str.sprintf("%5d. UT1-TAI 1, %s %12.4f ms/d %10.2f micros/d %11.2f micros/d %11.2f micros/d",
3181  idx,
3182  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3183  (erp_ut1_1_ + 2.0*erp_ut1_2_*dt + 3.0*erp_ut1_3_*dt*dt + p->getSolution())*DAY2SEC*1.0e3,
3184  p->getSolution()*DAY2SEC*1.0e6,
3185  p->getSigma()* DAY2SEC*1.0e6,
3186  p->getSigma()* DAY2SEC*1.0e6*chi
3187  );
3188  ts << str << "\n";
3189  idx++;
3190  isErpAdjusted = true;
3191  rUt1 = p->getSolution();
3192  p4erp = p;
3193  };
3194  if (isErpAdjusted && p4erp)
3195  {
3196  dt = p4erp->getTMean() - erpTref_;
3197  ts
3198 // << " EOP with included hi-freq variations (a-sigmas) \n"
3199  << " EOP without included hi-freq variations (a-sigmas) \n"
3200  << " XWOB YWOB UT1-TAI"
3201  << " XSIG YSIG USIG\n"
3202  << " mas mas ms "
3203  << " microasec microasec microsec\n";
3204 // str.sprintf("%s 0.0000 0.0000 0.0000 0.00 0.00 0.00",
3205  str.sprintf("%s %12.4f %12.4f %12.4f %11.2f %11.2f %11.2f",
3206  qPrintable(p4erp->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3207  (aprPmx + rPmx*dt + dPmx)*RAD2SEC*1.0e3,
3208  (aprPmy + rPmy*dt + dPmy)*RAD2SEC*1.0e3,
3209  (aprUt1 + rUt1*dt + dUt1)*DAY2SEC*1.0e3,
3210  sigPmx*RAD2SEC*1.0e6,
3211  sigPmy*RAD2SEC*1.0e6,
3212  sigUt1*DAY2SEC*1.0e6);
3213  ts << str << "\n" << "\n";
3214  };
3215  //
3216 //------------------------------------------------------------------------------------------------------
3217  // Nutation:
3220  {
3221  p = session_->pNutX();
3222  SgMJD epoch(p->getTMean());
3223  // conver UTC to TT, cheap'n'angry:
3224  epoch += (session_->getLeapSeconds() + 32.184)/DAY2SEC;
3225  //
3226  dt = p->getTMean() - erpTref_;
3227  aprCipX = eop_cix_0_ + eop_cix_1_*dt + eop_cix_2_*dt*dt + eop_cix_3_*dt*dt*dt;
3228  aprCipY = eop_ciy_0_ + eop_ciy_1_*dt + eop_ciy_2_*dt*dt + eop_ciy_3_*dt*dt*dt;
3229  //
3230  double dX, dY, dPsi, dEps;
3231  double dX_sigma, dY_sigma, dPsi_sigma, dEps_sigma;
3232  if (session_->hasCipPartials())
3233  {
3234  dX = session_->pNutX()->getSolution() + aprCipX;
3235  dX_sigma = session_->pNutX()->getSigma();
3236  dY = session_->pNutY()->getSolution() + aprCipY;
3237  dY_sigma = session_->pNutY()->getSigma();
3238 
3239  dPsi = dX/sin(84381.4059*SEC2RAD);
3240  dPsi_sigma = dX_sigma/sin(84381.4059*SEC2RAD);
3241  dEps = dY;
3242  dEps_sigma = dY_sigma;
3243  }
3244  else
3245  {
3246  dPsi = session_->pNutX()->getSolution();
3247  dPsi_sigma = session_->pNutX()->getSigma();
3248  dEps = session_->pNutY()->getSolution();
3249  dEps_sigma = session_->pNutY()->getSigma();
3250 
3251  dX = dPsi*sin(84381.4059*SEC2RAD) + aprCipX;
3252  dX_sigma = dPsi_sigma*sin(84381.4059*SEC2RAD);
3253  dY = dEps + aprCipY;
3254  dY_sigma = dEps_sigma;
3255  };
3256  double psiEst2Wahr=0.0, epsEst2Wahr=0.0;
3257  SgVlbiObservation *obs=session_->observations().at(0);
3258  if (obs)
3259  {
3260  calcCip2IAU1980(epoch, dX, dY,
3263  psiEst2Wahr, epsEst2Wahr);
3264  };
3265 
3266  // corrections to Celestial intermediate pole, x:
3267  p = session_->pNutX();
3268  str.sprintf(" EOP epoch (TT) MJD: %12.6f NUT epoch (TT) MJD: %12.6f",
3269  epoch.toDouble(), epoch.toDouble());
3270  ts << str << "\n";
3271  str.sprintf("%5d. Nutation offset in longitude (Psi) %14.3f mas %10.1f microasec"
3272  " %10.1f microasec ",
3273  idx,
3274  dPsi *RAD2SEC*1.0e3,
3275  dPsi_sigma*RAD2SEC*1.0e6,
3276  dPsi_sigma*RAD2SEC*1.0e6*chi
3277  );
3278  ts << str << "\n";
3279  idx++;
3280  str.sprintf(" Nutation offset around X-axis (dX) %14.3f mas %10.1f "
3281  "microasec %10.1f microasec ",
3282  dX *RAD2SEC*1.0e3,
3283  dX_sigma*RAD2SEC*1.0e6,
3284  dX_sigma*RAD2SEC*1.0e6*chi
3285  );
3286  ts << str << "\n";
3287  str.sprintf(" Nutation offset wrt IAU 1980 model (Psi) %14.3f mas %10.1f "
3288  "microasec %10.1f microasec ",
3289 // (dPsi + psiEst2Wahr)*RAD2SEC*1.0e3,
3290  psiEst2Wahr *RAD2SEC*1.0e3,
3291  dPsi_sigma *RAD2SEC*1.0e6,
3292  dPsi_sigma *RAD2SEC*1.0e6*chi
3293  );
3294  ts << str << "\n";
3295  // corrections to Celestial intermediate pole, y:
3296  p = session_->pNutY();
3297  str.sprintf("%5d. Nutation offset in obliquity (Eps) %14.3f mas %10.1f "
3298  "microasec %10.1f microasec ",
3299  idx,
3300  dEps *RAD2SEC*1.0e3,
3301  dEps_sigma*RAD2SEC*1.0e6,
3302  dEps_sigma*RAD2SEC*1.0e6*chi
3303  );
3304  ts << str << "\n";
3305  idx++;
3306  str.sprintf(" Nutation offset around Y-axis (dY) %14.3f mas "
3307  "%10.1f microasec %10.1f microasec ",
3308  dY *RAD2SEC*1.0e3,
3309  dY_sigma*RAD2SEC*1.0e6,
3310  dY_sigma*RAD2SEC*1.0e6*chi
3311  );
3312  ts << str << "\n";
3313  str.sprintf(" Nutation offset wrt IAU 1980 model (Eps) %14.3f mas "
3314  "%10.1f microasec %10.1f microasec ",
3315 // (dEps + epsEst2Wahr)*RAD2SEC*1.0e3,
3316  epsEst2Wahr *RAD2SEC*1.0e3,
3317  dEps_sigma *RAD2SEC*1.0e6,
3318  dEps_sigma *RAD2SEC*1.0e6*chi
3319  );
3320  ts << str << "\n";
3321  };//---------------------------------------------------------------------------------------------------
3322 
3323  // Baselines, clocks:
3325  {
3326  ts << "\n";
3327  BaselinesByName_it it_bl;
3328  for (it_bl=session_->baselinesByName().begin(); it_bl!=session_->baselinesByName().end(); ++it_bl)
3329  {
3330  SgVlbiBaselineInfo *bi=it_bl.value();
3331  QString blName;
3332  blName = bi->getKey();
3333  blName.replace(8, 1, "-");
3335  {
3336  str.sprintf("%5d. %-17s Clock offset "
3337  "%12.3f ps %9.3f ps %9.3f ps",
3338  idx, qPrintable(blName),
3339  bi->pClock()->getSolution()*1.0E12,
3340  bi->pClock()->getSigma() *1.0E12,
3341  bi->pClock()->getSigma() *1.0E12*chi );
3342  ts << str << "\n";
3343  idx++;
3344  };
3345  };
3346  };
3347  // Baselines, baseline vector:
3349  {
3350  ts << "\n";
3351  BaselinesByName_it it_bl;
3352  for (it_bl=session_->baselinesByName().begin(); it_bl!=session_->baselinesByName().end(); ++it_bl)
3353  {
3354  SgVlbiBaselineInfo *bi=it_bl.value();
3355  QString blName;
3356  blName = bi->getKey();
3357  blName.replace(8, 1, "-");
3358  // baseline vector:
3360  {
3361  SgVlbiStationInfo *s1, *s2;
3362  if (session_->stationsByName().contains(bi->getKey().mid(0,8)))
3363  s1 = session_->stationsByName().value(bi->getKey().mid(0,8));
3364  else
3365  s1 = NULL;
3366  if (session_->stationsByName().contains(bi->getKey().mid(9,8)))
3367  s2 = session_->stationsByName().value(bi->getKey().mid(9,8));
3368  else
3369  s2 = NULL;
3370  if (s1 && s2)
3371  {
3372  // covariances (i.e., rho_{1,2}*sigma_1*sigma_2):
3373  double cXY, cXZ, cYZ;
3374  cXY = PxAll_->getElement(bi->pBx()->getIdx(), bi->pBy()->getIdx());
3375  cXZ = PxAll_->getElement(bi->pBx()->getIdx(), bi->pBz()->getIdx());
3376  cYZ = PxAll_->getElement(bi->pBy()->getIdx(), bi->pBz()->getIdx());
3377  Sg3dVector b, b_apriori;
3378  b_apriori = (s2->getR() - s1->getR());
3380  {
3381  SgMJD t(bi->pBx()->getTMean());
3382  b_apriori = s2->getR_ea() - s1->getR_ea() +
3383  (s2->getV_ea() - s1->getV_ea())*(t - session_->getApStationVelocities().getT0());
3384  };
3385  b = b_apriori +
3386  Sg3dVector(bi->pBx()->getSolution(), bi->pBy()->getSolution(), bi->pBz()->getSolution());
3387  double l, lSigma;
3388  double x2, y2, z2, sigX2, sigY2, sigZ2;
3389  x2 = b.at(X_AXIS)*b.at(X_AXIS);
3390  y2 = b.at(Y_AXIS)*b.at(Y_AXIS);
3391  z2 = b.at(Z_AXIS)*b.at(Z_AXIS);
3392  sigX2 = bi->pBx()->getSigma()*bi->pBx()->getSigma();
3393  sigY2 = bi->pBy()->getSigma()*bi->pBy()->getSigma();
3394  sigZ2 = bi->pBz()->getSigma()*bi->pBz()->getSigma();
3395  l = b.module();
3396  lSigma = x2*sigX2 + y2*sigY2 + z2*sigZ2 +
3397  2.0*( b.at(X_AXIS)*b.at(Y_AXIS)*cXY +
3398  b.at(X_AXIS)*b.at(Z_AXIS)*cXZ +
3399  b.at(Y_AXIS)*b.at(Z_AXIS)*cYZ );
3400  lSigma = sqrt(lSigma)/l;
3401  // sigma of latitude:
3402  double phiSigma, a2, l4;
3403  a2 = x2 + y2;
3404  l4 = l*l*l*l;
3405  phiSigma = (x2*z2*sigX2 + y2*z2*sigY2 + a2*a2*sigZ2 +
3406  2.0*(b.at(X_AXIS)*b.at(Y_AXIS)*z2*cXY -
3407  a2*(b.at(X_AXIS)*b.at(Z_AXIS)*cXZ + b.at(Y_AXIS)*b.at(Z_AXIS)*cYZ)) )/l4/a2;
3408  phiSigma = sqrt(phiSigma);
3409  // sigma of longitude:
3410  double lambdaSigma;
3411  lambdaSigma = (y2*sigX2 + x2*sigY2 - 2.0*b.at(X_AXIS)*b.at(Y_AXIS)*cXY)/a2/a2;
3412  lambdaSigma = sqrt(lambdaSigma);
3413 
3414  str.sprintf("%5d. %-17s X Comp %15.2f mm %14.3f mm "
3415  "%14.3f mm %14.3f mm",
3416  idx, qPrintable(blName),
3417  b.at(X_AXIS) *1000.0,
3418  bi->pBx()->getSolution()*1000.0,
3419  bi->pBx()->getSigma() *1000.0,
3420  bi->pBx()->getSigma() *1000.0*chi );
3421  ts << str << "\n";
3422  idx++;
3423  str.sprintf("%5d. %-17s Y Comp %15.2f mm %14.3f mm "
3424  "%14.3f mm %14.3f mm",
3425  idx, qPrintable(blName),
3426  b.at(Y_AXIS) *1000.0,
3427  bi->pBy()->getSolution()*1000.0,
3428  bi->pBy()->getSigma() *1000.0,
3429  bi->pBy()->getSigma() *1000.0*chi );
3430  ts << str << "\n";
3431  idx++;
3432  str.sprintf("%5d. %-17s Z Comp %15.2f mm %14.3f mm "
3433  "%14.3f mm %14.3f mm",
3434  idx, qPrintable(blName),
3435  b.at(Z_AXIS) *1000.0,
3436  bi->pBz()->getSolution()*1000.0,
3437  bi->pBz()->getSigma() *1000.0,
3438  bi->pBz()->getSigma() *1000.0*chi );
3439  ts << str << "\n";
3440  idx++;
3441  // length
3442  str.sprintf(" %-17s length %15.2f mm %14.3f mm "
3443  "%14.3f mm %14.3f mm",
3444  qPrintable(blName),
3445  l *1000.0,
3446  (l - b_apriori.module())*1000.0,
3447  lSigma *1000.0,
3448  lSigma *1000.0*chi );
3449  ts << str << "\n";
3450  // latitude
3451  str.sprintf(" %-17s latitude %15.2f deg %13.3f mas "
3452  "%14.3f mas %14.3f mas",
3453  qPrintable(blName),
3454  b.phi() *RAD2DEG,
3455  (b.phi() - b_apriori.phi())*RAD2MAS,
3456  phiSigma *RAD2MAS,
3457  phiSigma *RAD2MAS*chi );
3458  ts << str << "\n";
3459  // longitude
3460  str.sprintf(" %-17s longitude %15.2f deg %13.3f mas "
3461  "%14.3f mas %14.3f mas",
3462  qPrintable(blName),
3463  b.lambda() *RAD2DEG,
3464  (b.lambda() - b_apriori.lambda()) *RAD2MAS,
3465  lambdaSigma *RAD2MAS,
3466  lambdaSigma *RAD2MAS*chi );
3467  ts << str << "\n";
3468  }
3469  else
3471  "::reportEstimationBlock_Output4Spoolfile(): a station pointer is NULL");
3472  };
3473  };
3474  };
3475  //
3476  //
3477  if (numOfConstraints_ || pwlList_.size())
3478  {
3479  ts
3480  << " \n"
3481  << " General constraints usage information: "
3482  << " \n"
3483  << " \n";
3484  str.sprintf(" 1) CLO_RATE \"Clock rate between segments \" sigma %10.3E 10^-14 sec/sec",
3487  /86400.0*1.0e14);
3488  ts << str << "\n";
3489  str.sprintf(" 2) ATM_RATE \"Atmosphere rate between segments\" sigma %10.3E psec/hr",
3492  /vLight/24.0*1.0e12);
3493  ts << str << "\n \n";
3494  }
3495  else
3496  ts << " No constraints have been imposed\n \n";
3497 
3498  str.sprintf(" Corrected Reduced Chi-Square %8.4f",
3499 // session_->primaryBand()->getChi2()/session_->primaryBand()->getNumOfDOF());
3500 // activeBand_->chi2(dType)/session_->getNumOfDOF());
3501  activeBand_->reducedChi2(dType));
3502  ts << str << "\n\n";
3503 };
3504 
3505 
3506 
3507 //
3508 bool SgSolutionReporter::reportAtmo(const QString& path, const QString& fileName)
3509 {
3510  // emulates SOLVE output:
3511  // ATMO<U.I.>
3512  QFile f(path + "/" + fileName);
3513  if (!f.open(QIODevice::WriteOnly))
3514  {
3516  "::reportAtmo(): error opening output file: " + path + "/" + fileName);
3517  return false;
3518  };
3519  //
3520  // check data type (it should be equidistant):
3521  int num;
3522  bool isOk;
3523  SgMJD t_i;
3524  double step;
3525  num = -1;
3526  step = -1.0;
3527  isOk = true;
3528  StationsByName_it it_st;
3529  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3530  if (isOk)
3531  {
3532  SgVlbiStationInfo *si = it_st.value();
3534  pwlByName_.contains(si->pZenithDelay()->getName()))
3535  {
3536  SgPwlStorage *pwl = pwlByName_.find(si->pZenithDelay()->getName()).value();
3537  if (num==-1 && pwl->getNumOfSegments()>0)
3538  {
3539  num = pwl->getNumOfSegments();
3540  t_i = pwl->tStart();
3541  step = pwl->step();
3542  }
3543  else if (num==-1 && pwl->getNumOfSegments()<=0)
3544  {
3546  "::reportAtmo(): cannot report PWL zenith delays, the number of parameteres less than 1");
3547  isOk = false;
3548  }
3549  else if (num != pwl->getNumOfSegments())
3550  {
3552  "::reportAtmo(): cannot report PWL zenith delays, non-equal number of parameters");
3553  isOk = false;
3554  }
3555  else if (step != pwl->step())
3556  {
3558  "::reportAtmo(): cannot report PWL zenith delays, non-equidistant steps");
3559  isOk = false;
3560  };
3561  }
3563  {
3565  "::reportAtmo(): cannot report PWL zenith delays, missed station" + si->getKey());
3566  isOk = false;
3567  };
3568  };
3569  if (!isOk)
3570  return false;
3571  //
3572  // make output:
3573  QTextStream ts(&f);
3574  QString str;
3575  ts << " yr mn dy hr min Julian Date ";
3576  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3577  ts << str.sprintf("%-8s ", qPrintable(it_st.value()->getKey()));
3578  ts << "\n ";
3579  for (int i=0; i<session_->stationsByName().size(); i++)
3580  ts << "offset sigma ";
3581  ts << "\n ";
3582  for (int i=0; i<session_->stationsByName().size(); i++)
3583  ts << " ps ps ";
3584  ts << "\n";
3585  for (int idx=0; idx<num+1; idx++)
3586  {
3587  int yr, mn, dy, hr, mi;
3588  double sc;
3589  SgMJD::MJD_reverse(t_i.getDate(), t_i.getTime(), yr, mn, dy, hr, mi, sc);
3590  mi = (60*mi + sc)/60;
3591  yr -= (yr/100)*100;
3592  str.sprintf(" %2d %2d %2d %2d %2d %.5f",
3593  yr, mn, dy, hr, mi, t_i.toDouble() + 2400000.5);
3594  ts << str;
3595  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3596  {
3597  SgVlbiStationInfo *si = it_st.value();
3599  {
3600  SgPwlStorage *pwl = pwlByName_.find(si->pZenithDelay()->getName()).value();
3601 // SgParameter *pB = pwl->getP_Bi(idx);
3602  ts << str.sprintf(" %14.0f %5.0f",
3603 // (si->getEstWetZenithDelay() + pwl->calcPolySolution(t_i) + pB->getSolution())/vLight*1.0e12,
3604  ( si->getEstWetZenithDelay() +
3605  pwl->calcPolySolution(t_i) +
3606  pwl->calcRateSolution(t_i) )/vLight*1.0e12,
3607 // pB->getSigma()/vLight*1.0e12);
3608  pwl->calcRateSigma(t_i)/vLight*1.0e12);
3609  }
3610  else
3611  ts << " 0 0";
3612  };
3613  ts << "\n";
3614  t_i += step;
3615  };
3616  // close the file:
3617  ts.setDevice(NULL);
3618  f.close();
3619  return true;
3620 };
3621 
3622 
3623 
3624 //
3625 bool SgSolutionReporter::reportCloc(const QString& path, const QString& fileName)
3626 {
3627  // emulates SOLVE output:
3628  // CLOC<U.I.>
3629  QFile f(path + "/" + fileName);
3630  if (!f.open(QIODevice::WriteOnly))
3631  {
3633  "::reportCloc(): error opening output file: " + path + "/" + fileName);
3634  return false;
3635  };
3636  //
3637  // check data type (it should be equidistant):
3638  int num;
3639  bool isOk;
3640  SgMJD t_i;
3641  double step;
3642  num = -1;
3643  step = -1.0;
3644  isOk = true;
3645  StationsByName_it it_st;
3646  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3647  if (isOk)
3648  {
3649  SgVlbiStationInfo *si = it_st.value();
3651  pwlByName_.contains(si->pClock0()->getName()))
3652  {
3653  SgPwlStorage *pwl = pwlByName_.find(si->pClock0()->getName()).value();
3654  if (num==-1 && pwl->getNumOfSegments()>0)
3655  {
3656  num = pwl->getNumOfSegments();
3657  t_i = pwl->tStart();
3658  step = pwl->step();
3659  }
3660  else if (num==-1 && pwl->getNumOfSegments()<=0)
3661  {
3663  "::reportCloc(): cannot report PWL clocks, the number of parameteres less than 1");
3664  isOk = false;
3665  }
3666  else if (num != pwl->getNumOfSegments())
3667  {
3669  "::reportCloc(): cannot report PWL clocks, non-equal number of parameters");
3670  isOk = false;
3671  }
3672  else if (step != pwl->step())
3673  {
3675  "::reportCloc(): cannot report PWL clocks, non-equidistant steps");
3676  isOk = false;
3677  };
3678  }
3681  {
3683  "::reportCloc(): cannot report PWL clocks, missed station " + si->getKey());
3684  isOk = false;
3685  };
3686  };
3687  if (!isOk)
3688  return false;
3689  //
3690  // make output:
3691  QTextStream ts(&f);
3692  QString str;
3693  ts << " yr mn dy hr min Julian Date ";
3694  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3695  ts << str.sprintf("%-8s ", qPrintable(it_st.value()->getKey()));
3696  ts << "\n ";
3697  for (int i=0; i<session_->stationsByName().size(); i++)
3698  ts << "offset sigma ";
3699  ts << "\n ";
3700  for (int i=0; i<session_->stationsByName().size(); i++)
3701  ts << " ps ps ";
3702  ts << "\n";
3703  for (int idx=0; idx<num+1; idx++)
3704  {
3705  int yr, mn, dy, hr, mi;
3706  double sc;
3707  SgMJD::MJD_reverse(t_i.getDate(), t_i.getTime(), yr, mn, dy, hr, mi, sc);
3708  mi = (60*mi + sc)/60;
3709  yr -= (yr/100)*100;
3710  str.sprintf(" %2d %2d %2d %2d %2d %.5f",
3711  yr, mn, dy, hr, mi, t_i.toDouble() + 2400000.5);
3712  ts << str;
3713  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3714  {
3715  SgVlbiStationInfo *si = it_st.value();
3718  {
3719  SgPwlStorage *pwl = pwlByName_.find(si->pClock0()->getName()).value();
3720  ts << str.sprintf(" %14.0f %5.0f",
3721  pwl->calcRateSolution(t_i)*1.0e12,
3722  pwl->calcRateSigma(t_i)*1.0e12);
3723  }
3724  else
3725  ts << " 0 0";
3726  };
3727  ts << "\n";
3728  t_i += step;
3729  };
3730  // close the file:
3731  ts.setDevice(NULL);
3732  f.close();
3733  return true;
3734 };
3735 
3736 
3737 
3738 //
3739 bool SgSolutionReporter::reportPall(const QString& path, const QString& fileName)
3740 {
3741  // emulates SOLVE output:
3742  // CLOC<U.I.>
3743  QFile f(path + "/" + fileName);
3744  if (!f.open(QIODevice::WriteOnly))
3745  {
3747  "::reportPall(): error opening the output file: " + path + "/" + fileName);
3748  return false;
3749  };
3750 
3751  //
3752  // make output:
3753  QTextStream ts(&f);
3754  QString str;
3755 
3756  ts << allParList_.size() << " parameters in the list\n";
3757  for (int i=0; i<allParList_.size(); i++)
3758  ts << str.sprintf("%4d ", i) << allParList_.at(i)->getName() << "\n";
3759 
3760  ts << "\n" << PxAll_->nRow() << " elements in a row of the covariance matrix\n";
3761  for (unsigned int i=0; i<PxAll_->nRow(); i++)
3762  for (unsigned int j=i; j<PxAll_->nCol(); j++)
3763  ts << str.sprintf("%4d %4d %22.15E", i, j, PxAll_->getElement(i, j)) << "\n";
3764 
3765  // close the file:
3766  ts.setDevice(NULL);
3767  f.close();
3768  return true;
3769 };
3770 
3771 
3772 
3773 //
3774 bool SgSolutionReporter::reportNotUsedObs(const QString& path, const QString& fileName)
3775 {
3776  QFile f(path + "/" + fileName);
3777  if (!f.open(QIODevice::WriteOnly))
3778  {
3780  "::reportNotUsedObs(): error opening output file: " + path + "/" + fileName);
3781  return false;
3782  };
3783  //
3784  QTextStream ts(&f);
3785 
3786 // reportDeselectedObsBlock_Output4Spoolfile(ts);
3787 // reportDeselectedObsBlock_Output4Spoolfile_v2(ts);
3789 
3790  // close the file:
3791  ts.setDevice(NULL);
3792  f.close();
3793  return true;
3794 };
3795 
3796 
3797 
3798 //
3800 {
3801  QString str;
3802  int n;
3803  SgMJD t(session_->tRefer());
3804 
3807  return;
3808 
3809  ts
3810  << "1 Baseline information for run " << qPrintable(reportID_) << "\n"
3811  << " Monument to monument values at epoch "
3812  << qPrintable(t.toString(SgMJD::F_YYYYMonDD)) << "\n"
3813  << " Baseline vector components: Length, Vertical and Transverse components\n"
3814  << " Vector mag c-sigma Length c-sigma "
3815  << "Horizontal c-sigma Vertical c-sigma\n"
3816  << " (mm) (mm) (mm) (mm)"
3817  << " (mm) (mm) (mm) (mm)\n";
3818  //
3820  {
3821  // stations:
3822  QList<SgVlbiStationInfo*> stations;
3823  for (StationsByName_it it=session_->stationsByName().begin(); it!=session_->stationsByName().end();
3824  ++it)
3825  if (!it.value()->isAttr(SgVlbiStationInfo::Attr_NOT_VALID))
3826  stations << it.value();
3827  //
3828  n = stations.size();
3829  for (int i=0; i<n; i++)
3830  for (int j=i+1; j<n; j++)
3831  {
3832  SgVlbiStationInfo *si=stations.at(i);
3833  SgVlbiStationInfo *sj=stations.at(j);
3834  bool isSi, isSj;
3835  isSi = si->pRx()->isAttr(SgParameter::Attr_IS_SOLVED);
3836  isSj = sj->pRx()->isAttr(SgParameter::Attr_IS_SOLVED);
3837  if (isSi || isSj)
3838  {
3839  Sg3dVector dr_i, dr_j;
3840  Sg3dVector ri_apriori(si->getR());
3841  Sg3dVector rj_apriori(sj->getR());
3842  Sg3dVector lhv, lhvSigma;
3843  double length, lengthSigma;
3844  if (isSi)
3845  dr_i = Sg3dVector(si->pRx()->getSolution(), si->pRy()->getSolution(),
3846  si->pRz()->getSolution());
3847  if (isSj)
3848  dr_j = Sg3dVector(sj->pRx()->getSolution(), sj->pRy()->getSolution(),
3849  sj->pRz()->getSolution());
3851  {
3852  ri_apriori = si->getR_ea() + si->getV_ea()*(t - session_->getApStationVelocities().getT0());
3853  rj_apriori = sj->getR_ea() + sj->getV_ea()*(t - session_->getApStationVelocities().getT0());
3854  };
3855  SgMatrix mA(6, 6);
3856  int idxs[6];
3857  if (isSi)
3858  {
3859  idxs[0] = si->pRx()->getIdx();
3860  idxs[1] = si->pRy()->getIdx();
3861  idxs[2] = si->pRz()->getIdx();
3862  }
3863  else
3864  idxs[0] = idxs[1] = idxs[2] = -1;
3865  if (isSj)
3866  {
3867  idxs[3] = sj->pRx()->getIdx();
3868  idxs[4] = sj->pRy()->getIdx();
3869  idxs[5] = sj->pRz()->getIdx();
3870  }
3871  else
3872  idxs[3] = idxs[4] = idxs[5] = -1;
3873  //
3874  for (int l=0; l<6; l++)
3875  for (int m=0; m<6; m++)
3876  if (idxs[l]>=0 && idxs[m]>=0)
3877  mA.setElement(l,m, PxAll_->getElement(idxs[l], idxs[m]));
3878  //
3879  calcLhv(ri_apriori, dr_i, rj_apriori, dr_j, mA, lhv, lhvSigma, length, lengthSigma);
3880  str.sprintf(" %-8s %04d to %-8s %04d %14.2f %6.2f %14.2f %6.2f %9.2f %6.2f"
3881  " %9.2f %6.2f",
3882  qPrintable(si->getKey()), si->getCdpNumber(),
3883  qPrintable(sj->getKey()), sj->getCdpNumber(),
3884  length*1000.0, lengthSigma*1000.0,
3885  lhv.at(X_AXIS)*1000.0, lhvSigma.at(X_AXIS)*1000.0,
3886  lhv.at(Y_AXIS)*1000.0, lhvSigma.at(Y_AXIS)*1000.0,
3887  lhv.at(Z_AXIS)*1000.0, lhvSigma.at(Z_AXIS)*1000.0);
3888 // ts << str << "\n";
3889  ts << str << " " << qPrintable(session_->getTMean().toString(SgMJD::F_Simple)) << "\n";
3890  };
3891  };
3892  }
3894  {
3895  // baselines:
3896  QList<SgVlbiBaselineInfo*> baselines;
3897  for (BaselinesByName_it it=session_->baselinesByName().begin();
3898  it!=session_->baselinesByName().end(); ++it)
3899  if (!it.value()->isAttr(SgVlbiStationInfo::Attr_NOT_VALID))
3900  baselines << it.value();
3901  //
3902  n = baselines.size();
3903  for (int i=0; i<n; i++)
3904  {
3905  SgVlbiBaselineInfo *bl=baselines.at(i);
3908 
3909  Sg3dVector db;
3910  Sg3dVector ri_apriori(si->getR());
3911  Sg3dVector rj_apriori(sj->getR());
3912  Sg3dVector lhv, lhvSigma;
3913  double length, lengthSigma;
3914 
3915  db = Sg3dVector(bl->pBx()->getSolution(), bl->pBy()->getSolution(), bl->pBz()->getSolution());
3917  {
3918  ri_apriori = si->getR_ea() + si->getV_ea()*(t - session_->getApStationVelocities().getT0());
3919  rj_apriori = sj->getR_ea() + sj->getV_ea()*(t - session_->getApStationVelocities().getT0());
3920  };
3921  SgMatrix mA(3, 3);
3922  int idxs[3];
3923  idxs[0] = bl->pBx()->getIdx();
3924  idxs[1] = bl->pBy()->getIdx();
3925  idxs[2] = bl->pBz()->getIdx();
3926  //
3927  for (int l=0; l<3; l++)
3928  for (int m=0; m<3; m++)
3929  mA.setElement(l,m, PxAll_->getElement(idxs[l], idxs[m]));
3930  //
3931  calcLhv(ri_apriori, rj_apriori, db, mA, lhv, lhvSigma, length, lengthSigma);
3932  str.sprintf(" %-8s %04d to %-8s %04d %14.2f %6.2f %14.2f %6.2f %9.2f %6.2f"
3933  " %9.2f %6.2f",
3934  qPrintable(si->getKey()), si->getCdpNumber(),
3935  qPrintable(sj->getKey()), sj->getCdpNumber(),
3936  length*1000.0, lengthSigma*1000.0,
3937  lhv.at(X_AXIS)*1000.0, lhvSigma.at(X_AXIS)*1000.0,
3938  lhv.at(Y_AXIS)*1000.0, lhvSigma.at(Y_AXIS)*1000.0,
3939  lhv.at(Z_AXIS)*1000.0, lhvSigma.at(Z_AXIS)*1000.0);
3940  ts << str << " " << qPrintable(bl->pBx()->getTMean().toString(SgMJD::F_Simple)) << "\n";
3941  };
3942  };
3943  //
3944  ts
3945  << "--\n"
3946  << "Note: a posteriori baseline vectors are expressed in a baseline-centric reference frames. "
3947  << "The first basis vector of the\nframe, l, is in direction of a priori baseline, (r_2 - r_1). "
3948  << "Direction of the second vector, h, is defined by a cross\nproduct of a priori baseline vector "
3949  << "and a priori geocentric vector of the 2nd station. The last basis vector, v, is\nperpendicular "
3950  << "to the vectors l and h and is radially inward at the center of the baseline. For the short "
3951  << "baselines, the\nvectors l and h are close to the horizontal plane and v is almost vertical "
3952  << "(with opposite sign). In the table above the\ncolumns are:\n * Vector mag: length of the a "
3953  << "posteriori baseline;\n * Length: l-component of the baseline;\n * Horizontal: "
3954  << "h-component of the baseline;\n * Vertical: v-component of the baseline;\n * c-sigma: "
3955  << "calculated (using standard deviations of adjusted station coordinates of baselines) standard "
3956  << "deviations\n of the corresponding values.\n\n";
3957 };
3958 
3959 
3960 
3961 //
3963 {
3964  QList<SgVlbiObservation*> excludedObs, unusableObs, includedObs, allObs;
3965  int outputVersion;
3966 
3967  outputVersion = activeBand_?activeBand_->getInputFileVersion()+1:1;
3968 
3969  for (int i=0; i<session_->observations().size(); i++)
3970  {
3971  SgVlbiObservation *obs=session_->observations().at(i);
3972  if (obs->activeObs() && !obs->activeObs()->isUsable())
3973  unusableObs << obs;
3974  else if (obs->isAttr(SgVlbiObservation::Attr_NOT_VALID) &&
3975  obs->activeObs() && obs->activeObs()->isUsable() )
3976  excludedObs << obs;
3977  else
3978  includedObs << obs;
3979  };
3980  //
3981  if (excludedObs.size() + unusableObs.size() + includedObs.size() == 0)
3982  {
3983  ts << "No observations are in the solution.\n";
3985  "::reportDeselectedObsBlock_Output4Spoolfile(): no obs to report");
3986  return;
3987  };
3988  //
3989  // reorder the observations:
3990  for (int idx=0; idx<unusableObs.size(); idx++)
3991  allObs << unusableObs.at(idx);
3992  for (int idx=0; idx<excludedObs.size(); idx++)
3993  allObs << excludedObs.at(idx);
3994  for (int idx=0; idx<includedObs.size(); idx++)
3995  allObs << includedObs.at(idx);
3996  //
3997  //
3998  ts << "# Status of observations of the solution of the Run " << reportID_ << "\n";
3999  ts << "# Session " << session_->getOfficialName() << "/" << session_->getSessionCode()
4000  << " database " << session_->getName() << " version " << outputVersion << "\n";
4001  ts << "# First column: a status flag:\n";
4002  ts << "# u - the observation is unusable: either missed data on one of the bands,\n";
4003  ts << "# low quality code, deselected baseline, station or sources.\n";
4004  ts << "# e - excluded observation, explicitly excluded observation either by user\n";
4005  ts << "# or by the software (due to a high residual or not so good quality factor).\n";
4006  ts << "# i - the observation was included in the solution.\n";
4007  ts << "# Second column: index in a database or other media.\n";
4008  ts << "# Third column: time of observation.\n";
4009  ts << "# Forth and fifth columns: quality code (QC) for S- and X-bands. The char `-' means\n";
4010  ts << "# no data on the band.\n";
4011  ts << "# Sixth and seventh columns: fourfit error code (EC) for S- and X-bands. The char `-' means\n";
4012  ts << "# no data on the band, the char '.' means no fourfit error code for the observation.\n";
4013  ts << "# Eighth and ninth columns: SNR on the S- and X-bands.\n";
4014  ts << "# Tenth and eleventh columns: number of used channels on the S- and X-bands.\n";
4015  ts << "# Twelveth and thirteenth columns: baseline and source names.\n";
4016  ts << "# The last three columns: residual and applied standard deviation (ps) and\n";
4017  ts << "# normalized residual (unitless).\n";
4018  ts << "#\n";
4019  ts << "# QC EC SNR SNR NumChan\n";
4020  ts << "# __N__ __Time__ S X S X S X S X ____Baseline_____ _Source_ Resid.(ps) ";
4021  ts << "_Std.Dev_ Normalized\n";
4022 
4023  QString strQC_S(""), strQC_X("");
4024  QString strEC_S(""), strEC_X("");
4025  QString strSnr_S(""), strSnr_X("");
4026  QString strNoC_S(""), strNoC_X("");
4027  QString str(""), sSts("");
4028  double scale4Delay(1.0e12);
4029 
4030  for (int idx=0; idx<allObs.size(); idx++)
4031  {
4032  SgVlbiObservation *obs=allObs.at(idx);
4033  SgVlbiObservable *o=obs->primeObs();
4034  strQC_S = "-";
4035  strQC_X = "-";
4036  strEC_S = "-";
4037  strEC_X = "-";
4038  strSnr_S = " ";
4039  strSnr_X = " ";
4040  strNoC_S = " ";
4041  strNoC_X = " ";
4042  sSts = "u ";
4043  if (obs->observableByKey().contains("S"))
4044  {
4045  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4046  strEC_S.sprintf("%s", qPrintable(
4047  obs->observable("S")->getErrorCode().size()==1?obs->observable("S")->getErrorCode():"."));
4048  strSnr_S.sprintf("%7.1f", obs->observable("S")->getSnr());
4049  strNoC_S.sprintf("%2d", obs->observable("S")->getNumOfChannels());
4050  };
4051  if (obs->observableByKey().contains("X"))
4052  {
4053  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4054  strEC_X.sprintf("%s", qPrintable(
4055  obs->observable("X")->getErrorCode().size()==1?obs->observable("X")->getErrorCode():"."));
4056  strSnr_X.sprintf("%7.1f", obs->observable("X")->getSnr());
4057  strNoC_X.sprintf("%2d", obs->observable("X")->getNumOfChannels());
4058  };
4059  str = QString("").sprintf("%5d ", o->getMediaIdx()+1) + obs->toString(SgMJD::F_HHMMSS) + " " +
4060  strQC_S + " " + strQC_X + " " +
4061  strEC_S + " " + strEC_X + " " +
4062  strSnr_S + " " + strSnr_X + " " +
4063  strNoC_S + " " + strNoC_X + " " +
4064  obs->baseline()->getKey() + " " + obs->src()->getKey();
4065 
4066  if (obs->activeObs()->isUsable())
4067  {
4069  sSts = "e ";
4070  else
4071  sSts = "i ";
4072  str += QString("").sprintf(" %10.1f %9.1f %8.1f",
4073  o->activeDelay()->getResidual()*scale4Delay,
4074  o->activeDelay()->sigma2Apply()*scale4Delay,
4075  o->activeDelay()->getResidualNorm());
4076  };
4077  ts << qPrintable(sSts + str) << "\n";
4078  };
4079  ts << "\n";
4080  //
4081  excludedObs.clear();
4082  unusableObs.clear();
4083  includedObs.clear();
4084  allObs.clear();
4085 };
4086 
4087 
4088 
4089 //
4091 {
4092  QList<SgVlbiObservation*> excludedObs, unusableObs;
4093 
4094  for (int i=0; i<session_->observations().size(); i++)
4095  {
4096  SgVlbiObservation *obs=session_->observations().at(i);
4098  {
4100  excludedObs << obs;
4101  else
4102  unusableObs << obs;
4103  };
4104  };
4105  //
4106  if (excludedObs.size() + unusableObs.size() == 0)
4107  {
4108  ts << "All observations were used in the solution.\n";
4110  "::reportDeselectedObsBlock_Output4Spoolfile(): no deselected obs to report");
4111  return;
4112  };
4113  //
4114  //
4115  ts << " Observations that are not in the solution of the Run " << reportID_ << "\n";
4116  ts << "# N __Time__ SQC XQC S_SNR_ X_SNR_ ____Baseline_____ _Source_ Resid.(ps) _Std.Dev_ NormResid\n";
4117 
4118  QString strQC_S(""), strQC_X("");
4119  QString strSnr_S(""), strSnr_X("");
4120  QString str("");
4121  double scale4Delay(1.0e12);
4122  for (int idx=0; idx<unusableObs.size(); idx++)
4123  {
4124  SgVlbiObservation *obs=unusableObs.at(idx);
4125  SgVlbiObservable *o=obs->primeObs();
4126  strQC_S = "-";
4127  strQC_X = "-";
4128  strSnr_S = " ";
4129  strSnr_X = " ";
4130  if (obs->observableByKey().contains("S"))
4131  {
4132  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4133  strSnr_S.sprintf("%4.1f", obs->observable("S")->getSnr());
4134  };
4135  if (obs->observableByKey().contains("X"))
4136  {
4137  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4138  strSnr_X.sprintf("%4.1f", obs->observable("X")->getSnr());
4139  };
4140  str = QString("").sprintf("%2d ", o->getMediaIdx()+1) + obs->toString(SgMJD::F_HHMMSS) +
4141  " S:" + strQC_S + " X:" + strQC_X + " S:" + strSnr_S + " X:" + strSnr_X + " " +
4142  obs->baseline()->getKey() + " " + obs->src()->getKey();
4143  ts << "u " << qPrintable(str) << "\n";
4144  };
4145  //
4146  for (int idx=0; idx<excludedObs.size(); idx++)
4147  {
4148  SgVlbiObservation *obs=excludedObs.at(idx);
4149  SgVlbiObservable *o=obs->primeObs();
4150  strQC_S = "-";
4151  strQC_X = "-";
4152  strSnr_S = " ";
4153  strSnr_X = " ";
4154  if (obs->observableByKey().contains("S"))
4155  {
4156  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4157  strSnr_S.sprintf("%4.1f", obs->observable("S")->getSnr());
4158  };
4159  if (obs->observableByKey().contains("X"))
4160  {
4161  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4162  strSnr_X.sprintf("%4.1f", obs->observable("X")->getSnr());
4163  };
4164  str = QString("").sprintf("%2d ", o->getMediaIdx()+1) + obs->toString(SgMJD::F_HHMMSS) +
4165  " S:" + strQC_S + " X:" + strQC_X + " S:" + strSnr_S + " X:" + strSnr_X + " " +
4166  obs->baseline()->getKey() + " " + obs->src()->getKey() +
4167  QString("").sprintf(" %10.1f %9.1f %8.1f",
4168  o->activeDelay()->getResidual()*scale4Delay,
4169  o->activeDelay()->sigma2Apply()*scale4Delay,
4170  o->activeDelay()->getResidualNorm());
4171 /*
4172  o->measurement(config_)->getResidual()*scale4Delay,
4173  o->measurement(config_)->sigma2Apply()*scale4Delay,
4174  o->measurement(config_)->getResidualNorm());
4175 */
4176  ts << "e " << qPrintable(str) << "\n";
4177  };
4178  ts << "\n";
4179 };
4180 
4181 
4182 
4183 //
4185 {
4186  QString str(""), str2copy(""), strQC_S(""), strQC_X("");
4187  double scale4Delay(1.0e12);
4188 
4189  QList<SgVlbiObservation*> /*excludedObs,*/ unusedObs;
4190 
4191  for (int i=0; i<session_->observations().size(); i++)
4192  {
4193  SgVlbiObservation *obs=session_->observations().at(i);
4195  {
4196  /*
4197  if (obs->isAttr(SgVlbiObservation::Attr_NOT_VALID))
4198  excludedObs<< obs;
4199  else
4200  */
4201  unusedObs << obs;
4202  };
4203  };
4204  //
4205  if (/*excludedObs.size() + */ unusedObs.size() == 0)
4206  {
4207  ts << "All observations were used in the solution.\n";
4209  "::reportDeselectedObsBlock_Output4Spoolfile(): no deselected obs to report");
4210  return;
4211  };
4212  //
4213  //
4214 // ts << " Observations that are not in the solution of the Run " << reportID_ << "\n";
4215 // ts << " scanId SQC XQC\n";
4216  for (int idx=0; idx<unusedObs.size(); idx++)
4217  {
4218  SgVlbiObservation *obs=unusedObs.at(idx);
4219  SgVlbiObservable *o=obs->primeObs();
4220  strQC_S = "-";
4221  strQC_X = "-";
4222  if (obs->observableByKey().contains("S"))
4223  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4224  if (obs->observableByKey().contains("X"))
4225  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4226 
4227  str2copy.sprintf("observation %2d, %s, %s, %s",
4228  o->getMediaIdx() + 1,
4229  qPrintable(o->baseline()->getKey().simplified()),
4230  qPrintable(o->src()->getKey().simplified()),
4231  qPrintable(o->epoch().toString(SgMJD::F_HHMMSS))
4232  );
4233 
4234  str2copy.sprintf("observation %2d, %s, %s, %s, which fits at %.2f +/- %.2f ps, norm: %.2f, ",
4235  o->getMediaIdx() + 1,
4236  qPrintable(o->baseline()->getKey().simplified()),
4237  qPrintable(o->src()->getKey().simplified()),
4238  qPrintable(o->epoch().toString(SgMJD::F_HHMMSS)),
4239  o->activeDelay()->getResidual()*scale4Delay,
4240  o->activeDelay()->sigma2Apply()*scale4Delay,
4242 /*
4243  o->measurement(config_)->getResidual()*scale4Delay,
4244  o->measurement(config_)->sigma2Apply()*scale4Delay,
4245  o->measurement(config_)->getResidualNorm()
4246 */
4247  );
4248  str.sprintf("S:%s X:%s",
4249 // qPrintable(obs->getScanName().simplified()),
4250  qPrintable(strQC_S), qPrintable(strQC_X));
4251 
4252  ts << qPrintable(str2copy + str) << "\n";
4253  };
4254  //
4255  /*
4256  for (int idx=0; idx<excludedObs.size(); idx++)
4257  {
4258  SgVlbiObservation *obs=excludedObs.at(idx);
4259  SgVlbiObservable *o=obs->primeObs();
4260  strQC_S = "-";
4261  strQC_X = "-";
4262  if (obs->observableByKey().contains("S"))
4263  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4264  if (obs->observableByKey().contains("X"))
4265  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4266 
4267  str2copyBlName = " " + o->baseline()->getKey().simplified() + ",";
4268 
4269  str2copy.sprintf(" observation %2d,%s %s, %s, which fits at %.2f +/- %.2f(ps), norm: %.2f",
4270  o->getMediaIdx() + 1,
4271  qPrintable(str2copyBlName),
4272  qPrintable(o->src()->getKey().simplified()),
4273  qPrintable(o->epoch().toString(SgMJD::F_HHMMSS)),
4274  o->measurement(config_)->getResidual()*scale4Delay,
4275  o->measurement(config_)->sigma2Apply()*scale4Delay,
4276  o->measurement(config_)->getResidualNorm()
4277  );
4278  str.sprintf("%23s S:%s X:%s",
4279  qPrintable(obs->getScanName().simplified()),
4280  qPrintable(strQC_S), qPrintable(strQC_X));
4281  ts << qPrintable(str + str2copy) << "\n";
4282  };
4283  */
4284  ts << "\n";
4285 };
4286 
4287 
4288 
4289 //
4291 {
4293  synchronizeInfo();
4294  //
4295  QDir dir(path);
4296  if (!dir.exists())
4297  {
4298  if (dir.mkpath(path))
4300  "::reportStochasticEstimations(): a directory \"" + path + "\" has been created");
4301  else
4303  "::reportStochasticEstimations(): creating a directory \"" + path + "\" has been failed");
4304  };
4305  //
4306  if (reportStoch4Stn(path))
4308  "::reportStochasticEstimations(): files with station dependent stochastic parameters "
4309  " have been created");
4310  else
4312  "::reportStochasticEstimations(): creating files with station dependent stochastic parameters "
4313  " have failed");
4314  //
4316 };
4317 
4318 
4319 
4320 //
4321 bool SgSolutionReporter::reportStoch4Stn(const QString& path)
4322 {
4323  QString prefix("Stn_"), suffix(".dat");
4324  StationsByName_it it_st;
4325  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
4326  {
4327  SgVlbiStationInfo *si=it_st.value();
4329  path, prefix + si->getKey().simplified() + "_Clocks" + suffix);
4331  path, prefix + si->getKey().simplified() + "_Zenith" + suffix);
4333  path, prefix + si->getKey().simplified() + "_AtmGrdN" + suffix);
4335  path, prefix + si->getKey().simplified() + "_AtmGrdE" + suffix);
4337  path, prefix + si->getKey().simplified() + "_Rx" + suffix);
4339  path, prefix + si->getKey().simplified() + "_Ry" + suffix);
4341  path, prefix + si->getKey().simplified() + "_Rz" + suffix);
4343  path, prefix + si->getKey().simplified() + "_AxsOff" + suffix);
4344  };
4345  prefix = "EOP_";
4347  path, prefix + "Px" + suffix);
4349  path, prefix + "Py" + suffix);
4351  path, prefix + "Ut1" + suffix);
4352  // do we need these at all:?
4354  path, prefix + "CipX" + suffix);
4356  path, prefix + "CipY" + suffix);
4357  //
4358  // what else I should add here?
4359  // ...
4360  return true;
4361 };
4362 
4363 
4364 
4365 //
4366 bool SgSolutionReporter::reportStochParameter(const QString& key, const SgParameterCfg& parCfg,
4367  const QString& path, const QString& fileName)
4368 {
4369  if (!stcParByName_.contains(key))
4370  return true; // it is ok
4371 
4372  QString str("");
4373  QFile f(path + "/" + fileName);
4374  if (!f.open(QIODevice::WriteOnly))
4375  {
4377  "::reportStochParameter(): error opening output file: " + path + "/" + fileName);
4378  return false;
4379  };
4380  //
4381  // make output:
4382  double scale(parCfg.getScale());
4383  QString scaleName(parCfg.getScaleName());
4384  QTextStream ts(&f);
4385  const QMap<QString, SgParameter*>
4386  &parByEpoch=stcParByName_.value(key);
4387  ts << "# Output of " << key << ", (" << scaleName << ")\n";
4388  for (QMap<QString, SgParameter*>::const_iterator it=parByEpoch.begin(); it!=parByEpoch.end(); ++it)
4389  {
4390  SgParameter *par=it.value();
4391  if (par)
4392  {
4393  str.sprintf("%s %.4f %.4f %d",
4394  qPrintable(par->getTMean().toString(SgMJD::F_Simple)),
4395  par->getSolution()*scale, par->getSigma()*scale, par->getNumObs());
4396  ts << str << "\n";
4397  }
4398  else
4399  {
4401  "::reportStochParameter(): the parameter " + key + " is NULL");
4402  ts << it.key() << ": the parameter \"" << key << "\" is NULL\n";
4403  };
4404  };
4405  //
4406  // close the file:
4407  ts.setDevice(NULL);
4408  f.close();
4409  return true;
4410 };
4411 
4412 
4413 
4414 //
4416 {
4417  QDir dir(path);
4418  if (!dir.exists())
4419  {
4420  if (dir.mkpath(path))
4422  "::reportTotalZenithDelays(): a directory \"" + path + "\" has been created");
4423  else
4424  {
4426  "::reportTotalZenithDelays(): creating a directory \"" + path + "\" has been failed");
4427  return false;
4428  };
4429  };
4430  //
4431  QString str("");
4432  QString prefix("Stn_"), suffix("_Tzd.dat");
4433  StationsByName_it it_st;
4434  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
4435  {
4436  SgVlbiStationInfo *si=it_st.value();
4437  QMap<QString, SgVlbiAuxObservation*>
4438  *auxObservationsByScan=si->auxObservationByScanId();
4439  //
4440  if (auxObservationsByScan->size())
4441  {
4442  QFile f(path + "/" + prefix + si->getKey().simplified() + suffix);
4443  if (!f.open(QIODevice::WriteOnly))
4444  {
4446  "::reportTotalZenithDelays(): error opening output file: \"" + f.fileName() + "\"");
4447  return false;
4448  };
4449  //
4450  // make output:
4451  QTextStream ts(&f);
4452  ts << "# Output of Total zenith delays for " << si->getKey().simplified() << ", (cm)\n";
4453 
4454  QMap<QString, SgVlbiAuxObservation*>::const_iterator jt=auxObservationsByScan->constBegin();
4455  for (int idx=0; jt!=auxObservationsByScan->constEnd(); ++jt, idx++)
4456  {
4457  SgVlbiAuxObservation *auxObs=jt.value();
4458  double tzd, tzdSigma;
4459  tzd = (auxObs->getZenithDelayH() + auxObs->getZenithDelayW())*100.0 + auxObs->getEstZenithDelay();
4460  tzdSigma = auxObs->getEstZenithDelaySigma();
4461  if (tzdSigma > 0.0)
4462  {
4463  str.sprintf("%s %.4f %.4f",
4464  qPrintable(auxObs->toString(SgMJD::F_Simple)), tzd, tzdSigma);
4465  ts << str << "\n";
4466  };
4467  };
4468  ts.setDevice(NULL);
4469  f.close();
4470  };
4471  };
4472  return true;
4473 };
4474 
4475 
4476 
4477 //
4478 void SgSolutionReporter::report2MyFile(const QString& path, const QString& fileName)
4479 {
4480  QDir dir(path);
4481  if (!dir.exists())
4482  {
4483  if (dir.mkpath(path))
4485  "::report2MyFile(): a directory \"" + path + "\" has been created");
4486  else
4487  {
4489  "::report2MyFile(): creating a directory \"" + path + "\" has been failed");
4490  return;
4491  };
4492  };
4493  //
4494  QFile f(path + "/" + fileName);
4495  if (!f.open(QIODevice::WriteOnly))
4496  {
4498  "::report2MyFile(): error opening output file: \"" + f.fileName() + "\"");
4499  return;
4500  };
4501  //
4502  // make output:
4503  QTextStream ts(&f);
4504  ts << "# test outputs...\n";
4505 
4506  for (int i=0; i<session_->observations().size(); i++)
4507  {
4508  SgVlbiObservation *obs=session_->observations().at(i);
4509  SgVlbiObservable *o=obs->primeObs();
4510  SgVlbiAuxObservation *auxObs_1=obs->auxObs_1(), *auxObs_2=obs->auxObs_2();
4511  QString str("");
4512 // if (obs->isAttr(SgVlbiObservation::Attr_PROCESSED) && o && auxObs_1 && auxObs_2)
4513  if (!obs->isAttr(SgVlbiObservation::Attr_NOT_VALID) && o && auxObs_1 && auxObs_2)
4514  {
4515  str.sprintf("%s %16.4f %8.4f %14.2f %14.2f %14.2f %14.2f %-8s:%-8s %-8s PP:%s",
4516  qPrintable(obs->toString(SgMJD::F_Simple)),
4517  o->grDelay().getResidual()*1.0e12, o->grDelay().sigma2Apply()*1.0e12,
4518  o->getUvFrPerAsec(0)*360.0*3600.0/2.0/M_PI, o->getUvFrPerAsec(1)*360.0*3600.0/2.0/M_PI,
4519  auxObs_1->getParallacticAngle()*RAD2DEG, auxObs_2->getParallacticAngle()*RAD2DEG,
4520  qPrintable(obs->stn_1()->getKey()),
4521  qPrintable(obs->stn_2()->getKey()),
4522  qPrintable(obs->src()->getKey()),
4524 
4525 
4526  );
4527 
4528  ts << str << "\n";
4529  };
4530  };
4531  ts.setDevice(NULL);
4532  f.close();
4533 }
4534 /*=====================================================================================================*/
4535 
4536 
4537 
4538 
4539 
4540 
4541 /*=====================================================================================================*/
4542 //
4543 // FRIENDS:
4544 //
4545 /*=====================================================================================================*/
4546 //
4547 
4548 /*=====================================================================================================*/
4549 //
4550 // aux functions:
4551 //
4553 {
4554  return src1->getRA() < src2->getRA();
4555 };
4556 
4557 
4558 
4559 // progs/solve/basfe/*.f:
4560 void calcLhv(const Sg3dVector& r1, const Sg3dVector& dr1, const Sg3dVector& r2, const Sg3dVector& dr2,
4561  const SgMatrix& r, Sg3dVector& lhv, Sg3dVector& lhvSigma, double& length, double& lengthSigma)
4562 {
4563  Sg3dVector l,h,v;
4564  Sg3dVector b;
4565  SgMatrix a(4, 6); // matrix of the derivatives
4566  double d;
4567 
4568  // calculate lhv unit vectors:
4569  l = (b = r2-r1);
4570  l.unify();
4571 
4572  h = r2%r1;
4573  h.unify();
4574 
4575  v = l%h;
4576  v.unify();
4577 
4578  b += dr2 - dr1; // a posteriori
4579  length = b.module();
4580 
4581  lhv(X_AXIS) = b*l;
4582  lhv(Y_AXIS) = b*h;
4583  lhv(Z_AXIS) = b*v;
4584 
4585  a.setElement(0, 0, -l.at(X_AXIS)); // d(lhv_1)/d(x_1)
4586  a.setElement(0, 1, -l.at(Y_AXIS)); // d(lhv_1)/d(y_1)
4587  a.setElement(0, 2, -l.at(Z_AXIS)); // d(lhv_1)/d(z_1)
4588 
4589  a.setElement(1, 0, -h.at(X_AXIS)); // d(lhv_2)/d(x_1)
4590  a.setElement(1, 1, -h.at(Y_AXIS)); // d(lhv_2)/d(y_1)
4591  a.setElement(1, 2, -h.at(Z_AXIS)); // d(lhv_2)/d(z_1)
4592 
4593  a.setElement(2, 0, -v.at(X_AXIS)); // d(lhv_3)/d(x_1)
4594  a.setElement(2, 1, -v.at(Y_AXIS)); // d(lhv_3)/d(y_1)
4595  a.setElement(2, 2, -v.at(Z_AXIS)); // d(lhv_3)/d(z_1)
4596 
4597 //a.setElement(3, 0, -1.0); // d(length)/d(x_1)
4598 //a.setElement(3, 1, -1.0); // d(length)/d(y_1)
4599 //a.setElement(3, 2, -1.0); // d(length)/d(z_1)
4600  a.setElement(3, 0, b.at(X_AXIS)/length); // d(length)/d(b_x)
4601  a.setElement(3, 1, b.at(Y_AXIS)/length); // d(length)/d(b_y)
4602  a.setElement(3, 2, b.at(Z_AXIS)/length); // d(length)/d(b_z)
4603 
4604  // for the second station the partials are the same just with reverted sign:
4605  for (int i=0; i<4; i++)
4606  for (int j=0; j<3; j++)
4607  a.setElement(i, j+3, -a.getElement(i,j));
4608 
4609  // r is a matrix of covariations for (x1,y1,z1,x2,y2,z2)
4610  for (int k=0; k<4; k++)
4611  {
4612  d = 0.0;
4613  for (int i=0; i<6; i++)
4614  {
4615  d += a.getElement(k, i)*a.getElement(k, i)*r.getElement(i, i);
4616  for (int j=i+1; j<6; j++)
4617  d += 2.0*a.getElement(k, i)*a.getElement(k, j)*r.getElement(i, j);
4618  };
4619  if (d > 0.0)
4620  {
4621  if (k < 3)
4622  lhvSigma((DIRECTION)k) = sqrt(d);
4623  else
4624  lengthSigma = sqrt(d);
4625  }
4626  else
4627  {
4628  logger->write(SgLogger::INF, SgLogger::REPORT, "calcLhv(): "
4629  "the sigma2 is less than zero: " + QString("").sprintf("%g", d));
4630  lhvSigma((DIRECTION)k) = 1.0;
4631  };
4632  };
4633 };
4634 
4635 
4636 
4637 // another version: the baselines have been estimated:
4638 void calcLhv(const Sg3dVector& r1, const Sg3dVector& r2, const Sg3dVector& db,
4639  const SgMatrix& r, Sg3dVector& lhv, Sg3dVector& lhvSigma, double& length, double& lengthSigma)
4640 {
4641  Sg3dVector l,h,v;
4642  Sg3dVector b;
4643  SgMatrix a(4, 3); // matrix of the derivatives
4644  double d;
4645 
4646  // calculate lhv unit vectors:
4647  l = (b = r2-r1);
4648  l.unify();
4649 
4650  h = r2%r1;
4651  h.unify();
4652 
4653  v = l%h;
4654  v.unify();
4655 
4656  b += db; // a posteriori
4657  length = b.module();
4658 
4659  lhv(X_AXIS) = b*l;
4660  lhv(Y_AXIS) = b*h;
4661  lhv(Z_AXIS) = b*v;
4662 
4663  a.setElement(0, 0, l.at(X_AXIS)); // d(lhv_1)/d(b_x)
4664  a.setElement(0, 1, l.at(Y_AXIS)); // d(lhv_1)/d(b_y)
4665  a.setElement(0, 2, l.at(Z_AXIS)); // d(lhv_1)/d(b_z)
4666 
4667  a.setElement(1, 0, h.at(X_AXIS)); // d(lhv_2)/d(b_x)
4668  a.setElement(1, 1, h.at(Y_AXIS)); // d(lhv_2)/d(b_y)
4669  a.setElement(1, 2, h.at(Z_AXIS)); // d(lhv_2)/d(b_z)
4670 
4671  a.setElement(2, 0, v.at(X_AXIS)); // d(lhv_3)/d(b_x)
4672  a.setElement(2, 1, v.at(Y_AXIS)); // d(lhv_3)/d(b_y)
4673  a.setElement(2, 2, v.at(Z_AXIS)); // d(lhv_3)/d(b_z)
4674 
4675 //a.setElement(3, 0, 1.0); // d(length)/d(b_x)
4676 //a.setElement(3, 1, 1.0); // d(length)/d(b_y)
4677 //a.setElement(3, 2, 1.0); // d(length)/d(b_z)
4678  a.setElement(3, 0, b.at(X_AXIS)/length); // d(length)/d(b_x)
4679  a.setElement(3, 1, b.at(Y_AXIS)/length); // d(length)/d(b_y)
4680  a.setElement(3, 2, b.at(Z_AXIS)/length); // d(length)/d(b_z)
4681 
4682  // r is a matrix of covariations for (b_x,b_y,b_z)
4683  for (int k=0; k<4; k++)
4684  {
4685  d = 0.0;
4686  for (int i=0; i<3; i++)
4687  {
4688  d += a.getElement(k, i)*a.getElement(k, i)*r.getElement(i, i);
4689  for (int j=i+1; j<3; j++)
4690  d += 2.0*a.getElement(k, i)*a.getElement(k, j)*r.getElement(i, j);
4691  };
4692  if (d > 0.0)
4693  {
4694  if (k < 3)
4695  lhvSigma((DIRECTION)k) = sqrt(d);
4696  else
4697  lengthSigma = sqrt(d);
4698  }
4699  else
4700  {
4701  logger->write(SgLogger::INF, SgLogger::REPORT, "calcLhv(): "
4702  "the sigma2 is less than zero: " + QString("").sprintf("%g", d));
4703  lhvSigma((DIRECTION)k) = 1.0;
4704  };
4705  };
4706 };
4707 
4708 
4709 
4710 /*=====================================================================================================*/
4711 //
4712 // constants:
4713 //
4714 
4715 /*=====================================================================================================*/
const double vLight
Definition: SgConstants.cpp:33
void calcCip2IAU1980(const SgMJD &epoch, double dX, double dY, double dPsi_1980, double dEps_1980, double dPsi_2000, double dEps_2000, double &diffPsi, double &diffEps)
Definition: SgConstants.cpp:41
SgLogger * logger
Definition: SgLogger.cpp:231
const SgMJD tZero(1957, 10, 4)
#define RAD2MAS
radians to ms:
Definition: SgMathSupport.h:60
#define SEC2RAD
radians to arc seconds:
Definition: SgMathSupport.h:48
#define DAY2SEC
radians to mas:
Definition: SgMathSupport.h:56
double signum(const double x)
Definition: SgMathSupport.h:71
DIRECTION
Definition: SgMathSupport.h:68
@ VERTICAL
Definition: SgMathSupport.h:68
@ Z_AXIS
Definition: SgMathSupport.h:68
@ X_AXIS
Definition: SgMathSupport.h:68
@ Y_AXIS
Definition: SgMathSupport.h:68
@ EAST
Definition: SgMathSupport.h:68
@ NORTH
Definition: SgMathSupport.h:68
#define RAD2DEG
< radians to degrees:
Definition: SgMathSupport.h:32
#define RAD2SEC
seconds in one day:
Definition: SgMathSupport.h:52
#define RAD2MS
Definition: SgMathSupport.h:64
static const QString srcChars[]
void calcLhv(const Sg3dVector &r1, const Sg3dVector &dr1, const Sg3dVector &r2, const Sg3dVector &dr2, const SgMatrix &r, Sg3dVector &lhv, Sg3dVector &lhvSigma, double &length, double &lengthSigma)
bool rightAscensionSortingOrderLessThan(SgVlbiSourceInfo *, SgVlbiSourceInfo *)
static const int numOfSrcChars
SgVersion libraryVersion("SgLib", 0, 7, 5, "Tuscarora (rc1)", SgMJD(2022, 2, 18, 17, 34))
QMap< QString, SgVlbiBaselineInfo * >::iterator BaselinesByName_it
const QString defaultNetIdName
QMap< QString, SgVlbiSourceInfo * >::iterator SourcesByName_it
QMap< QString, SgVlbiStationInfo * >::iterator StationsByName_it
DataType
Definition: SgWrmsable.h:43
@ DT_DELAY
Definition: SgWrmsable.h:44
@ DT_RATE
Definition: SgWrmsable.h:45
double at(DIRECTION i, DIRECTION j) const
Definition: Sg3dMatrix.h:93
double lambda() const
Definition: Sg3dVector.h:107
Sg3dVector & unify()
Definition: Sg3dVector.h:112
double module() const
Definition: Sg3dVector.h:99
double phi() const
Definition: Sg3dVector.h:103
double at(DIRECTION i) const
Definition: Sg3dVector.h:91
const SgMJD & getT0() const
SgParameter * getPOrig()
Definition: SgArcStorage.h:200
bool isAttr(uint a) const
Definition: SgAttribute.h:226
QList< SgArcStorage * > * arcStorage()
Definition: SgEstimator.h:420
QList< SgPwlStorage * > * pwlStorage()
Definition: SgEstimator.h:404
double maxConditionNumber() const
Definition: SgEstimator.h:171
SgSymMatrix * mPall()
Definition: SgEstimator.h:428
void addParametersList(QList< SgParameter * > *, bool=false)
void prepare2Run(int numOfExpectedObs, const SgMJD &, const SgMJD &, const SgMJD &)
const QMap< QString, StochasticSolutionCarrier > & stcSolutions()
Definition: SgEstimator.h:110
QList< SgParameter * > * allRegularParametersList()
Definition: SgEstimator.h:380
void processObs(const SgMJD &t, const SgVector &o_c, const SgVector &sigma)
const QString & getAcAbbName() const
Definition: SgIdentities.h:255
const QString & getUserEmailAddress() const
Definition: SgIdentities.h:223
const QString & getMachineMachineName() const
Definition: SgIdentities.h:303
const QString & getMachineRelease() const
Definition: SgIdentities.h:319
const QString & getMachineNodeName() const
Definition: SgIdentities.h:295
const QString & getUserDefaultInitials() const
Definition: SgIdentities.h:231
const QString & getAcFullName() const
Definition: SgIdentities.h:239
const QString & getCurrentDir() const
Definition: SgIdentities.h:271
const QString & getExecDir() const
Definition: SgIdentities.h:263
const QString & getUserName() const
Definition: SgIdentities.h:215
const QString & getMachineSysName() const
Definition: SgIdentities.h:311
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ DATA
Definition: SgLogger.h:78
@ REPORT
Definition: SgLogger.h:95
Definition: SgMJD.h:59
double getTime() const
Definition: SgMJD.h:457
@ F_SOLVE_SPLFL_LONG
Another version from spoolfile format: 12/01/20 00:02.
Definition: SgMJD.h:78
@ F_SOLVE_SPLFL_SHORT
Another spoolfile represenation of epoch: 2012.01.20-09:14:28.05.
Definition: SgMJD.h:77
@ F_YYYYMonDD
Date in digits: 2010.04.02.
Definition: SgMJD.h:90
@ F_HHMMSS
Just time: 17:02:43.6.
Definition: SgMJD.h:96
@ F_SOLVE_SPLFL_V2
A spoolfile represenation of epoch: 2012.01.20-09:14:28.
Definition: SgMJD.h:75
@ F_Simple
Digits: 2010/04/02 17:02:43.6.
Definition: SgMJD.h:68
@ F_Date
RFC2822 date format realized by Qt (Qt::RFC2822Date)
Definition: SgMJD.h:86
@ F_SOLVE_SPLFL
That was used in ECC.dat files: 2010.04.02-17.02.
Definition: SgMJD.h:74
@ F_INTERNAL
Digits, date and time: 20100402.71.
Definition: SgMJD.h:72
QString toString(Format format=F_Verbose) const
Definition: SgMJD.cpp:1007
double toDouble() const
Definition: SgMJD.h:533
int getDate() const
Definition: SgMJD.h:449
static SgMJD currentMJD()
Definition: SgMJD.cpp:118
static void MJD_reverse(int date, double time, int &nYear, int &nMonth, int &nDay, int &nHour, int &nMin, double &dSec)
Definition: SgMJD.cpp:74
unsigned int nRow() const
Definition: SgMatrix.h:352
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
unsigned int nCol() const
Definition: SgMatrix.h:360
double getPressure() const
Definition: SgMeteoData.h:242
double getTemperature() const
Definition: SgMeteoData.h:234
@ Attr_ARTIFICIAL_DATA
data are artificial (mean values or some model);
Definition: SgMeteoData.h:52
double getRelativeHumidity() const
Definition: SgMeteoData.h:250
double getDversion() const
Definition: SgModelsInfo.h:114
double getSFF_NrmRes_plus_15(DataType) const
Definition: SgObjectInfo.h:407
double getSigma2add(DataType) const
Definition: SgObjectInfo.h:367
const QString & getKey() const
Definition: SgObjectInfo.h:319
int numProcessed(DataType dType) const
Definition: SgObjectInfo.h:351
double getSFF_NrmRes(DataType) const
Definition: SgObjectInfo.h:399
void setSFF_NrmRes_plus_15(DataType dType, double d)
Definition: SgObjectInfo.h:503
void setSFF_NrmRes(DataType dType, double d)
Definition: SgObjectInfo.h:495
int numUsable(DataType) const
Definition: SgObjectInfo.h:359
void setNormedResid(DataType dType, double d)
Definition: SgObjectInfo.h:487
double chi2(DataType) const
Definition: SgObjectInfo.h:415
double wrms(DataType) const
Definition: SgObjectInfo.h:567
double reducedChi2(DataType) const
Definition: SgObjectInfo.h:423
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
SgParameter * pA2()
Definition: SgBreakModel.h:164
double getS0() const
Definition: SgBreakModel.h:387
SgParameter * pA0()
Definition: SgBreakModel.h:162
double getA0() const
Definition: SgBreakModel.h:363
@ Attr_DYNAMIC
parameters supposed to be estimated during the common solution;
Definition: SgBreakModel.h:60
SgParameter * pA1()
Definition: SgBreakModel.h:163
const QString & getScaleName() const
double getPwlAPriori() const
double getScale() const
double getSolution() const
Definition: SgParameter.h:435
SgParameterCfg::PMode getPMode() const
Definition: SgParameter.h:459
double getSigma() const
Definition: SgParameter.h:443
int getIdx() const
Definition: SgParameter.h:563
double getSigmaAPriori() const
Definition: SgParameter.h:475
void setScale(double v)
Definition: SgParameter.h:595
@ Attr_IS_SOLVED
for estimator use
Definition: SgParameter.h:57
void setSigmaAPriori(double v)
Definition: SgParameter.h:619
void setPMode(SgParameterCfg::PMode mode)
Definition: SgParameter.h:603
const SgParameterCfg & getZenith() const
const SgParameterCfg & getAtmGrad() const
SgParameterCfg::PMode getStnCooMode() const
const SgParameterCfg & getPolusUT1() const
SgParameterCfg::PMode getClock0Mode() const
const SgParameterCfg & getPolusXY() const
const SgParameterCfg & getPolusNut() const
const SgParameterCfg & getClock0() const
SgParameterCfg::PMode getZenithMode() const
SgParameterCfg::PMode getBlLengthMode() const
SgParameterCfg::PMode getSrcCooMode() const
SgParameterCfg::PMode getBlClockMode() const
void setD(double d)
Definition: SgPartial.h:347
int getNumObs() const
Definition: SgPartial.h:299
SgMJD getTMean(const SgMJD &=tZero) const
Definition: SgPartial.h:416
const QString & getName() const
Definition: SgPartial.h:283
@ Attr_IS_SPECIAL
for estimator use
Definition: SgPartial.h:54
double calcMean()
Definition: SgPwlStorage.h:359
int getNumOfPolynomials() const
Definition: SgPwlStorage.h:259
const SgMJD & tStart() const
Definition: SgPwlStorage.h:275
SgParameter * getP_Bi(int)
Definition: SgPwlStorage.h:307
SgParameter * getPOrig()
Definition: SgPwlStorage.h:325
int getNumOfNodes() const
Definition: SgPwlStorage.h:251
SgMJD tMean() const
Definition: SgPwlStorage.h:299
virtual int getNumOfSegments()=0
SgParameter * getP_Ai(int)
Definition: SgPwlStorage.h:316
double step() const
Definition: SgPwlStorage.h:267
virtual double calcRateRms4Sfo()
double calcWRMS()
Definition: SgPwlStorage.h:367
double calcPolySolution(const SgMJD &)
virtual double calcRateSolution(const SgMJD &)=0
const SgMJD & tFinis() const
Definition: SgPwlStorage.h:283
double trace() const
Definition: SgPwlStorage.h:100
virtual double calcRateSigma(const SgMJD &)
QMap< QString, SgArcStorage * > arcByName_
bool reportAtmo(const QString &path, const QString &fileName)
QList< SgParameter * > parList_
void absorbInfo(SgTaskManager *)
void reportAPrioriBlock_Output4Spoolfile(QTextStream &)
SgVlbiSession * session_
void reportStationStatsBlock_Output4Spoolfile(QTextStream &)
void setSession(SgVlbiSession *)
void reportGeneralStatsBlock_Output4Spoolfile(QTextStream &)
void reportResidualsBlock_Output4Spoolfile(QTextStream &)
SgSolutionReporter(SgVlbiSession *, const SgIdentities &)
void reportDeselectedObsBlock_Output4Spoolfile(QTextStream &)
QList< QString > userComents_
SgTaskConfig * config_
bool reportSources_Output4AposterioriFiles(const QString &path, const QString &fileName)
void reportBaselineVariationsBlock_Output4Spoolfile(QTextStream &)
void reportDeselectedObsBlock_Output4Spoolfile_v2(QTextStream &)
QList< SgPwlStorage * > pwlList_
bool reportNotUsedObs(const QString &path, const QString &fileName)
bool reportTotalZenithDelays(const QString &path)
QMap< QString, SgPwlStorage * > pwlByName_
QList< SgVlbiSourceInfo * > usedSources_
QList< SgParameter * > allParList_
void reportSourceStatsBlock_Output4Spoolfile(QTextStream &)
void reportIdentitiesBlock_Output4Spoolfile(QTextStream &)
void report2aposterioriFiles(const QString &path, const QString &fileNameBase)
bool reportStoch4Stn(const QString &path)
void report2MyFile(const QString &path, const QString &fileName)
void reportMetStatsBlock_Output4Spoolfile(QTextStream &)
void reportEstimationBlock_Output4Spoolfile(QTextStream &)
void reportConfiguresBlock_Output4Spoolfile(QTextStream &)
void lookupParameter(SgParameter *)
void reportResidualsBlock_Output4Spoolfile_old(QTextStream &)
SgParametersDescriptor * parametersDescriptor_
QList< SgArcStorage * > arcList_
void reportBaselineStatsBlock_Output4Spoolfile(QTextStream &)
bool reportStations_Output4AposterioriFiles(const QString &path, const QString &fileName)
QMap< QString, SgEstimator::StochasticSolutionCarrier > stcSolutions_
bool reportCloc(const QString &path, const QString &fileName)
QMap< QString, SgParameter * > parByName_
bool reportStochParameter(const QString &key, const SgParameterCfg &parCfg, const QString &path, const QString &fileName)
void reportDeselectedObsBlock_Output4Spoolfile_v3(QTextStream &)
QMap< QString, QMap< QString, SgParameter * > > stcParByName_
bool reportPall(const QString &path, const QString &fileName)
void report2spoolFile(const QString &path, const QString &path2obsStatus, const QString &fileName, bool=false)
QList< SgVlbiSourceInfo * > skippedSources_
void reportStochasticEstimations(const QString &path)
static const QString className()
double getElement(unsigned int i, unsigned int j) const
Definition: SgSymMatrix.h:274
bool getHave2ApplyNutationHFContrib() const
Definition: SgTaskConfig.h:374
const QString & getExtAPrioriSitesVelocitiesFileName() const
bool getUseExtAPrioriSitesVelocities() const
bool getHave2ApplyOldPoleTideContrib() const
Definition: SgTaskConfig.h:381
bool getUseExtAPrioriHiFyErp() const
bool getUseExtAPrioriSitesPositions() const
bool getUseExtAPrioriErp() const
bool getIsSolveCompatible() const
Definition: SgTaskConfig.h:897
VlbiDelayType getUseDelayType() const
Definition: SgTaskConfig.h:857
bool getHave2ApplyEarthTideContrib() const
Definition: SgTaskConfig.h:367
EstimatorPwlMode getPwlMode() const
Definition: SgTaskConfig.h:937
bool getHave2ApplyPyContrib() const
Definition: SgTaskConfig.h:366
const QString & getExtAPrioriSitesPositionsFileName() const
const QString & getExtAPrioriHiFyErpFileName() const
QMap< QString, AutomaticProcessing > & apByNetId()
Definition: SgTaskConfig.h:623
bool getHave2ApplyOceanTideContrib() const
Definition: SgTaskConfig.h:368
int getQualityCodeThreshold() const
Definition: SgTaskConfig.h:817
bool getUseExtAPrioriSourcesPositions() const
VlbiRateType getUseRateType() const
Definition: SgTaskConfig.h:865
bool getHave2ApplyUt1OceanTideHFContrib() const
Definition: SgTaskConfig.h:372
bool getHave2ApplyPxyOceanTideHFContrib() const
Definition: SgTaskConfig.h:373
bool getHave2ApplyOldOceanTideContrib() const
Definition: SgTaskConfig.h:380
bool getHave2ApplyPoleTideContrib() const
Definition: SgTaskConfig.h:369
bool getUseExtAPrioriAxisOffsets() const
bool getHave2ApplyPxyLibrationContrib() const
Definition: SgTaskConfig.h:376
bool getHave2ApplyTiltRemvrContrib() const
Definition: SgTaskConfig.h:379
const QString & getExtAPrioriSourcesPositionsFileName() const
bool getHave2ApplyPxContrib() const
Definition: SgTaskConfig.h:365
bool getHave2ApplyOceanPoleTideContrib() const
Definition: SgTaskConfig.h:377
bool getHave2outputCovarMatrix() const
Definition: SgTaskConfig.h:284
const QString & getExtAPrioriAxisOffsetsFileName() const
int getActiveBandIdx() const
Definition: SgTaskConfig.h:873
bool getHave2ApplyFeedCorrContrib() const
Definition: SgTaskConfig.h:378
const QString & getExtAPrioriErpFileName() const
bool getHave2ApplyUt1LibrationContrib() const
Definition: SgTaskConfig.h:375
SgEstimator * estimator()
int getNumOfParameters() const
int getNumOfConstraints() const
unsigned int n() const
Definition: SgUtMatrix.h:290
void setElement(unsigned int i, double d)
Definition: SgVector.h:348
double getElement(unsigned int i) const
Definition: SgVector.h:362
const SgMJD & getReleaseEpoch() const
Definition: SgVersion.h:294
QString name(NameFormat fmt=NF_Human) const
Definition: SgVersion.cpp:54
double getZenithDelayW() const
double getElevationAngle() const
double getEstZenithDelay() const
const SgMeteoData & getMeteoData() const
double getZenithDelayH() const
double getEstZenithDelaySigma() const
double getParallacticAngle() const
double getAzimuthAngle() const
QMap< QString, SgVlbiBaselineInfo * > & baselinesByName()
Definition: SgVlbiBand.h:376
QMap< QString, SgVlbiStationInfo * > & stationsByName()
Definition: SgVlbiBand.h:368
int getInputFileVersion() const
Definition: SgVlbiBand.h:344
QMap< QString, SgVlbiSourceInfo * > & sourcesByName()
Definition: SgVlbiBand.h:384
const QString & getCorrelatorType() const
Definition: SgVlbiBand.h:352
SgVlbiStationInfo * stn_2(QMap< QString, SgVlbiStationInfo * >) const
@ Attr_USE_IONO4GRD
use ionosphere corrections for group delays;
@ Attr_USE_IONO4PHD
use ionosphere corrections for phase delays;
@ Attr_NOT_VALID
omit the baseline;
SgVlbiStationInfo * stn_1(QMap< QString, SgVlbiStationInfo * >) const
QList< SgVlbiObservable * > & observables()
SgParameter * pClock()
double sigma2Apply() const
double getAmbiguitySpacing() const
double ambiguity() const
double getValue() const
double getQ2() const
int getNumOfAmbiguities() const
double getSigma() const
double getSigma2add() const
double getResidual() const
double getResidualNorm() const
bool isUsable() const
double getUvFrPerAsec(int i) const
const SgMJD & epoch() const
int getQualityFactor() const
SgVlbiStationInfo *& stn_2()
SgVlbiStationInfo *& stn_1()
int getNumOfChannels() const
const QString & getErrorCode() const
SgVlbiObservation * owner()
SgVlbiMeasurement & phDRate()
double getEffIntegrationTime() const
SgVlbiSourceInfo *& src()
double getTotalPhase() const
double getSnr() const
SgVlbiBaselineInfo *& baseline()
SgVlbiMeasurement * activeDelay()
double getCorrCoeff() const
SgVlbiMeasurement & grDelay()
int getMediaIdx() const
double theoRate() const
double getCalcNutWahr_dEpsV() const
double aPrioriCipY() const
SgVlbiStationInfo * stn_1()
double getNormalizedRateResidual()
SgVlbiAuxObservation * auxObs_2()
double getCalcNutWahr_dPsiV() const
double aPrioriCipX() const
SgVlbiSourceInfo * src()
double getCalcNut2006_dPsiV() const
double theoDelay() const
SgVlbiBaselineInfo * baseline()
double getCalcNut2006_dEpsV() const
double aPrioriPx() const
double getNormalizedDelayResidual()
double aPrioriUt1() const
SgVlbiStationInfo * stn_2()
SgVlbiObservable * observable(const QString &)
SgVlbiObservable * primeObs()
QMap< QString, SgVlbiObservable * > & observableByKey()
SgVlbiAuxObservation * auxObs_1()
double aPrioriPy() const
double sumAX_4delay() const
double sumAX_4rate() const
SgVlbiObservable * activeObs()
const SgMJD & getTFinis() const
const QString & getName() const
const QString & getNetworkID() const
const SgMJD & getTStart() const
@ Attr_HAS_IONO_CORR
the theoretical values are available;
const QString & getOfficialName() const
const QString & getNetworkSuffix() const
const QString & getSessionCode() const
const SgMJD & getTMean() const
SgVlbiBand * primaryBand()
const SgAPriories & getApStationVelocities() const
SgModelsInfo & calcInfo()
QList< SgVlbiBand * > & bands()
SgParameter * pUT1()
double getLeapSeconds()
QMap< QString, SgVlbiStationInfo * > & stationsByName()
SgParameter * pPolusYRate()
const SgMJD & tRefer() const
SgParameter * pPolusY()
SgParameter * pUT1Rate()
SgParameter * pPolusXRate()
QList< SgVlbiObservation * > & observations()
bool hasCipPartials() const
void setReporter(SgSolutionReporter *reporter)
SgTaskConfig * getConfig()
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)
QMap< QString, SgVlbiSourceInfo * > & sourcesByName()
void createParameters()
SgParametersDescriptor * getParametersDescriptor()
SgParameter * pNutY()
SgParameter * pNutX()
QMap< QString, SgVlbiBaselineInfo * > & baselinesByName()
void releaseParameters()
SgParameter * pPolusX()
const QString & getAprioriComments() const
double getDN_ea() const
double getRA_ea() const
static QString dn2String(double dn, bool mandatorySign=false)
double getRA() const
static QString ra2String(double ra)
SgParameter * pRA()
double getDN() const
SgParameter * pDN()
@ Attr_NOT_VALID
omit the source;
SgParameter * pAtmGradN()
QMap< QString, SgVlbiAuxObservation * > * auxObservationByScanId()
const Sg3dVector & getV_ea()
SgParameter * pRz()
double getAxisOffset() const
SgParameter * pClock0()
SgParameter * pRx()
const QString & getTectonicPlateName() const
@ Attr_NOT_VALID
omit the station;
@ Attr_REFERENCE_CLOCKS
the clocks are the reference ones;
@ Attr_IGNORE_CABLE_CAL
do not apply cable calibration;
int getCdpNumber() const
const Sg3dVector & getR()
SgParameter * pClocks(int i)
SgParameter * pAtmGradE()
SgParameter * pZenithDelay()
double getEstWetZenithDelay() const
double getAxisOffset_ea() const
const Sg3dVector & getR_ea()
SgBreakModel & clockBreaks()
int getClocksModelOrder() const
double getEstClockModel(int idx) const
static void calcRLF(double &latitude, double &longitude, double &height, const Sg3dVector &r, bool useOldEllipsoid)
SgParameter * pAxisOffset()
double getEstClockModelSigma(int idx) const
SgParameter * pRy()
QList< SgParameter * > * list_
Definition: SgEstimator.h:70