42 #include "Eigen/Cholesky" 57 if (shift ==
nullptr)
return false;
59 static const double eps = 1e-5;
61 double dx = shift->
coeff(0, 0, 0);
62 double dy = shift->
coeff(0, 0, 1);
64 static Point dumb(4000, 4000);
66 fabs(dumb.
x + dx - shift->
apply(dumb).x) < eps &&
fabs(dumb.
y + dy - shift->
apply(dumb).y) < eps)
74 Frame Gtransfo::apply(
Frame const &inputframe,
bool inscribed)
const {
76 double xtmin1, xtmax1, ytmin1, ytmax1;
77 apply(inputframe.
xMin, inputframe.
yMin, xtmin1, ytmin1);
78 apply(inputframe.
xMax, inputframe.
yMax, xtmax1, ytmax1);
82 double xtmin2, xtmax2, ytmin2, ytmax2;
83 apply(inputframe.
xMin, inputframe.
yMax, xtmin2, ytmax2);
84 apply(inputframe.
xMax, inputframe.
yMin, xtmax2, ytmin2);
88 if (inscribed)
return fr1 * fr2;
99 double eps = x * 0.01;
100 if (eps == 0) eps = 0.01;
103 apply(x + eps, y, dxdx, dydx);
107 apply(x, y + eps, dxdy, dydy);
110 return ((dxdx * dydy - dxdy * dydx) / (eps * eps));
120 apply(x, y, xp0, yp0);
123 apply(x + step, y, xp, yp);
124 derivative.
a11() = (xp - xp0) / step;
125 derivative.
a21() = (yp - yp0) / step;
126 apply(x, y + step, xp, yp);
127 derivative.
a12() = (xp - xp0) / step;
128 derivative.
a22() = (yp - yp0) / step;
134 Point outwhere = apply(where);
136 computeDerivative(where, der, step);
146 computeDerivative(in, der, 0.01);
147 double a11 = der.
A11();
148 double a22 = der.
A22();
149 double a21 = der.
A21();
150 double a12 = der.
A12();
151 res.
vx = a11 * (a11 * in.
vx + 2 * a12 * in.
vxy) + a12 * a12 * in.
vy;
152 res.
vy = a21 * a21 * in.
vx + a22 * a22 * in.
vy + 2. * a21 * a22 * in.
vxy;
153 res.
vxy = a21 * a11 * in.
vx + a22 * a12 * in.
vy + (a21 * a12 + a11 * a22) * in.
vxy;
157 void Gtransfo::transformErrors(
Point const &where,
const double *vIn,
double *vOut)
const {
159 computeDerivative(where, der, 0.01);
160 double a11 = der.
A11();
161 double a22 = der.
A22();
162 double a21 = der.
A21();
163 double a12 = der.
A12();
178 double b11 = a11 * vIn[xx] + a12 * vIn[xy];
179 double b22 = a21 * vIn[xy] + a22 * vIn[yy];
180 double b12 = a11 * vIn[xy] + a12 * vIn[yy];
181 double b21 = a21 * vIn[xx] + a22 * vIn[xy];
185 vOut[xx] = b11 * a11 + b12 * a12;
186 vOut[xy] = b11 * a21 + b12 * a22;
187 vOut[yy] = b21 * a21 + b22 * a22;
193 Point centerIn = apply(centerOut);
211 int npar = getNpar();
212 for (
int i = 0; i < npar; ++i) params[i] = paramRef(i);
215 void Gtransfo::offsetParams(Eigen::VectorXd
const &delta) {
216 int npar = getNpar();
217 for (
int i = 0; i < npar; ++i) paramRef(i) += delta[i];
220 double Gtransfo::paramRef(
const int)
const {
222 std::string(
"Gtransfo::paramRef should never be called "));
225 double &Gtransfo::paramRef(
const int) {
229 void Gtransfo::paramDerivatives(
Point const &,
double *,
double *)
const {
231 "Gtransfo::paramDerivatives() should never be called ");
235 gtransfo.
dump(stream);
246 "Gtransfo::write, something went wrong for file " + fileName);
251 "Gtransfo::write(ostream), should never be called. MEans that it is missing in some " 270 void apply(
const double xIn,
const double yIn,
double &xOut,
double &yOut)
const;
297 _direct = direct->
clone();
298 _roughInverse = _direct->roughInverse(region);
303 _direct = model._direct->clone();
304 _roughInverse = model._roughInverse->clone();
305 precision2 = model.precision2;
311 _direct = model._direct->clone();
312 _roughInverse = model._roughInverse->clone();
313 precision2 = model.precision2;
318 Point outGuess = _roughInverse->apply(in);
325 Point inGuess = _direct->apply(outGuess);
326 _direct->computeDerivative(outGuess, directDer);
328 double xShift, yShift;
329 reverseDer.
apply(xIn - inGuess.
x, yIn - inGuess.
y, xShift, yShift);
330 outGuess.
x += xShift;
331 outGuess.
y += yShift;
332 move2 = xShift * xShift + yShift * yShift;
333 }
while ((move2 > precision2) && (loop < maxloop));
334 if (loop == maxloop)
LOGLS_WARN(_log,
"Problems applying GtransfoInverse at " << in);
340 stream <<
" GtransfoInverse of :" <<
endl << *_direct <<
endl;
367 void apply(
const double xIn,
const double yIn,
double &xOut,
double &yOut)
const;
378 _first = first.
clone();
379 _second = second.
clone();
384 _first->apply(xIn, yIn, xout, yout);
385 _second->apply(xout, yout, xOut, yOut);
389 _first->dump(stream);
390 _second->dump(stream);
395 return _first->fit(starMatchList);
399 return std::make_unique<GtransfoComposition>(*_second, *_first);
413 if (composition ==
nullptr)
414 return std::make_unique<GtransfoComposition>(left, right);
430 return std::make_shared<ast::UnitMap>(2);
440 " GtransfoIdentity::read : format is not 1 ");
448 _nterms = (order + 1) * (order + 2) / 2;
451 _coeffs.
resize(2 * _nterms, 0.);
464 for (
double x = frame.
xMin + step / 2;
x <= frame.
xMax;
x += step)
465 for (
double y = frame.
yMin + step / 2;
y <= frame.
yMax;
y += step) {
466 auto pix = std::make_shared<BaseStar>(
x,
y, 0, 0);
468 gtransfo->
apply(x, y, xtr, ytr);
469 auto tp = std::make_shared<BaseStar>(xtr, ytr, 0, 0);
481 jointcal::Frame const &domain,
unsigned const order,
unsigned const nSteps) {
483 double xStart = domain.
xMin;
484 double yStart = domain.
yMin;
485 double xStep = domain.
getWidth() / (nSteps + 1);
486 double yStep = domain.
getHeight() / (nSteps + 1);
487 for (
unsigned i = 0; i < nSteps; ++i) {
488 for (
unsigned j = 0; j < nSteps; ++j) {
498 poly.
fit(starMatchList);
502 void GtransfoPoly::computeMonomials(
double xIn,
double yIn,
double *monomial)
const {
513 for (
unsigned ix = 0; ix <= _order; ++ix) {
515 unsigned k = ix * (ix + 1) / 2;
516 for (
unsigned iy = 0; iy <= _order - ix; ++iy) {
517 monomial[k] = xx * yy;
527 unsigned old_nterms = _nterms;
528 _nterms = (_order + 1) * (_order + 2) / 2;
533 _coeffs.
resize(2 * _nterms);
536 for (
unsigned k = 0; k < _nterms; ++k) _coeffs[k] = 0;
538 unsigned kmax =
min(old_nterms, _nterms);
539 for (
unsigned k = 0; k < kmax; ++k) {
540 _coeffs[k] = old_coeffs[k];
541 _coeffs[k + _nterms] = old_coeffs[k + old_nterms];
556 double monomials[_nterms];
557 computeMonomials(xIn, yIn, monomials);
561 const double *c = &_coeffs[0];
562 const double *pm = &monomials[0];
564 for (
int k = _nterms; k--;) xOut += (*(pm++)) * (*(c++));
566 for (
int k = _nterms; k--;) yOut += (*(pm++)) * (*(c++));
573 derivative.
dx() = derivative.
dy() = 0;
577 double dermx[2 * _nterms];
578 double *dermy = dermx + _nterms;
579 double xin = where.
x;
580 double yin = where.
y;
584 for (
unsigned ix = 0; ix <= _order; ++ix) {
585 unsigned k = (ix) * (ix + 1) / 2;
587 dermx[k] = ix * xxm1;
591 for (
unsigned iy = 1; iy <= _order - ix; ++iy) {
592 dermx[k] = ix * xxm1 * yym1 * yin;
593 dermy[k] = iy * xx * yym1;
598 if (ix >= 1) xxm1 *= xin;
604 const double *mx = &dermx[0];
605 const double *my = &dermy[0];
606 const double *c = &_coeffs[0];
608 double a11 = 0, a12 = 0;
609 for (
int k = _nterms; k--;) {
610 a11 += (*(mx++)) * (*c);
611 a12 += (*(my++)) * (*(c++));
613 derivative.
a11() = a11;
614 derivative.
a12() = a12;
616 double a21 = 0, a22 = 0;
619 for (
int k = _nterms; k--;) {
620 a21 += (*(mx++)) * (*c);
621 a22 += (*(my++)) * (*(c++));
623 derivative.
a21() = a21;
624 derivative.
a22() = a22;
640 double monomials[_nterms];
644 double dermx[2 * _nterms];
645 double *dermy = dermx + _nterms;
651 for (
unsigned ix = 0; ix <= _order; ++ix) {
652 unsigned k = (ix) * (ix + 1) / 2;
654 dermx[k] = ix * xxm1;
660 for (
unsigned iy = 1; iy <= _order - ix; ++iy) {
661 monomials[k] = xx * yy;
662 dermx[k] = ix * xxm1 * yy;
663 dermy[k] = iy * xx * yym1;
669 if (ix >= 1) xxm1 *= xin;
673 double xout = 0, yout = 0;
674 const double *c = &_coeffs[0];
675 const double *pm = &monomials[0];
676 for (
int k = _nterms; k--;) xout += (*(pm++)) * (*(c++));
678 for (
int k = _nterms; k--;) yout += (*(pm++)) * (*(c++));
684 const double *mx = &dermx[0];
685 const double *my = &dermy[0];
686 double a11 = 0, a12 = 0;
687 for (
int k = _nterms; k--;) {
688 a11 += (*(mx++)) * (*c);
689 a12 += (*(my++)) * (*(c++));
692 double a21 = 0, a22 = 0;
695 for (
int k = _nterms; k--;) {
696 a21 += (*(mx++)) * (*c);
697 a22 += (*(my++)) * (*(c++));
701 res.
vx = a11 * (a11 * in.
vx + 2 * a12 * in.
vxy) + a12 * a12 * in.
vy;
702 res.
vy = a21 * a21 * in.
vx + a22 * a22 * in.
vy + 2. * a21 * a22 * in.
vxy;
703 res.
vxy = a21 * a11 * in.
vx + a22 * a12 * in.
vy + (a21 * a12 + a11 * a22) * in.
vxy;
712 assert((degX + degY <= _order) && whichCoord < 2);
716 return _coeffs[(degX + degY) * (degX + degY + 1) / 2 + degY + whichCoord * _nterms];
720 assert((degX + degY <= _order) && whichCoord < 2);
721 return _coeffs[(degX + degY) * (degX + degY + 1) / 2 + degY + whichCoord * _nterms];
726 assert(whichCoord < 2);
727 if (degX + degY <= _order)
728 return _coeffs[(degX + degY) * (degX + degY + 1) / 2 + degY + whichCoord * _nterms];
734 assert(
unsigned(i) < 2 * _nterms);
739 assert(
unsigned(i) < 2 * _nterms);
745 computeMonomials(where.
x, where.
y, dx);
746 for (
unsigned k = 0; k < _nterms; ++k) {
747 dy[_nterms + k] = dx[k];
748 dx[_nterms + k] = dy[k] = 0;
753 static string monomialString(
const unsigned powX,
const unsigned powY) {
755 if (powX + powY) ss <<
"*";
756 if (powX > 0) ss <<
"x";
757 if (powX > 1) ss <<
"^" << powX;
758 if (powY > 0) ss <<
"y";
759 if (powY > 1) ss <<
"^" << powY;
766 for (
unsigned ic = 0; ic < 2; ++ic) {
771 for (
unsigned p = 0; p <= _order; ++p)
772 for (
unsigned py = 0;
py <= p; ++
py) {
773 if (p +
py != 0) stream <<
" + ";
774 stream <<
coeff(p -
py,
py, ic) << monomialString(p -
py,
py);
778 if (_order > 0) stream <<
" Linear determinant = " <<
determinant() <<
endl;
801 for (
auto it = starMatchList.
begin(); it != starMatchList.
end(); ++it) {
819 static double sq(
double x) {
return x *
x; }
822 const bool useErrors) {
823 Eigen::MatrixXd A(2 * _nterms, 2 * _nterms);
825 Eigen::VectorXd B(2 * _nterms);
828 double monomials[_nterms];
829 for (
auto it = starMatchList.
begin(); it != starMatchList.
end(); ++it) {
834 double wxx, wyy, wxy;
836 computeMonomials(point1.
x, point1.
y, monomials);
839 double vxx = (tr1.
vx + point2.
vx);
840 double vyy = (tr1.
vy + point2.
vy);
841 double vxy = (tr1.
vxy + point2.
vxy);
842 double det = vxx * vyy - vxy * vxy;
851 double resx = point2.
x - tr1.
x;
852 double resy = point2.
y - tr1.
y;
853 sumr2 += wxx * sq(resx) + wyy * sq(resy) + 2 * wxy * resx * resy;
855 double bxcoeff = wxx * resx + wxy * resy;
856 double bycoeff = wyy * resy + wxy * resx;
857 for (
unsigned j = 0; j < _nterms; ++j) {
858 for (
unsigned i = j; i < _nterms; ++i) {
859 A(i, j) += wxx * monomials[i] * monomials[j];
860 A(i + _nterms, j + _nterms) += wyy * monomials[i] * monomials[j];
861 A(j, i + _nterms) = A(i, j + _nterms) += wxy * monomials[i] * monomials[j];
863 B(j) += bxcoeff * monomials[j];
864 B(j + _nterms) += bycoeff * monomials[j];
867 Eigen::LDLT<Eigen::MatrixXd, Eigen::Lower> factor(A);
869 if (factor.info() != Eigen::Success) {
870 LOGL_ERROR(_log,
"GtransfoPoly::fit could not factorize");
874 Eigen::VectorXd sol = factor.solve(B);
875 for (
unsigned k = 0; k < 2 * _nterms; ++k) _coeffs[k] += sol(k);
876 if (starMatchList.
size() == _nterms)
return 0;
877 return (sumr2 - B.dot(sol));
881 if (starMatchList.
size() < _nterms) {
882 LOGLS_FATAL(_log,
"GtransfoPoly::fit trying to fit a polynomial transfo of order " 883 << _order <<
" with only " << starMatchList.
size() <<
" matches.");
887 GtransfoPoly conditionner = shiftAndNormalize(starMatchList);
889 computeFit(starMatchList, conditionner,
false);
890 computeFit(starMatchList, conditionner,
true);
891 double chi2 = computeFit(starMatchList, conditionner,
true);
893 (*this) = (*this) * conditionner;
894 if (starMatchList.
size() == _nterms)
return 0;
900 return std::make_unique<GtransfoLin>((*
this) * (right));
902 return std::make_unique<GtransfoPoly>((*this) * (right));
920 PolyXY(
const int order) : order(order), nterms((order + 1) * (order + 2) / 2) {
928 : order(gtransfoPoly.
getOrder()), nterms((order + 1) * (order + 2) / 2), coeffs(nterms, 0L) {
929 for (
unsigned px = 0; px <= order; ++px)
930 for (
unsigned py = 0;
py <= order - px; ++
py)
934 long double coeff(
const unsigned powX,
const unsigned powY)
const {
935 assert(powX + powY <= order);
936 return coeffs.
at((powX + powY) * (powX + powY + 1) / 2 + powY);
939 long double &
coeff(
const unsigned powX,
const unsigned powY) {
940 assert(powX + powY <= order);
941 return coeffs.
at((powX + powY) * (powX + powY + 1) / 2 + powY);
950 for (
unsigned i = 0; i <= rdeg; ++i)
951 for (
unsigned j = 0; j <= rdeg - i; ++j) left.
coeff(i, j) += right.
coeff(i, j);
959 for (
unsigned i = 0; i <= order; ++i)
960 for (
unsigned j = 0; j <= order - i; ++j) result.
coeff(i, j) *=
a;
969 for (
unsigned i1 = 0; i1 <= deg1; ++i1)
970 for (
unsigned j1 = 0; j1 <= deg1 - i1; ++j1)
971 for (
unsigned i2 = 0; i2 <= deg2; ++i2)
972 for (
unsigned j2 = 0; j2 <= deg2 - i2; ++j2)
981 powers[0].coeff(0, 0) = 1L;
982 for (
unsigned k = 1; k <= maxP; ++k) powers.
push_back(product(powers[k - 1], polyXY));
991 computePowers(polyX, pdeg, pXPowers);
992 computePowers(polyY, pdeg, pYPowers);
993 for (
unsigned px = 0; px <= pdeg; ++px)
994 for (
unsigned py = 0;
py <= pdeg - px; ++
py)
995 result += polyXY.
coeff(px,
py) * product(pXPowers.
at(px), pYPowers.
at(
py));
1011 PolyXY rx(composition(plx, prx, pry));
1012 PolyXY ry(composition(ply, prx, pry));
1016 for (
unsigned px = 0; px <= result._order; ++px)
1017 for (
unsigned py = 0;
py <= result._order - px; ++
py) {
1025 if (_order >= right._order) {
1027 for (
unsigned i = 0; i <= right._order; ++i)
1028 for (
unsigned j = 0; j <= right._order - i; ++j) {
1034 return (right + (*
this));
1039 for (
unsigned i = 0; i <= res._order; ++i)
1040 for (
unsigned j = 0; j <= res._order - i; ++j) {
1049 return std::make_shared<ast::PolyMap>(toAstPolyMapCoefficients(), inverse->toAstPolyMapCoefficients());
1053 s <<
" GtransfoPoly 1" <<
endl;
1054 s <<
"order " << _order << endl;
1057 for (
unsigned k = 0; k < 2 * _nterms; ++k) s << _coeffs[k] <<
' ';
1059 s << setprecision(oldprec);
1069 s >> order >> _order;
1070 if (order !=
"order")
1072 " GtransfoPoly::read : expecting \"order\" and found " + order);
1074 for (
unsigned k = 0; k < 2 * _nterms; ++k) s >> _coeffs[k];
1077 ndarray::Array<double, 2, 2> GtransfoPoly::toAstPolyMapCoefficients()
const {
1078 int nCoeffs = _coeffs.size();
1079 ndarray::Array<double, 2, 2>
result = ndarray::allocate(ndarray::makeVector(nCoeffs, 4));
1081 ndarray::Size k = 0;
1082 for (
unsigned iCoord = 0; iCoord < 2; ++iCoord) {
1083 for (
unsigned p = 0; p <= _order; ++p) {
1084 for (
unsigned py = 0;
py <= p; ++
py, ++k) {
1085 result[k][0] =
coeff(p -
py,
py, iCoord);
1086 result[k][1] = iCoord + 1;
1087 result[k][2] = p -
py;
1097 double const precision,
int const maxOrder,
1098 unsigned const nSteps) {
1100 double xStart = domain.
xMin;
1101 double yStart = domain.
yMin;
1102 double xStep = domain.
getWidth() / (nSteps - 1);
1103 double yStep = domain.
getHeight() / (nSteps - 1);
1104 for (
unsigned i = 0; i < nSteps; ++i) {
1105 for (
unsigned j = 0; j < nSteps; ++j) {
1106 Point in(xStart + i * xStep, yStart + j * yStep);
1111 unsigned npairs = sm.
size();
1117 for (order = 1; order <= maxOrder; ++order) {
1119 auto success = poly->fit(sm);
1120 if (success == -1) {
1122 errMsg <<
"Cannot fit a polynomial of order " << order <<
" with " << nSteps <<
"^2 points";
1127 for (
auto const &i : sm) chi2 += i.point2.computeDist2(poly->apply((i.point1)));
1128 LOGLS_TRACE(_log,
"inversePoly order " << order <<
": " << chi2 <<
" / " << npairs <<
" = " 1129 << chi2 / npairs <<
" < " << precision * precision);
1131 if (chi2 / npairs < precision * precision)
break;
1134 if (chi2 > oldChi2) {
1135 LOGLS_WARN(_log,
"inversePolyTransfo: chi2 increases (" << chi2 <<
" > " << oldChi2
1136 <<
"); ending fit with order: " << order);
1137 LOGLS_WARN(_log,
"inversePolyTransfo: requested precision not reached: " 1138 << chi2 <<
" / " << npairs <<
" = " << chi2 / npairs <<
" < " 1139 << precision * precision);
1149 if (order > maxOrder)
1150 LOGLS_WARN(_log,
"inversePolyTransfo: Reached max order without reaching requested precision: " 1151 << chi2 <<
" / " << npairs <<
" = " << chi2 / npairs <<
" < " 1152 << precision * precision);
1162 const double A21,
const double A22)
1175 "Trying to build a GtransfoLin from a higher order transfo. Aborting. ");
1196 derivative.
coeff(0, 0, 0) = 0;
1197 derivative.
coeff(0, 0, 1) = 0;
1213 double d = (a11 * a22 - a12 *
a21);
1216 "GtransfoLin::invert singular transformation: transfo contents will be dumped to stderr.");
1237 int npairs = starMatchList.
size();
1239 LOGLS_FATAL(_log,
"GtransfoLinShift::fit trying to fit a linear transfo with only " << npairs
1246 Eigen::VectorXd B(2);
1248 Eigen::MatrixXd A(2, 2);
1251 for (
auto const &it : starMatchList) {
1252 FatPoint const &point1 = it.point1;
1253 FatPoint const &point2 = it.point2;
1254 double deltax = point2.
x - point1.
x;
1255 double deltay = point2.
y - point1.
y;
1256 double vxx = point1.
vx + point2.
vx;
1257 double vyy = point1.
vy + point2.
vy;
1258 double vxy = point1.
vxy + point2.
vxy;
1259 double det = vxx * vyy - vxy * vxy;
1260 double wxx = vyy / det;
1261 double wyy = vxx / det;
1262 double wxy = -vxy / det;
1263 B(0) += deltax * wxx + wxy * deltay;
1264 B(1) += deltay * wyy + wxy * deltax;
1268 sumr2 += deltax * deltax * wxx + deltay * deltay * wyy + 2. * wxy * deltax * deltay;
1270 double det = A(0, 0) * A(1, 1) - A(0, 1) * A(1, 0);
1271 if (det <= 0)
return -1;
1272 double tmp = A(0, 0);
1273 A(0, 0) = A(1, 1) / det;
1274 A(1, 1) = tmp / det;
1275 A(0, 1) = A(1, 0) = -A(0, 1) / det;
1276 Eigen::VectorXd sol = A * B;
1278 return (sumr2 - sol.dot(B));
1282 double c = scaleFactor *
std::cos(angleRad);
1283 double s = scaleFactor *
std::sin(angleRad);
1289 Point a_point(0., 0.);
1290 if (center) a_point = *center;
1294 dx() = a_point.
x -
Dx();
1295 dy() = a_point.
y -
dy();
1298 static double deg2rad(
double degree) {
return degree *
M_PI / 180.; }
1300 static double rad2deg(
double rad) {
return rad * 180. /
M_PI; }
1323 linPixelToTan = pixToTan;
1324 ra0 = deg2rad(tangentPoint.
x);
1325 dec0 = deg2rad(tangentPoint.
y);
1329 if (corrections) corr.reset(
new GtransfoPoly(*corrections));
1362 LOGL_WARN(_log,
"No sidereal coordinates at pole!");
1371 if (rat < 0.0) rat += (2. *
M_PI);
1373 xOut = rad2deg(rat);
1374 yOut = rad2deg(dect);
1392 return Point(inverse.
Dx(), inverse.
Dy());
1401 xOut = outCoord[0].asDegrees();
1402 yOut = outCoord[1].asDegrees();
1419 :
BaseTanWcs(pixToTan, tangentPoint, corrections) {}
1426 return std::make_unique<TanPixelToRaDec>((*this) * (right));
1439 if (
corr !=
nullptr) {
1440 LOGL_WARN(_log,
"You are inverting a TanPixelToRaDec with corrections.");
1441 LOGL_WARN(_log,
"The inverse you get ignores the corrections!");
1465 double &yTangentPlane)
const {
1469 double xtmp = xTangentPlane;
1470 double ytmp = yTangentPlane;
1471 corr->apply(xtmp, ytmp, xTangentPlane, yTangentPlane);
1482 stream <<
" tangent point " << tp.
x <<
' ' << tp.
y <<
endl;
1484 stream <<
" crpix " << crpix.
x <<
' ' << crpix.
y <<
endl;
1485 if (
corr) stream <<
"PV correction: " <<
endl << *
corr;
1498 "TanPixelToRaDec::fit is NOT implemented (although it is doable)) ");
1506 :
BaseTanWcs(pixToTan, tangentPoint, corrections) {}
1534 double &yTangentPlane)
const {
1538 corr->apply(xPixel, yPixel, xtmp, ytmp);
1551 stream <<
" tangent point " << tp.
x <<
' ' << tp.
y <<
endl;
1553 stream <<
" crpix " << crpix.
x <<
' ' << crpix.
y <<
endl;
1554 if (
corr) stream <<
"PV correction: " <<
endl << *
corr;
1567 "TanSipPixelToRaDec::fit is NOT implemented (although it is doable)) ");
1574 : linTan2Pix(tan2Pix) {
1581 ra0 = deg2rad(tangentPoint.
x);
1582 dec0 = deg2rad(tangentPoint.
y);
1614 double ra = deg2rad(in.
x);
1615 double dec = deg2rad(in.
y);
1616 if (ra - ra0 >
M_PI) ra -= (2. *
M_PI);
1617 if (ra - ra0 < -
M_PI) ra += (2. *
M_PI);
1625 double l = sinda * coss;
1626 double m = sins * sin0 + coss * cos0 * cosda;
1628 m = (sins * cos0 - coss * sin0 * cosda) / m;
1632 sq(sin0) - sq(coss) + sq(coss * cos0) * (1 + sq(cosda)) + 2 * sins * sin0 * coss * cos0 * cosda;
1633 double a11 = coss * (cosda * sins * sin0 + coss * cos0) / deno;
1634 double a12 = -sinda * sin0 / deno;
1635 double a21 = coss * sinda * sins / deno;
1636 double a22 = cosda / deno;
1639 tmp.
vx = a11 * (a11 * in.
vx + 2 * a12 * in.
vxy) + a12 * a12 * in.
vy;
1640 tmp.
vy = a21 * a21 * in.
vx + a22 * a22 * in.
vy + 2. * a21 * a22 * in.
vxy;
1641 tmp.
vxy = a21 * a11 * in.
vx + a22 * a12 * in.
vy + (a21 * a12 + a11 * a22) * in.
vxy;
1651 double ra = deg2rad(xIn);
1652 double dec = deg2rad(yIn);
1653 if (ra - ra0 >
M_PI) ra -= (2. *
M_PI);
1654 if (ra - ra0 < -
M_PI) ra += (2. *
M_PI);
1659 double l =
std::sin(ra - ra0) * coss;
1660 double m = sins * sin0 + coss * cos0 *
std::cos(ra - ra0);
1662 m = (sins * cos0 - coss * sin0 *
std::cos(ra - ra0)) / m;
1666 linTan2Pix.
apply(l, m, xOut, yOut);
1675 stream <<
" tan2pix " << linTan2Pix <<
" tangent point " << tp.
x <<
' ' << tp.
y <<
endl;
1692 "TanRaDecToPixel::fit is NOT implemented (although it is doable)) ");
1700 : _userFun(userFun), _userData(userData) {}
1703 _userFun(xIn, yIn, xOut, yOut, _userData);
1707 stream <<
"UserTransfo with user function @ " << _userFun <<
"and userData@ " << _userData <<
endl;
1712 "UserTransfo::fit is NOT implemented (and will never be)) ");
1741 "gtransfoRead : could not find a Gtransfotype");
1742 if (type ==
"GtransfoIdentity") {
1746 }
else if (type ==
"GtransfoPoly") {
1752 " gtransfoRead : No reader for Gtransfo type " + type);
#define LOGLS_WARN(logger, message)
Log a warn-level message using an iostream-based interface.
std::unique_ptr< Gtransfo > composeAndReduce(GtransfoLin const &right) const
Return a reduced composition of newTransfo = this(right()), or nullptr if it cannot be reduced...
virtual std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
void dump(std::ostream &stream=std::cout) const
dumps the transfo coefficients to stream.
std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
implements the linear transformations (6 real coefficients).
the transformation that handles pix to sideral transfos (Gnomonic, possibly with polynomial distortio...
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const override
GtransfoLin getLinPart() const
The Linear part (corresponding to CD's and CRPIX's)
std::shared_ptr< ast::Mapping > toAstMap(jointcal::Frame const &domain) const override
Create an equivalent AST mapping for this transformation, including an analytic inverse if possible...
double paramRef(const int i) const override
GtransfoLin inverted() const
returns the inverse: T1 = T2.inverted();
A hanger for star associations.
void() GtransfoFun(const double, const double, double &, double &, const void *)
signature of the user-provided routine that actually does the coordinate transfo for UserTransfo...
void setCorrections(std::unique_ptr< GtransfoPoly > corrections)
Assign the correction polynomial (what it means is left to derived classes)
Low-level polynomials (including special polynomials) in C++.
double fit(StarMatchList const &starMatchList)
fits a transfo to a std::list of Point pairs (p1,p2, the Point fields in StarMatch).
long double & coeff(const unsigned powX, const unsigned powY)
double fit(StarMatchList const &starMatchList)
guess what
PolyXY(GtransfoPoly const >ransfoPoly, const unsigned whichCoord)
void setOrder(const unsigned order)
Sets the polynomial order (the highest sum of exponents of the largest monomial). ...
double fit(StarMatchList const &starMatchList)
fits a transfo to a std::list of Point pairs (p1,p2, the Point fields in StarMatch).
GtransfoLin operator*(GtransfoLin const &right) const
enables to combine linear tranformations: T1=T2*T3 is legal.
void write(std::ostream &s) const override
GtransfoPoly(const unsigned order=1)
Default transfo : identity for all orders (>=1 ).
table::PointKey< double > crpix
std::unique_ptr< Gtransfo > roughInverse(const Frame &) const
Overload the "generic routine".
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
implements an iterative (Gauss-Newton) solver.
double fit(StarMatchList const &starMatchList)
Not implemented yet, because we do it otherwise.
virtual void pixToTangentPlane(double xPixel, double yPixel, double &xTangentPlane, double &yTangentPlane) const =0
Transform from pixels to tangent plane (degrees)
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
void computeDerivative(Point const &where, GtransfoLin &derivative, const double step=0.01) const override
Computes the local Derivative of a transfo, w.r.t.
std::unique_ptr< Gtransfo > clone() const override
returns a copy (allocated by new) of the transformation.
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
return second(first(xIn,yIn))
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
Transform pixels to ICRS RA, Dec in degrees.
void computeDerivative(Point const &where, GtransfoLin &derivative, const double step=0.01) const
specialised analytic routine
double xMin
coordinate of boundary.
#define LOGL_ERROR(logger, message...)
Log a error-level message using a varargs/printf style interface.
std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
GtransfoPoly operator*(GtransfoPoly const &right) const
Composition (internal stuff in quadruple precision)
GtransfoLin linPixelToTan
double fit(StarMatchList const &starMatchList)
fits a transfo to a std::list of Point pairs (p1,p2, the Point fields in StarMatch).
Polynomial transformation class.
std::shared_ptr< GtransfoPoly > inversePolyTransfo(Gtransfo const &forward, Frame const &domain, double const precision, int const maxOrder=9, unsigned const nSteps=50)
Approximate the inverse by a polynomial, to some precision.
GtransfoLin normalizeCoordinatesTransfo(const Frame &frame)
Returns the transformation that maps the input frame along both axes to [-1,1].
GtransfoInverse(const Gtransfo *direct, const double precision, const Frame ®ion)
A Point with uncertainties.
std::ostream & operator<<(std::ostream &os, CameraSysPrefix const &detSysPrefix)
LSST DM logging module built on log4cxx.
GtransfoLin()
the default constructor constructs the do-nothing transformation.
bool isIntegerShift(const Gtransfo *gtransfo)
Shorthand test to tell if a transfo is a simple integer shift.
double getHeight() const
size along y axis
TanPixelToRaDec inverted() const
exact typed inverse:
Reports attempts to access elements using an invalid key.
virtual char const * what(void) const noexcept
Return a character string summarizing this exception.
void setTangentPoint(Point const &tangentPoint)
Resets the projection (or tangent) point.
double coeffOrZero(const unsigned powX, const unsigned powY, const unsigned whichCoord) const
read access, zero if beyond order
std::unique_ptr< Gtransfo > roughInverse(const Frame ®ion) const
Overload the "generic routine" (available for all Gtransfo types.
#define LOGL_FATAL(logger, message...)
Log a fatal-level message using a varargs/printf style interface.
virtual void pixToTangentPlane(double xPixel, double yPixel, double &xTangentPlane, double &yTangentPlane) const
transforms from pixel space to tangent plane (degrees)
void read(std::istream &s)
rectangle with sides parallel to axes.
GtransfoComposition(Gtransfo const &second, Gtransfo const &first)
will pipe transfos
void dump(std::ostream &stream) const
dumps the transfo coefficients to stream.
A base class for image defects.
#define LOGLS_TRACE(logger, message)
Log a trace-level message using an iostream-based interface.
Point getCrPix() const
Get the pixel origin of the WCS (CRPIX in FITS WCS terminology, but zero-based)
std::unique_ptr< Gtransfo > inverseTransfo(const double precision, const Frame ®ion) const
Inverse transfo: returns a TanPixelToRaDec.
GtransfoLin getLinPart() const
The Linear part (corresponding to CD's and CRPIX's)
void dump(std::ostream &stream) const
dumps the transfo coefficients to stream.
std::unique_ptr< Gtransfo > inverseTransfo(const double precision, const Frame ®ion) const
returns an inverse transfo. Numerical if not overloaded.
std::unique_ptr< Gtransfo > inverseTransfo(const double precision, const Frame ®ion) const
Inverse transfo: returns a TanRaDecToPixel if there are no corrections, or the iterative solver if th...
void dump(ostream &stream=cout) const
dumps the transfo coefficients to stream.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
GtransfoPoly getPixelToTangentPlane() const
the transformation from pixels to tangent plane (degrees)
void read(std::istream &s)
std::shared_ptr< afw::geom::SkyWcs > getSkyWcs() const
def getParams(record, galType='sersic')
std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
table::Key< table::Array< int > > degree
This one is the Tangent Plane (called gnomonic) projection (from celestial sphere to tangent plane) ...
std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
virtual std::unique_ptr< Gtransfo > composeAndReduce(Gtransfo const &right) const
Return a reduced composition of newTransfo = this(right()), or nullptr if it cannot be reduced...
double fit(StarMatchList const &starMatchList) override
guess what
T dynamic_pointer_cast(T... args)
std::shared_ptr< ast::Mapping > toAstMap(jointcal::Frame const &domain) const override
Create an equivalent AST mapping for this transformation, including an analytic inverse if possible...
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
double fit(StarMatchList const &starMatchList)
guess what
#define LOGL_WARN(logger, message...)
Log a warn-level message using a varargs/printf style interface.
void dump(std::ostream &stream=std::cout) const override
print out of coefficients in a readable form.
std::unique_ptr< Gtransfo > inverseTransfo(const double precision, const Frame ®ion) const
Inverse transfo: returns a TanRaDecToPixel if there are no corrections, or the iterative solver if th...
BaseTanWcs(GtransfoLin const &pixToTan, Point const &tangentPoint, const GtransfoPoly *corrections=nullptr)
Reports errors in the logical structure of the program.
virtual GtransfoLin linearApproximation(Point const &where, const double step=0.01) const override
linear approximation.
double fit(StarMatchList const &starMatchList)
Not implemented yet, because we do it otherwise.
double fit(StarMatchList const &starMatchList)
fits a transfo to a std::list of Point pairs (p1,p2, the Point fields in StarMatch).
double getWidth() const
size along x axis
unsigned getOrder() const
Returns the polynomial order.
void transformPosAndErrors(const FatPoint &in, FatPoint &out) const
transform with analytical derivatives
Point getCenter() const
Center of the frame.
A do-nothing transformation. It anyway has dummy routines to mimick a Gtransfo.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
just here to provide a specialized constructor, and fit.
void computeDerivative(Point const &where, GtransfoLin &derivative, const double step=0.01) const override
specialised analytic routine
void dump(std::ostream &stream) const
dumps the transfo coefficients to stream.
std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
friend class GtransfoPoly
just here to provide specialized constructors. GtransfoLin fit routine.
a virtual (interface) class for geometric transformations.
virtual void pixToTangentPlane(double xPixel, double yPixel, double &xTangentPlane, double &yTangentPlane) const
transforms from pixel space to tangent plane (degrees)
Point getTangentPoint() const
Get the sky origin (CRVAL in FITS WCS terminology) in degrees.
std::unique_ptr< GtransfoPoly > corr
Reports invalid arguments.
double coeff(const unsigned powX, const unsigned powY, const unsigned whichCoord) const
access to coefficients (read only)
Private class to handle Gtransfo compositions (i.e.
GtransfoPoly operator-(GtransfoPoly const &right) const
Subtraction.
GtransfoPoly getPixelToTangentPlane() const
the transformation from pixels to tangent plane (degrees)
#define LOGLS_FATAL(logger, message)
Log a fatal-level message using an iostream-based interface.
TanRaDecToPixel inverted() const
approximate inverse : it ignores corrections;
GtransfoSkyWcs(std::shared_ptr< afw::geom::SkyWcs > skyWcs)
long double coeff(const unsigned powX, const unsigned powY) const
#define LOG_GET(logger)
Returns a Log object associated with logger.
void paramDerivatives(Point const &where, double *dx, double *dy) const override
Derivative w.r.t parameters.
void write(std::ostream &s) const override
std::unique_ptr< Gtransfo > gtransfoRead(const std::string &fileName)
The virtual constructor from a file.
T setprecision(T... args)
virtual std::unique_ptr< Gtransfo > clone() const =0
returns a copy (allocated by new) of the transformation.
virtual void dump(std::ostream &stream=std::cout) const =0
dumps the transfo coefficients to stream.
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const override
UserTransfo(GtransfoFun &fun, const void *userData)
the transfo routine and extra data that it may need.
unsigned getOrder() const
double fit(const StarMatchList &starMatchList) override
Not implemented; throws pex::exceptions::LogicError.
TanPixelToRaDec operator*(GtransfoLin const &right) const
composition with GtransfoLin
GtransfoLin linearApproximation(Point const &where, const double step=0.01) const
linear (local) approximation.
virtual void transformPosAndErrors(const FatPoint &in, FatPoint &out) const override
a mix of apply and Derivative
virtual void apply(const double xIn, const double yIn, double &xOut, double &yOut) const =0
void dump(ostream &stream) const
dumps the transfo coefficients to stream.
void operator=(const BaseTanWcs &original)
std::unique_ptr< Gtransfo > inverseTransfo(double, const Frame &) const
Inverse transfo: returns the direct one!
std::unique_ptr< Gtransfo > composeAndReduce(GtransfoPoly const &right) const
Return a reduced composition of newTransfo = this(right()), or nullptr if it cannot be reduced...
double determinant() const
Reports errors that are due to events beyond the control of the program.
std::unique_ptr< Gtransfo > roughInverse(const Frame ®ion) const
Overload the "generic routine" (available for all Gtransfo types.
void dump(std::ostream &stream=std::cout) const override
dumps the transfo coefficients to stream.
Point getTangentPoint() const
tangent point coordinates (degrees)
T emplace_back(T... args)
GtransfoPoly operator+(GtransfoPoly const &right) const
Addition.
std::unique_ptr< Gtransfo > gtransfoCompose(Gtransfo const &left, Gtransfo const &right)
Returns a pointer to a composition of gtransfos, representing left(right()).