35 std::ostringstream os;
36 os <<
"date = " << date <<
" too large; should be TDB years";
37 throw std::runtime_error(os.str());
40 double dDate = date - this->
_date;
42 if (std::isfinite(date) && (date != 0)) {
43 if (
cacheOK() && ((std::abs(date - _cacheDate) < _maxAge) || (std::abs(dDate) < _maxDDate))) {
48 double tdbDays = slaEpj2d(date);
50 slaMappa(2000.0, tdbDays, amprms);
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];
71 throw std::runtime_error(
"cache not valid");
73 Eigen::Vector3d fk5J2000Pos = coord.
getVecPos();
74 Eigen::Vector3d fk5J2000PM = coord.
getVecPM();
77 Eigen::Vector3d pos1 = fk5J2000Pos + (fk5J2000PM * _pmSpan) - _bcPos;
80 Eigen::Vector3d pos2 = pos1;
83 double pos2Mag = pos2.norm();
84 double dot2 = pos2.dot(_bcBeta) / pos2Mag;
85 double vfac = pos2Mag * (1.0 + dot2 / (1.0 + _gammaI));
86 Eigen::Vector3d pos3 = ((_gammaI * pos2) + (vfac * _bcBeta)) / (1.0 + dot2);
89 Eigen::Vector3d appGeoPos = _pnMat * pos3;
90 return Coord(appGeoPos);
112 throw std::runtime_error(
"cache not valid");
114 Eigen::Vector3d appGeoPos = coord.
getVecPos();
117 const int MaxIter = 20;
120 const double Accuracy = 1.0e-10;
123 const double approxMagP = appGeoPos.norm();
124 const double allowedErr = Accuracy * approxMagP;
127 Eigen::Vector3d pos3 = _pnMat.transpose() * appGeoPos;
131 double maxErr = approxMagP;
132 Eigen::Vector3d pos2 = pos3;
133 while (maxErr > allowedErr) {
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());
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();
151 Eigen::Vector3d pos1 = pos2;
154 Eigen::Vector3d fk5J2000Pos = pos1 + _bcPos;
156 return Coord(fk5J2000Pos);
160 std::ostringstream os;
161 os <<
"AppGeoCoordSys(" <<
getDate() <<
")";
virtual Coord toFK5J2000(Coord const &coord, Site const &site) const
virtual void _setDate(double date) const
virtual std::string __repr__() const
Eigen::Vector3d const getVecPM() const
double getDate(bool zeroIfCurrent=true) const
void setDate(double date)
boost::shared_ptr< CoordSys > Ptr
double _date
name of coordinate system
virtual CoordSys::Ptr clone() const
bool cacheOK() const
return true if cache is valid
Eigen::Vector3d const getVecPos() const
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))