General Purpose Geodetic Library
SgVlbiSourceInfo.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is a part of Space Geodetic Library. The library is used by
4  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
5  * geodetic VLBI observations.
6  * Copyright (C) 2010-2020 Sergei Bolotin.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include <iostream>
24 #include <stdlib.h>
25 #include <math.h>
26 
27 #include <QtCore/QDataStream>
28 
29 #include <SgVlbiSourceInfo.h>
30 
31 #include <SgLogger.h>
32 //#include <SgParametersDescriptor.h>
33 
34 
35 
36 /*=======================================================================================================
37 *
38 * METHODS (aux):
39 *
40 *======================================================================================================*/
41 //
42 //
43 double SgVlbiSourceInfo::StructModel::tauS(double f, double u, double v) const
44 {
45  double d=0.0;
46  double r, c, s, a;
47 
48  r = u*x_ + v*y_;
49 
50  sincos(2.0*M_PI*r, &s, &c);
51  a = k_*k_ + 2.0*k_*c + 1.0;
52 
53  d = k_*(1.0 - k_)*r*(1.0 - c)/f/(1.0 + k_)/a;
54 
55  return d;
56 };
57 /*=====================================================================================================*/
58 
59 
60 
61 
62 
63 /*=====================================================================================================*/
64 //
65 //
67 {
68  dR_ = u*getX() + v*getY();
69  sincos(2.0*M_PI*dR_, &dS_, &dC_);
70  return;
71 };
72 /*=====================================================================================================*/
73 
74 
75 
76 
77 
78 /*=======================================================================================================
79 *
80 * METHODS:
81 *
82 *======================================================================================================*/
83 //
84 // static first:
86 {
87  return "SgVlbiSourceInfo";
88 };
89 
90 
91 
92 // A constructor:
93 SgVlbiSourceInfo::SgVlbiSourceInfo(int idx, const QString& key, const QString& aka) :
94  SgObjectInfo(idx, key, aka),
95  aprioriReference_("Unrefered"),
96  aprioriComments_(""),
97 // aPrioriStructModels_(),
98  sModel_()
99 {
100  RA_ = RA_ea_ = 0.0;
101  DN_ = DN_ea_ = 0.0;
102  al2ExtA_ = al2Estd_ = 0.0;
103  pRA_ = NULL;
104  pDN_ = NULL;
105 
106 // addAttr(Attr_ESTIMATE_COO);
108  totalScanNum_ = 0;
109  procdScanNum_ = 0;
110  isSsModelEstimating_ = false;
111 };
112 
113 
114 
115 //
117  SgObjectInfo(src),
118  aprioriReference_(src.getAprioriReference()),
119  aprioriComments_(src.getAprioriComments()),
120  sModel_(src.sModel_)
121 {
124  RA_ = RA_;
125  DN_ = DN_;
126  RA_ea_ = RA_ea_;
127  DN_ea_ = DN_ea_;
128  al2ExtA_ = al2ExtA_;
129  al2Estd_ = al2Estd_;
130 
131  if (src.pRA_)
132  pRA_ = new SgParameter(*src.pRA_);
133  else
134  pRA_ = NULL;
135  if (src.pDN_)
136  pDN_ = new SgParameter(*src.pDN_);
137  else
138  pDN_ = NULL;
139 
141 };
142 
143 
144 
145 
146 //
147 double SgVlbiSourceInfo::arcLength(double ra_1, double dn_1, double ra_2, double dn_2)
148 {
149  long double sdn1=0.0, cdn1=0.0, sdn2=0.0, cdn2=0.0;
150  long double cdra=0.0;
151 
152  if (abs(ra_1-ra_2)<20.0/RAD2MAS && abs(dn_1-dn_2)<20.0/RAD2MAS) // almost linear
153  return sqrt((ra_1-ra_2)*(ra_1-ra_2)*cos(dn_1)*cos(dn_1) + (dn_1-dn_2)*(dn_1-dn_2));
154 
155  // calculate arc-length:
156  sincosl(dn_1, &sdn1, &cdn1);
157  sincosl(dn_2, &sdn2, &cdn2);
158  cdra = cosl(ra_1 - ra_2);
159  return acosl(sdn1*sdn2 + cdn1*cdn2*cdra);
160 };
161 
162 
163 
164 //
165 QString SgVlbiSourceInfo::ra2String(double ra)
166 {
167  QString str;
168  int nHour, nMin;
169  double dSec, dTmp;
170 
171  dTmp = ra*RAD2MS;
172  nHour = (int)(dTmp/3600.0/1000.0);
173  nMin = (int)((dTmp - 3600.0*1000.0*nHour)/60.0/1000.0);
174  dSec = (dTmp - 3600.0*1000.0*nHour - 60.0*1000.0*nMin)/1000.0;
175 
176  str.sprintf("%02d %02d %011.8f", nHour, nMin, dSec);
177 
178  return str;
179 };
180 
181 
182 
183 //
184 QString SgVlbiSourceInfo::dn2String(double dn, bool mandatorySign)
185 {
186  QString str;
187  int nDeg, nMin;
188  double dSec, dTmp;
189  char cSign=mandatorySign?'+':' ';
190  if (dn<0.0)
191  {
192  dn = -dn;
193  cSign = '-';
194  };
195 
196  dTmp = dn*RAD2MAS;
197  nDeg = (int)(dTmp/3600/1000.0);
198  nMin = (int)((dTmp - 3600.0*1000.0*nDeg)/60.0/1000.0);
199  dSec = (dTmp - 3600.0*1000.0*nDeg - 60.0*1000.0*nMin)/1000.0;
200 
201  str.sprintf("%c%02d %02d %011.8f", cSign, nDeg, nMin, dSec);
202 
203  return str;
204 };
205 
206 
207 
208 //
210 {
211  QString prefix = "Src " + getKey().leftJustified(8, ' ') + ": ";
213  pRA_ = new SgParameter(prefix + "RA");
214  pDN_ = new SgParameter(prefix + "DN");
215 
216  for (int i=0; i<sModel_.size(); i++)
217  {
218  sModel_[i].pK() = new SgParameter(prefix + "k_" + QString("").sprintf("%03d", i));
219  sModel_[i].pB() = new SgParameter(prefix + "b_" + QString("").sprintf("%03d", i));
220  sModel_[i].pX() = new SgParameter(prefix + "x_" + QString("").sprintf("%03d", i));
221  sModel_[i].pY() = new SgParameter(prefix + "y_" + QString("").sprintf("%03d", i));
222  };
223 };
224 
225 
226 
227 //
229 {
230  if (pRA_)
231  {
232  delete pRA_;
233  pRA_ = NULL;
234  };
235  if (pDN_)
236  {
237  delete pDN_;
238  pDN_ = NULL;
239  };
240  for (int i=0; i<sModel_.size(); i++)
241  {
242  if (sModel_[i].pK())
243  {
244  delete sModel_[i].pK();
245  sModel_[i].pK() = NULL;
246  };
247  if (sModel_[i].pB())
248  {
249  delete sModel_[i].pB();
250  sModel_[i].pB() = NULL;
251  };
252  if (sModel_[i].pX())
253  {
254  delete sModel_[i].pX();
255  sModel_[i].pX() = NULL;
256  };
257  if (sModel_[i].pY())
258  {
259  delete sModel_[i].pY();
260  sModel_[i].pY() = NULL;
261  };
262  };
263 };
264 
265 
266 
267 //
269 {
271  if (s.status() == QDataStream::Ok)
272  {
273  s << sModel_.size();
274  for (int i=0; i<sModel_.size(); i++)
275  {
276  const StructModelMp &m=sModel_.at(i);
277  s << m.getK() << m.getB() << m.getX() << m.getY()
279  };
280  };
281  return s.status() == QDataStream::Ok;
282 };
283 
284 
285 
286 //
288 {
289  sModel_.clear();
291  if (s.status() == QDataStream::Ok)
292  {
293  int n;
294  double x, y, k, b;
295  bool eR, eK, eB;
296  s >> n;
297  for (int i=0; i<n; i++)
298  {
299  s >> k >> b >> x >> y
300  >> eK >> eB >> eR;
301  sModel_.append(StructModelMp(k, b, x, y, eK, eB, eR));
302  };
303  };
304  return s.status()==QDataStream::Ok;
305 };
306 
307 
308 
309 //
310 double SgVlbiSourceInfo::tauS(double f, double u, double v)
311 {
312  double d=0.0;
313  if (!sModel_.size())
314  return d;
315 
316  double dT1, dT2, dQ;
317  double s1, s2, s3, s4, s5;
318  double ss1, ss2, ss3;
319  int n=sModel_.size();
320  s1 = s2 = s3 = s4 = s5 = ss1 = ss2 = ss3 = 0.0;
321 
322  for (int i=0; i<n; i++)
323  {
324  sModel_[i].prepareModel(u, v);
325  s1 += sModel_.at(i).getB()*sModel_.at(i).getK()*sModel_.at(i).getS();
326  s2 += sModel_.at(i).getK()*sModel_.at(i).getR()*sModel_.at(i).getC();
327  s3 += sModel_.at(i).getK()*sModel_.at(i).getK()*sModel_.at(i).getR();
328  s4 += sModel_.at(i).getK()*sModel_.at(i).getK();
329  s5 += sModel_.at(i).getK()*sModel_.at(i).getC();
330  };
331 
332  for (int i=0; i<n-1; i++)
333  for (int j=i+1; j<n; j++)
334  {
335  double sPhi_ij, cPhi_ij;
336 
337  sincos(2.0*M_PI*(sModel_.at(i).getR() - sModel_.at(j).getR()), &sPhi_ij, &cPhi_ij);
338 
339  ss1 += sModel_.at(i).getK()*sModel_.at(j).getK()*
340  (sModel_.at(i).getB() - sModel_.at(j).getB())*sPhi_ij;
341 
342  ss2 += sModel_.at(i).getK()*sModel_.at(j).getK()*
343  (sModel_.at(i).getR() + sModel_.at(j).getR())*cPhi_ij;
344 
345  ss3 += sModel_.at(i).getK()*sModel_.at(j).getK()*cPhi_ij;
346  };
347 
348  dT1 = -1.0/(2.0*M_PI*f)*(s1 + ss1);
349  dT2 = -1.0/f*(s2 + s3 + ss2);
350  dQ = 1.0 + s4 + 2.0*(s5 + ss3);
351 
352  d = (dT1 + dT2)/dQ;
353 
354  return d;
355 };
356 
357 
358 
359 //
361  double f, double u, double v)
362 {
363  if (!sModel_.size())
364  return;
365 
366  double dT1, dT2, dQ;
367  double s1, s2, s3, s4, s5;
368  double ss1, ss2, ss3;
369  int n=sModel_.size();
370  s1 = s2 = s3 = s4 = s5 = ss1 = ss2 = ss3 = 0.0;
371  for (int i=0; i<n; i++)
372  {
373  sModel_[i].prepareModel(u, v);
374  s1 += sModel_.at(i).getB()*sModel_.at(i).getK()*sModel_.at(i).getS();
375  s2 += sModel_.at(i).getK()*sModel_.at(i).getR()*sModel_.at(i).getC();
376  s3 += sModel_.at(i).getK()*sModel_.at(i).getK()*sModel_.at(i).getR();
377  s4 += sModel_.at(i).getK()*sModel_.at(i).getK();
378  s5 += sModel_.at(i).getK()*sModel_.at(i).getC();
379  };
380 
381  for (int i=0; i<n-1; i++)
382  for (int j=i+1; j<n; j++)
383  {
384  double sPhi_ij, cPhi_ij;
385  sincos(2.0*M_PI*(sModel_.at(i).getR() - sModel_.at(j).getR()), &sPhi_ij, &cPhi_ij);
386  ss1 += sModel_.at(i).getK()*sModel_.at(j).getK()*
387  (sModel_.at(i).getB() - sModel_.at(j).getB())*sPhi_ij;
388  ss2 += sModel_.at(i).getK()*sModel_.at(j).getK()*
389  (sModel_.at(i).getR() + sModel_.at(j).getR())*cPhi_ij;
390  ss3 += sModel_.at(i).getK()*sModel_.at(j).getK()*cPhi_ij;
391  };
392 
393  dT1 = -1.0/(2.0*M_PI*f)*(s1 + ss1);
394  dT2 = -1.0/f*(s2 + s3 + ss2);
395  dQ = 1.0 + s4 + 2.0*(s5 + ss3);
396 
397  for (int l=0; l<n; l++)
398  {
399  double dCl=sModel_.at(l).getC();
400  double dSl=sModel_.at(l).getS();
401  double dRl=sModel_.at(l).getR();
402  double dKl=sModel_.at(l).getK();
403  double dBl=sModel_.at(l).getB();
404  double t1L, t1R, t2L, t2R, t3L, t3R, t4L, t4R, t5L, t5R, t6L, t6R;
405  t1L = t1R = t2L = t2R = t3L = t3R = t4L = t4R = t5L = t5R = t6L = t6R = 0.0;
406 
407  double sPhi_il, cPhi_il;
408  double sPhi_li, cPhi_li;
409 
410  // left part:
411  for (int i=0; i<l; i++)
412  {
413  sincos(2.0*M_PI*(sModel_.at(i).getR() - sModel_.at(l).getR()), &sPhi_il, &cPhi_il);
414  sPhi_li =-sPhi_il;
415  cPhi_li = cPhi_il;
416 
417  t1L = sModel_.at(i).getK()*sPhi_il;
418  t2L = sModel_.at(i).getK()*(sModel_.at(i).getB() - sModel_.at(l).getB())*sPhi_il;
419  t3L = sModel_.at(i).getK()*(sModel_.at(i).getR() + sModel_.at(l).getR())*cPhi_il;
420  t4L = sModel_.at(i).getK()*cPhi_il;
421  t5L = sModel_.at(i).getK()*(sModel_.at(i).getB() - sModel_.at(l).getB())*cPhi_il;
422  t6L = sModel_.at(i).getK()*(sModel_.at(i).getR() + sModel_.at(l).getR())*sPhi_il;
423  };
424  // right part:
425  for (int i=l+1; i<n; i++)
426  {
427  sincos(2.0*M_PI*(sModel_.at(i).getR() - sModel_.at(l).getR()), &sPhi_il, &cPhi_il);
428  sPhi_li =-sPhi_il;
429  cPhi_li = cPhi_il;
430 
431  t1R = sModel_.at(i).getK()*sPhi_li;
432  t2R = sModel_.at(i).getK()*(sModel_.at(l).getB() - sModel_.at(i).getB())*sPhi_li;
433  t3R = sModel_.at(i).getK()*(sModel_.at(l).getR() + sModel_.at(i).getR())*cPhi_li;
434  t4R = sModel_.at(i).getK()*cPhi_li;
435  t5R = sModel_.at(i).getK()*(sModel_.at(l).getB() - sModel_.at(i).getB())*cPhi_li;
436  t6R = sModel_.at(i).getK()*(sModel_.at(l).getR() + sModel_.at(i).getR())*sPhi_li;
437  };
438  double dTau1_dBl, dTau1_dKl, dTau2_dKl, dQ_dKl, dTau1_dRl, dTau2_dRl, dQ_dRl;
439 
440  dTau1_dBl = -dKl/(2.0*M_PI*f)*(dSl - t1L + t1R);
441 
442  dTau1_dKl = -1.0/(2.0*M_PI*f)*(dBl*dSl + t2L + t2R);
443  dTau2_dKl = -1.0/f*(dRl*(dCl + 2.0*dKl) + t3L + t3R);
444  dQ_dKl = 2.0*(dKl + dCl + t4L + t4R);
445 
446  dTau1_dRl = -dKl/f*(dBl*dCl - t5L + t5R);
447  dTau2_dRl = -dKl/f*(dCl + dKl - 2.0*M_PI*dRl*dSl + t4L + t4R + 2.0*M_PI*(t6L - t6R));
448  dQ_dRl = -4.0*M_PI*dKl*(dSl - t1L + t1R);
449 
450  double d;
451  if (sModel_[l].pK()->isAttr(SgPartial::Attr_IS_IN_RUN))
452  {
453  d = (dTau1_dKl + dTau2_dKl)/dQ - (dT1 + dT2)*dQ_dKl/dQ/dQ;
454  sModel_[l].pK()->setD(d);
455  parameters.append(sModel_[l].pK());
456  };
457  if (sModel_[l].pB()->isAttr(SgPartial::Attr_IS_IN_RUN))
458  {
459  d = dTau1_dBl/dQ;
460  sModel_[l].pB()->setD(d);
461  parameters.append(sModel_[l].pB());
462  };
463 
464  if (sModel_[l].pX()->isAttr(SgPartial::Attr_IS_IN_RUN))
465  {
466  d = (dTau1_dRl + dTau2_dRl)/dQ - (dT1 + dT2)*dQ_dRl/dQ/dQ;
467  sModel_[l].pX()->setD(d*u);
468  sModel_[l].pY()->setD(d*v);
469  parameters.append(sModel_[l].pX());
470  parameters.append(sModel_[l].pY());
471  };
472  };
473 
474 };
475 
476 
477 
478 //
480 {
481  short bitArray;
482  bitArray = 0;
483  //
484  // ! * *
485  // ! * Format of SOURSTAT_I2 array: *
486  // ! * Array SOURSTAT_I2 contains NUMSTR elements, where NUMSTR *
487  // ! * is the number of sources in database. *
488  // ! * Each element of the array is 16-bits bit field. I-th element*
489  // ! * of SOURSTAT_I2 corresponds to the I-th element of the *
490  // ! * source name array kept in database under lcode *
491  // ! * STRNAMES. In general source order in this array *
492  // ! * MAY NOT coincide with order of sources in the list *
493  // ! * ISTRN_CHR kept in prfil.i !! *
494  // ! * Bits are counted from 1. *
495  // ! * 1-st bit is set when the source was selected in solution. *
496  // ! * 2-nd bit reserved for future use. It is always 1. *
497  // ! * 3-rd bit is set if right ascension of the I-th source *
498  // ! * was estimated in solution. *
499  // ! * 4-th bit is set if declination of the I-th source *
500  // ! * was estimated in solution. *
501  //
502  // first bit:
504  bitArray |= (1<<0);
505  // second bit:
506  bitArray |= (1<<1);
507  // third and fourth bits:
509  {
510  bitArray |= (1<<2);
511  bitArray |= (1<<3);
512  };
513 
514  return bitArray;
515 };
516 
517 
518 
519 //
520 //
522 {
523  // check for deselect flag:
524  if (!(bitArray & (1<<0)))
526 
527  // third and fourth bits:
528  if (bitArray & (1<<2|1<<3)) // if one of bits is on
530 };
531 
532 
533 
534 //
536 {
537  int num=0, n=sModel_.size();
538  for (int i=0; i<n; i++)
539  {
540  if (sModel_.at(i).getEstimateRatio())
541  num++;
542  if (sModel_.at(i).getEstimateSpIdx())
543  num++;
544  if (sModel_.at(i).getEstimatePosition())
545  num += 2;
546  };
547  return num;
548 };
549 
550 
551 /*=====================================================================================================*/
552 
553 
554 
555 
556 /*=====================================================================================================*/
557 //
558 // FRIENDS:
559 //
560 /*=====================================================================================================*/
561 //
562 
563 /*=====================================================================================================*/
564 //
565 // aux functions:
566 //
567 
568 /*=====================================================================================================*/
569 //
570 // constants:
571 //
572 
573 /*=====================================================================================================*/
#define RAD2MAS
radians to ms:
Definition: SgMathSupport.h:60
#define RAD2MS
Definition: SgMathSupport.h:64
bool isAttr(uint a) const
Definition: SgAttribute.h:226
void delAttr(uint a)
Definition: SgAttribute.h:210
void addAttr(uint a)
Definition: SgAttribute.h:202
bool loadIntermediateResults(QDataStream &)
const QString & getKey() const
Definition: SgObjectInfo.h:319
bool saveIntermediateResults(QDataStream &) const
@ Attr_IS_IN_RUN
Definition: SgPartial.h:52
void prepareModel(double u, double v)
double tauS(double f, double u, double v) const
SgVlbiSourceInfo(int idx=-1, const QString &key="Unknown", const QString &aka="Unknown too")
double tauS(double f, double u, double v)
static QString dn2String(double dn, bool mandatorySign=false)
void applyStatusBits(short bitArray)
static const QString className()
SgParameter * pRA_
int procdScanNum_
total number of scans for the source;
SgParameter * pDN_
double RA_
number of processed scans for the source;
int calcNumOfEstimatedSsmParameters() const
bool loadIntermediateResults(QDataStream &)
void processPartials4SrcStructModel(QList< SgParameter * > &parameters, double f, double u, double v)
QList< StructModelMp > sModel_
static QString ra2String(double ra)
bool saveIntermediateResults(QDataStream &) const
static double arcLength(double ra_1, double dn_1, double ra_2, double dn_2)
@ Attr_NOT_VALID
omit the source;
@ Attr_ESTIMATE_COO
estimate source position;