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^2)")));
649  prs_ut->append((pD_ut=new SgParameter("UT1, 3-term (ms/d^3)")));
650  prs_px->append((pC_px=new SgParameter("PMx, 2-term (mas/d^2)")));
651  prs_px->append((pD_px=new SgParameter("PMx, 3-term (mas/d^3)")));
652  prs_py->append((pC_py=new SgParameter("PMy, 2-term (mas/d^2)")));
653  prs_py->append((pD_py=new SgParameter("PMy, 3-term (mas/d^3)")));
654  prs_cx->append((pC_cx=new SgParameter("CIPx, 2-term (mas/d^2)")));
655  prs_cx->append((pD_cx=new SgParameter("CIPx, 3-term (mas/d^3)")));
656  prs_cy->append((pC_cy=new SgParameter("CIPy, 2-term (mas/d^2)")));
657  prs_cy->append((pD_cy=new SgParameter("CIPy, 3-term (mas/d^3)")));
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 
1416  // keep $-sign for old names still:
1417  if (dbName.size() <= 9)
1418  dbName = "$" + dbName;
1419 
1420  if (false)
1421  {
1422  if (session_->bands().size() == 2)
1423  dbName = dbName.mid(0, 7) + activeBand_->getKey() + session_->getNetworkSuffix();
1424  };
1425 //str.sprintf(" Data base $%9s Ver%3d",
1426  str.sprintf(" Data base %s Ver%3d",
1427 // qPrintable(session_->getName()), session_->primaryBand()->getInputFileVersion());
1428 // qPrintable(session_->getName()), activeBand_->getInputFileVersion());
1429  qPrintable(dbName), activeBand_->getInputFileVersion());
1430  ts << str << "\n\n";
1431 
1432  str.sprintf(" Matrix Condition Number =%24.15E",
1433  condNumber_);
1434  ts << str << "\n\n";
1435 
1436  // should be replaced with actual info later:
1437  ts << " Listing_Options: CRES_EMULATION NO BASELINES NO MINIMUM NO" << "\n"
1438  << " Listing_Options: MAPPED_EOP_OUTPUT NO SEG_OUTPUT NO APRIORI_ZENDEL NO" << "\n"
1439  << " Listing_Options: NRD_TABLE YES CHI_TABLE NO SRC_STAT PRE2004 SEG_STYLE PRE2005" << "\n";
1440  ts << " SgLib release : " <<
1441  qPrintable(libraryVersion.getReleaseEpoch().toString(SgMJD::F_Date)) << "\n\n";
1442 
1443  if (userComents_.size())
1444  {
1445  ts << " User comments:" << "\n";
1446  for (int i=0; i<userComents_.size(); i++)
1447  ts << " " << identities_.getUserDefaultInitials() << ": " << userComents_.at(i) << "\n";
1448  ts << "\n";
1449  };
1450 };
1451 
1452 
1453 
1454 //
1456 {
1457  ts << " Flyby Station Cals: DB Station Cals: | DB Non-station Cals: "
1458  << "| Atmosphere Partial:\n"
1459  << " ------------------------------------------------------------------------------"
1460  << "--------------------\n";
1461 
1462  QString str;
1463  QList<QString> listOfContributions;
1464  int numOfStrings, idxStr, idxContr;
1465  StationsByName_it it;
1466 
1468  listOfContributions << "Pol Tide";
1470  listOfContributions << "WobXCont";
1472  listOfContributions << "WobYCont";
1474  listOfContributions << "EarthTid";
1476  listOfContributions << "Ocean";
1478  listOfContributions << "UT1Ortho";
1480  listOfContributions << "XpYpOrth";
1481  //
1482  if (session_->calcInfo().getDversion()<11.0)
1483  {
1485  listOfContributions << "PxyNutat";
1486  }
1487  else
1488  {
1490  listOfContributions << "XpYpLib";
1492  listOfContributions << "UT1Libra";
1493  };
1494  //
1496  listOfContributions << "FeedCorr";
1498  listOfContributions << "TiltRmvr";
1500  listOfContributions << "OPTLCont";
1502  listOfContributions << "OldOcean";
1504  listOfContributions << "OldPTide";
1505 
1506 
1507  // determine how the ionosphere corrections were applied:
1508  QString sIono("SION");
1510  sIono = "GION";
1512  sIono = "PION";
1513  QMap<QString, int> gionByName;
1514  QString sIonos[3]={"", sIono, ""};
1515  sIonos[2] = sIono + "/no" + sIono;
1516  //
1517  for (StationsByName_it it=session_->stationsByName().begin();
1518  it!=session_->stationsByName().end(); ++it)
1519  {
1520  QString stName=it.value()->getKey();
1521  for (BaselinesByName_it jt=session_->baselinesByName().begin();
1522  jt!=session_->baselinesByName().end(); ++jt)
1523  {
1524  SgVlbiBaselineInfo *bln=jt.value();
1526  {
1527  QString blName=bln->getKey();
1528  if (blName.contains(stName + ":") || blName.contains(":" + stName))
1529  {
1530  int nVal(0);
1535  nVal = 1;
1536  if (!gionByName.contains(stName))
1537  gionByName.insert(stName, nVal);
1538  else if (gionByName.value(stName)!=2 && gionByName.value(stName)!=nVal)
1539  gionByName[stName] = 2;
1540  };
1541  };
1542  };
1543  };
1544  // fill default value for not used objects:
1545  for (StationsByName_it it=session_->stationsByName().begin();
1546  it!=session_->stationsByName().end(); ++it)
1547  if (!gionByName.contains(it.value()->getKey()))
1548  gionByName.insert(it.value()->getKey(), 0);
1549  //
1550  numOfStrings = std::max(session_->stationsByName().size(), listOfContributions.size());
1551  idxStr = idxContr = 0;
1552  it = session_->stationsByName().begin();
1553  while (idxStr<numOfStrings)
1554  {
1555  if (it!=session_->stationsByName().end())
1556  {
1557  SgVlbiStationInfo *si=it.value();
1558  str.sprintf(" %-8s:NMFDRFLY %-8s %-11s ",
1559  qPrintable(si->getKey()),
1561  qPrintable(sIonos[gionByName[si->getKey()]])
1562 // session_->isAttr(SgVlbiSessionInfo::Attr_FF_ION_C_CALCULATED)?"GION":" "
1563  );
1564  ++it;
1565  }
1566  else
1567  str = " ";
1568  ts << str;
1569  if (idxContr<listOfContributions.size())
1570  {
1571  str.sprintf("| %-8s |",
1572  qPrintable(listOfContributions.at(idxContr)));
1573  idxContr++;
1574  }
1575  else
1576  str = "| |";
1577  ts << str;
1578  if (idxStr==0)
1579  ts << " NMFWTFLY \n";
1580  else
1581  ts << " \n";
1582  idxStr++;
1583  };
1584 
1585  ts << " ----------------------------------------------------------------------------"
1586  << "----------------------\n";
1587  str.sprintf(" CALC Version: %.2f ", //SOLVE release: ????.??.?? SOLVE revision: ????.??.?? ",
1589  ts << str << qPrintable(libraryVersion.name()) << "\n\n";
1590  // << " Fast_mode: ??? Fast_cov: ??? \n\n";
1591 
1592 //QString primaryBandKey = session_->primaryBand()->getKey(), auxBandKey, s2;
1593 /*
1594  QString auxBandKey, s2;
1595  for (int i=0; i<session_->bands().size(); i++)
1596  {
1597  auxBandKey = session_->bands().at(i)->getKey();
1598  if (auxBandKey != activeBandKey_)
1599  {
1600  s2 = session_->getName();
1601  str.sprintf(" %10s %2d NOT IN SOLUTION",
1602  qPrintable(s2.replace(s2.size()-2, 1, auxBandKey)),
1603  session_->bands().at(i)->getInputFileVersion());
1604  ts << str << "\n";
1605  };
1606  };
1607  ts << "\n";
1608 */
1609 };
1610 
1611 
1612 
1613 //
1615 {
1616  QString str(""), useChar1(""), useChar2(""), sQcOb("");
1617  QString sVal("");
1618  QString oppBandKey("");
1619  double dSnrOb, dDelay;
1620  bool isMultipleBand;
1621  isMultipleBand = session_->bands().size() > 1;
1622  for (int i=0; i<session_->bands().size(); i++)
1623  if (session_->bands().at(i)->getKey() != activeBandKey_)
1624  oppBandKey = session_->bands().at(i)->getKey();
1625  //
1626 
1627  ts << "1Residuals from Run " << reportID_ << "\n";
1628  ts << " Baseline Source Date Time Obs del Del res "
1629  << "Del er. Obs rate Rate res R.err elev azim frq2-rat QC XS"
1630  << " SNR / SNS_S Tau_obs_x #AmbX Tau_obs_s #AmbS Tau_apriori_clo "
1631  << "Tau_theoretical Tau_est_contrb Rate_obs_x Rate_obs_s"
1632  << " Rate_apriori_clock Rate_theoretical Rate_estim_contrib Eff. Dur. "
1633  << "Res_gr_del_X Res_gr_del_S Gr_Spc_X Gr_Spc_S USR Ampltude Phase Obsind DS "
1634  << "Delay_residual\n";
1635  ts << " ps ps ps"
1636  << " fs/s fs/s fs/s deg deg deg deg seconds"
1637  << " seconds seconds seconds seconds"
1638  << " d/l d/l d/l d/l d/l"
1639  << " sec sec sec ns ns "
1640  << "d/l d/l rad seconds\n";
1641 
1642  for (int idx=0; idx<session_->observations().size(); idx++)
1643  {
1644  SgVlbiObservation *obs=session_->observations().at(idx);
1645  SgVlbiObservable *o=obs?obs->activeObs():NULL;
1646  SgVlbiObservable *o_ob=NULL;
1647  SgVlbiAuxObservation *aux_1=NULL, *aux_2=NULL;
1648  aux_1 = obs?obs->auxObs_1():NULL;
1649  aux_2 = obs?obs->auxObs_2():NULL;
1650 
1651  double delay_clock=0.0, rate_clock=0.0;
1652 
1653  if (o && aux_1 && aux_2)
1654  {
1655  if (obs->observableByKey().contains(oppBandKey))
1656  o_ob = obs->observableByKey().value(oppBandKey);
1657  else
1658  o_ob = NULL;
1660  {
1661  useChar1 = " ";
1662  useChar2 = " ";
1663  }
1664  else
1665  {
1666  useChar1 = ">";
1667  // no or bad opposite-band observable:
1668  if (isMultipleBand &&
1669  (o_ob==NULL || (o_ob->getQualityFactor() < config_->getQualityCodeThreshold())))
1670  useChar2 = "I";
1671  // bad quality of the active band observable:
1673  useChar2 = "F";
1674  // everything else:
1675  else
1676  useChar2 = "H";
1677  };
1678  if (o_ob)
1679  {
1680  sQcOb.sprintf("%2d", o_ob->getQualityFactor());
1681  dSnrOb = o_ob->getSnr();
1682  }
1683  else
1684  {
1685  sQcOb = " ";
1686  dSnrOb = -1.0;
1687  };
1688 // dGrDelay = o->grDelay().getValue() + o->grDelay().ambiguity();
1689  dDelay = o->activeDelay()->getValue() + o->activeDelay()->ambiguity();
1690  // mimic FORTRAN's deficiency of data representation:
1691  if (dDelay<=-1.0 || dDelay>=10.0)
1692  sVal = "**************";
1693  else
1694  sVal.sprintf("%#14.0f", dDelay*1.0e12);
1695 
1696  str.sprintf("%7d%1s %8s/%8s %8s %s %s%#8.0f %1s %#6.0f%#14.0f%#8.0f %1s %#6.0f"
1697  "%4d%4d%4d%4d %9.6f %2d/%2s %6.1f / %6.1f"
1698  " %17.13f %5d %17.13f %5d"
1699  " %16.13f %16.13f %17.13f"
1700  " %20.12e %20.12e %20.12e %20.12e %20.12e @@ "
1701  " %9.4f %17.8e %17.8e %9.4f %9.4f %3d %10.7f %9.5f %6d %24.12e"
1702  //
1703  ,
1704  o->getMediaIdx() + 1,
1705  qPrintable(useChar1),
1706  qPrintable(obs->stn_1()->getKey()),
1707  qPrintable(obs->stn_2()->getKey()),
1708  qPrintable(obs->src()->getKey()),
1709  qPrintable(obs->toString(SgMJD::F_SOLVE_SPLFL_V2)),
1710  // delay:
1711  qPrintable(sVal),
1712  o->activeDelay()->getResidual()*1.0e12,
1713  qPrintable(useChar2),
1714  o->activeDelay()->sigma2Apply()*1.0e12,
1715  // delay rate:
1716  o->phDRate().getValue()*1.0e15,
1717  o->phDRate().getResidual()*1.0e15,
1718  qPrintable(useChar2),
1719  o->phDRate().getSigma()*1.0e15,
1720  //
1721  (int)round(aux_1->getElevationAngle()*RAD2DEG),
1722  (int)round(aux_2->getElevationAngle()*RAD2DEG),
1723  (int)round(aux_1->getAzimuthAngle()*RAD2DEG),
1724  (int)round(aux_2->getAzimuthAngle()*RAD2DEG),
1725  o->activeDelay()->getQ2() + 1.0,
1726  o->getQualityFactor(),
1727  qPrintable(sQcOb),
1728  o->getSnr(),
1729  dSnrOb,
1730 
1731  o->grDelay().getValue(),
1733  o_ob?o_ob->grDelay().getValue():0.0,
1734  o_ob?o_ob->grDelay().getNumOfAmbiguities():0,
1735 
1736  delay_clock,
1737  obs->theoDelay(),
1738  obs->sumAX_4delay(),
1739  // e:
1740  o->phDRate().getValue(),
1741  o_ob?o_ob->phDRate().getValue():0.0,
1742  rate_clock,
1743  obs->theoRate(),
1744  obs->sumAX_4rate(),
1745  // @@
1746  o->getEffIntegrationTime(),
1747  o->grDelay().getResidual(),
1748  o_ob?o->grDelay().getResidual():0.0,
1749  o->grDelay().getAmbiguitySpacing()*1.0e9,
1750  o_ob?o->grDelay().getAmbiguitySpacing()*1.0e9:-1,
1751  1,
1752  o->getCorrCoeff(),
1753  o->getTotalPhase(),
1754  obs->getMediaIdx() + 1,
1755  o->activeDelay()->getResidual()
1756  );
1757 
1758 
1759 // Tau_obs_x #AmbX Tau_obs_s #AmbS Tau_apriori_clo Tau_theoretical Tau_est_contrb Rate_obs_x
1760 // 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
1761 // USR Ampltude Phase Obsind DS Delay_residual
1762 
1763 
1764 
1765 
1766 // 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
1767 // 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
1768 //
1769 // mk5_merge_v03/progs/solve/cres/secnd.f:
1770 // WRITE ( 23, 120 ) IOBS, IDLT, ISITN_CHR(ISITE(1)), &
1771 // & ISITN_CHR(ISITE(2)), ISTRN_CHR(ISTAR), STR_DATE(1:21), &
1772 // & FOBS*1.D3, DOC*1.D3, IPUNC, DOERR*1.D3, &
1773 // & ROBS*1.D3, ROC*1.D3, IPUNC, RERR*1.D3, &
1774 // & IPELV, IPAZ, COEF_IONO, LQUAL_CHR, LQUALXS_CHR, &
1775 // & SNR, SNR_S
1776 //
1777 // 120 FORMAT ( I7, A1, 1X, A8, "/", A8, 1X, A, 1X, A, 1X, &
1778 // & 2(F14.0, F8.0, 1X, A1, 1X, F6.0), 4I4, 2X, F9.6, &
1779 // & 1X, A2, '/', A2, 1X, F6.1, ' / ', F6.1 )
1780 // 120 FORMAT (
1781 // I7, IOBS
1782 // A1, 1X, IDLT
1783 // A8, "/", ISITN_CHR(ISITE(1)),
1784 // A8, 1X, ISITN_CHR(ISITE(2))
1785 // A, 1X, ISTRN_CHR(ISTAR)
1786 // A, 1X, STR_DATE(1:21),
1787 // 2(F14.0, F8.0, 1X, A1, 1X, F6.0),
1788 //==FOBS*1.D3, DOC*1.D3, IPUNC, DOERR*1.D3,
1789 //==ROBS*1.D3, ROC*1.D3, IPUNC, RERR*1.D3,
1790 // 4I4, 2X, IPELV IPAZ arrays?
1791 // F9.6, 1X, COEF_IONO,
1792 // A2, '/', LQUAL_CHR
1793 // A2, 1X, LQUALXS_CHR
1794 // F6.1, ' / ', SNR
1795 // F6.1 SNR_S
1796  ts << qPrintable(str) << "\n";
1797  };
1798  };
1799 
1800  ts << "\n";
1801 };
1802 
1803 
1804 
1805 //
1807 {
1808  QString str(""), useChar1(""), useChar2(""), sQcOb("");
1809  QString sVal("");
1810  QString oppBandKey("");
1811  double dSnrOb, dDelay;
1812  bool isMultipleBand;
1813  isMultipleBand = session_->bands().size() > 1;
1814  for (int i=0; i<session_->bands().size(); i++)
1815  if (session_->bands().at(i)->getKey() != activeBandKey_)
1816  oppBandKey = session_->bands().at(i)->getKey();
1817  //
1818  //
1819  ts << "1Residuals from Run " << reportID_ << "\n";
1820  ts << " Baseline Source Date Time Obs del Del res Del err"
1821  << " Obs rate Rate res Rate err elev frq2-rat QC XS SNR / SNS_S\n"
1822  << " ps ps ps"
1823  << " fs/s fs/s fs/s deg\n";
1824  for (int idx=0; idx<session_->observations().size(); idx++)
1825  {
1826  SgVlbiObservation *obs=session_->observations().at(idx);
1827  SgVlbiObservable *o=obs?obs->activeObs():NULL;
1828  SgVlbiObservable *o_ob=NULL;
1829  SgVlbiAuxObservation *aux_1=NULL, *aux_2=NULL;
1830  aux_1 = obs?obs->auxObs_1():NULL;
1831  aux_2 = obs?obs->auxObs_2():NULL;
1832  if (o && aux_1 && aux_2)
1833  {
1834  if (obs->observableByKey().contains(oppBandKey))
1835  o_ob = obs->observableByKey().value(oppBandKey);
1836  else
1837  o_ob = NULL;
1839  {
1840  useChar1 = " ";
1841  useChar2 = " ";
1842  }
1843  else
1844  {
1845  useChar1 = ">";
1846  // no or bad opposite-band observable:
1847  if (isMultipleBand &&
1848  (o_ob==NULL || (o_ob->getQualityFactor() < config_->getQualityCodeThreshold())))
1849  useChar2 = "I";
1850  // bad quality of the active band observable:
1852  useChar2 = "F";
1853  // everything else:
1854  else
1855  useChar2 = "H";
1856  };
1857  if (o_ob)
1858  {
1859  sQcOb.sprintf("%2d", o_ob->getQualityFactor());
1860  dSnrOb = o_ob->getSnr();
1861  }
1862  else
1863  {
1864  sQcOb = " ";
1865  dSnrOb = -1.0;
1866  };
1867 // dGrDelay = o->grDelay().getValue() + o->grDelay().ambiguity();
1868  dDelay = o->activeDelay()->getValue() + o->activeDelay()->ambiguity();
1869  // mimic FORTRAN's deficiency of data representation:
1870  if (dDelay<=-1.0 || dDelay>=10.0)
1871  sVal = "**************";
1872  else
1873  sVal.sprintf("%#14.0f", dDelay*1.0e12);
1874 
1875  str.sprintf("%7d%1s %8s/%8s %8s %s %s%#8.0f %1s %#6.0f%#14.0f%#8.0f %1s %#6.0f"
1876  "%4d%4d%4d%4d %9.6f %2d/%2s %6.1f / %6.1f",
1877  o->getMediaIdx() + 1, qPrintable(useChar1),
1878  qPrintable(obs->stn_1()->getKey()),
1879  qPrintable(obs->stn_2()->getKey()),
1880  qPrintable(obs->src()->getKey()),
1881  qPrintable(obs->toString(SgMJD::F_SOLVE_SPLFL_V2)),
1882  // delay:
1883  qPrintable(sVal),
1884  o->activeDelay()->getResidual()*1.0e12,
1885  qPrintable(useChar2),
1886  o->activeDelay()->sigma2Apply()*1.0e12,
1887  // delay rate:
1888  o->phDRate().getValue()*1.0e15,
1889  o->phDRate().getResidual()*1.0e15,
1890  qPrintable(useChar2),
1891  o->phDRate().getSigma()*1.0e15,
1892  //
1893  (int)round(aux_1->getElevationAngle()*RAD2DEG),
1894  (int)round(aux_2->getElevationAngle()*RAD2DEG),
1895  (int)round(aux_1->getAzimuthAngle()*RAD2DEG),
1896  (int)round(aux_2->getAzimuthAngle()*RAD2DEG),
1897  o->activeDelay()->getQ2() + 1.0,
1898  o->getQualityFactor(), qPrintable(sQcOb),
1899  o->getSnr(), dSnrOb
1900  );
1901 // 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
1902 // 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
1903 //
1904 // mk5_merge_v03/progs/solve/cres/secnd.f:
1905 // WRITE ( 23, 120 ) IOBS, IDLT, ISITN_CHR(ISITE(1)), &
1906 // & ISITN_CHR(ISITE(2)), ISTRN_CHR(ISTAR), STR_DATE(1:21), &
1907 // & FOBS*1.D3, DOC*1.D3, IPUNC, DOERR*1.D3, &
1908 // & ROBS*1.D3, ROC*1.D3, IPUNC, RERR*1.D3, &
1909 // & IPELV, IPAZ, COEF_IONO, LQUAL_CHR, LQUALXS_CHR, &
1910 // & SNR, SNR_S
1911 //
1912 // 120 FORMAT ( I7, A1, 1X, A8, "/", A8, 1X, A, 1X, A, 1X, &
1913 // & 2(F14.0, F8.0, 1X, A1, 1X, F6.0), 4I4, 2X, F9.6, &
1914 // & 1X, A2, '/', A2, 1X, F6.1, ' / ', F6.1 )
1915 // 120 FORMAT (
1916 // I7, IOBS
1917 // A1, 1X, IDLT
1918 // A8, "/", ISITN_CHR(ISITE(1)),
1919 // A8, 1X, ISITN_CHR(ISITE(2))
1920 // A, 1X, ISTRN_CHR(ISTAR)
1921 // A, 1X, STR_DATE(1:21),
1922 // 2(F14.0, F8.0, 1X, A1, 1X, F6.0),
1923 //==FOBS*1.D3, DOC*1.D3, IPUNC, DOERR*1.D3,
1924 //==ROBS*1.D3, ROC*1.D3, IPUNC, RERR*1.D3,
1925 // 4I4, 2X, IPELV IPAZ arrays?
1926 // F9.6, 1X, COEF_IONO,
1927 // A2, '/', LQUAL_CHR
1928 // A2, 1X, LQUALXS_CHR
1929 // F6.1, ' / ', SNR
1930 // F6.1 SNR_S
1931  ts << qPrintable(str) << "\n";
1932  };
1933  };
1934 
1935  ts << "\n";
1936 };
1937 
1938 
1939 
1940 //
1942 {
1943  ts << " Met Statistics:\n"
1944  << " Temperature Pressure Humidity\n"
1945  <<" Station average rms average rms average rms\n";
1946 
1947  QString str;
1948  StationsByName_it it;
1949  it=session_->stationsByName().begin();
1950 
1951  for (it=session_->stationsByName().begin(); it!=session_->stationsByName().end(); ++it)
1952  {
1953  SgVlbiStationInfo *si=it.value();
1954  str.sprintf(" %-8s MET",
1955  qPrintable(si->getKey()));
1956  ts << str;
1957 
1958  int num;
1959  double sumT_1, sumT_2, sumP_1, sumP_2, sumH_1, sumH_2;
1960  double rmsT, rmsP, rmsH, d;
1961  sumT_1 = sumT_2 = sumP_1 = sumP_2 = sumH_1 = sumH_2 = 0.0;
1962  rmsT = rmsP = rmsH = 0.0;
1963  num = 0;
1964 // QMap<SgMJD, SgVlbiAuxObservation*>::iterator jt;
1965 // for (jt=si->auxObservationByEpoch()->begin(); jt!=si->auxObservationByEpoch()->end(); ++jt)
1966  QMap<QString, SgVlbiAuxObservation*>::iterator jt;
1967  for (jt=si->auxObservationByScanId()->begin(); jt!=si->auxObservationByScanId()->end(); ++jt)
1968  {
1969  SgVlbiAuxObservation *auxObs=jt.value();
1971  {
1972  double t, p, h;
1973  t = auxObs->getMeteoData().getTemperature();
1974  p = auxObs->getMeteoData().getPressure();
1975  h = auxObs->getMeteoData().getRelativeHumidity()*100.0;
1976  sumT_1 += t;
1977  sumT_2 += t*t;
1978  sumP_1 += p;
1979  sumP_2 += p*p;
1980  sumH_1 += h;
1981  sumH_2 += h*h;
1982  num++;
1983  };
1984  };
1985  if (num>0)
1986  {
1987  d = sumT_2 - sumT_1*sumT_1/num;
1988  if (d<=0.0 && fabs(d)/sumT_2<1.0e-12)
1989  rmsT = 0.0;
1990  else
1991  rmsT = sqrt(d/num);
1992  d = sumP_2 - sumP_1*sumP_1/num;
1993  if (d<=0.0 && fabs(d)/sumP_2<1.0e-12)
1994  rmsP = 0.0;
1995  else
1996  rmsP = sqrt(d/num);
1997  d = sumH_2 - sumH_1*sumH_1/num;
1998  if (d<=0.0 && fabs(d)/sumH_2<1.0e-12)
1999  rmsH = 0.0;
2000  else
2001  rmsH = sqrt(d/num);
2002  str.sprintf(" %6.1f %6.1f %6.1f %6.1f%8.1f %7.1f",
2003  sumT_1/num, rmsT, sumP_1/num, rmsP, sumH_1/num, rmsH);
2004  }
2005  else
2006  str = " -999.0 0.0 -999.0 0.0-99900.0 0.0";
2007  ts << str << "\n";
2008  };
2009  ts << "\n";
2010 };
2011 
2012 
2013 
2014 //
2016 {
2017  const int qCodeLimit(config_->getQualityCodeThreshold());
2018  QString str;
2019  int numRecObs, numRec59Obs, numProcdObs, num;
2020  int nYear, nMonth, nDay, nHour, nMin;
2021  int numOfBands;
2022  double dSec, fInterval;
2023  int numProcRateObs;
2024  double rmsDelay(0.0), nrmsDelay(0.0), chi2Delay(0.0);
2025  double rmsRate(0.0), nrmsRate(0.0), chi2Rate(0.0);
2026  double nrmsCombined(0.0), chi2Combined(0.0);
2027  double sum1d, sum2d;
2028  double sum1r, sum2r;
2029  SgMJD t(session_->getTStart());
2031  numOfBands = session_->bands().size();
2032 
2033 //pBand = session_->primaryBand();
2034  SgMJD::MJD_reverse(t.getDate(), t.getTime(), nYear, nMonth, nDay, nHour, nMin, dSec);
2035  fInterval = session_->getTFinis() - t;
2036 
2037  numProcdObs = activeBand_->numProcessed(dType);
2038  numRecObs = numProcRateObs = numRec59Obs = 0;
2039  numRecObs = session_->primaryBand()->numUsable(DT_DELAY);
2040  // clear "num of recoverable obs" per object values:
2041  /*
2042  for (StationsByName_it it=activeBand_->stationsByName().begin();
2043  it!=activeBand_->stationsByName().end(); ++it)
2044  it.value()->setNumUsable(DT_DELAY, 0);
2045  for (BaselinesByName_it it=activeBand_->baselinesByName().begin();
2046  it!=activeBand_->baselinesByName().end(); ++it)
2047  it.value()->setNumUsable(DT_DELAY, 0);
2048  for (SourcesByName_it it=activeBand_->sourcesByName().begin();
2049  it!=activeBand_->sourcesByName().end(); ++it)
2050  it.value()->setNumUsable(DT_DELAY, 0);
2051  */
2052  for (int i=0; i<session_->observations().size(); i++)
2053  {
2054  SgVlbiObservation *obs=session_->observations().at(i);
2055  bool isOk=obs->observableByKey().size()==numOfBands;
2056  bool isOk59=obs->observableByKey().size()==numOfBands;
2057 
2058  for (QMap<QString, SgVlbiObservable*>::iterator it=obs->observableByKey().begin();
2059  it!=obs->observableByKey().end(); ++it)
2060  {
2061  int qCode=it.value()->getQualityFactor();
2062  isOk = isOk && qCode>=qCodeLimit;
2063  isOk59 = isOk59 && qCode>=5;
2064  };
2065 /*
2066  if (isOk)
2067  {
2068  numRecObs++;
2069  int idx;
2070  idx = obs->getStation1Idx();
2071  if (activeBand_->stationsByIdx().contains(idx))
2072  activeBand_->stationsByIdx().find(idx).value()->incNumUsable(DT_DELAY);
2073 
2074  idx = obs->getStation2Idx();
2075  if (activeBand_->stationsByIdx().contains(idx))
2076  activeBand_->stationsByIdx().find(idx).value()->incNumUsable(DT_DELAY);
2077 
2078  idx = obs->getSourceIdx();
2079  if (activeBand_->sourcesByIdx().contains(idx))
2080  activeBand_->sourcesByIdx().find(idx).value()->incNumUsable(DT_DELAY);
2081 
2082  idx = obs->getBaselineIdx();
2083  if (activeBand_->baselinesByIdx().contains(idx))
2084  activeBand_->baselinesByIdx().find(idx).value()->incNumUsable(DT_DELAY);
2085  };
2086 */
2087  if (isOk59)
2088  numRec59Obs++;
2089  };
2090  sum1r = sum2r = sum1d = sum2d = 0.0;
2091  num = 0;
2092  for (int i=0; i<session_->observations().size(); i++)
2093  {
2094  SgVlbiObservation *obs=session_->observations().at(i);
2096  {
2097  sum1d += obs->getNormalizedDelayResidual();
2099  sum1r += obs->getNormalizedRateResidual();
2101  num++;
2102  };
2103  };
2104  if (num != numProcdObs)
2105  std::cout << "num != numProcdObs: " << num << " vs " << numProcdObs << "\n";
2106  rmsDelay = activeBand_->wrms(dType)*1.0E12;
2107  nrmsDelay = sqrt((sum2d - sum1d*sum1d/num)/num);
2108 //chi2Delay = activeBand_->chi2(dType)/session_->getNumOfDOF();
2109  chi2Delay = activeBand_->reducedChi2(dType);
2110 
2112  {
2113  numProcRateObs = activeBand_->numProcessed(DT_RATE);
2114  rmsRate = activeBand_->wrms(DT_RATE)*1.0e15;
2115  nrmsRate = sqrt((sum2r - sum1r*sum1r/num)/num);
2116 // chi2Rate = activeBand_->chi2(DT_RATE)/dof;
2117  chi2Rate = activeBand_->reducedChi2(DT_RATE);
2118  };
2119 
2120  str.sprintf(" Run %10s %7d Observation Pairs Available ",
2121  qPrintable(reportID_), session_->observations().size());
2122  ts << str << "\n";
2123 
2124  str.sprintf(" Session started on: %14.6f %04d.%02d.%02d %02d:%02d:%06.3f UTC",
2125  t.toDouble() + 2400000.5,
2126  nYear, nMonth, nDay, nHour, nMin, dSec);
2127  ts << str << "\n";
2128 
2129  nDay = (int)trunc(fInterval);
2130  fInterval = fInterval - nDay;
2131 
2132  fInterval *= DAY2SEC;
2133  nHour = (int)(fInterval/3600.0);
2134  nMin = (int)((fInterval - 3600.0*nHour)/60.0);
2135  dSec = fInterval - 3600.0*nHour - 60.0*nMin;
2136  str.sprintf(" Actual duration: %9.3f sec %02d %02d:%02d:%06.3f sec",
2137  fInterval + nDay*DAY2SEC, nDay, nHour, nMin, dSec);
2138  ts << str << "\n";
2139 
2140  str.sprintf(" Solution type: %-17s ",
2141  qPrintable(solutionTypeName_));
2142  ts << str << "\n\n";
2143 
2144  ts <<
2145  " Data Type Number of Weighted RMS Normalized RMS Chi Square" << "\n"
2146  " Observations Residual Residual (precis)" << "\n"
2147  " Used" << "\n"
2148  " " << "\n";
2149 
2150  str.sprintf(" Delay %8d %18.3f ps %17.2f %12.4f",
2151  numProcdObs, rmsDelay, nrmsDelay, chi2Delay);
2152  ts << str << "\n";
2153 
2154  str.sprintf(" Rate %8d %18g fs/s %15.2f %12.4f",
2155  numProcRateObs, rmsRate, nrmsRate, chi2Rate);
2156  ts << str << "\n";
2157 
2158  str.sprintf("Combined %8d %15.2f %12.4f",
2159  0, nrmsCombined, chi2Combined);
2160  ts << str << "\n";
2161 
2162  ts << "----------------------------------------------------------------------- \n";
2163  // << " CRES mode: ?????? \n"
2164  // << " Suppression method in use: ????????????? \n";
2165 
2166  str.sprintf(" Used quality_code_limit: %3d ",
2167  qCodeLimit);
2168  ts << str << "\n";
2169 
2170  str.sprintf(" Number of potentially recoverable observations: %8d ",
2171  numRecObs);
2172  ts << str << "\n";
2173 
2174  str.sprintf(" Number of potentially good observations with QC 5-9:%7d ",
2175  numRec59Obs);
2176  ts << str << "\n";
2177 
2178  str.sprintf(" Number of used observations: %8d (%6.2f%%) ",
2179  numProcdObs, numProcdObs*100.0/numRecObs);
2180  ts << str << "\n";
2181 
2182  str.sprintf(" Number of suppressed observations: %8d (%6.2f%%) ",
2183  (numRecObs - numProcdObs), (numRecObs - numProcdObs)*100.0/numRecObs);
2184  ts << str << "\n";
2185 
2186  ts << "----------------------------------------------------------------------- \n\n\n\n";
2187 };
2188 
2189 
2190 
2191 //
2193 {
2194  QString str;
2195  // print a header:
2196  ts
2197  << " Baseline Statistics\n"
2198  << " Baseline # W.Obs W.RMS Del N.R.D. N.R.D. W.RMS Rate N.R.R. "
2199  << "D.RW R.RW \n"
2200  << " used/recov ps standard ( 15ps+i) fs/s "
2201  << "ps fs/s \n\n";
2202 
2203  // colect a list of "supressed" stations:
2204  QMap<QString, SgVlbiStationInfo*> skippedStationsByName;
2205  QMap<QString, SgVlbiStationInfo*>::iterator itSi;
2206  for (itSi=session_->stationsByName().begin(); itSi!=session_->stationsByName().end(); ++itSi)
2207  {
2208  SgVlbiStationInfo *si=itSi.value();
2210  skippedStationsByName.insert(si->getKey(), si);
2211  };
2212  // report baselines' statistics:
2213  QList<SgVlbiBaselineInfo*> skippedBaselines;
2214  QMap<QString, SgVlbiBaselineInfo*>::iterator it;
2215  for (it=activeBand_->baselinesByName().begin(); it!=activeBand_->baselinesByName().end(); ++it)
2216  {
2217  SgVlbiBaselineInfo *bi=it.value();
2218  QString biName=bi->getKey();
2219  QString st1Name=biName.left(8);
2220  QString st2Name=biName.right(8);
2222  !skippedStationsByName.contains(st1Name) &&
2223  !skippedStationsByName.contains(st2Name) )
2224  {
2225 // 1 2 3 4 5 6 7 8 9 10
2226 //01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
2227 // HOBART12-KATH12M 967/ 1004 37 0.97 1.38 202 5.40 29 0
2228 // HOBART12-YARRA12M 947/ 982 42 0.97 1.52 227 5.19 36 0
2229 // KATH12M -YARRA12M 1009/ 1029 32 0.95 1.24 216 4.74 26 0
2230 
2231  str.sprintf(" %-17s%5d/%5d%8.1f %9.2f %9.2f %7.1f %10.2f%7.1f%7.1f",
2232  qPrintable(biName.replace(8, 1, "-")),
2234  bi->wrms(DT_DELAY)*1.0E12,
2235 
2236 // bi->getNrmRes(),
2237  bi->getSFF_NrmRes(DT_DELAY),
2239 // 0.0, // nrd (15ps+i) ?
2240  bi->wrms(DT_RATE)*1.0E15, // wrms rate
2241  bi->getSFF_NrmRes(DT_RATE), // nrr
2242  bi->getSigma2add(DT_DELAY)*1.0E12,
2243  bi->getSigma2add(DT_RATE )*1.0E15 // rate's sigma2add
2244  );
2245  ts << str << "\n";
2246  }
2247  else
2248  skippedBaselines.append(bi);
2249  };
2250  ts << "\n\n";
2251 
2252  if (skippedBaselines.size())
2253  {
2254  ts << " Not included: \n\n";
2255  for (int i=0; i<skippedBaselines.size(); i++)
2256  {
2257  SgVlbiBaselineInfo *bi=skippedBaselines.at(i);
2258  QString biName=bi->getKey();
2259  str.sprintf(" %-17s%5d/%5d deselected",
2260  qPrintable(biName.replace(8, 1, "-")),
2262  ts << str << "\n";
2263  };
2264  ts << "\n\n";
2265  };
2266  // clear aux stuff:
2267  skippedStationsByName.clear();
2268  skippedBaselines.clear();
2269 };
2270 
2271 
2272 
2273 //
2275 {
2276  QString str;
2277  // print a header:
2278  ts
2279  << " Source Statistics \n"
2280  << " Source # W.Obs W.RMS Del N.R.D. N.R.D. W.RMS Rate N.R.R. \n"
2281  << " ps standard ( 15ps) fs/s \n \n";
2282 
2283  usedSources_.clear();
2284  skippedSources_.clear();
2285  QMap<QString, SgVlbiSourceInfo*>::iterator it;
2286  for (it=activeBand_->sourcesByName().begin(); it!=activeBand_->sourcesByName().end(); ++it)
2287  {
2288  SgVlbiSourceInfo *si=it.value();
2290  usedSources_.append(si);
2291  else
2292  skippedSources_.append(si);
2293  };
2294  // sort in RA order:
2297  // report sources' statistics:
2298  for (int i=0; i<usedSources_.size(); i++)
2299  {
2300  // 0059+581 A 58/ 60 655 0.33 29.76 195 0.77
2301  SgVlbiSourceInfo *si=usedSources_.at(i);
2302  str.sprintf(" %12s %1s %5d/%5d%8.1f %9.2f %8.2f %7.1f %10.2f",
2303  qPrintable(si->getKey()), qPrintable(srcChars[i % numOfSrcChars]),
2304  si->numProcessed(DT_DELAY), si->numUsable(DT_DELAY),// numbers of observations, processed and total
2305  si->wrms(DT_DELAY)*1.0E12, // WRMS delay
2306  si->getSFF_NrmRes(DT_DELAY), // nomalized residuals
2307  si->getSFF_NrmRes_plus_15(DT_DELAY), // nomalized residuals with fixed aux. weight
2308  si->wrms(DT_RATE)*1.0E15, // wrms rate
2309  si->getSFF_NrmRes(DT_RATE) // nrr
2310  );
2311  ts << str << "\n";
2312  };
2313  ts << "\n\n";
2314 
2315  if (skippedSources_.size())
2316  {
2317  ts << " Not included: \n\n";
2318  for (int i=0; i<skippedSources_.size(); i++)
2319  {
2321  str.sprintf(" %-10s%5d/%5d deselected",
2322  qPrintable(si->getKey()),
2324  ts << str << "\n";
2325  };
2326  ts << "\n\n";
2327  };
2328  //
2329  // at the end, collect stats from session level:
2330  usedSources_.clear();
2331  skippedSources_.clear();
2332  for (it=session_->sourcesByName().begin(); it!=session_->sourcesByName().end(); ++it)
2333  {
2334  SgVlbiSourceInfo *si=it.value();
2336  usedSources_.append(si);
2337  else
2338  skippedSources_.append(si);
2339  };
2340  // sort in RA order:
2343 };
2344 
2345 
2346 
2347 //
2349 {
2350  QString str;
2351  // print a header:
2352  ts
2353  << " Station Statistics \n"
2354  << " Station # W.Obs W.RMS Del N.R.D. N.R.D. W.RMS Rate N.R.R. \n"
2355  << " ps standard ( 15ps) fs/s \n \n";
2356 
2357 //pBand = session_->primaryBand();
2358  // report stations' statistics:
2359  QList<SgVlbiStationInfo*> skippedStations;
2360  QMap<QString, SgVlbiStationInfo*>::iterator it;
2361  for (it=activeBand_->stationsByName().begin(); it!=activeBand_->stationsByName().end(); ++it)
2362  {
2363  SgVlbiStationInfo *si=it.value();
2365  {
2366  str.sprintf(" %12s %5d/%5d%8.1f %9.2f %8.2f %7.1f %10.2f",
2367  qPrintable(si->getKey()),
2369  si->wrms(DT_DELAY)*1.0E12,
2370 // si->getNrmRes(),
2371  si->getSFF_NrmRes(DT_DELAY),
2373 // 0.0, // nrd (15ps+i) ?
2374  si->wrms(DT_RATE)*1.0E15, // wrms rate
2375  si->getSFF_NrmRes(DT_RATE) // nrr
2376  );
2377  ts << str << "\n";
2378  }
2379  else
2380  skippedStations.append(si);
2381  };
2382  ts << "\n\n";
2383 
2384  if (skippedStations.size())
2385  {
2386  ts << " Not included: \n\n";
2387  for (int i=0; i<skippedStations.size(); i++)
2388  {
2389  SgVlbiStationInfo *si=skippedStations.at(i);
2390  str.sprintf(" %-10s%5d/%5d deselected",
2391  qPrintable(si->getKey()),
2393  ts << str << "\n";
2394  };
2395  ts << "\n\n";
2396  };
2397  // clear aux stuff:
2398  skippedStations.clear();
2399 };
2400 
2401 
2402 
2403 //
2405 {
2406  QString path2AF;
2407  if (path2APrioriFiles_.at(0)=='/')
2408  path2AF = path2APrioriFiles_;
2409  else
2410  path2AF = identities_.getCurrentDir() + "/" + path2APrioriFiles_;
2411 
2412  ts
2413  << " *** Flyby Status ***\n\n"
2414  << " directory: " << qPrintable(path2AF) << "\n\n"
2415  << "Station Source Nutation Nutation Earth Earth Station "
2416  << "Pressure EOP Intp. EOP Intp. High Freq Axis \n"
2417  << "Positions Positions Model Time Rotation Rotation Velocity "
2418  << "Loading Smoothing Smoothing EOP Offset \n"
2419  << " Series Series Interpol. Model "
2420  << " CALC Mod File Model Mod File \n"
2421  << "--------- --------- --------- --------- --------- --------- --------- "
2422  << "--------- --------- --------- --------- ---------\n";
2423  // Station Positions
2424  ts << qPrintable((config_->getUseExtAPrioriSitesPositions() ?
2425  config_->getExtAPrioriSitesPositionsFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2426  // Source Positions
2427  ts << qPrintable((config_->getUseExtAPrioriSourcesPositions() ?
2428  config_->getExtAPrioriSourcesPositionsFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2429  // Nutation Model
2430  ts << qPrintable(QString("NONE").leftJustified(9, ' ', true)) << " ";
2431  // Nutation Time Series
2432  ts << qPrintable(QString("NONE").leftJustified(9, ' ', true)) << " ";
2433  // Earth Rotation Series
2434  ts << qPrintable((config_->getUseExtAPrioriErp() ?
2435  config_->getExtAPrioriErpFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2436  // Earth Rotation Interpol.
2437  ts << qPrintable((config_->getUseExtAPrioriErp() ?
2438  QString("C. Spline") : "NONE").leftJustified(9, ' ', true)) << " ";
2439  // Station Velocity Model
2440  ts << qPrintable((config_->getUseExtAPrioriSitesVelocities() ?
2441  config_->getExtAPrioriSitesVelocitiesFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2442  // Pressure Loading
2443  ts << qPrintable(QString("NONE").leftJustified(9, ' ', true)) << " ";
2444  // EOP Intp. Smoothing CALC
2445  ts << qPrintable(QString("NO_ZONAL").leftJustified(9, ' ', true)) << " ";
2446  // EOP Intp. Smoothing Mod File
2447  ts << qPrintable(QString("N/A").leftJustified(9, ' ', true)) << " ";
2448  // High Freq EOP Model
2449  ts << qPrintable((config_->getUseExtAPrioriHiFyErp() ?
2450  config_->getExtAPrioriHiFyErpFileName() : "NONE").leftJustified(9, ' ', true)) << " ";
2451  // Axis Offset Mod File
2452  ts << qPrintable((config_->getUseExtAPrioriAxisOffsets() ?
2453  config_->getExtAPrioriAxisOffsetsFileName() : "NONE").leftJustified(9, ' ', true)) << " \n\n";
2454  //
2455  ts << "Site Plate Map: " << qPrintable(path2AF) << "/sitpl.dat \n\n";
2456 };
2457 
2458 
2459 
2460 //
2462 {
2463  static const double clcScaleVals[10] =
2464  {1.0e09, 1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0,
2465  1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0, 1.0e14/86400.0};
2466  static const QString clcScaleNames[10] =
2467  {"ns ", "D-14 ", "D-14/day ", "D-14/day^2", "D-14/day^3",
2468  "D-14/day^4", "D-14/day^5", "D-14/day^6", "D-14/day^7", "D-14/day^8"};
2469 
2470  QString str;
2471  int idx;
2472  SgPwlStorage *pwl=NULL;
2473  double chi;
2475 
2476 // if (session_->primaryBand()->getChi2()>0.0)
2477 // chi = sqrt(session_->primaryBand()->getChi2()/session_->primaryBand()->getNumOfDOF());
2478  if (activeBand_->chi2(dType) > 0.0)
2479 // chi = sqrt(activeBand_->chi2(dType)/session_->getNumOfDOF());
2480  chi = sqrt(activeBand_->reducedChi2(dType));
2481  else
2482  chi = 1.0; // do not scale at all
2483  // SgArcStorage *arc=NULL;
2484 
2485  ts
2486  << " Parameter adjustments for run " << qPrintable(reportID_)
2487  << " User=" << qPrintable(identities_.getUserDefaultInitials()) << "\n"
2488  << " Reference epoch for polynomial models: "
2489  << qPrintable(session_->tRefer().toString(SgMJD::F_SOLVE_SPLFL_SHORT)) << "\n"
2490  << " Parameter"
2491  << " Adjustment a-sigma m-sigma\n";
2492 
2493  StationsByName_it it_st;
2494  // reference clocks:
2495  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
2496  {
2497  SgVlbiStationInfo *si=it_st.value();
2500  {
2501  SgMJD t=*si->auxObservationByScanId()->begin().value();
2502  // WESTFORD CLCK 12/06/21 18:29 Reference
2503  str.sprintf(" %8s CLCK %s Reference",
2504  qPrintable(si->getKey()),
2505  qPrintable(t.toString(SgMJD::F_SOLVE_SPLFL_SHORT)));
2506  ts << str << "\n";
2507  };
2508  };
2509 
2510  idx = 1;
2511  // stations:
2512  Sg3dMatrixR W(EAST), V(NORTH);
2513  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
2514  {
2515  SgVlbiStationInfo *si=it_st.value();
2517  {
2518  // coordinates:
2520  {
2521  double cXY, cXZ, cYZ;
2522  double latitude, longitude, height;
2523  Sg3dVector r, rs;
2524  Sg3dVector r_apriori(si->getR());
2525  Sg3dMatrix m3M;
2526  SgMJD t(si->pRx()->getTMean());
2528  r_apriori = si->getR_ea() + si->getV_ea()*(t - session_->getApStationVelocities().getT0());
2529 
2530  geocentric2geodetic(r_apriori, latitude, longitude, height, config_->getIsSolveCompatible());
2531  m3M = W(-latitude)*V(longitude);
2532 
2533  // covariances (i.e., rho_{1,2}*sigma_1*sigma_2):
2534  cXY = PxAll_->getElement(si->pRx()->getIdx(), si->pRy()->getIdx());
2535  cXZ = PxAll_->getElement(si->pRx()->getIdx(), si->pRz()->getIdx());
2536  cYZ = PxAll_->getElement(si->pRy()->getIdx(), si->pRz()->getIdx());
2537 
2538  // evaluate displacement in VEN:
2539  r = m3M*Sg3dVector(si->pRx()->getSolution(), si->pRy()->getSolution(), si->pRz()->getSolution());
2540  // evaluate std. deviations:
2541  rs(VERTICAL) = sqrt(
2542  m3M.at(VERTICAL, X_AXIS)*m3M.at(VERTICAL, X_AXIS)*si->pRx()->getSigma()*si->pRx()->getSigma() +
2543  m3M.at(VERTICAL, Y_AXIS)*m3M.at(VERTICAL, Y_AXIS)*si->pRy()->getSigma()*si->pRy()->getSigma() +
2544  m3M.at(VERTICAL, Z_AXIS)*m3M.at(VERTICAL, Z_AXIS)*si->pRz()->getSigma()*si->pRz()->getSigma() +
2545  2.0*(m3M.at(VERTICAL, X_AXIS)*m3M.at(VERTICAL, Y_AXIS)*cXY +
2546  m3M.at(VERTICAL, X_AXIS)*m3M.at(VERTICAL, Z_AXIS)*cXZ +
2547  m3M.at(VERTICAL, Y_AXIS)*m3M.at(VERTICAL, Z_AXIS)*cYZ
2548  )
2549  );
2550  rs(EAST) = sqrt(
2551  m3M.at(EAST, X_AXIS)*m3M.at(EAST, X_AXIS)*si->pRx()->getSigma()*si->pRx()->getSigma() +
2552  m3M.at(EAST, Y_AXIS)*m3M.at(EAST, Y_AXIS)*si->pRy()->getSigma()*si->pRy()->getSigma() +
2553  m3M.at(EAST, Z_AXIS)*m3M.at(EAST, Z_AXIS)*si->pRz()->getSigma()*si->pRz()->getSigma() +
2554  2.0*(m3M.at(EAST, X_AXIS)*m3M.at(EAST, Y_AXIS)*cXY +
2555  m3M.at(EAST, X_AXIS)*m3M.at(EAST, Z_AXIS)*cXZ +
2556  m3M.at(EAST, Y_AXIS)*m3M.at(EAST, Z_AXIS)*cYZ
2557  )
2558  );
2559  rs(NORTH) = sqrt(
2560  m3M.at(NORTH, X_AXIS)*m3M.at(NORTH, X_AXIS)*si->pRx()->getSigma()*si->pRx()->getSigma() +
2561  m3M.at(NORTH, Y_AXIS)*m3M.at(NORTH, Y_AXIS)*si->pRy()->getSigma()*si->pRy()->getSigma() +
2562  m3M.at(NORTH, Z_AXIS)*m3M.at(NORTH, Z_AXIS)*si->pRz()->getSigma()*si->pRz()->getSigma() +
2563  2.0*(m3M.at(NORTH, X_AXIS)*m3M.at(NORTH, Y_AXIS)*cXY +
2564  m3M.at(NORTH, X_AXIS)*m3M.at(NORTH, Z_AXIS)*cXZ +
2565  m3M.at(NORTH, Y_AXIS)*m3M.at(NORTH, Z_AXIS)*cYZ
2566  )
2567  );
2568 
2569  ts << "Station positions are for epoch: "
2570  << qPrintable(si->pRx()->getTMean().toString(SgMJD::F_SOLVE_SPLFL)) << "\n";
2571  str.sprintf("%5d. %-8s %04d %4s X 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(X_AXIS) + si->pRx()->getSolution())*1000.0,
2574  si->pRx()->getSolution()*1000.0,
2575  si->pRx()->getSigma()*1000.0,
2576  si->pRx()->getSigma()*1000.0*chi );
2577  ts << str << "\n";
2578  idx++;
2579 
2580  str.sprintf("%5d. %-8s %04d %4s Y 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(Y_AXIS) + si->pRy()->getSolution())*1000.0,
2583  si->pRy()->getSolution()*1000.0,
2584  si->pRy()->getSigma()*1000.0,
2585  si->pRy()->getSigma()*1000.0*chi );
2586  ts << str << "\n";
2587  idx++;
2588 
2589  str.sprintf("%5d. %-8s %04d %4s Z Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2590  idx, qPrintable(si->getKey()), si->getCdpNumber(), qPrintable(si->getTectonicPlateName()),
2591  (r_apriori.at(Z_AXIS) + si->pRz()->getSolution())*1000.0,
2592  si->pRz()->getSolution()*1000.0,
2593  si->pRz()->getSigma()*1000.0,
2594  si->pRz()->getSigma()*1000.0*chi );
2595  ts << str << "\n";
2596  idx++;
2597 
2598  // the same but in VEN:
2599  str.sprintf(" %-8s %04d U Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2600  qPrintable(si->getKey()), si->getCdpNumber(),
2601  r.at(VERTICAL)*1000.0,
2602  r.at(VERTICAL)*1000.0,
2603  rs.at(VERTICAL)*1000.0,
2604  rs.at(VERTICAL)*1000.0*chi);
2605  ts << str << "\n";
2606  str.sprintf(" %-8s %04d E Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2607  qPrintable(si->getKey()), si->getCdpNumber(),
2608  r.at(EAST)*1000.0,
2609  r.at(EAST)*1000.0,
2610  rs.at(EAST)*1000.0,
2611  rs.at(EAST)*1000.0*chi);
2612  ts << str << "\n";
2613  str.sprintf(" %-8s %04d N Comp %14.2f mm %14.3f mm %14.3f mm %14.3f mm",
2614  qPrintable(si->getKey()), si->getCdpNumber(),
2615  r.at(NORTH)*1000.0,
2616  r.at(NORTH)*1000.0,
2617  rs.at(NORTH)*1000.0,
2618  rs.at(NORTH)*1000.0*chi);
2619  ts << str << "\n";
2620  };
2621  // axis offset:
2623  {
2624  double vAxisOffset, sAxisOffset;
2626  vAxisOffset+= si->pAxisOffset()->getSolution();
2627  sAxisOffset = si->pAxisOffset()->getSigma();
2628 
2629  str.sprintf("%5d. %-8s Axis Offset %24.2f mm %14.3f mm %18.3f mm %18.3f mm",
2630  idx,
2631  qPrintable(si->getKey()),
2632  vAxisOffset*1.0e3,
2633  si->pAxisOffset()->getSolution()*1.0e3,
2634  sAxisOffset*1.0e3,
2635  sAxisOffset*1.0e3*chi );
2636  ts << str << "\n";
2637  idx++;
2638  };
2639  //
2640  // clocks:
2641  SgMJD t=*si->auxObservationByScanId()->begin().value();
2642  if (si->pClock0()->getPMode() != SgParameterCfg::PM_NONE)
2643  {
2644  int nPwl, nLoc, nMax;
2645  double *dVal, *dSig;
2646  pwl = pwlByName_.contains(si->pClock0()->getName())?
2647  pwlByName_.find(si->pClock0()->getName()).value():NULL;
2648  nPwl = pwl?pwl->getNumOfPolynomials():0;
2649  nLoc = si->getClocksModelOrder();
2650  nMax = std::max(nPwl, nLoc);
2651  dVal = new double[nMax];
2652  dSig = new double[nMax];
2653  for (int i=0; i<nMax; i++)
2654  dVal[i] = dSig[i] = 0.0;
2655  for (int i=0; i<nLoc; i++)
2656  {
2657  dVal[i] = si->getEstClockModel(i);
2658  dSig[i] = si->getEstClockModelSigma(i);
2659  };
2660  for (int i=0; i<nPwl; i++)
2661  {
2662  dVal[i]+= pwl->getP_Ai(i)->getSolution();
2663  dSig[i] = pwl->getP_Ai(i)->getSigma();
2664  };
2665  for (int i=0; i<nMax; i++)
2666  {
2667  str.sprintf("%5d. %-8s CL %1d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2668  idx, qPrintable(si->getKey()), i,
2669  qPrintable(t.toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2670  dVal[i]*clcScaleVals[i], qPrintable(clcScaleNames[i]),
2671  dSig[i]*clcScaleVals[i], qPrintable(clcScaleNames[i]),
2672  dSig[i]*clcScaleVals[i]*chi, qPrintable(clcScaleNames[i]));
2673  ts << str << "\n";
2674  idx++;
2675  };
2676  delete[] dVal;
2677  delete[] dSig;
2678  // adjust index for pwl/arc parameters (clocks):
2679  if (pwlByName_.contains(si->pClock0()->getName()))
2680  idx += pwlByName_.find(si->pClock0()->getName()).value()->getNumOfNodes();
2681  else if (arcByName_.contains(si->pClock0()->getName()))
2682  idx += arcByName_.find(si->pClock0()->getName()).value()->getNum();
2683  };
2684  if (si->clockBreaks().size())
2685  {
2686  si->clockBreaks().sortEvents();
2687  for (int j=0; j<si->clockBreaks().size(); j++)
2688  {
2689  SgParameterBreak *pb=si->clockBreaks().at(j);
2691  {
2692  if (pb->pA0())
2693  {
2694 // 219. SVETLOE BR 0 15/07/31 07:19 3.006 ns 0.022 ns 0.022 ns
2695  str.sprintf("%5d. %-8s BR %1d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2696  idx, qPrintable(si->getKey()), 0,
2697  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2698  pb->pA0()->getSolution()*clcScaleVals[0], qPrintable(clcScaleNames[0]),
2699  pb->pA0()->getSigma()*clcScaleVals[0], qPrintable(clcScaleNames[0]),
2700  pb->pA0()->getSigma()*clcScaleVals[0]*chi, qPrintable(clcScaleNames[0]));
2701  ts << str << "\n";
2702  idx++;
2703  };
2704  if (pb->pA1() && si->getClocksModelOrder()>1)
2705  {
2706 // 220. SVETLOE BR 1 15/07/31 07:19 -2.092 D-14 1.794 D-14 1.816 D-14
2707  str.sprintf("%5d. %-8s BR %1d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2708  idx, qPrintable(si->getKey()), 1,
2709  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2710  pb->pA1()->getSolution()*clcScaleVals[1], qPrintable(clcScaleNames[1]),
2711  pb->pA1()->getSigma()*clcScaleVals[1], qPrintable(clcScaleNames[1]),
2712  pb->pA1()->getSigma()*clcScaleVals[1]*chi, qPrintable(clcScaleNames[1]));
2713  ts << str << "\n";
2714  idx++;
2715  };
2716  if (pb->pA2() && si->getClocksModelOrder()>2)
2717  {
2718 // 221. SVETLOE BR 2 15/07/31 07:19 -2.186 D-14/day 4.439 D-14/day 4.494 D-14/day
2719  str.sprintf("%5d. %-8s BR %1d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2720  idx, qPrintable(si->getKey()), 2,
2721  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2722  pb->pA2()->getSolution()*clcScaleVals[2], qPrintable(clcScaleNames[2]),
2723  pb->pA2()->getSigma()*clcScaleVals[2], qPrintable(clcScaleNames[2]),
2724  pb->pA2()->getSigma()*clcScaleVals[2]*chi, qPrintable(clcScaleNames[2]));
2725  ts << str << "\n";
2726  idx++;
2727  };
2728  }
2729  else
2730  {
2731 //
2732 // 390. YARRA12M BR 0 14/11/13 23:44 0.472 ns 0.075 ns 0.075 ns
2733 //
2734  str.sprintf(" %-8s BR 0 %s #%3d band=* %15.3f ns %15.3f ns %18.3f ns",
2735  qPrintable(si->getKey()),
2736  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)), j,
2737  pb->getA0(),
2738  pb->getS0(),
2739  pb->getS0()*chi);
2740  ts << str << "\n";
2741  };
2742  };
2743  };
2744  // band-dependent breaks:
2745  for (int i=0; i<session_->bands().size(); i++)
2746  {
2747  SgVlbiBand *band=session_->bands().at(i);
2748  if (band->stationsByName().contains(si->getKey()))
2749  {
2750  SgVlbiStationInfo *sib=band->stationsByName().value(si->getKey());
2751  if (sib->clockBreaks().size())
2752  {
2753  sib->clockBreaks().sortEvents();
2754  for (int j=0; j<sib->clockBreaks().size(); j++)
2755  {
2756  SgParameterBreak *pb=sib->clockBreaks().at(j);
2757  str.sprintf(" %-8s BR 0 %s #%3d band=%s %15.3f ns %15.3f ns %18.3f ns",
2758  qPrintable(sib->getKey()),
2759  qPrintable(pb->toString(SgMJD::F_SOLVE_SPLFL_SHORT)), j, qPrintable(band->getKey()),
2760  pb->getA0(),
2761  pb->getS0(),
2762  pb->getS0()*chi);
2763  ts << str << "\n";
2764  };
2765  };
2766  }
2767  else
2769  "::reportEstimationBlock_Output4Spoolfile(): cannot find station " + si->getKey() +
2770  " in the " + band->getKey() + "-band");
2771  };
2772  // zenith delay:
2773  // adjust index for pwl/arc parameters (zenith delay):
2774  if (pwlByName_.contains(si->pZenithDelay()->getName()))
2775  {
2776  pwl = pwlByName_.find(si->pZenithDelay()->getName()).value();
2777  for (int i=0; i<pwl->getNumOfPolynomials(); i++)
2778  {
2779  str.sprintf("%5d. %-8s AT %d %s %20.3f %-s %10.3f %-s %10.3f %-s",
2780  idx, qPrintable(si->getKey()), i,
2781  qPrintable(pwl->tStart().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2782  (i==0 ? pwl->getP_Ai(i)->getSolution() + si->getEstWetZenithDelay() :
2783  pwl->getP_Ai(i)->getSolution() )/vLight*1.0e12, "ps ",
2784  pwl->getP_Ai(i)->getSigma()/vLight*1.0e12, "ps ",
2785  pwl->getP_Ai(i)->getSigma()/vLight*1.0e12*chi, "ps");
2786  ts << str << "\n";
2787  idx++;
2788  };
2789  str.sprintf(" %-8s Atm %s Avg: %9.3f ps Rms: %11.3f ps Tot_Rms: %11.3f ps",
2790  qPrintable(si->getKey()),
2791  qPrintable(
2792  pwl->tMean()
2793  // si->pZenithDelay()->getTMean()
2795  pwl->calcMean()/vLight*1.0e12,
2796  pwl->calcWRMS()/vLight*1.0e12,
2797  pwl->calcWRMS()/vLight*1.0e12*chi);
2798  ts << str << "\n";
2799  idx += pwl->getNumOfNodes();
2800  }
2801  else if (arcByName_.contains(si->pZenithDelay()->getName()))
2802  idx += arcByName_.find(si->pZenithDelay()->getName()).value()->getNum();
2804  {
2805  str.sprintf("%5d. %-8s AT 0 %s %20.3f %-s %10.3f %-s %10.3f %-s",
2806  idx, qPrintable(si->getKey()),
2807  qPrintable(t.toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2808  si->pZenithDelay()->getSolution()/vLight*1.0e12, "ps ",
2809  si->pZenithDelay()->getSigma()/vLight*1.0e12, "ps ",
2810  si->pZenithDelay()->getSigma()/vLight*1.0e12*chi, "ps");
2811  ts << str << "\n";
2812  idx++;
2813  };
2814  //
2815  // adjust index for pwl/arc parameters (gradients):
2816  if (pwlByName_.contains(si->pAtmGradN()->getName()))
2817  {
2818  pwl = pwlByName_.find(si->pAtmGradN()->getName()).value();
2819  if (pwl->getNumOfSegments()==1)
2820  {
2821  SgPwlStorage *pwlGrdN, *pwlGrdE;
2822  pwlGrdN = pwl;
2823  pwlGrdE = pwlByName_.find(si->pAtmGradE()->getName()).value();
2824  // gradient north, left:
2825  str.sprintf("%5d. %-8s NG %s %20.3f %-s %10.3f %-s %10.3f %-s",
2826  idx, qPrintable(si->getKey()),
2827  qPrintable(pwlGrdN->tStart().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2828  pwlGrdN->getP_Bi(0)->getSolution()*1.0e3, "mm ",
2829  pwlGrdN->getP_Bi(0)->getSigma()*1.0e3, "mm ",
2830  pwlGrdN->getP_Bi(0)->getSigma()*1.0e3*chi,"mm ");
2831  ts << str << "\n";
2832  idx++;
2833  // gradient east, left:
2834  str.sprintf("%5d. %-8s EG %s %20.3f %-s %10.3f %-s %10.3f %-s",
2835  idx, qPrintable(si->getKey()),
2836  qPrintable(pwlGrdE->tStart().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2837  pwlGrdE->getP_Bi(0)->getSolution()*1.0e3, "mm ",
2838  pwlGrdE->getP_Bi(0)->getSigma()*1.0e3, "mm ",
2839  pwlGrdE->getP_Bi(0)->getSigma()*1.0e3*chi,"mm ");
2840  ts << str << "\n";
2841  idx++;
2842  // gradient north, right:
2843  str.sprintf("%5d. %-8s NG %s %20.3f %-s %10.3f %-s %10.3f %-s",
2844  idx, qPrintable(si->getKey()),
2845  qPrintable(pwlGrdN->tFinis().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2846  pwlGrdN->getP_Bi(1)->getSolution()*1.0e3, "mm ",
2847  pwlGrdN->getP_Bi(1)->getSigma()*1.0e3, "mm ",
2848  pwlGrdN->getP_Bi(1)->getSigma()*1.0e3*chi,"mm ");
2849  ts << str << "\n";
2850  idx++;
2851  // gradient east, right:
2852  str.sprintf("%5d. %-8s EG %s %20.3f %-s %10.3f %-s %10.3f %-s",
2853  idx, qPrintable(si->getKey()),
2854  qPrintable(pwlGrdE->tFinis().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
2855  pwlGrdE->getP_Bi(1)->getSolution()*1.0e3, "mm ",
2856  pwlGrdE->getP_Bi(1)->getSigma()*1.0e3, "mm ",
2857  pwlGrdE->getP_Bi(1)->getSigma()*1.0e3*chi,"mm ");
2858  ts << str << "\n";
2859  idx++;
2860  }
2861  else // report in the same way as zenith delays:
2862  {
2863  str.sprintf(" %-8s NGr %s Avg: %9.3f ps Rms: %11.3f ps Tot_Rms: %11.3f ps",
2864  qPrintable(si->getKey()),
2865 // qPrintable(si->pAtmGradN()->getTMean().toString(SgMJD::F_SOLVE_SPLFL_LONG)),
2866  qPrintable(pwl->tMean().toString(SgMJD::F_SOLVE_SPLFL_LONG)),
2867  pwl->calcMean()/vLight*1.0e12,
2868  pwl->calcWRMS()/vLight*1.0e12,
2869  pwl->calcWRMS()/vLight*1.0e12*chi);
2870  ts << str << "\n";
2871  idx += pwl->getNumOfNodes() + pwl->getNumOfPolynomials();
2872  pwl = pwlByName_.find(si->pAtmGradE()->getName()).value();
2873  str.sprintf(" %-8s EGr %s Avg: %9.3f ps Rms: %11.3f ps Tot_Rms: %11.3f ps",
2874  qPrintable(si->getKey()),
2875  qPrintable(pwl->tMean().toString(SgMJD::F_SOLVE_SPLFL_LONG)),
2876 // qPrintable(si->pAtmGradN()->getTMean().toString(SgMJD::F_SOLVE_SPLFL_LONG)),
2877  pwl->calcMean()/vLight*1.0e12,
2878  pwl->calcWRMS()/vLight*1.0e12,
2879  pwl->calcWRMS()/vLight*1.0e12*chi);
2880  ts << str << "\n";
2881  idx += pwl->getNumOfNodes() + pwl->getNumOfPolynomials();
2882  };
2883  }
2884  else
2885  {
2886  if (arcByName_.contains(si->pAtmGradN()->getName()))
2887  idx += arcByName_.find(si->pAtmGradN()->getName()).value()->getNum();
2888  if (arcByName_.contains(si->pAtmGradE()->getName()))
2889  idx += arcByName_.find(si->pAtmGradE()->getName()).value()->getNum();
2890  };
2891  ts << "\n";
2892  };
2893  };
2894  //
2895  //
2897  {
2898  for (int i=0; i<usedSources_.size(); i++)
2899  {
2900  SgVlbiSourceInfo *si=usedSources_.at(i);
2901  if (si->pRA()->isAttr(SgParameter::Attr_IS_SOLVED) &&
2903  {
2904  double vRA, vDN;
2905  double d;
2908  vRA+= si->pRA()->getSolution();
2909  vDN+= si->pDN()->getSolution();
2910  //
2911  // RA:
2912  str.sprintf("%5d.%s %-8s RT. ASC. %s %11.4f m-asec %10.4f m-asec %10.4f"
2913  " m-asec",
2914  idx,
2915  qPrintable(srcChars[i % numOfSrcChars]),
2916  qPrintable(si->getKey()),
2917  qPrintable(si->ra2String(vRA)),
2918  si->pRA()->getSolution()*RAD2MAS,
2919  si->pRA()->getSigma()*RAD2MAS,
2920  si->pRA()->getSigma()*RAD2MAS*chi
2921  );
2922  ts << str << "\n";
2923  str.sprintf(" CORRECTION %20.7f\n SCALED SIGMA %20.7f",
2924  si->pRA()->getSolution()*RAD2SEC/15.0,
2925  si->pRA()->getSigma()*RAD2SEC/15.0*chi
2926  );
2927  ts << str << "\n";
2928  ts << "\n";
2929  idx++;
2930 
2931  // DN:
2932  str.sprintf("%5d.%s %-8s DEC. %s %16.4f m-asec %15.4f m-asec %15.4f m-asec",
2933  idx,
2934  qPrintable(srcChars[i % numOfSrcChars]),
2935  qPrintable(si->getKey()),
2936  qPrintable(si->dn2String(vDN)),
2937  si->pDN()->getSolution()*RAD2MAS,
2938  si->pDN()->getSigma()*RAD2MAS,
2939  si->pDN()->getSigma()*RAD2MAS*chi
2940  );
2941  ts << str << "\n";
2942  str.sprintf(" CORRECTION %20.7f\n SCALED SIGMA %20.7f",
2943  si->pDN()->getSolution()*RAD2SEC,
2944  si->pDN()->getSigma()*RAD2SEC*chi
2945  );
2946  ts << str << "\n";
2947  ts << "\n";
2948  idx++;
2949  //
2950  // correlation:
2951  // covariances (i.e., rho_{1,2}*sigma_1*sigma_2):
2952  d = PxAll_->getElement(si->pRA()->getIdx(), si->pDN()->getIdx());
2953  if (si->pRA()->getSigma()>0.0 && si->pDN()->getSigma()>0.0)
2954  str.sprintf(" %-8s CORRELATION %10.4f Reference date: 2000.01.01-12:00:00",
2955  qPrintable(si->getKey()),
2956  d/(si->pRA()->getSigma()*si->pDN()->getSigma())
2957  );
2958  else
2959  str.sprintf(" %-8s CORRELATION ------- Reference date: 2000.01.01-12:00:00",
2960  qPrintable(si->getKey()));
2961  ts << str << "\n";
2962  };
2963  };
2964  };
2965  //
2966  // stations again:
2967  //
2968  // zenith delays:
2969  int idxAux, sum;
2971  {
2972  idxAux = 1;
2973  sum = 0;
2974  ts << " Atmosphere Constraint Statistics\n";
2975  double d, ovrl_rms, ovrl_rel, ovrl_trace;
2976  double scale=1.0e12/vLight/24.0;
2977  ovrl_rms = ovrl_trace = ovrl_rel = 0.0;
2978  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
2979  {
2980  SgVlbiStationInfo *si = it_st.value();
2981  if (pwlByName_.contains(si->pZenithDelay()->getName()))
2982  {
2983  pwl = pwlByName_.find(si->pZenithDelay()->getName()).value();
2984 // pwl->calcMeansResids4Sfo(d, v_sig);
2985  d = pwl->calcRateRms4Sfo();
2986 // double sigmaAPriori=pwl->getP_Bi(0)->getSigmaAPriori(); // actual
2987  double sigmaAPriori=pwl->getPOrig()->getSigmaAPriori(); // nominal
2988  ovrl_rms += d;
2989  ovrl_rel += d/sigmaAPriori/sigmaAPriori;
2990  d = sqrt(d/pwl->getNumOfNodes());
2991  ovrl_trace += pwl->trace();
2992  str.sprintf("%3d. %-8s Input %6.2f ps/h RMS %6.2f ps/h NRMS %5.2f share %4.2f count %3d",
2993  idxAux, qPrintable(si->getKey()),
2994  pwl->getPOrig()->getSigmaAPriori()*scale,
2995  d*scale,
2996  d/sigmaAPriori,
2997  pwl->getNumOfNodes()>0?pwl->trace()/pwl->getNumOfNodes():0.0,
2998  pwl->getNumOfNodes());
2999  ts << str << "\n";
3000  idxAux++;
3001  sum += pwl->getNumOfNodes();
3002  };
3003  };
3004  ovrl_rms = sqrt(ovrl_rms/sum);
3005  ovrl_rel = sqrt(ovrl_rel/sum);
3006  str.sprintf(" Overall RMS %6.2f ps/h NRMS %5.2f share %4.2f count %3d",
3007  ovrl_rms*scale,
3008  ovrl_rel,
3009  ovrl_trace/sum,
3010  sum);
3011  ts << str << "\n\n";
3012  };
3013  // clocks:
3015  {
3016  double d, ovrl_rms, ovrl_rel, ovrl_trace;
3017  double scale=1.0e14/86400.0;
3018  ovrl_rms = ovrl_trace = ovrl_rel = 0.0;
3019  idxAux = 1;
3020  sum = 0;
3021  ts << " Clock Constraint Statistics\n";
3022  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3023  {
3024  SgVlbiStationInfo *si = it_st.value();
3025  if (pwlByName_.contains(si->pClock0()->getName()))
3026  {
3027  pwl = pwlByName_.find(si->pClock0()->getName()).value();
3028 // pwl->calcMeansResids4Sfo(d, v_sig);
3029  d = pwl->calcRateRms4Sfo();
3030 // double sigmaAPriori=pwl->getP_Bi(0)->getSigmaAPriori(); // actual
3031  double sigmaAPriori=pwl->getPOrig()->getSigmaAPriori(); // nominal
3032  ovrl_rms += d;
3033  ovrl_rel += d/sigmaAPriori/sigmaAPriori;
3034  d = sqrt(d/pwl->getNumOfNodes());
3035  ovrl_trace += pwl->trace();
3036  str.sprintf("%3d. %-8s Input %6.2f D-14 RMS %6.2f D-14 NRMS %5.2f share %4.2f count %3d",
3037  idxAux, qPrintable(si->getKey()),
3038  pwl->getPOrig()->getSigmaAPriori()*scale,
3039  d*scale,
3040  d/sigmaAPriori,
3041  pwl->getNumOfNodes()>0?pwl->trace()/pwl->getNumOfNodes():0.0,
3042  pwl->getNumOfNodes());
3043  ts << str << "\n";
3044  idxAux++;
3045  sum += pwl->getNumOfNodes();
3046  };
3047  };
3048  ovrl_rms = sqrt(ovrl_rms/sum);
3049  ovrl_rel = sqrt(ovrl_rel/sum);
3050  str.sprintf(" Overall RMS %6.2f D-14 NRMS %5.2f share %4.2f count %3d",
3051  ovrl_rms*scale,
3052  ovrl_rel,
3053  ovrl_trace/sum,
3054  sum);
3055  ts << str << "\n\n";
3056  };
3057  //
3058  // EOPs:
3059  SgParameter *p, *p4erp=NULL;
3060  bool isErpAdjusted(false);
3061  double dUt1=0.0, dPmx=0.0, dPmy=0.0;
3062  double rUt1=0.0, rPmx=0.0, rPmy=0.0;
3063  double sigUt1=0.0, sigPmx=0.0, sigPmy=0.0;
3064  double aprUt1=0.0, aprPmx=0.0, aprPmy=0.0, dt, dd;
3065  double aprCipX=0.0, aprCipY=0.0;
3066  //
3067  // corrections to polar motion, x:
3068  p = session_->pPolusX();
3069  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3070  {
3071  dt = p->getTMean() - erpTref_;
3072  aprPmx = erp_pmx_0_ + erp_pmx_1_*dt + erp_pmx_2_*dt*dt + erp_pmx_3_*dt*dt*dt;
3073  dd = 0.0;
3075  dd = session_->pPolusXRate()->getSolution()*dt;
3076  str.sprintf("%5d. X Wobble 0, %s %12.4f masec %10.2f microasec %10.2f microasec %10.2f microasec",
3077  idx,
3078  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3079  (aprPmx + p->getSolution() + dd)*RAD2SEC*1.0e3,
3080  p->getSolution()*RAD2SEC*1.0e6,
3081  p->getSigma()* RAD2SEC*1.0e6,
3082  p->getSigma()* RAD2SEC*1.0e6*chi
3083  );
3084  ts << str << "\n";
3085  idx++;
3086  isErpAdjusted = true;
3087  p4erp = p;
3088  dPmx = p->getSolution();
3089  sigPmx= p->getSigma();
3090  };
3091  // corrections to polar-x motion rate:
3092  p = session_->pPolusXRate();
3093  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3094  {
3095  dt = p->getTMean() - erpTref_;
3096  str.sprintf("%5d. X Wobble 1, %s %12.4f mas/d %10.2f microas/d %10.2f microas/d %10.2f microas/d",
3097  idx,
3098  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3099  (erp_pmx_1_ + 2.0*erp_pmx_2_*dt + 3.0*erp_pmx_3_*dt*dt + p->getSolution())*RAD2SEC*1.0e3,
3100  p->getSolution()*RAD2SEC*1.0e6,
3101  p->getSigma()* RAD2SEC*1.0e6,
3102  p->getSigma()* RAD2SEC*1.0e6*chi
3103  );
3104  ts << str << "\n";
3105  idx++;
3106  isErpAdjusted = true;
3107  rPmx = p->getSolution();
3108  p4erp = p;
3109  };
3110  //
3111  // corrections to polar-y motion:
3112  p = session_->pPolusY();
3113  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3114  {
3115  dt = p->getTMean() - erpTref_;
3116  aprPmy = erp_pmy_0_ + erp_pmy_1_*dt + erp_pmy_2_*dt*dt + erp_pmy_3_*dt*dt*dt;
3117  dd = 0.0;
3119  dd = session_->pPolusYRate()->getSolution()*dt;
3120  str.sprintf("%5d. Y Wobble 0, %s %12.4f masec %10.2f microasec %10.2f microasec %10.2f microasec",
3121  idx,
3122  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3123  (aprPmy + p->getSolution() + dd)*RAD2SEC*1.0e3,
3124  p->getSolution()*RAD2SEC*1.0e6,
3125  p->getSigma()* RAD2SEC*1.0e6,
3126  p->getSigma()* RAD2SEC*1.0e6*chi
3127  );
3128  ts << str << "\n";
3129  idx++;
3130  isErpAdjusted = true;
3131  p4erp = p;
3132  dPmy = p->getSolution();
3133  sigPmy= p->getSigma();
3134  };
3135  // corrections to polar-y motion rate:
3136  p = session_->pPolusYRate();
3137  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3138  {
3139  dt = p->getTMean() - erpTref_;
3140  str.sprintf("%5d. Y Wobble 1, %s %12.4f mas/d %10.2f microas/d %10.2f microas/d %10.2f microas/d",
3141  idx,
3142  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3143  (erp_pmy_1_ + 2.0*erp_pmy_2_*dt + 3.0*erp_pmy_3_*dt*dt + p->getSolution())*RAD2SEC*1.0e3,
3144  p->getSolution()*RAD2SEC*1.0e6,
3145  p->getSigma()* RAD2SEC*1.0e6,
3146  p->getSigma()* RAD2SEC*1.0e6*chi
3147  );
3148  ts << str << "\n";
3149  idx++;
3150  isErpAdjusted = true;
3151  rPmy = p->getSolution();
3152  p4erp = p;
3153  };
3154  //
3155  // corrections to UT1:
3156  p = session_->pUT1();
3157  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3158  {
3159  dt = p->getTMean() - erpTref_;
3160  aprUt1 = erp_ut1_0_ + erp_ut1_1_*dt + erp_ut1_2_*dt*dt + erp_ut1_3_*dt*dt*dt;
3161  dd = 0.0;
3163  dd = session_->pUT1Rate()->getSolution()*dt;
3164  str.sprintf("%5d. UT1-TAI 0, %s %12.4f msec %10.2f microsec %11.2f microsec %11.2f microsec",
3165  idx,
3166  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3167  (aprUt1 + p->getSolution() + dd)*DAY2SEC*1.0e3,
3168  p->getSolution()*DAY2SEC*1.0e6,
3169  p->getSigma()* DAY2SEC*1.0e6,
3170  p->getSigma()* DAY2SEC*1.0e6*chi);
3171  ts << str << "\n";
3172  idx++;
3173  isErpAdjusted = true;
3174  p4erp = p;
3175  dUt1 = p->getSolution();
3176  sigUt1= p->getSigma();
3177  //
3178  dUt1Value_ = aprUt1 + p->getSolution() + dd;
3180  dUt1StdDev_ = p->getSigma();
3181  //
3182  };
3183  // corrections to UT1 rate:
3184  p = session_->pUT1Rate();
3185  if (p && p->isAttr(SgParameter::Attr_IS_SOLVED))
3186  {
3187  dt = p->getTMean() - erpTref_;
3188  // progs/solve/adjst/a2jst_segeop.f ?
3189  str.sprintf("%5d. UT1-TAI 1, %s %12.4f ms/d %10.2f micros/d %11.2f micros/d %11.2f micros/d",
3190  idx,
3191  qPrintable(p->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3192  (erp_ut1_1_ + 2.0*erp_ut1_2_*dt + 3.0*erp_ut1_3_*dt*dt + p->getSolution())*DAY2SEC*1.0e3,
3193  p->getSolution()*DAY2SEC*1.0e6,
3194  p->getSigma()* DAY2SEC*1.0e6,
3195  p->getSigma()* DAY2SEC*1.0e6*chi
3196  );
3197  ts << str << "\n";
3198  idx++;
3199  isErpAdjusted = true;
3200  rUt1 = p->getSolution();
3201  p4erp = p;
3202  };
3203  if (isErpAdjusted && p4erp)
3204  {
3205  dt = p4erp->getTMean() - erpTref_;
3206  ts
3207 // << " EOP with included hi-freq variations (a-sigmas) \n"
3208  << " EOP without included hi-freq variations (a-sigmas) \n"
3209  << " XWOB YWOB UT1-TAI"
3210  << " XSIG YSIG USIG\n"
3211  << " mas mas ms "
3212  << " microasec microasec microsec\n";
3213 // str.sprintf("%s 0.0000 0.0000 0.0000 0.00 0.00 0.00",
3214  str.sprintf("%s %12.4f %12.4f %12.4f %11.2f %11.2f %11.2f",
3215  qPrintable(p4erp->getTMean().toString(SgMJD::F_SOLVE_SPLFL_SHORT)),
3216  (aprPmx + rPmx*dt + dPmx)*RAD2SEC*1.0e3,
3217  (aprPmy + rPmy*dt + dPmy)*RAD2SEC*1.0e3,
3218  (aprUt1 + rUt1*dt + dUt1)*DAY2SEC*1.0e3,
3219  sigPmx*RAD2SEC*1.0e6,
3220  sigPmy*RAD2SEC*1.0e6,
3221  sigUt1*DAY2SEC*1.0e6);
3222  ts << str << "\n" << "\n";
3223  };
3224  //
3225 //------------------------------------------------------------------------------------------------------
3226  // Nutation:
3229  {
3230  p = session_->pNutX();
3231  SgMJD epoch(p->getTMean());
3232  // conver UTC to TT, cheap'n'angry:
3233  epoch += (session_->getLeapSeconds() + 32.184)/DAY2SEC;
3234  //
3235  dt = p->getTMean() - erpTref_;
3236  aprCipX = eop_cix_0_ + eop_cix_1_*dt + eop_cix_2_*dt*dt + eop_cix_3_*dt*dt*dt;
3237  aprCipY = eop_ciy_0_ + eop_ciy_1_*dt + eop_ciy_2_*dt*dt + eop_ciy_3_*dt*dt*dt;
3238  //
3239  double dX, dY, dPsi, dEps;
3240  double dX_sigma, dY_sigma, dPsi_sigma, dEps_sigma;
3241  if (session_->hasCipPartials())
3242  {
3243  dX = session_->pNutX()->getSolution() + aprCipX;
3244  dX_sigma = session_->pNutX()->getSigma();
3245  dY = session_->pNutY()->getSolution() + aprCipY;
3246  dY_sigma = session_->pNutY()->getSigma();
3247 
3248  dPsi = dX/sin(84381.4059*SEC2RAD);
3249  dPsi_sigma = dX_sigma/sin(84381.4059*SEC2RAD);
3250  dEps = dY;
3251  dEps_sigma = dY_sigma;
3252  }
3253  else
3254  {
3255  dPsi = session_->pNutX()->getSolution();
3256  dPsi_sigma = session_->pNutX()->getSigma();
3257  dEps = session_->pNutY()->getSolution();
3258  dEps_sigma = session_->pNutY()->getSigma();
3259 
3260  dX = dPsi*sin(84381.4059*SEC2RAD) + aprCipX;
3261  dX_sigma = dPsi_sigma*sin(84381.4059*SEC2RAD);
3262  dY = dEps + aprCipY;
3263  dY_sigma = dEps_sigma;
3264  };
3265  double psiEst2Wahr=0.0, epsEst2Wahr=0.0;
3266  SgVlbiObservation *obs=session_->observations().at(0);
3267  if (obs)
3268  {
3269  calcCip2IAU1980(epoch, dX, dY,
3272  psiEst2Wahr, epsEst2Wahr);
3273  };
3274 
3275  // corrections to Celestial intermediate pole, x:
3276  p = session_->pNutX();
3277  str.sprintf(" EOP epoch (TT) MJD: %12.6f NUT epoch (TT) MJD: %12.6f",
3278  epoch.toDouble(), epoch.toDouble());
3279  ts << str << "\n";
3280  str.sprintf("%5d. Nutation offset in longitude (Psi) %14.3f mas %10.1f microasec"
3281  " %10.1f microasec ",
3282  idx,
3283  dPsi *RAD2SEC*1.0e3,
3284  dPsi_sigma*RAD2SEC*1.0e6,
3285  dPsi_sigma*RAD2SEC*1.0e6*chi
3286  );
3287  ts << str << "\n";
3288  idx++;
3289  str.sprintf(" Nutation offset around X-axis (dX) %14.3f mas %10.1f "
3290  "microasec %10.1f microasec ",
3291  dX *RAD2SEC*1.0e3,
3292  dX_sigma*RAD2SEC*1.0e6,
3293  dX_sigma*RAD2SEC*1.0e6*chi
3294  );
3295  ts << str << "\n";
3296  str.sprintf(" Nutation offset wrt IAU 1980 model (Psi) %14.3f mas %10.1f "
3297  "microasec %10.1f microasec ",
3298 // (dPsi + psiEst2Wahr)*RAD2SEC*1.0e3,
3299  psiEst2Wahr *RAD2SEC*1.0e3,
3300  dPsi_sigma *RAD2SEC*1.0e6,
3301  dPsi_sigma *RAD2SEC*1.0e6*chi
3302  );
3303  ts << str << "\n";
3304  // corrections to Celestial intermediate pole, y:
3305  p = session_->pNutY();
3306  str.sprintf("%5d. Nutation offset in obliquity (Eps) %14.3f mas %10.1f "
3307  "microasec %10.1f microasec ",
3308  idx,
3309  dEps *RAD2SEC*1.0e3,
3310  dEps_sigma*RAD2SEC*1.0e6,
3311  dEps_sigma*RAD2SEC*1.0e6*chi
3312  );
3313  ts << str << "\n";
3314  idx++;
3315  str.sprintf(" Nutation offset around Y-axis (dY) %14.3f mas "
3316  "%10.1f microasec %10.1f microasec ",
3317  dY *RAD2SEC*1.0e3,
3318  dY_sigma*RAD2SEC*1.0e6,
3319  dY_sigma*RAD2SEC*1.0e6*chi
3320  );
3321  ts << str << "\n";
3322  str.sprintf(" Nutation offset wrt IAU 1980 model (Eps) %14.3f mas "
3323  "%10.1f microasec %10.1f microasec ",
3324 // (dEps + epsEst2Wahr)*RAD2SEC*1.0e3,
3325  epsEst2Wahr *RAD2SEC*1.0e3,
3326  dEps_sigma *RAD2SEC*1.0e6,
3327  dEps_sigma *RAD2SEC*1.0e6*chi
3328  );
3329  ts << str << "\n";
3330  };//---------------------------------------------------------------------------------------------------
3331 
3332  // Baselines, clocks:
3334  {
3335  ts << "\n";
3336  BaselinesByName_it it_bl;
3337  for (it_bl=session_->baselinesByName().begin(); it_bl!=session_->baselinesByName().end(); ++it_bl)
3338  {
3339  SgVlbiBaselineInfo *bi=it_bl.value();
3340  QString blName;
3341  blName = bi->getKey();
3342  blName.replace(8, 1, "-");
3344  {
3345  str.sprintf("%5d. %-17s Clock offset "
3346  "%12.3f ps %9.3f ps %9.3f ps",
3347  idx, qPrintable(blName),
3348  bi->pClock()->getSolution()*1.0E12,
3349  bi->pClock()->getSigma() *1.0E12,
3350  bi->pClock()->getSigma() *1.0E12*chi );
3351  ts << str << "\n";
3352  idx++;
3353  };
3354  };
3355  };
3356  // Baselines, baseline vector:
3358  {
3359  ts << "\n";
3360  BaselinesByName_it it_bl;
3361  for (it_bl=session_->baselinesByName().begin(); it_bl!=session_->baselinesByName().end(); ++it_bl)
3362  {
3363  SgVlbiBaselineInfo *bi=it_bl.value();
3364  QString blName;
3365  blName = bi->getKey();
3366  blName.replace(8, 1, "-");
3367  // baseline vector:
3369  {
3370  SgVlbiStationInfo *s1, *s2;
3371  if (session_->stationsByName().contains(bi->getKey().mid(0,8)))
3372  s1 = session_->stationsByName().value(bi->getKey().mid(0,8));
3373  else
3374  s1 = NULL;
3375  if (session_->stationsByName().contains(bi->getKey().mid(9,8)))
3376  s2 = session_->stationsByName().value(bi->getKey().mid(9,8));
3377  else
3378  s2 = NULL;
3379  if (s1 && s2)
3380  {
3381  // covariances (i.e., rho_{1,2}*sigma_1*sigma_2):
3382  double cXY, cXZ, cYZ;
3383  cXY = PxAll_->getElement(bi->pBx()->getIdx(), bi->pBy()->getIdx());
3384  cXZ = PxAll_->getElement(bi->pBx()->getIdx(), bi->pBz()->getIdx());
3385  cYZ = PxAll_->getElement(bi->pBy()->getIdx(), bi->pBz()->getIdx());
3386  Sg3dVector b, b_apriori;
3387  b_apriori = (s2->getR() - s1->getR());
3389  {
3390  SgMJD t(bi->pBx()->getTMean());
3391  b_apriori = s2->getR_ea() - s1->getR_ea() +
3392  (s2->getV_ea() - s1->getV_ea())*(t - session_->getApStationVelocities().getT0());
3393  };
3394  b = b_apriori +
3395  Sg3dVector(bi->pBx()->getSolution(), bi->pBy()->getSolution(), bi->pBz()->getSolution());
3396  double l, lSigma;
3397  double x2, y2, z2, sigX2, sigY2, sigZ2;
3398  x2 = b.at(X_AXIS)*b.at(X_AXIS);
3399  y2 = b.at(Y_AXIS)*b.at(Y_AXIS);
3400  z2 = b.at(Z_AXIS)*b.at(Z_AXIS);
3401  sigX2 = bi->pBx()->getSigma()*bi->pBx()->getSigma();
3402  sigY2 = bi->pBy()->getSigma()*bi->pBy()->getSigma();
3403  sigZ2 = bi->pBz()->getSigma()*bi->pBz()->getSigma();
3404  l = b.module();
3405  lSigma = x2*sigX2 + y2*sigY2 + z2*sigZ2 +
3406  2.0*( b.at(X_AXIS)*b.at(Y_AXIS)*cXY +
3407  b.at(X_AXIS)*b.at(Z_AXIS)*cXZ +
3408  b.at(Y_AXIS)*b.at(Z_AXIS)*cYZ );
3409  lSigma = sqrt(lSigma)/l;
3410  // sigma of latitude:
3411  double phiSigma, a2, l4;
3412  a2 = x2 + y2;
3413  l4 = l*l*l*l;
3414  phiSigma = (x2*z2*sigX2 + y2*z2*sigY2 + a2*a2*sigZ2 +
3415  2.0*(b.at(X_AXIS)*b.at(Y_AXIS)*z2*cXY -
3416  a2*(b.at(X_AXIS)*b.at(Z_AXIS)*cXZ + b.at(Y_AXIS)*b.at(Z_AXIS)*cYZ)) )/l4/a2;
3417  phiSigma = sqrt(phiSigma);
3418  // sigma of longitude:
3419  double lambdaSigma;
3420  lambdaSigma = (y2*sigX2 + x2*sigY2 - 2.0*b.at(X_AXIS)*b.at(Y_AXIS)*cXY)/a2/a2;
3421  lambdaSigma = sqrt(lambdaSigma);
3422 
3423  str.sprintf("%5d. %-17s X Comp %15.2f mm %14.3f mm "
3424  "%14.3f mm %14.3f mm",
3425  idx, qPrintable(blName),
3426  b.at(X_AXIS) *1000.0,
3427  bi->pBx()->getSolution()*1000.0,
3428  bi->pBx()->getSigma() *1000.0,
3429  bi->pBx()->getSigma() *1000.0*chi );
3430  ts << str << "\n";
3431  idx++;
3432  str.sprintf("%5d. %-17s Y Comp %15.2f mm %14.3f mm "
3433  "%14.3f mm %14.3f mm",
3434  idx, qPrintable(blName),
3435  b.at(Y_AXIS) *1000.0,
3436  bi->pBy()->getSolution()*1000.0,
3437  bi->pBy()->getSigma() *1000.0,
3438  bi->pBy()->getSigma() *1000.0*chi );
3439  ts << str << "\n";
3440  idx++;
3441  str.sprintf("%5d. %-17s Z Comp %15.2f mm %14.3f mm "
3442  "%14.3f mm %14.3f mm",
3443  idx, qPrintable(blName),
3444  b.at(Z_AXIS) *1000.0,
3445  bi->pBz()->getSolution()*1000.0,
3446  bi->pBz()->getSigma() *1000.0,
3447  bi->pBz()->getSigma() *1000.0*chi );
3448  ts << str << "\n";
3449  idx++;
3450  // length
3451  str.sprintf(" %-17s length %15.2f mm %14.3f mm "
3452  "%14.3f mm %14.3f mm",
3453  qPrintable(blName),
3454  l *1000.0,
3455  (l - b_apriori.module())*1000.0,
3456  lSigma *1000.0,
3457  lSigma *1000.0*chi );
3458  ts << str << "\n";
3459  // latitude
3460  str.sprintf(" %-17s latitude %15.2f deg %13.3f mas "
3461  "%14.3f mas %14.3f mas",
3462  qPrintable(blName),
3463  b.phi() *RAD2DEG,
3464  (b.phi() - b_apriori.phi())*RAD2MAS,
3465  phiSigma *RAD2MAS,
3466  phiSigma *RAD2MAS*chi );
3467  ts << str << "\n";
3468  // longitude
3469  str.sprintf(" %-17s longitude %15.2f deg %13.3f mas "
3470  "%14.3f mas %14.3f mas",
3471  qPrintable(blName),
3472  b.lambda() *RAD2DEG,
3473  (b.lambda() - b_apriori.lambda()) *RAD2MAS,
3474  lambdaSigma *RAD2MAS,
3475  lambdaSigma *RAD2MAS*chi );
3476  ts << str << "\n";
3477  }
3478  else
3480  "::reportEstimationBlock_Output4Spoolfile(): a station pointer is NULL");
3481  };
3482  };
3483  };
3484  //
3485  //
3486  if (numOfConstraints_ || pwlList_.size())
3487  {
3488  ts
3489  << " \n"
3490  << " General constraints usage information: "
3491  << " \n"
3492  << " \n";
3493  str.sprintf(" 1) CLO_RATE \"Clock rate between segments \" sigma %10.3E 10^-14 sec/sec",
3496  /86400.0*1.0e14);
3497  ts << str << "\n";
3498  str.sprintf(" 2) ATM_RATE \"Atmosphere rate between segments\" sigma %10.3E psec/hr",
3501  /vLight/24.0*1.0e12);
3502  ts << str << "\n \n";
3503  }
3504  else
3505  ts << " No constraints have been imposed\n \n";
3506 
3507  str.sprintf(" Corrected Reduced Chi-Square %8.4f",
3508 // session_->primaryBand()->getChi2()/session_->primaryBand()->getNumOfDOF());
3509 // activeBand_->chi2(dType)/session_->getNumOfDOF());
3510  activeBand_->reducedChi2(dType));
3511  ts << str << "\n\n";
3512 };
3513 
3514 
3515 
3516 //
3517 bool SgSolutionReporter::reportAtmo(const QString& path, const QString& fileName)
3518 {
3519  // emulates SOLVE output:
3520  // ATMO<U.I.>
3521  QFile f(path + "/" + fileName);
3522  if (!f.open(QIODevice::WriteOnly))
3523  {
3525  "::reportAtmo(): error opening output file: " + path + "/" + fileName);
3526  return false;
3527  };
3528  //
3529  // check data type (it should be equidistant):
3530  int num;
3531  bool isOk;
3532  SgMJD t_i;
3533  double step;
3534  num = -1;
3535  step = -1.0;
3536  isOk = true;
3537  StationsByName_it it_st;
3538  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3539  if (isOk)
3540  {
3541  SgVlbiStationInfo *si = it_st.value();
3543  pwlByName_.contains(si->pZenithDelay()->getName()))
3544  {
3545  SgPwlStorage *pwl = pwlByName_.find(si->pZenithDelay()->getName()).value();
3546  if (num==-1 && pwl->getNumOfSegments()>0)
3547  {
3548  num = pwl->getNumOfSegments();
3549  t_i = pwl->tStart();
3550  step = pwl->step();
3551  }
3552  else if (num==-1 && pwl->getNumOfSegments()<=0)
3553  {
3555  "::reportAtmo(): cannot report PWL zenith delays, the number of parameteres less than 1");
3556  isOk = false;
3557  }
3558  else if (num != pwl->getNumOfSegments())
3559  {
3561  "::reportAtmo(): cannot report PWL zenith delays, non-equal number of parameters");
3562  isOk = false;
3563  }
3564  else if (step != pwl->step())
3565  {
3567  "::reportAtmo(): cannot report PWL zenith delays, non-equidistant steps");
3568  isOk = false;
3569  };
3570  }
3572  {
3574  "::reportAtmo(): cannot report PWL zenith delays, missed station" + si->getKey());
3575  isOk = false;
3576  };
3577  };
3578  if (!isOk)
3579  return false;
3580  //
3581  // make output:
3582  QTextStream ts(&f);
3583  QString str;
3584  ts << " yr mn dy hr min Julian Date ";
3585  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3586  ts << str.sprintf("%-8s ", qPrintable(it_st.value()->getKey()));
3587  ts << "\n ";
3588  for (int i=0; i<session_->stationsByName().size(); i++)
3589  ts << "offset sigma ";
3590  ts << "\n ";
3591  for (int i=0; i<session_->stationsByName().size(); i++)
3592  ts << " ps ps ";
3593  ts << "\n";
3594  for (int idx=0; idx<num+1; idx++)
3595  {
3596  int yr, mn, dy, hr, mi;
3597  double sc;
3598  SgMJD::MJD_reverse(t_i.getDate(), t_i.getTime(), yr, mn, dy, hr, mi, sc);
3599  mi = (60*mi + sc)/60;
3600  yr -= (yr/100)*100;
3601  str.sprintf(" %2d %2d %2d %2d %2d %.5f",
3602  yr, mn, dy, hr, mi, t_i.toDouble() + 2400000.5);
3603  ts << str;
3604  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3605  {
3606  SgVlbiStationInfo *si = it_st.value();
3608  {
3609  SgPwlStorage *pwl = pwlByName_.find(si->pZenithDelay()->getName()).value();
3610 // SgParameter *pB = pwl->getP_Bi(idx);
3611  ts << str.sprintf(" %14.0f %5.0f",
3612 // (si->getEstWetZenithDelay() + pwl->calcPolySolution(t_i) + pB->getSolution())/vLight*1.0e12,
3613  ( si->getEstWetZenithDelay() +
3614  pwl->calcPolySolution(t_i) +
3615  pwl->calcRateSolution(t_i) )/vLight*1.0e12,
3616 // pB->getSigma()/vLight*1.0e12);
3617  pwl->calcRateSigma(t_i)/vLight*1.0e12);
3618  }
3619  else
3620  ts << " 0 0";
3621  };
3622  ts << "\n";
3623  t_i += step;
3624  };
3625  // close the file:
3626  ts.setDevice(NULL);
3627  f.close();
3628  return true;
3629 };
3630 
3631 
3632 
3633 //
3634 bool SgSolutionReporter::reportCloc(const QString& path, const QString& fileName)
3635 {
3636  // emulates SOLVE output:
3637  // CLOC<U.I.>
3638  QFile f(path + "/" + fileName);
3639  if (!f.open(QIODevice::WriteOnly))
3640  {
3642  "::reportCloc(): error opening output file: " + path + "/" + fileName);
3643  return false;
3644  };
3645  //
3646  // check data type (it should be equidistant):
3647  int num;
3648  bool isOk;
3649  SgMJD t_i;
3650  double step;
3651  num = -1;
3652  step = -1.0;
3653  isOk = true;
3654  StationsByName_it it_st;
3655  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3656  if (isOk)
3657  {
3658  SgVlbiStationInfo *si = it_st.value();
3660  pwlByName_.contains(si->pClock0()->getName()))
3661  {
3662  SgPwlStorage *pwl = pwlByName_.find(si->pClock0()->getName()).value();
3663  if (num==-1 && pwl->getNumOfSegments()>0)
3664  {
3665  num = pwl->getNumOfSegments();
3666  t_i = pwl->tStart();
3667  step = pwl->step();
3668  }
3669  else if (num==-1 && pwl->getNumOfSegments()<=0)
3670  {
3672  "::reportCloc(): cannot report PWL clocks, the number of parameteres less than 1");
3673  isOk = false;
3674  }
3675  else if (num != pwl->getNumOfSegments())
3676  {
3678  "::reportCloc(): cannot report PWL clocks, non-equal number of parameters");
3679  isOk = false;
3680  }
3681  else if (step != pwl->step())
3682  {
3684  "::reportCloc(): cannot report PWL clocks, non-equidistant steps");
3685  isOk = false;
3686  };
3687  }
3690  {
3692  "::reportCloc(): cannot report PWL clocks, missed station " + si->getKey());
3693  isOk = false;
3694  };
3695  };
3696  if (!isOk)
3697  return false;
3698  //
3699  // make output:
3700  QTextStream ts(&f);
3701  QString str;
3702  ts << " yr mn dy hr min Julian Date ";
3703  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3704  ts << str.sprintf("%-8s ", qPrintable(it_st.value()->getKey()));
3705  ts << "\n ";
3706  for (int i=0; i<session_->stationsByName().size(); i++)
3707  ts << "offset sigma ";
3708  ts << "\n ";
3709  for (int i=0; i<session_->stationsByName().size(); i++)
3710  ts << " ps ps ";
3711  ts << "\n";
3712  for (int idx=0; idx<num+1; idx++)
3713  {
3714  int yr, mn, dy, hr, mi;
3715  double sc;
3716  SgMJD::MJD_reverse(t_i.getDate(), t_i.getTime(), yr, mn, dy, hr, mi, sc);
3717  mi = (60*mi + sc)/60;
3718  yr -= (yr/100)*100;
3719  str.sprintf(" %2d %2d %2d %2d %2d %.5f",
3720  yr, mn, dy, hr, mi, t_i.toDouble() + 2400000.5);
3721  ts << str;
3722  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
3723  {
3724  SgVlbiStationInfo *si = it_st.value();
3727  {
3728  SgPwlStorage *pwl = pwlByName_.find(si->pClock0()->getName()).value();
3729  ts << str.sprintf(" %14.0f %5.0f",
3730  pwl->calcRateSolution(t_i)*1.0e12,
3731  pwl->calcRateSigma(t_i)*1.0e12);
3732  }
3733  else
3734  ts << " 0 0";
3735  };
3736  ts << "\n";
3737  t_i += step;
3738  };
3739  // close the file:
3740  ts.setDevice(NULL);
3741  f.close();
3742  return true;
3743 };
3744 
3745 
3746 
3747 //
3748 bool SgSolutionReporter::reportPall(const QString& path, const QString& fileName)
3749 {
3750  // emulates SOLVE output:
3751  // CLOC<U.I.>
3752  QFile f(path + "/" + fileName);
3753  if (!f.open(QIODevice::WriteOnly))
3754  {
3756  "::reportPall(): error opening the output file: " + path + "/" + fileName);
3757  return false;
3758  };
3759 
3760  //
3761  // make output:
3762  QTextStream ts(&f);
3763  QString str;
3764 
3765  ts << allParList_.size() << " parameters in the list\n";
3766  for (int i=0; i<allParList_.size(); i++)
3767  ts << str.sprintf("%4d ", i) << allParList_.at(i)->getName() << "\n";
3768 
3769  ts << "\n" << PxAll_->nRow() << " elements in a row of the covariance matrix\n";
3770  for (unsigned int i=0; i<PxAll_->nRow(); i++)
3771  for (unsigned int j=i; j<PxAll_->nCol(); j++)
3772  ts << str.sprintf("%4d %4d %22.15E", i, j, PxAll_->getElement(i, j)) << "\n";
3773 
3774  // close the file:
3775  ts.setDevice(NULL);
3776  f.close();
3777  return true;
3778 };
3779 
3780 
3781 
3782 //
3783 bool SgSolutionReporter::reportNotUsedObs(const QString& path, const QString& fileName)
3784 {
3785  QFile f(path + "/" + fileName);
3786  if (!f.open(QIODevice::WriteOnly))
3787  {
3789  "::reportNotUsedObs(): error opening output file: " + path + "/" + fileName);
3790  return false;
3791  };
3792  //
3793  QTextStream ts(&f);
3794 
3795 // reportDeselectedObsBlock_Output4Spoolfile(ts);
3796 // reportDeselectedObsBlock_Output4Spoolfile_v2(ts);
3798 
3799  // close the file:
3800  ts.setDevice(NULL);
3801  f.close();
3802  return true;
3803 };
3804 
3805 
3806 
3807 //
3809 {
3810  QString str;
3811  int n;
3812  SgMJD t(session_->tRefer());
3813 
3816  return;
3817 
3818  ts
3819  << "1 Baseline information for run " << qPrintable(reportID_) << "\n"
3820  << " Monument to monument values at epoch "
3821  << qPrintable(t.toString(SgMJD::F_YYYYMonDD)) << "\n"
3822  << " Baseline vector components: Length, Vertical and Transverse components\n"
3823  << " Vector mag c-sigma Length c-sigma "
3824  << "Horizontal c-sigma Vertical c-sigma\n"
3825  << " (mm) (mm) (mm) (mm)"
3826  << " (mm) (mm) (mm) (mm)\n";
3827  //
3829  {
3830  // stations:
3831  QList<SgVlbiStationInfo*> stations;
3832  for (StationsByName_it it=session_->stationsByName().begin(); it!=session_->stationsByName().end();
3833  ++it)
3834  if (!it.value()->isAttr(SgVlbiStationInfo::Attr_NOT_VALID))
3835  stations << it.value();
3836  //
3837  n = stations.size();
3838  for (int i=0; i<n; i++)
3839  for (int j=i+1; j<n; j++)
3840  {
3841  SgVlbiStationInfo *si=stations.at(i);
3842  SgVlbiStationInfo *sj=stations.at(j);
3843  bool isSi, isSj;
3844  isSi = si->pRx()->isAttr(SgParameter::Attr_IS_SOLVED);
3845  isSj = sj->pRx()->isAttr(SgParameter::Attr_IS_SOLVED);
3846  if (isSi || isSj)
3847  {
3848  Sg3dVector dr_i, dr_j;
3849  Sg3dVector ri_apriori(si->getR());
3850  Sg3dVector rj_apriori(sj->getR());
3851  Sg3dVector lhv, lhvSigma;
3852  double length, lengthSigma;
3853  if (isSi)
3854  dr_i = Sg3dVector(si->pRx()->getSolution(), si->pRy()->getSolution(),
3855  si->pRz()->getSolution());
3856  if (isSj)
3857  dr_j = Sg3dVector(sj->pRx()->getSolution(), sj->pRy()->getSolution(),
3858  sj->pRz()->getSolution());
3860  {
3861  ri_apriori = si->getR_ea() + si->getV_ea()*(t - session_->getApStationVelocities().getT0());
3862  rj_apriori = sj->getR_ea() + sj->getV_ea()*(t - session_->getApStationVelocities().getT0());
3863  };
3864  SgMatrix mA(6, 6);
3865  int idxs[6];
3866  if (isSi)
3867  {
3868  idxs[0] = si->pRx()->getIdx();
3869  idxs[1] = si->pRy()->getIdx();
3870  idxs[2] = si->pRz()->getIdx();
3871  }
3872  else
3873  idxs[0] = idxs[1] = idxs[2] = -1;
3874  if (isSj)
3875  {
3876  idxs[3] = sj->pRx()->getIdx();
3877  idxs[4] = sj->pRy()->getIdx();
3878  idxs[5] = sj->pRz()->getIdx();
3879  }
3880  else
3881  idxs[3] = idxs[4] = idxs[5] = -1;
3882  //
3883  for (int l=0; l<6; l++)
3884  for (int m=0; m<6; m++)
3885  if (idxs[l]>=0 && idxs[m]>=0)
3886  mA.setElement(l,m, PxAll_->getElement(idxs[l], idxs[m]));
3887  //
3888  calcLhv(ri_apriori, dr_i, rj_apriori, dr_j, mA, lhv, lhvSigma, length, lengthSigma);
3889  str.sprintf(" %-8s %04d to %-8s %04d %14.2f %6.2f %14.2f %6.2f %9.2f %6.2f"
3890  " %9.2f %6.2f",
3891  qPrintable(si->getKey()), si->getCdpNumber(),
3892  qPrintable(sj->getKey()), sj->getCdpNumber(),
3893  length*1000.0, lengthSigma*1000.0,
3894  lhv.at(X_AXIS)*1000.0, lhvSigma.at(X_AXIS)*1000.0,
3895  lhv.at(Y_AXIS)*1000.0, lhvSigma.at(Y_AXIS)*1000.0,
3896  lhv.at(Z_AXIS)*1000.0, lhvSigma.at(Z_AXIS)*1000.0);
3897 // ts << str << "\n";
3898  ts << str << " " << qPrintable(session_->getTMean().toString(SgMJD::F_Simple)) << "\n";
3899  };
3900  };
3901  }
3903  {
3904  // baselines:
3905  QList<SgVlbiBaselineInfo*> baselines;
3906  for (BaselinesByName_it it=session_->baselinesByName().begin();
3907  it!=session_->baselinesByName().end(); ++it)
3908  if (!it.value()->isAttr(SgVlbiStationInfo::Attr_NOT_VALID))
3909  baselines << it.value();
3910  //
3911  n = baselines.size();
3912  for (int i=0; i<n; i++)
3913  {
3914  SgVlbiBaselineInfo *bl=baselines.at(i);
3917 
3918  Sg3dVector db;
3919  Sg3dVector ri_apriori(si->getR());
3920  Sg3dVector rj_apriori(sj->getR());
3921  Sg3dVector lhv, lhvSigma;
3922  double length, lengthSigma;
3923 
3924  db = Sg3dVector(bl->pBx()->getSolution(), bl->pBy()->getSolution(), bl->pBz()->getSolution());
3926  {
3927  ri_apriori = si->getR_ea() + si->getV_ea()*(t - session_->getApStationVelocities().getT0());
3928  rj_apriori = sj->getR_ea() + sj->getV_ea()*(t - session_->getApStationVelocities().getT0());
3929  };
3930  SgMatrix mA(3, 3);
3931  int idxs[3];
3932  idxs[0] = bl->pBx()->getIdx();
3933  idxs[1] = bl->pBy()->getIdx();
3934  idxs[2] = bl->pBz()->getIdx();
3935  //
3936  for (int l=0; l<3; l++)
3937  for (int m=0; m<3; m++)
3938  mA.setElement(l,m, PxAll_->getElement(idxs[l], idxs[m]));
3939  //
3940  calcLhv(ri_apriori, rj_apriori, db, mA, lhv, lhvSigma, length, lengthSigma);
3941  str.sprintf(" %-8s %04d to %-8s %04d %14.2f %6.2f %14.2f %6.2f %9.2f %6.2f"
3942  " %9.2f %6.2f",
3943  qPrintable(si->getKey()), si->getCdpNumber(),
3944  qPrintable(sj->getKey()), sj->getCdpNumber(),
3945  length*1000.0, lengthSigma*1000.0,
3946  lhv.at(X_AXIS)*1000.0, lhvSigma.at(X_AXIS)*1000.0,
3947  lhv.at(Y_AXIS)*1000.0, lhvSigma.at(Y_AXIS)*1000.0,
3948  lhv.at(Z_AXIS)*1000.0, lhvSigma.at(Z_AXIS)*1000.0);
3949  ts << str << " " << qPrintable(bl->pBx()->getTMean().toString(SgMJD::F_Simple)) << "\n";
3950  };
3951  };
3952  //
3953  ts
3954  << "--\n"
3955  << "Note: a posteriori baseline vectors are expressed in a baseline-centric reference frames. "
3956  << "The first basis vector of the\nframe, l, is in direction of a priori baseline, (r_2 - r_1). "
3957  << "Direction of the second vector, h, is defined by a cross\nproduct of a priori baseline vector "
3958  << "and a priori geocentric vector of the 2nd station. The last basis vector, v, is\nperpendicular "
3959  << "to the vectors l and h and is radially inward at the center of the baseline. For the short "
3960  << "baselines, the\nvectors l and h are close to the horizontal plane and v is almost vertical "
3961  << "(with opposite sign). In the table above the\ncolumns are:\n * Vector mag: length of the a "
3962  << "posteriori baseline;\n * Length: l-component of the baseline;\n * Horizontal: "
3963  << "h-component of the baseline;\n * Vertical: v-component of the baseline;\n * c-sigma: "
3964  << "calculated (using standard deviations of adjusted station coordinates of baselines) standard "
3965  << "deviations\n of the corresponding values.\n\n";
3966 };
3967 
3968 
3969 
3970 //
3972 {
3973  QList<SgVlbiObservation*> excludedObs, unusableObs, includedObs, allObs;
3974  int outputVersion;
3975 
3976  outputVersion = activeBand_?activeBand_->getInputFileVersion()+1:1;
3977 
3978  for (int i=0; i<session_->observations().size(); i++)
3979  {
3980  SgVlbiObservation *obs=session_->observations().at(i);
3981  if (obs->activeObs() && !obs->activeObs()->isUsable())
3982  unusableObs << obs;
3983  else if (obs->isAttr(SgVlbiObservation::Attr_NOT_VALID) &&
3984  obs->activeObs() && obs->activeObs()->isUsable() )
3985  excludedObs << obs;
3986  else
3987  includedObs << obs;
3988  };
3989  //
3990  if (excludedObs.size() + unusableObs.size() + includedObs.size() == 0)
3991  {
3992  ts << "No observations are in the solution.\n";
3994  "::reportDeselectedObsBlock_Output4Spoolfile(): no obs to report");
3995  return;
3996  };
3997  //
3998  // reorder the observations:
3999  for (int idx=0; idx<unusableObs.size(); idx++)
4000  allObs << unusableObs.at(idx);
4001  for (int idx=0; idx<excludedObs.size(); idx++)
4002  allObs << excludedObs.at(idx);
4003  for (int idx=0; idx<includedObs.size(); idx++)
4004  allObs << includedObs.at(idx);
4005  //
4006  //
4007  ts << "# Status of observations of the solution of the Run " << reportID_ << "\n";
4008  ts << "# Session " << session_->getOfficialName() << "/" << session_->getSessionCode()
4009  << " database " << session_->getName() << " version " << outputVersion << "\n";
4010  ts << "# First column: a status flag:\n";
4011  ts << "# u - the observation is unusable: either missed data on one of the bands,\n";
4012  ts << "# low quality code, deselected baseline, station or sources.\n";
4013  ts << "# e - excluded observation, explicitly excluded observation either by user\n";
4014  ts << "# or by the software (due to a high residual or not so good quality factor).\n";
4015  ts << "# i - the observation was included in the solution.\n";
4016  ts << "# Second column: index in a database or other media.\n";
4017  ts << "# Third column: time of observation.\n";
4018  ts << "# Forth and fifth columns: quality code (QC) for S- and X-bands. The char `-' means\n";
4019  ts << "# no data on the band.\n";
4020  ts << "# Sixth and seventh columns: fourfit error code (EC) for S- and X-bands. The char `-' means\n";
4021  ts << "# no data on the band, the char '.' means no fourfit error code for the observation.\n";
4022  ts << "# Eighth and ninth columns: SNR on the S- and X-bands.\n";
4023  ts << "# Tenth and eleventh columns: number of used channels on the S- and X-bands.\n";
4024  ts << "# Twelveth and thirteenth columns: baseline and source names.\n";
4025  ts << "# The last three columns: residual and applied standard deviation (ps) and\n";
4026  ts << "# normalized residual (unitless).\n";
4027  ts << "#\n";
4028  ts << "# QC EC SNR SNR NumChan\n";
4029  ts << "# __N__ __Time__ S X S X S X S X ____Baseline_____ _Source_ Resid.(ps) ";
4030  ts << "_Std.Dev_ Normalized\n";
4031 
4032  QString strQC_S(""), strQC_X("");
4033  QString strEC_S(""), strEC_X("");
4034  QString strSnr_S(""), strSnr_X("");
4035  QString strNoC_S(""), strNoC_X("");
4036  QString str(""), sSts("");
4037  double scale4Delay(1.0e12);
4038 
4039  for (int idx=0; idx<allObs.size(); idx++)
4040  {
4041  SgVlbiObservation *obs=allObs.at(idx);
4042  SgVlbiObservable *o=obs->primeObs();
4043  strQC_S = "-";
4044  strQC_X = "-";
4045  strEC_S = "-";
4046  strEC_X = "-";
4047  strSnr_S = " ";
4048  strSnr_X = " ";
4049  strNoC_S = " ";
4050  strNoC_X = " ";
4051  sSts = "u ";
4052  if (obs->observableByKey().contains("S"))
4053  {
4054  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4055  strEC_S.sprintf("%s", qPrintable(
4056  obs->observable("S")->getErrorCode().size()==1?obs->observable("S")->getErrorCode():"."));
4057  strSnr_S.sprintf("%7.1f", obs->observable("S")->getSnr());
4058  strNoC_S.sprintf("%2d", obs->observable("S")->getNumOfChannels());
4059  };
4060  if (obs->observableByKey().contains("X"))
4061  {
4062  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4063  strEC_X.sprintf("%s", qPrintable(
4064  obs->observable("X")->getErrorCode().size()==1?obs->observable("X")->getErrorCode():"."));
4065  strSnr_X.sprintf("%7.1f", obs->observable("X")->getSnr());
4066  strNoC_X.sprintf("%2d", obs->observable("X")->getNumOfChannels());
4067  };
4068  str = QString("").sprintf("%5d ", o->getMediaIdx()+1) + obs->toString(SgMJD::F_HHMMSS) + " " +
4069  strQC_S + " " + strQC_X + " " +
4070  strEC_S + " " + strEC_X + " " +
4071  strSnr_S + " " + strSnr_X + " " +
4072  strNoC_S + " " + strNoC_X + " " +
4073  obs->baseline()->getKey() + " " + obs->src()->getKey();
4074 
4075  if (obs->activeObs()->isUsable())
4076  {
4078  sSts = "e ";
4079  else
4080  sSts = "i ";
4081  str += QString("").sprintf(" %10.1f %9.1f %8.1f",
4082  o->activeDelay()->getResidual()*scale4Delay,
4083  o->activeDelay()->sigma2Apply()*scale4Delay,
4084  o->activeDelay()->getResidualNorm());
4085  };
4086  ts << qPrintable(sSts + str) << "\n";
4087  };
4088  ts << "\n";
4089  //
4090  excludedObs.clear();
4091  unusableObs.clear();
4092  includedObs.clear();
4093  allObs.clear();
4094 };
4095 
4096 
4097 
4098 //
4100 {
4101  QList<SgVlbiObservation*> excludedObs, unusableObs;
4102 
4103  for (int i=0; i<session_->observations().size(); i++)
4104  {
4105  SgVlbiObservation *obs=session_->observations().at(i);
4107  {
4109  excludedObs << obs;
4110  else
4111  unusableObs << obs;
4112  };
4113  };
4114  //
4115  if (excludedObs.size() + unusableObs.size() == 0)
4116  {
4117  ts << "All observations were used in the solution.\n";
4119  "::reportDeselectedObsBlock_Output4Spoolfile(): no deselected obs to report");
4120  return;
4121  };
4122  //
4123  //
4124  ts << " Observations that are not in the solution of the Run " << reportID_ << "\n";
4125  ts << "# N __Time__ SQC XQC S_SNR_ X_SNR_ ____Baseline_____ _Source_ Resid.(ps) _Std.Dev_ NormResid\n";
4126 
4127  QString strQC_S(""), strQC_X("");
4128  QString strSnr_S(""), strSnr_X("");
4129  QString str("");
4130  double scale4Delay(1.0e12);
4131  for (int idx=0; idx<unusableObs.size(); idx++)
4132  {
4133  SgVlbiObservation *obs=unusableObs.at(idx);
4134  SgVlbiObservable *o=obs->primeObs();
4135  strQC_S = "-";
4136  strQC_X = "-";
4137  strSnr_S = " ";
4138  strSnr_X = " ";
4139  if (obs->observableByKey().contains("S"))
4140  {
4141  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4142  strSnr_S.sprintf("%4.1f", obs->observable("S")->getSnr());
4143  };
4144  if (obs->observableByKey().contains("X"))
4145  {
4146  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4147  strSnr_X.sprintf("%4.1f", obs->observable("X")->getSnr());
4148  };
4149  str = QString("").sprintf("%2d ", o->getMediaIdx()+1) + obs->toString(SgMJD::F_HHMMSS) +
4150  " S:" + strQC_S + " X:" + strQC_X + " S:" + strSnr_S + " X:" + strSnr_X + " " +
4151  obs->baseline()->getKey() + " " + obs->src()->getKey();
4152  ts << "u " << qPrintable(str) << "\n";
4153  };
4154  //
4155  for (int idx=0; idx<excludedObs.size(); idx++)
4156  {
4157  SgVlbiObservation *obs=excludedObs.at(idx);
4158  SgVlbiObservable *o=obs->primeObs();
4159  strQC_S = "-";
4160  strQC_X = "-";
4161  strSnr_S = " ";
4162  strSnr_X = " ";
4163  if (obs->observableByKey().contains("S"))
4164  {
4165  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4166  strSnr_S.sprintf("%4.1f", obs->observable("S")->getSnr());
4167  };
4168  if (obs->observableByKey().contains("X"))
4169  {
4170  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4171  strSnr_X.sprintf("%4.1f", obs->observable("X")->getSnr());
4172  };
4173  str = QString("").sprintf("%2d ", o->getMediaIdx()+1) + obs->toString(SgMJD::F_HHMMSS) +
4174  " S:" + strQC_S + " X:" + strQC_X + " S:" + strSnr_S + " X:" + strSnr_X + " " +
4175  obs->baseline()->getKey() + " " + obs->src()->getKey() +
4176  QString("").sprintf(" %10.1f %9.1f %8.1f",
4177  o->activeDelay()->getResidual()*scale4Delay,
4178  o->activeDelay()->sigma2Apply()*scale4Delay,
4179  o->activeDelay()->getResidualNorm());
4180 /*
4181  o->measurement(config_)->getResidual()*scale4Delay,
4182  o->measurement(config_)->sigma2Apply()*scale4Delay,
4183  o->measurement(config_)->getResidualNorm());
4184 */
4185  ts << "e " << qPrintable(str) << "\n";
4186  };
4187  ts << "\n";
4188 };
4189 
4190 
4191 
4192 //
4194 {
4195  QString str(""), str2copy(""), strQC_S(""), strQC_X("");
4196  double scale4Delay(1.0e12);
4197 
4198  QList<SgVlbiObservation*> /*excludedObs,*/ unusedObs;
4199 
4200  for (int i=0; i<session_->observations().size(); i++)
4201  {
4202  SgVlbiObservation *obs=session_->observations().at(i);
4204  {
4205  /*
4206  if (obs->isAttr(SgVlbiObservation::Attr_NOT_VALID))
4207  excludedObs<< obs;
4208  else
4209  */
4210  unusedObs << obs;
4211  };
4212  };
4213  //
4214  if (/*excludedObs.size() + */ unusedObs.size() == 0)
4215  {
4216  ts << "All observations were used in the solution.\n";
4218  "::reportDeselectedObsBlock_Output4Spoolfile(): no deselected obs to report");
4219  return;
4220  };
4221  //
4222  //
4223 // ts << " Observations that are not in the solution of the Run " << reportID_ << "\n";
4224 // ts << " scanId SQC XQC\n";
4225  for (int idx=0; idx<unusedObs.size(); idx++)
4226  {
4227  SgVlbiObservation *obs=unusedObs.at(idx);
4228  SgVlbiObservable *o=obs->primeObs();
4229  strQC_S = "-";
4230  strQC_X = "-";
4231  if (obs->observableByKey().contains("S"))
4232  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4233  if (obs->observableByKey().contains("X"))
4234  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4235 
4236  str2copy.sprintf("observation %2d, %s, %s, %s",
4237  o->getMediaIdx() + 1,
4238  qPrintable(o->baseline()->getKey().simplified()),
4239  qPrintable(o->src()->getKey().simplified()),
4240  qPrintable(o->epoch().toString(SgMJD::F_HHMMSS))
4241  );
4242 
4243  str2copy.sprintf("observation %2d, %s, %s, %s, which fits at %.2f +/- %.2f ps, norm: %.2f, ",
4244  o->getMediaIdx() + 1,
4245  qPrintable(o->baseline()->getKey().simplified()),
4246  qPrintable(o->src()->getKey().simplified()),
4247  qPrintable(o->epoch().toString(SgMJD::F_HHMMSS)),
4248  o->activeDelay()->getResidual()*scale4Delay,
4249  o->activeDelay()->sigma2Apply()*scale4Delay,
4251 /*
4252  o->measurement(config_)->getResidual()*scale4Delay,
4253  o->measurement(config_)->sigma2Apply()*scale4Delay,
4254  o->measurement(config_)->getResidualNorm()
4255 */
4256  );
4257  str.sprintf("S:%s X:%s",
4258 // qPrintable(obs->getScanName().simplified()),
4259  qPrintable(strQC_S), qPrintable(strQC_X));
4260 
4261  ts << qPrintable(str2copy + str) << "\n";
4262  };
4263  //
4264  /*
4265  for (int idx=0; idx<excludedObs.size(); idx++)
4266  {
4267  SgVlbiObservation *obs=excludedObs.at(idx);
4268  SgVlbiObservable *o=obs->primeObs();
4269  strQC_S = "-";
4270  strQC_X = "-";
4271  if (obs->observableByKey().contains("S"))
4272  strQC_S.setNum(obs->observable("S")->getQualityFactor());
4273  if (obs->observableByKey().contains("X"))
4274  strQC_X.setNum(obs->observable("X")->getQualityFactor());
4275 
4276  str2copyBlName = " " + o->baseline()->getKey().simplified() + ",";
4277 
4278  str2copy.sprintf(" observation %2d,%s %s, %s, which fits at %.2f +/- %.2f(ps), norm: %.2f",
4279  o->getMediaIdx() + 1,
4280  qPrintable(str2copyBlName),
4281  qPrintable(o->src()->getKey().simplified()),
4282  qPrintable(o->epoch().toString(SgMJD::F_HHMMSS)),
4283  o->measurement(config_)->getResidual()*scale4Delay,
4284  o->measurement(config_)->sigma2Apply()*scale4Delay,
4285  o->measurement(config_)->getResidualNorm()
4286  );
4287  str.sprintf("%23s S:%s X:%s",
4288  qPrintable(obs->getScanName().simplified()),
4289  qPrintable(strQC_S), qPrintable(strQC_X));
4290  ts << qPrintable(str + str2copy) << "\n";
4291  };
4292  */
4293  ts << "\n";
4294 };
4295 
4296 
4297 
4298 //
4300 {
4302  synchronizeInfo();
4303  //
4304  QDir dir(path);
4305  if (!dir.exists())
4306  {
4307  if (dir.mkpath(path))
4309  "::reportStochasticEstimations(): a directory \"" + path + "\" has been created");
4310  else
4312  "::reportStochasticEstimations(): creating a directory \"" + path + "\" has been failed");
4313  };
4314  //
4315  if (reportStoch4Stn(path))
4317  "::reportStochasticEstimations(): files with station dependent stochastic parameters "
4318  " have been created");
4319  else
4321  "::reportStochasticEstimations(): creating files with station dependent stochastic parameters "
4322  " have failed");
4323  //
4325 };
4326 
4327 
4328 
4329 //
4330 bool SgSolutionReporter::reportStoch4Stn(const QString& path)
4331 {
4332  QString prefix("Stn_"), suffix(".dat");
4333  StationsByName_it it_st;
4334  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
4335  {
4336  SgVlbiStationInfo *si=it_st.value();
4338  path, prefix + si->getKey().simplified() + "_Clocks" + suffix);
4340  path, prefix + si->getKey().simplified() + "_Zenith" + suffix);
4342  path, prefix + si->getKey().simplified() + "_AtmGrdN" + suffix);
4344  path, prefix + si->getKey().simplified() + "_AtmGrdE" + suffix);
4346  path, prefix + si->getKey().simplified() + "_Rx" + suffix);
4348  path, prefix + si->getKey().simplified() + "_Ry" + suffix);
4350  path, prefix + si->getKey().simplified() + "_Rz" + suffix);
4352  path, prefix + si->getKey().simplified() + "_AxsOff" + suffix);
4353  };
4354  prefix = "EOP_";
4356  path, prefix + "Px" + suffix);
4358  path, prefix + "Py" + suffix);
4360  path, prefix + "Ut1" + suffix);
4361  // do we need these at all:?
4363  path, prefix + "CipX" + suffix);
4365  path, prefix + "CipY" + suffix);
4366  //
4367  // what else I should add here?
4368  // ...
4369  return true;
4370 };
4371 
4372 
4373 
4374 //
4375 bool SgSolutionReporter::reportStochParameter(const QString& key, const SgParameterCfg& parCfg,
4376  const QString& path, const QString& fileName)
4377 {
4378  if (!stcParByName_.contains(key))
4379  return true; // it is ok
4380 
4381  QString str("");
4382  QFile f(path + "/" + fileName);
4383  if (!f.open(QIODevice::WriteOnly))
4384  {
4386  "::reportStochParameter(): error opening output file: " + path + "/" + fileName);
4387  return false;
4388  };
4389  //
4390  // make output:
4391  double scale(parCfg.getScale());
4392  QString scaleName(parCfg.getScaleName());
4393  QTextStream ts(&f);
4394  const QMap<QString, SgParameter*>
4395  &parByEpoch=stcParByName_.value(key);
4396  ts << "# Output of " << key << ", (" << scaleName << ")\n";
4397  for (QMap<QString, SgParameter*>::const_iterator it=parByEpoch.begin(); it!=parByEpoch.end(); ++it)
4398  {
4399  SgParameter *par=it.value();
4400  if (par)
4401  {
4402  str.sprintf("%s %.4f %.4f %d",
4403  qPrintable(par->getTMean().toString(SgMJD::F_Simple)),
4404  par->getSolution()*scale, par->getSigma()*scale, par->getNumObs());
4405  ts << str << "\n";
4406  }
4407  else
4408  {
4410  "::reportStochParameter(): the parameter " + key + " is NULL");
4411  ts << it.key() << ": the parameter \"" << key << "\" is NULL\n";
4412  };
4413  };
4414  //
4415  // close the file:
4416  ts.setDevice(NULL);
4417  f.close();
4418  return true;
4419 };
4420 
4421 
4422 
4423 //
4425 {
4426  QDir dir(path);
4427  if (!dir.exists())
4428  {
4429  if (dir.mkpath(path))
4431  "::reportTotalZenithDelays(): a directory \"" + path + "\" has been created");
4432  else
4433  {
4435  "::reportTotalZenithDelays(): creating a directory \"" + path + "\" has been failed");
4436  return false;
4437  };
4438  };
4439  //
4440  QString str("");
4441  QString prefix("Stn_"), suffix("_Tzd.dat");
4442  StationsByName_it it_st;
4443  for (it_st=session_->stationsByName().begin(); it_st!=session_->stationsByName().end(); ++it_st)
4444  {
4445  SgVlbiStationInfo *si=it_st.value();
4446  QMap<QString, SgVlbiAuxObservation*>
4447  *auxObservationsByScan=si->auxObservationByScanId();
4448  //
4449  if (auxObservationsByScan->size())
4450  {
4451  QFile f(path + "/" + prefix + si->getKey().simplified() + suffix);
4452  if (!f.open(QIODevice::WriteOnly))
4453  {
4455  "::reportTotalZenithDelays(): error opening output file: \"" + f.fileName() + "\"");
4456  return false;
4457  };
4458  //
4459  // make output:
4460  QTextStream ts(&f);
4461  ts << "# Output of Total zenith delays for " << si->getKey().simplified() << ", (cm)\n";
4462 
4463  QMap<QString, SgVlbiAuxObservation*>::const_iterator jt=auxObservationsByScan->constBegin();
4464  for (int idx=0; jt!=auxObservationsByScan->constEnd(); ++jt, idx++)
4465  {
4466  SgVlbiAuxObservation *auxObs=jt.value();
4467  double tzd, tzdSigma;
4468  tzd = (auxObs->getZenithDelayH() + auxObs->getZenithDelayW())*100.0 + auxObs->getEstZenithDelay();
4469  tzdSigma = auxObs->getEstZenithDelaySigma();
4470  if (tzdSigma > 0.0)
4471  {
4472  str.sprintf("%s %.4f %.4f",
4473  qPrintable(auxObs->toString(SgMJD::F_Simple)), tzd, tzdSigma);
4474  ts << str << "\n";
4475  };
4476  };
4477  ts.setDevice(NULL);
4478  f.close();
4479  };
4480  };
4481  return true;
4482 };
4483 
4484 
4485 
4486 //
4487 void SgSolutionReporter::report2MyFile(const QString& path, const QString& fileName)
4488 {
4489  QDir dir(path);
4490  if (!dir.exists())
4491  {
4492  if (dir.mkpath(path))
4494  "::report2MyFile(): a directory \"" + path + "\" has been created");
4495  else
4496  {
4498  "::report2MyFile(): creating a directory \"" + path + "\" has been failed");
4499  return;
4500  };
4501  };
4502  //
4503  QFile f(path + "/" + fileName);
4504  if (!f.open(QIODevice::WriteOnly))
4505  {
4507  "::report2MyFile(): error opening output file: \"" + f.fileName() + "\"");
4508  return;
4509  };
4510  //
4511  // make output:
4512  QTextStream ts(&f);
4513  ts << "# test outputs...\n";
4514 
4515  for (int i=0; i<session_->observations().size(); i++)
4516  {
4517  SgVlbiObservation *obs=session_->observations().at(i);
4518  SgVlbiObservable *o=obs->primeObs();
4519  SgVlbiAuxObservation *auxObs_1=obs->auxObs_1(), *auxObs_2=obs->auxObs_2();
4520  QString str("");
4521 // if (obs->isAttr(SgVlbiObservation::Attr_PROCESSED) && o && auxObs_1 && auxObs_2)
4522  if (!obs->isAttr(SgVlbiObservation::Attr_NOT_VALID) && o && auxObs_1 && auxObs_2)
4523  {
4524  str.sprintf("%s %16.4f %8.4f %14.2f %14.2f %14.2f %14.2f %-8s:%-8s %-8s PP:%s",
4525  qPrintable(obs->toString(SgMJD::F_Simple)),
4526  o->grDelay().getResidual()*1.0e12, o->grDelay().sigma2Apply()*1.0e12,
4527  o->getUvFrPerAsec(0)*360.0*3600.0/2.0/M_PI, o->getUvFrPerAsec(1)*360.0*3600.0/2.0/M_PI,
4528  auxObs_1->getParallacticAngle()*RAD2DEG, auxObs_2->getParallacticAngle()*RAD2DEG,
4529  qPrintable(obs->stn_1()->getKey()),
4530  qPrintable(obs->stn_2()->getKey()),
4531  qPrintable(obs->src()->getKey()),
4533 
4534 
4535  );
4536 
4537  ts << str << "\n";
4538  };
4539  };
4540  ts.setDevice(NULL);
4541  f.close();
4542 }
4543 /*=====================================================================================================*/
4544 
4545 
4546 
4547 
4548 
4549 
4550 /*=====================================================================================================*/
4551 //
4552 // FRIENDS:
4553 //
4554 /*=====================================================================================================*/
4555 //
4556 
4557 /*=====================================================================================================*/
4558 //
4559 // aux functions:
4560 //
4562 {
4563  return src1->getRA() < src2->getRA();
4564 };
4565 
4566 
4567 
4568 // progs/solve/basfe/*.f:
4569 void calcLhv(const Sg3dVector& r1, const Sg3dVector& dr1, const Sg3dVector& r2, const Sg3dVector& dr2,
4570  const SgMatrix& r, Sg3dVector& lhv, Sg3dVector& lhvSigma, double& length, double& lengthSigma)
4571 {
4572  Sg3dVector l,h,v;
4573  Sg3dVector b;
4574  SgMatrix a(4, 6); // matrix of the derivatives
4575  double d;
4576 
4577  // calculate lhv unit vectors:
4578  l = (b = r2-r1);
4579  l.unify();
4580 
4581  h = r2%r1;
4582  h.unify();
4583 
4584  v = l%h;
4585  v.unify();
4586 
4587  b += dr2 - dr1; // a posteriori
4588  length = b.module();
4589 
4590  lhv(X_AXIS) = b*l;
4591  lhv(Y_AXIS) = b*h;
4592  lhv(Z_AXIS) = b*v;
4593 
4594  a.setElement(0, 0, -l.at(X_AXIS)); // d(lhv_1)/d(x_1)
4595  a.setElement(0, 1, -l.at(Y_AXIS)); // d(lhv_1)/d(y_1)
4596  a.setElement(0, 2, -l.at(Z_AXIS)); // d(lhv_1)/d(z_1)
4597 
4598  a.setElement(1, 0, -h.at(X_AXIS)); // d(lhv_2)/d(x_1)
4599  a.setElement(1, 1, -h.at(Y_AXIS)); // d(lhv_2)/d(y_1)
4600  a.setElement(1, 2, -h.at(Z_AXIS)); // d(lhv_2)/d(z_1)
4601 
4602  a.setElement(2, 0, -v.at(X_AXIS)); // d(lhv_3)/d(x_1)
4603  a.setElement(2, 1, -v.at(Y_AXIS)); // d(lhv_3)/d(y_1)
4604  a.setElement(2, 2, -v.at(Z_AXIS)); // d(lhv_3)/d(z_1)
4605 
4606 //a.setElement(3, 0, -1.0); // d(length)/d(x_1)
4607 //a.setElement(3, 1, -1.0); // d(length)/d(y_1)
4608 //a.setElement(3, 2, -1.0); // d(length)/d(z_1)
4609  a.setElement(3, 0, b.at(X_AXIS)/length); // d(length)/d(b_x)
4610  a.setElement(3, 1, b.at(Y_AXIS)/length); // d(length)/d(b_y)
4611  a.setElement(3, 2, b.at(Z_AXIS)/length); // d(length)/d(b_z)
4612 
4613  // for the second station the partials are the same just with reverted sign:
4614  for (int i=0; i<4; i++)
4615  for (int j=0; j<3; j++)
4616  a.setElement(i, j+3, -a.getElement(i,j));
4617 
4618  // r is a matrix of covariations for (x1,y1,z1,x2,y2,z2)
4619  for (int k=0; k<4; k++)
4620  {
4621  d = 0.0;
4622  for (int i=0; i<6; i++)
4623  {
4624  d += a.getElement(k, i)*a.getElement(k, i)*r.getElement(i, i);
4625  for (int j=i+1; j<6; j++)
4626  d += 2.0*a.getElement(k, i)*a.getElement(k, j)*r.getElement(i, j);
4627  };
4628  if (d > 0.0)
4629  {
4630  if (k < 3)
4631  lhvSigma((DIRECTION)k) = sqrt(d);
4632  else
4633  lengthSigma = sqrt(d);
4634  }
4635  else
4636  {
4637  logger->write(SgLogger::INF, SgLogger::REPORT, "calcLhv(): "
4638  "the sigma2 is less than zero: " + QString("").sprintf("%g", d));
4639  lhvSigma((DIRECTION)k) = 1.0;
4640  };
4641  };
4642 };
4643 
4644 
4645 
4646 // another version: the baselines have been estimated:
4647 void calcLhv(const Sg3dVector& r1, const Sg3dVector& r2, const Sg3dVector& db,
4648  const SgMatrix& r, Sg3dVector& lhv, Sg3dVector& lhvSigma, double& length, double& lengthSigma)
4649 {
4650  Sg3dVector l,h,v;
4651  Sg3dVector b;
4652  SgMatrix a(4, 3); // matrix of the derivatives
4653  double d;
4654 
4655  // calculate lhv unit vectors:
4656  l = (b = r2-r1);
4657  l.unify();
4658 
4659  h = r2%r1;
4660  h.unify();
4661 
4662  v = l%h;
4663  v.unify();
4664 
4665  b += db; // a posteriori
4666  length = b.module();
4667 
4668  lhv(X_AXIS) = b*l;
4669  lhv(Y_AXIS) = b*h;
4670  lhv(Z_AXIS) = b*v;
4671 
4672  a.setElement(0, 0, l.at(X_AXIS)); // d(lhv_1)/d(b_x)
4673  a.setElement(0, 1, l.at(Y_AXIS)); // d(lhv_1)/d(b_y)
4674  a.setElement(0, 2, l.at(Z_AXIS)); // d(lhv_1)/d(b_z)
4675 
4676  a.setElement(1, 0, h.at(X_AXIS)); // d(lhv_2)/d(b_x)
4677  a.setElement(1, 1, h.at(Y_AXIS)); // d(lhv_2)/d(b_y)
4678  a.setElement(1, 2, h.at(Z_AXIS)); // d(lhv_2)/d(b_z)
4679 
4680  a.setElement(2, 0, v.at(X_AXIS)); // d(lhv_3)/d(b_x)
4681  a.setElement(2, 1, v.at(Y_AXIS)); // d(lhv_3)/d(b_y)
4682  a.setElement(2, 2, v.at(Z_AXIS)); // d(lhv_3)/d(b_z)
4683 
4684 //a.setElement(3, 0, 1.0); // d(length)/d(b_x)
4685 //a.setElement(3, 1, 1.0); // d(length)/d(b_y)
4686 //a.setElement(3, 2, 1.0); // d(length)/d(b_z)
4687  a.setElement(3, 0, b.at(X_AXIS)/length); // d(length)/d(b_x)
4688  a.setElement(3, 1, b.at(Y_AXIS)/length); // d(length)/d(b_y)
4689  a.setElement(3, 2, b.at(Z_AXIS)/length); // d(length)/d(b_z)
4690 
4691  // r is a matrix of covariations for (b_x,b_y,b_z)
4692  for (int k=0; k<4; k++)
4693  {
4694  d = 0.0;
4695  for (int i=0; i<3; i++)
4696  {
4697  d += a.getElement(k, i)*a.getElement(k, i)*r.getElement(i, i);
4698  for (int j=i+1; j<3; j++)
4699  d += 2.0*a.getElement(k, i)*a.getElement(k, j)*r.getElement(i, j);
4700  };
4701  if (d > 0.0)
4702  {
4703  if (k < 3)
4704  lhvSigma((DIRECTION)k) = sqrt(d);
4705  else
4706  lengthSigma = sqrt(d);
4707  }
4708  else
4709  {
4710  logger->write(SgLogger::INF, SgLogger::REPORT, "calcLhv(): "
4711  "the sigma2 is less than zero: " + QString("").sprintf("%g", d));
4712  lhvSigma((DIRECTION)k) = 1.0;
4713  };
4714  };
4715 };
4716 
4717 
4718 
4719 /*=====================================================================================================*/
4720 //
4721 // constants:
4722 //
4723 
4724 /*=====================================================================================================*/
const double vLight
Definition: SgConstants.cpp:35
SgLogger * logger
Definition: SgLogger.cpp:231
const SgMJD tZero(1957, 10, 4)
void geocentric2geodetic(const Sg3dVector &r, double &latitude, double &longitude, double &height, bool useOldEllipsoid)
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)
#define RAD2MAS
radians to ms:
Definition: SgMathSupport.h:73
#define SEC2RAD
radians to arc seconds:
Definition: SgMathSupport.h:61
#define DAY2SEC
radians to mas:
Definition: SgMathSupport.h:69
double signum(const double x)
Definition: SgMathSupport.h:89
DIRECTION
Definition: SgMathSupport.h:81
@ VERTICAL
Definition: SgMathSupport.h:81
@ Z_AXIS
Definition: SgMathSupport.h:81
@ X_AXIS
Definition: SgMathSupport.h:81
@ Y_AXIS
Definition: SgMathSupport.h:81
@ EAST
Definition: SgMathSupport.h:81
@ NORTH
Definition: SgMathSupport.h:81
#define RAD2DEG
radians to degrees:
Definition: SgMathSupport.h:41
#define RAD2SEC
seconds in one day:
Definition: SgMathSupport.h:65
#define RAD2MS
Definition: SgMathSupport.h:77
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, 8, 2, "Compton Peak (rc2)", SgMJD(2023, 4, 3, 10, 59))
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:455
@ 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:1008
double toDouble() const
Definition: SgMJD.h:531
int getDate() const
Definition: SgMJD.h:447
static SgMJD currentMJD()
Definition: SgMJD.cpp:119
static void MJD_reverse(int date, double time, int &nYear, int &nMonth, int &nDay, int &nHour, int &nMin, double &dSec)
Definition: SgMJD.cpp:75
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:386
const QString & getExtAPrioriSitesVelocitiesFileName() const
bool getUseExtAPrioriSitesVelocities() const
bool getHave2ApplyOldPoleTideContrib() const
Definition: SgTaskConfig.h:393
bool getUseExtAPrioriHiFyErp() const
bool getUseExtAPrioriSitesPositions() const
bool getUseExtAPrioriErp() const
bool getIsSolveCompatible() const
Definition: SgTaskConfig.h:913
VlbiDelayType getUseDelayType() const
Definition: SgTaskConfig.h:873
bool getHave2ApplyEarthTideContrib() const
Definition: SgTaskConfig.h:379
EstimatorPwlMode getPwlMode() const
Definition: SgTaskConfig.h:953
bool getHave2ApplyPyContrib() const
Definition: SgTaskConfig.h:378
const QString & getExtAPrioriSitesPositionsFileName() const
const QString & getExtAPrioriHiFyErpFileName() const
QMap< QString, AutomaticProcessing > & apByNetId()
Definition: SgTaskConfig.h:637
bool getHave2ApplyOceanTideContrib() const
Definition: SgTaskConfig.h:380
int getQualityCodeThreshold() const
Definition: SgTaskConfig.h:833
bool getUseExtAPrioriSourcesPositions() const
VlbiRateType getUseRateType() const
Definition: SgTaskConfig.h:881
bool getHave2ApplyUt1OceanTideHFContrib() const
Definition: SgTaskConfig.h:384
bool getHave2ApplyPxyOceanTideHFContrib() const
Definition: SgTaskConfig.h:385
bool getHave2ApplyOldOceanTideContrib() const
Definition: SgTaskConfig.h:392
bool getHave2ApplyPoleTideContrib() const
Definition: SgTaskConfig.h:381
bool getUseExtAPrioriAxisOffsets() const
bool getHave2ApplyPxyLibrationContrib() const
Definition: SgTaskConfig.h:388
bool getHave2ApplyTiltRemvrContrib() const
Definition: SgTaskConfig.h:391
const QString & getExtAPrioriSourcesPositionsFileName() const
bool getHave2ApplyPxContrib() const
Definition: SgTaskConfig.h:377
bool getHave2ApplyOceanPoleTideContrib() const
Definition: SgTaskConfig.h:389
bool getHave2outputCovarMatrix() const
Definition: SgTaskConfig.h:296
const QString & getExtAPrioriAxisOffsetsFileName() const
int getActiveBandIdx() const
Definition: SgTaskConfig.h:889
bool getHave2ApplyFeedCorrContrib() const
Definition: SgTaskConfig.h:390
const QString & getExtAPrioriErpFileName() const
bool getHave2ApplyUt1LibrationContrib() const
Definition: SgTaskConfig.h:387
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
SgParameter * pAxisOffset()
double getEstClockModelSigma(int idx) const
SgParameter * pRy()
QList< SgParameter * > * list_
Definition: SgEstimator.h:70