Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.apo.nmsu.edu/Telescopes/coordConv/html/app_geo_coord_sys_8cc_source.html
Дата изменения: Thu May 7 21:42:46 2015
Дата индексирования: Sun Apr 10 04:53:43 2016
Кодировка:
lsst.coordConv: src/appGeoCoordSys.cc Source File
lsst.coordConv  unknown
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
appGeoCoordSys.cc
Go to the documentation of this file.
1 #include <cmath>
2 #include <iomanip>
3 #include <stdexcept>
4 #include <sstream>
5 #include "slalib.h"
6 #include "coordConv/mathUtils.h"
7 #include "coordConv/physConst.h"
8 #include "coordConv/time.h"
9 #include "coordConv/coordSys.h"
10 
11 namespace coordConv {
12 
13  AppGeoCoordSys::AppGeoCoordSys(double date, double maxAge, double maxDDate)
14  :
15  ApparentCoordSys("appgeo", date, DateType_Julian),
16  _maxAge(maxAge),
17  _maxDDate(maxDDate),
18  _cacheDate(DoubleNaN)
19  {
20  setDate(date);
21  };
22 
24  return clone(getDate());
25  }
26 
27  CoordSys::Ptr AppGeoCoordSys::clone(double date) const {
28  return CoordSys::Ptr(new AppGeoCoordSys(date, _maxAge));
29  };
30 
31  void AppGeoCoordSys::_setDate(double date) const {
32  // sanity-check the date, since very large values can cause NaNs
33  // and since a common mistake is to call with TAI, MJD seconds
34  if (date > 9999) {
35  std::ostringstream os;
36  os << "date = " << date << " too large; should be TDB years";
37  throw std::runtime_error(os.str());
38  }
39  // std::cout << std::fixed << std::setprecision(11) << "AppGeoCoordSys._setDate: date=" << date << "; _date=" << _date << "; _cacheDate=" << _cacheDate;
40  double dDate = date - this->_date;
41  this->_date = date;
42  if (std::isfinite(date) && (date != 0)) {
43  if (cacheOK() && ((std::abs(date - _cacheDate) < _maxAge) || (std::abs(dDate) < _maxDDate))) {
44  // std::cout << "; NOT updating AppGeo cache" << std::endl;
45  return;
46  }
47  // std::cout << "; updating AppGeo cache" << std::endl;
48  double tdbDays = slaEpj2d(date);
49  double amprms[21];
50  slaMappa(2000.0, tdbDays, amprms);
51 
52  _pmSpan = amprms[0];
53  _gravRad = amprms[7];
54  _gammaI = amprms[11];
55  for (int i = 0; i < 3; ++i) {
56  _bcPos(i) = amprms[1+i];
57  _hcDir(i) = amprms[4+i];
58  _bcBeta(i) = amprms[8+i];
59  for (int j = 0; j < 3; ++j) {
60  _pnMat(i,j) = amprms[12+(i*3)+j];
61  }
62  }
63  _cacheDate = date;
64  // } else {
65  // std::cout << "; nothing to update" << std::endl;
66  }
67  }
68 
69  Coord AppGeoCoordSys::fromFK5J2000(Coord const &coord, Site const &site) const {
70  if (!cacheOK()) {
71  throw std::runtime_error("cache not valid");
72  }
73  Eigen::Vector3d fk5J2000Pos = coord.getVecPos();
74  Eigen::Vector3d fk5J2000PM = coord.getVecPM();
75 
76  // correct for velocity and Earth's offset from the barycenter
77  Eigen::Vector3d pos1 = fk5J2000Pos + (fk5J2000PM * _pmSpan) - _bcPos;
78 
79  // here is where the correction for sun's gravity belongs
80  Eigen::Vector3d pos2 = pos1;
81 
82  // correct for annual aberration
83  double pos2Mag = pos2.norm();
84  double dot2 = pos2.dot(_bcBeta) / pos2Mag;
85  double vfac = pos2Mag * (1.0 + dot2 / (1.0 + _gammaI)); // the presence of pos2Mag is due to light travel time from the target
86  Eigen::Vector3d pos3 = ((_gammaI * pos2) + (vfac * _bcBeta)) / (1.0 + dot2);
87 
88  // correct position for precession and nutation
89  Eigen::Vector3d appGeoPos = _pnMat * pos3;
90  return Coord(appGeoPos);
91  };
92 
110  Coord AppGeoCoordSys::toFK5J2000(Coord const &coord, Site const &site) const {
111  if (!cacheOK()) {
112  throw std::runtime_error("cache not valid");
113  }
114  Eigen::Vector3d appGeoPos = coord.getVecPos();
115 
117  const int MaxIter = 20;
120  const double Accuracy = 1.0e-10;
121 
122  // compute constants needed to check iteration
123  const double approxMagP = appGeoPos.norm();
124  const double allowedErr = Accuracy * approxMagP;
125 
126  // correct position for nutation and precession
127  Eigen::Vector3d pos3 = _pnMat.transpose() * appGeoPos;
128 
129  // iterate to correct for annual aberration
130  int iter = 0;
131  double maxErr = approxMagP;
132  Eigen::Vector3d pos2 = pos3;
133  while (maxErr > allowedErr) {
134  iter += 1;
135  if (iter > MaxIter) {
136  std::ostringstream os;
137  os << "aberration correction failed to converge in " << MaxIter <<
138  " iterations; error = " << maxErr << " > " << allowedErr << " allowed";
139  throw std::runtime_error(os.str());
140  }
141 
142  double p2Mag = pos2.norm();
143  double dot2 = pos2.dot(_bcBeta) / p2Mag;
144  double fac = p2Mag * (1.0 + (dot2 / (1.0 + _gammaI)));
145  Eigen::Vector3d oldP2 = pos2;
146  pos2 = (((1.0 + dot2) * pos3) - (fac * _bcBeta)) / _gammaI;
147  maxErr = (pos2 - oldP2).array().abs().maxCoeff();
148  }
149 
150  // here is where the (iterative) correction for sun's gravity belongs
151  Eigen::Vector3d pos1 = pos2;
152 
153  // correct for Earth's offset from the barycenter
154  Eigen::Vector3d fk5J2000Pos = pos1 + _bcPos;
155 
156  return Coord(fk5J2000Pos);
157  }
158 
159  std::string AppGeoCoordSys::__repr__() const {
160  std::ostringstream os;
161  os << "AppGeoCoordSys(" << getDate() << ")";
162  return os.str();
163  }
164 
165 }
virtual Coord toFK5J2000(Coord const &coord, Site const &site) const
const double DoubleNaN
Definition: mathUtils.h:16
virtual void _setDate(double date) const
virtual std::string __repr__() const
Eigen::Vector3d const getVecPM() const
Definition: coord.h:142
double getDate(bool zeroIfCurrent=true) const
Definition: coordSys.h:86
void setDate(double date)
Definition: coordSys.h:93
boost::shared_ptr< CoordSys > Ptr
Definition: coordSys.h:32
double _date
name of coordinate system
Definition: coordSys.h:249
virtual CoordSys::Ptr clone() const
bool cacheOK() const
return true if cache is valid
Definition: coordSys.h:426
Eigen::Vector3d const getVecPos() const
Definition: coord.h:135
Julian years.
Definition: coordSys.h:19
virtual Coord fromFK5J2000(Coord const &coord, Site const &site) const
AppGeoCoordSys(double date=0, double maxAge=0.05/(SecPerDay *DaysPerYear), double maxDDate=2 *DeltaTForPos/(SecPerDay *DaysPerYear))