General Purpose Geodetic Library
SgModelEop_JMG_96_hf.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 <math.h>
24 
25 
26 #include <QtCore/QFile>
27 #include <QtCore/QStringList>
28 #include <QtCore/QTextStream>
29 
30 #include <SgModelEop_JMG_96_hf.h>
31 
32 #include <SgLogger.h>
33 #include <SgMatrix.h>
34 #include <SgVector.h>
35 
36 
37 void fundArgs_Old(const SgMJD&, double[6]);
38 
39 
40 /*=======================================================================================================
41 *
42 * SgModelEop_JMG_96_hf's METHODS:
43 *
44 *======================================================================================================*/
45 //
46 // static first:
48 {
49  return "SgModelEop_JMG_96_hf";
50 };
51 
52 
53 
54 //
55 bool SgModelEop_JMG_96_hf::readFile(const QString& fileName)
56 {
57  QString str;
58  QFile f((fileName_=fileName));
59  bool isOk;
60  isOk_ = false;
61  if (!f.exists())
62  {
64  ": the file [" + fileName + "] with a priori data does not exist");
65  return false;
66  };
67  //
68  // clear the stuff:
69  numUt_ = 0;
70  numPm_ = 0;
71  if (baseModel_)
72  {
73  delete baseModel_;
74  baseModel_ = NULL;
75  };
76  utModel_ = NULL;
77  pmModel_ = NULL;
78  //
79  if (f.open(QFile::ReadOnly))
80  {
81  QTextStream s(&f);
82  int idx=0;
83  while (!s.atEnd())
84  {
85  str = s.readLine();
86  if (str.at(0)==' ')
87  {
88  if (numUt_*numPm_ == 0) // first non-comments string, determine number of arrays:
89  {
90  QStringList l = str.simplified().split(' ', QString::SkipEmptyParts);
91  if (l.size() != 2)
92  {
94  ": the file [" + fileName + "]: cannot guess numbers of arrays from the string: [" +
95  str + "]");
96  return false;
97  };
98  numUt_ = l.at(0).toInt(&isOk);
99  if (!isOk)
100  {
101  numUt_ = 0;
103  ": the file [" + fileName + "]: failed to get the array size for UT1, the string: [" +
104  str + "]");
105  return false;
106  };
107  numPm_ = l.at(1).toInt(&isOk);
108  if (!isOk)
109  {
110  numUt_ = 0;
111  numPm_ = 0;
113  ": the file [" + fileName + "]: failed to get the array size for PM, the string: [" +
114  str + "]");
115  return false;
116  };
117  // arrange some space for the data:
118  baseModel_ = new HfEopRec[numUt_ + numPm_];
122  ": the file [" + fileName + "]: allocated " + QString("").setNum(numUt_) +
123  " records for UT1 and " + QString("").setNum(numPm_) + " records for PM");
124  }
125  else
126  {
127  int n[6];
128  double a_c, a_s;
129  QStringList l = str.simplified().split(' ', QString::SkipEmptyParts);
130  if (l.size() != 10)
131  {
133  ": the file [" + fileName + "]: cannot guess format of the string: [" +
134  str + "]");
135  return false;
136  };
137  for (int i=0; i<6; i++)
138  {
139  n[i] = l.at(i).toInt(&isOk);
140  if (!isOk)
141  {
143  ": the file [" + fileName + "]: failed to acquire info (n_" + QString("").setNum(i) +
144  "), the string: [" + str + "]");
145  return false;
146  };
147  };
148  a_c = l.at(6).toDouble(&isOk);
149  if (!isOk)
150  {
152  ": the file [" + fileName + "]: failed to acquire info (a_c), the string: [" + str + "]");
153  return false;
154  };
155  a_s = l.at(7).toDouble(&isOk);
156  if (!isOk)
157  {
159  ": the file [" + fileName + "]: failed to acquire info (a_s), the string: [" + str + "]");
160  return false;
161  };
162  for (int i=0; i<6; i++)
163  baseModel_[idx].n_[i] = n[i];
164  baseModel_[idx].a_cos_ = a_c;
165  baseModel_[idx].a_sin_ = a_s;
166  idx++;
167  };
168  };
169  };
170  f.close();
171  s.setDevice(NULL);
172  };
173 
174  if (0<numUt_ && 0<numPm_)
175  isOk_ = true;
176 
177  return isOk_;
178 };
179 
180 
181 
182 //
183 void SgModelEop_JMG_96_hf::calcCorrections(const SgMJD& t, double& dUt1, double& dPx, double& dPy)
184 {
185  QString str;
186  double fundArgs[6];
187  double arg;
188 
189  // zerofy values:
190  fundArgs[0] = fundArgs[1] = fundArgs[2] = fundArgs[3] = fundArgs[4] = fundArgs[5] = 0.0;
191  dUt1 = dPx = dPy = 0.0;
192 
193  if (!isOk_)
194  return;
195 
196  fundArgs_Old(t, fundArgs);
197 
198  for (int i=0; i<numUt_; i++)
199  {
200  // Get the argument
201  arg = 0.0;
202  for (int j=0; j<6; j++)
203  arg += utModel_[i].n_[j]*fundArgs[j];
204  // Increment the change to UT1
205  dUt1 += utModel_[i].a_cos_*cos(arg) + utModel_[i].a_sin_*sin(arg);
206  };
207  // convert from mas to mts:
208  // WTF?
209  // dUt1 /= 15.0;
210 
211  //**** Now do polar motion
212  for (int i=0; i<numPm_; i++)
213  {
214  // Get the argument
215  arg = 0.0;
216  for (int j=0; j<6; j++)
217  arg += pmModel_[i].n_[j]*fundArgs[j];
218  // Increment the change to the X anf Y positions
219  // dx = dx + (-xy_val(1,i)* cos(arg) + xy_val(2,i)* sin(arg))
220  dPx += -pmModel_[i].a_cos_*cos(arg) + pmModel_[i].a_sin_*sin(arg);
221  // dy = dy + (xy_val(1,i)* sin(arg) + xy_val(2,i) * cos(arg))
222  dPy += pmModel_[i].a_cos_*sin(arg) + pmModel_[i].a_sin_*cos(arg);
223  };
224  // ***** That is all.
225  // return
226  // end
227 };
228 /*=====================================================================================================*/
229 
230 
231 
232 
233 
234 /*=======================================================================================================
235 *
236 * FRIENDS:
237 *
238 *======================================================================================================*/
239 //
240 
241 
242 
243 /*=====================================================================================================*/
244 //
245 // aux functions:
246 //
247 void fundArgs_Old_another_verison(const SgMJD& t, double args[6])
248 {
249  static const double argsConsts[5][5] =
250  { //0,0 0,1 0,2 0,3 0,4
251  { 0.064, 31.310, 715922.633, 485866.733, 1325.0},
252  {-0.012, -0.577, 1292581.224, 1287099.804, 99.0},
253  { 0.011, -13.257, 295263.137, 335778.877, 1342.0},
254  { 0.019, -6.891, 1105601.328, 1072261.307, 1236.0},
255  { 0.008, 7.455, -482890.539, 450160.280, -5.0}
256  };
257 
258  double tc((t - tEphem)/36525.0);
259  double ts[4];
260  ts[0] = 1.0;
261  ts[1] = tc;
262  ts[2] = tc*tc;
263  ts[3] = tc*tc*tc;
264 
265  for (int i=0; i<5; i++)
266  {
267  args[i] = 0.0;
268  for (int j=0; j<4; j++)
269  args[i] += argsConsts[i][j]*ts[3-j];
270  args[i] += fmod(argsConsts[i][4]*tc, 1.0)*1296000.0;
271  args[i] = fmod(args[i], 1296000.0)*SEC2RAD;
272  };
273 
274  //***** Now compute GMST. (CALC 7.1 Algorithm)
275  // Remove the fractional part of the julian date
276  // Get fjday at 0:00 UT
277  // fjday_0hr = aint(epoch-0.5) + 0.5;
278  // ! Days since J2000.0
279  // t_0hr = fjday_0hr - dj2000;
280  // ! 0:00 hrs at start of day
281  // cent = t_0hr / 36525.0;
282  tc = (t.getDate() - tEphem)/36525.0;
283  ts[1] = tc;
284  ts[2] = tc*tc;
285  ts[3] = tc*tc*tc;
286  //
287  // ! Fraction of a day
288  double fract = t.getTime();
289  double diurnv = (1.002737909350795 + 5.9006e-11*ts[1] - 5.9e-15*ts[2]);
290 
291  //**** COMPUTE GST in cycles
292  double gstd = (24110.54841 + 8640184.81266*ts[1] + 0.093104*ts[2] - 6.2e-6*ts[3])/86400.0;
293  gstd = fmod(gstd, 1.0);
294  args[5] = (gstd + diurnv*fract)*2.0*M_PI + M_PI;
295 };
296 
297 
298 
299 // it mimicks TIDE_ANGLES for compatibility
300 void fundArgs_Old(const SgMJD& t, double args[6])
301 {
302  double sec360(1296000.0);
303  double pi(3.1415926535897932);
304  double twopi(2.0*pi);
305  double arcsec2rad(twopi/sec360);
306  double elc [5] = { 0.064, 31.310, 715922.633, 485866.733, 1325.0};
307  double elpc[5] = {-0.012, -0.577, 1292581.224, 1287099.804, 99.0};
308  double fc [5] = { 0.011, -13.257, 295263.137, 335778.877, 1342.0};
309  double dc [5] = { 0.019, -6.891, 1105601.328, 1072261.307, 1236.0};
310  double omc [5] = { 0.008, 7.455, -482890.539, 450160.280, -5.0};
311  double cent((t - tEphem)/36525.0);
312  double cent2, cent3;
313  double el, elp, f, d, om, gst;
314 
315  cent2 = cent*cent;
316  cent3 = cent2*cent;
317 
318  el = elc[0]*cent3 + elc[1]*cent2 + elc[2]*cent + elc[3] + fmod(elc[4]*cent, 1.0)*sec360;
319  el = fmod(el, sec360);
320  //
321  elp = elpc[0]*cent3 + elpc[1]*cent2 + elpc[2]*cent + elpc[3] + fmod(elpc[4]*cent, 1.0)*sec360;
322  elp = fmod(elp, sec360);
323  //
324  f = fc[0]*cent3 + fc[1]*cent2 + fc[2]*cent + fc[3] + fmod(fc[4]*cent, 1.0)*sec360;
325  f = fmod(f, sec360);
326  //
327  d = dc[0]*cent3 + dc[1]*cent2 + dc[2]*cent + dc[3] + fmod(dc[4]*cent, 1.0)*sec360;
328  d = fmod(d, sec360);
329  //
330  om = omc[0]*cent3 + omc[1]*cent2 + omc[2]*cent + omc[3] + fmod(omc[4]*cent, 1.0)*sec360;
331  om = fmod(om, sec360);
332 
333 
337  double t_0hr = (t.getDate() - tEphem);
339  cent = t_0hr/36525.0;
340  cent2 = cent*cent;
341  cent3 = cent2*cent;
344  double fract = t.getTime();
346  double diurnv = (1.002737909350795 + 5.9006e-11*cent - 5.9e-15*cent2);
349  double gstd = (24110.54841 + 8640184.81266*cent + 0.093104*cent2 - 6.2e-6*cent3 )/86400.0;
351  gstd = fmod(gstd, 1.0);
353  gst = (gstd + diurnv*fract)*twopi;
354 
355 
356  args[0] = el;
357  args[1] = elp;
358  args[2] = f;
359  args[3] = d;
360  args[4] = om;
361  for (int i=0; i<5; i++)
362  args[i] *= arcsec2rad;
363  args[5] = gst + pi;
364 };
365 
366 
367 
368 /*
369  *
370  *
371  *
372 !TITLE TIDE_ANGLES
373  SUBROUTINE tide_angles( epoch, fund_arg )
374  IMPLICIT NONE !Added by IMP/jwr
375 !
376 !-----The following type specification statements added automatically
377 ! by imp/jwr July 2002
378 !
379  INTEGER*2 i
380  REAL*4 gstdot
381 !-----END of imp added lines.
382 !
383 ! Routine to compute the value of the fundamental argument
384 ! for Brown's arguments. The sixth entry is returned as GST
385 ! plus pi. The additional pi is used for compatability with
386 ! Doodson's Tide argument.
387 !
388 ! original routine From Tom Herring.
389 ! modified by JMGipson to compute derivatives of tide angles.
390 ! Tide angles are returned in radians.
391 ! Derivatives in radians/sec.
392 !
393 ! PHYSICAL CONSTANTS NEEDED FOR SD_COMP
394 !
395 ! pi - Define here to full precision
396 ! rad_to_deg - Conversion from radians to degs.
397 ! DJ2000 - Julian date of J2000
398 ! sec360 - number of seconds in 360 degreees.
399 !
400  real*8 pi, rad_to_deg, DJ2000, sec360,arcsec2rad,twopi
401  real*8 century2sec
402 !
403  parameter ( pi = 3.1415926535897932D0 )
404  parameter ( twopi = 2.d0*pi)
405  parameter ( DJ2000 = 2451545.d0 )
406  parameter ( sec360 = 1296000.d0 )
407 !
408 ! Computed quanities
409  parameter ( rad_to_deg = 180.d0 /pi )
410 ! conversion from arcseconds to radians.
411  parameter (arcsec2rad= twopi/sec360)
412  parameter(century2sec=86400.d0*36525.d0)
413 !
414 !-------------------------------------------------------------------
415 !
416 ! PASSED VARIABLES
417 !
418 ! INPUT
419 ! epoch - Julian date for arguments (fjday + fraction of day)
420 !
421 ! OUTPUT
422 ! fund_arg(6,2) - Brown's arguments plus GST+pi (rads)
423 !
424  real*8 epoch, fund_arg(6,2)
425 !
426 !
427 ! LOCAL VARIABLES
428 ! cent - Julian centuries to DJ2000.
429 ! el,eld - Mean longitude of moon minus mean
430 ! - longitude of moon's perigee (arcsec)
431 ! elc(5) - Coefficients for computing el
432 ! elp,elpd - Mean longitude of the sun minus mean
433 ! - longitude of sun perigee (arcsec)
434 ! elpc(5) - Coeffiecents for computing elp
435 ! f,fd - Moon's mean longitude minus omega (sec)
436 ! fc(5) - Coefficients for computing f
437 ! d,dd - Mean elongation of the moon from the
438 ! - sun (arcsec)
439 ! dc(5) - coefficients for computing d
440 ! om,omd - longitude of the ascending node of the
441 ! - moon's mean orbit on the elliptic
442 ! - measured from the mean equinox of date
443 ! omc(5) - Coefficients for computing om.
444 ! gst - Greenwich mean sidereal time (rad)
445 !
446  real*8 cent, el,eld, elc(5), elp, elpd, elpc(5), &
447  & f,fd, fc(5), d,dd, dc(5), om,omd, omc(5), gst
448 ! fract - fraction of a day from 0:00 hrs UT.
449 ! Jd_0hr - Julian date at zero hours UT
450 ! t_0hr - Days since DJ2000 at 0:00 hrs UT
451 ! gstd - GMST at 0:00 hrs UT1 of day being evaluated
452 ! diurnv - Ratio of solar days to sidreal days on
453 ! day of evalution.
454 !
455  real*8 fract, t_0hr, gstd, diurnv, fjday_0hr
456 !
457 !**** DATA statements for the fundamental arguments.
458 !
459  data elc / 0.064d0, 31.310d0, 715922.633d0, &
460  & 485866.733d0, 1325.0d0 /
461  data elpc / -0.012d0, -0.577d0, 1292581.224d0, &
462  & 1287099.804d0, 99.0d0 /
463  data fc / 0.011d0, -13.257d0, 295263.137d0, &
464  & 335778.877d0, 1342.0d0/
465  data dc / 0.019d0, -6.891d0, 1105601.328d0, &
466  & 1072261.307d0, 1236.0d0/
467  data omc / 0.008d0, 7.455d0, -482890.539d0, &
468  & 450160.280d0, -5.0d0/
469 !
470 !**** Get the number of centuries to current time
471 !
472  cent = (epoch-dj2000) / 36525.d0
473 !
474 !**** Compute angular arguments
475  el = elc(1) * cent**3 + elc(2) * cent**2 + elc(3) * cent &
476  & + elc(4) + dmod( elc(5) * cent, 1.d0 ) * sec360
477  el = dmod( el, sec360 )
478  eld = 3.d0 * elc(1) * cent**2 + 2.d0 * elc(2) * cent + elc(3) &
479  & + elc(5) * sec360
480 !
481  elp = elpc(1) * cent**3 + elpc(2) * cent**2 + elpc(3) * cent &
482  & + elpc(4) + dmod( elpc(5) * cent, 1.d0 ) * sec360
483  elp = dmod( elp, sec360 )
484  elpd = 3.d0 * elpc(1) * cent**2 + 2.d0 * elpc(2) * cent + elpc(3) &
485  & + elpc(5) * sec360
486 !
487  f = fc(1) * cent**3 + fc(2) * cent**2 + fc(3) * cent &
488  & + fc(4) + dmod( fc(5) * cent, 1.d0 ) * sec360
489  f = dmod( f, sec360 )
490  fd = 3.d0 * fc(1) * cent**2 + 2.d0 * fc(2) * cent + fc(3) &
491  & + fc(5) * sec360
492 !
493  d = dc(1) * cent**3 + dc(2) * cent**2 + dc(3) * cent &
494  & + dc(4) + dmod( dc(5) * cent, 1.d0 ) * sec360
495  d = dmod( d, sec360 )
496  dd = 3.d0 * dc(1) * cent**2 + 2.d0 * dc(2) * cent + dc(3) &
497  & + dc(5) * sec360
498 !
499  om = omc(1) * cent**3 + omc(2) * cent**2 + omc(3) * cent &
500  & + omc(4) + dmod( omc(5) * cent, 1.d0 ) * sec360
501  om = dmod( om, sec360 )
502  omd = 3.d0 * omc(1) * cent**2 + 2.d0 * omc(2) * cent + omc(3) &
503  & + omc(5) * sec360
504 !
505 !
506 !***** Now compute GMST. (CALC 7.1 Algorithm)
507 ! Remove the fractional part of the julian date
508 ! Get fjday at 0:00 UT
509  fjday_0hr = aint(epoch-0.5d0) + 0.5d0
510 ! ! Days since J2000.0
511  t_0hr = fjday_0hr - dj2000
512 ! ! 0:00 hrs at start of day
513  cent = t_0hr / 36525.d0
514 !
515 ! ! Fraction of a day
516  fract = epoch - fjday_0hr
517 !
518  diurnv = ( 1.002737909350795d0 + 5.9006d-11*cent &
519  & - 5.9d-15*cent**2 )
520 !
521 !**** COMPUTE GST in cycles
522  gstd = ( 24110.54841d0 + 8640184.81266d0*cent &
523  & + 0.093104d0*cent**2 &
524  & - 6.2d-6*cent**3 ) /86400.d0
525 !
526  gstd = dmod(gstd,1.d0)
527 ! ! Rads
528  gst = (gstd + diurnv*fract) * twopi
529 !
530  gstdot=(diurnv/86400.+ &
531  & (8640184.81266d0+2.*0.093104d0*cent - 3.d0*6.2d-6*cent*3 ) &
532  & /86400.d0/century2sec)
533 !
534 !
535 !**** Now save the values. Convert values from arcseconds to radians
536 !
537  fund_arg(1,1) = el
538  fund_arg(2,1) = elp
539  fund_arg(3,1) = f
540  fund_arg(4,1) = d
541  fund_arg(5,1) = om
542 !
543  fund_arg(1,2) = eld
544  fund_arg(2,2) = elpd
545  fund_arg(3,2) = fd
546  fund_arg(4,2) = dd
547  fund_arg(5,2) = omd
548 !
549  do i=1,5
550  fund_arg(i,1)=fund_arg(i,1)*arcsec2rad
551  fund_arg(i,2)=fund_arg(i,2)*arcsec2rad/century2sec
552  end do
553 !
554  fund_arg(6,1) = gst + pi
555  fund_arg(6,2) = gstdot*twopi
556 !***** Thats all
557  return
558  end
559 !
560 !********************************************************
561 
562 */
563 
564 // i/o:
565 
566 
567 /*=====================================================================================================*/
568 //
569 // constants:
570 //
571 /*=====================================================================================================*/
572 
573 
574 
575 
576 
577 
578 
579 
580 /*=====================================================================================================*/
SgLogger * logger
Definition: SgLogger.cpp:231
const SgMJD tEphem(51544.5)
#define SEC2RAD
radians to arc seconds:
Definition: SgMathSupport.h:48
void fundArgs_Old_another_verison(const SgMJD &t, double args[6])
void fundArgs_Old(const SgMJD &, double[6])
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ IO_TXT
Definition: SgLogger.h:65
Definition: SgMJD.h:59
double getTime() const
Definition: SgMJD.h:457
int getDate() const
Definition: SgMJD.h:449
bool readFile(const QString &)
void calcCorrections(const SgMJD &, double &dUt1, double &dPx, double &dPy)
static const QString className()