17 #include "Eigen/Cholesky" 31 return (dynamic_cast<const GtransfoIdentity *>(gtransfo) !=
nullptr);
36 if (shift ==
nullptr)
return false;
38 static const double eps = 1e-5;
40 double dx = shift->
coeff(0, 0, 0);
41 double dy = shift->
coeff(0, 0, 1);
43 static Point dumb(4000, 4000);
45 fabs(dumb.
x + dx - shift->
apply(dumb).x) < eps &&
fabs(dumb.
y + dy - shift->
apply(dumb).y) < eps)
59 double eps = x * 0.01;
60 if (eps == 0) eps = 0.01;
63 apply(x + eps, y, dxdx, dydx);
67 apply(x, y + eps, dxdy, dydy);
70 return ((dxdx * dydy - dxdy * dydx) / (eps * eps));
80 apply(x, y, xp0, yp0);
83 apply(x + step, y, xp, yp);
84 derivative.
a11() = (xp - xp0) / step;
85 derivative.
a21() = (yp - yp0) / step;
86 apply(x, y + step, xp, yp);
87 derivative.
a12() = (xp - xp0) / step;
88 derivative.
a22() = (yp - yp0) / step;
94 Point outwhere = apply(where);
96 computeDerivative(where, der, step);
106 computeDerivative(in, der, 0.01);
107 double a11 = der.
A11();
108 double a22 = der.
A22();
109 double a21 = der.
A21();
110 double a12 = der.
A12();
111 res.
vx = a11 * (a11 * in.
vx + 2 * a12 * in.
vxy) + a12 * a12 * in.
vy;
112 res.
vy = a21 * a21 * in.
vx + a22 * a22 * in.
vy + 2. * a21 * a22 * in.
vxy;
113 res.
vxy = a21 * a11 * in.
vx + a22 * a12 * in.
vy + (a21 * a12 + a11 * a22) * in.
vxy;
117 void Gtransfo::transformErrors(
const Point &where,
const double *vIn,
double *vOut)
const {
119 computeDerivative(where, der, 0.01);
120 double a11 = der.
A11();
121 double a22 = der.
A22();
122 double a21 = der.
A21();
123 double a12 = der.
A12();
138 double b11 = a11 * vIn[xx] + a12 * vIn[xy];
139 double b22 = a21 * vIn[xy] + a22 * vIn[yy];
140 double b12 = a11 * vIn[xy] + a12 * vIn[yy];
141 double b21 = a21 * vIn[xx] + a22 * vIn[xy];
145 vOut[xx] = b11 * a11 + b12 * a12;
146 vOut[xy] = b11 * a21 + b12 * a22;
147 vOut[yy] = b21 * a21 + b22 * a22;
153 Point centerIn = apply(centerOut);
155 computeDerivative(centerOut, der,
sqrt(region.
getArea()) / 5.);
170 void Gtransfo::getParams(
double *params)
const {
171 int npar = getNpar();
172 for (
int i = 0; i < npar; ++i) params[i] = paramRef(i);
175 void Gtransfo::offsetParams(Eigen::VectorXd
const &delta) {
176 int npar = getNpar();
177 for (
int i = 0; i < npar; ++i) paramRef(i) += delta[i];
180 double Gtransfo::paramRef(
const int)
const {
182 std::string(
"Gtransfo::paramRef should never be called "));
185 double &Gtransfo::paramRef(
const int) {
189 void Gtransfo::paramDerivatives(
const Point &,
double *,
double *)
const {
191 "Gtransfo::paramDerivatives() should never be called ");
195 gtransfo.
dump(stream);
206 "Gtransfo::write, something went wrong for file " + fileName);
211 "Gtransfo::write(ostream), should never be called. MEans that it is missing in some " 230 void apply(
const double xIn,
const double yIn,
double &xOut,
double &yOut)
const;
257 _direct = direct->
clone();
258 _roughInverse = _direct->roughInverse(region);
286 _direct->computeDerivative(outGuess, directDer);
287 reverseDer = directDer.
invert();
288 double xShift, yShift;
289 reverseDer.
apply(xIn - inGuess.
x, yIn - inGuess.
y, xShift, yShift);
290 outGuess.
x += xShift;
291 outGuess.
y += yShift;
292 move2 = xShift * xShift + yShift * yShift;
293 }
while ((move2 >
precision2) && (loop < maxloop));
294 if (loop == maxloop)
LOGLS_WARN(_log,
"Problems applying GtransfoInverse at " << in);
327 void apply(
const double xIn,
const double yIn,
double &xOut,
double &yOut)
const;
338 _first = first->
clone();
339 _second = second->
clone();
344 _first->apply(xIn, yIn, xout, yout);
345 _second->apply(xout, yout, xOut, yOut);
349 _first->dump(stream);
350 _second->dump(stream);
355 return _first->fit(starMatchList);
371 return left->
clone();
379 if (composition ==
nullptr)
402 " GtransfoIdentity::read : format is not 1 ");
410 _nterms = (degree + 1) * (degree + 2) / 2;
426 for (
double x = frame.
xMin + step / 2;
x <= frame.
xMax;
x += step)
427 for (
double y = frame.
yMin + step / 2; y <= frame.
yMax; y += step) {
428 auto pix = std::make_shared<BaseStar>(
x, y, 0, 0);
430 gtransfo->
apply(x, y, xtr, ytr);
431 auto tp = std::make_shared<BaseStar>(xtr, ytr, 0, 0);
453 for (
unsigned ix = 0; ix <=
_degree; ++ix) {
455 unsigned k = ix * (ix + 1) / 2;
456 for (
unsigned iy = 0; iy <=
_degree - ix; ++iy) {
457 monomial[k] = xx * yy;
478 unsigned kmax =
min(old_nterms, _nterms);
479 for (
unsigned k = 0; k < kmax; ++k) {
502 const double *pm = &monomials[0];
504 for (
int k =
_nterms; k--;) xOut += (*(pm++)) * (*(c++));
506 for (
int k =
_nterms; k--;) yOut += (*(pm++)) * (*(c++));
513 derivative.
dx() = derivative.
dy() = 0;
518 double *dermy = dermx +
_nterms;
519 double xin = where.
x;
520 double yin = where.
y;
524 for (
unsigned ix = 0; ix <=
_degree; ++ix) {
525 unsigned k = (ix) * (ix + 1) / 2;
527 dermx[k] = ix * xxm1;
531 for (
unsigned iy = 1; iy <=
_degree - ix; ++iy) {
532 dermx[k] = ix * xxm1 * yym1 * yin;
533 dermy[k] = iy * xx * yym1;
538 if (ix >= 1) xxm1 *= xin;
544 const double *mx = &dermx[0];
545 const double *my = &dermy[0];
548 double a11 = 0, a12 = 0;
549 for (
int k = _nterms; k--;) {
550 a11 += (*(mx++)) * (*c);
551 a12 += (*(my++)) * (*(c++));
553 derivative.
a11() = a11;
554 derivative.
a12() = a12;
556 double a21 = 0, a22 = 0;
559 for (
int k = _nterms; k--;) {
560 a21 += (*(mx++)) * (*c);
561 a22 += (*(my++)) * (*(c++));
563 derivative.
a21() = a21;
564 derivative.
a22() = a22;
585 double *dermy = dermx +
_nterms;
591 for (
unsigned ix = 0; ix <=
_degree; ++ix) {
592 unsigned k = (ix) * (ix + 1) / 2;
594 dermx[k] = ix * xxm1;
600 for (
unsigned iy = 1; iy <=
_degree - ix; ++iy) {
601 monomials[k] = xx * yy;
602 dermx[k] = ix * xxm1 * yy;
603 dermy[k] = iy * xx * yym1;
609 if (ix >= 1) xxm1 *= xin;
613 double xout = 0, yout = 0;
615 const double *pm = &monomials[0];
616 for (
int k = _nterms; k--;) xout += (*(pm++)) * (*(c++));
618 for (
int k = _nterms; k--;) yout += (*(pm++)) * (*(c++));
624 const double *mx = &dermx[0];
625 const double *my = &dermy[0];
626 double a11 = 0, a12 = 0;
627 for (
int k = _nterms; k--;) {
628 a11 += (*(mx++)) * (*c);
629 a12 += (*(my++)) * (*(c++));
632 double a21 = 0, a22 = 0;
635 for (
int k = _nterms; k--;) {
636 a21 += (*(mx++)) * (*c);
637 a22 += (*(my++)) * (*(c++));
641 res.
vx = a11 * (a11 * in.
vx + 2 * a12 * in.
vxy) + a12 * a12 * in.
vy;
642 res.
vy = a21 * a21 * in.
vx + a22 * a22 * in.
vy + 2. * a21 * a22 * in.
vxy;
643 res.
vxy = a21 * a11 * in.
vx + a22 * a12 * in.
vy + (a21 * a12 + a11 * a22) * in.
vxy;
652 assert((degX + degY <=
_degree) && whichCoord < 2);
656 return _coeffs[(degX + degY) * (degX + degY + 1) / 2 + degY + whichCoord *
_nterms];
660 assert((degX + degY <=
_degree) && whichCoord < 2);
661 return _coeffs[(degX + degY) * (degX + degY + 1) / 2 + degY + whichCoord *
_nterms];
666 assert(whichCoord < 2);
668 return _coeffs[(degX + degY) * (degX + degY + 1) / 2 + degY + whichCoord *
_nterms];
674 assert(
unsigned(i) < 2 *
_nterms);
679 assert(
unsigned(i) < 2 *
_nterms);
686 for (
unsigned k = 0; k <
_nterms; ++k) {
687 dy[_nterms + k] = dx[k];
688 dx[_nterms + k] = dy[k] = 0;
693 static string monomialString(
const unsigned powX,
const unsigned powY) {
695 if (powX + powY) ss <<
"*";
696 if (powX > 0) ss <<
"x";
697 if (powX > 1) ss <<
"^" << powX;
698 if (powY > 0) ss <<
"y";
699 if (powY > 1) ss <<
"^" << powY;
704 for (
unsigned ic = 0; ic < 2; ++ic) {
709 for (
unsigned p = 0; p <=
_degree; ++p)
710 for (
unsigned py = 0; py <= p; ++py) {
711 if (p + py != 0) stream <<
" + ";
712 stream <<
coeff(p - py, py, ic) << monomialString(p - py, py);
738 for (
auto it = starMatchList.
begin(); it != starMatchList.
end(); ++it) {
751 double xspan = 3.5 *
sqrt(x2 / count -
std::pow(xav, 2));
752 double yspan = 3.5 *
sqrt(y2 / count -
std::pow(yav, 2));
756 static double sq(
double x) {
return x *
x; }
759 const bool useErrors) {
762 Eigen::VectorXd B(2 *
_nterms);
766 for (
auto it = starMatchList.
begin(); it != starMatchList.
end(); ++it) {
771 double wxx, wyy, wxy;
776 double vxx = (tr1.
vx + point2.
vx);
777 double vyy = (tr1.
vy + point2.
vy);
778 double vxy = (tr1.
vxy + point2.
vxy);
779 double det = vxx * vyy - vxy * vxy;
788 double resx = point2.
x - tr1.
x;
789 double resy = point2.
y - tr1.
y;
790 sumr2 += wxx * sq(resx) + wyy * sq(resy) + 2 * wxy * resx * resy;
792 double bxcoeff = wxx * resx + wxy * resy;
793 double bycoeff = wyy * resy + wxy * resx;
794 for (
unsigned j = 0; j <
_nterms; ++j) {
795 for (
unsigned i = j; i <
_nterms; ++i) {
796 A(i, j) += wxx * monomials[i] * monomials[j];
797 A(i + _nterms, j + _nterms) += wyy * monomials[i] * monomials[j];
798 A(j, i + _nterms) = A(i, j + _nterms) += wxy * monomials[i] * monomials[j];
800 B(j) += bxcoeff * monomials[j];
801 B(j + _nterms) += bycoeff * monomials[j];
804 Eigen::LDLT<Eigen::MatrixXd, Eigen::Lower> factor(A);
806 if (factor.info() != Eigen::Success) {
807 LOGL_ERROR(_log,
"GtransfoPoly::fit could not factorize");
811 Eigen::VectorXd sol = factor.solve(B);
814 return (sumr2 - B.dot(sol));
819 LOGLS_FATAL(_log,
"GtransfoPoly::fit trying to fit a polynomial transfo of degree " 820 <<
_degree <<
" with only " << starMatchList.
size() <<
" matches.");
824 GtransfoPoly conditionner = shiftAndNormalize(starMatchList);
826 computeFit(starMatchList, conditionner,
false);
827 computeFit(starMatchList, conditionner,
true);
828 double chi2 =
computeFit(starMatchList, conditionner,
true);
830 (*this) = (*this) * conditionner;
861 PolyXY(
const int degree) : degree(degree), nterms((degree + 1) * (degree + 2) / 2) {
869 : degree(gtransfoPoly.
getDegree()), nterms((degree + 1) * (degree + 2) / 2), coeffs(nterms, 0L) {
870 for (
unsigned px = 0; px <=
degree; ++px)
871 for (
unsigned py = 0; py <= degree - px; ++py)
872 coeff(px, py) = gtransfoPoly.
coeff(px, py, whichCoord);
875 long double coeff(
const unsigned powX,
const unsigned powY)
const {
876 assert(powX + powY <= degree);
877 return coeffs.
at((powX + powY) * (powX + powY + 1) / 2 + powY);
880 long double &
coeff(
const unsigned powX,
const unsigned powY) {
881 assert(powX + powY <= degree);
882 return coeffs.
at((powX + powY) * (powX + powY + 1) / 2 + powY);
891 for (
unsigned i = 0; i <= rdeg; ++i)
892 for (
unsigned j = 0; j <= rdeg - i; ++j) left.
coeff(i, j) += right.
coeff(i, j);
900 for (
unsigned i = 0; i <=
degree; ++i)
901 for (
unsigned j = 0; j <= degree - i; ++j) result.
coeff(i, j) *=
a;
909 PolyXY result(deg1 + deg2);
910 for (
unsigned i1 = 0; i1 <= deg1; ++i1)
911 for (
unsigned j1 = 0; j1 <= deg1 - i1; ++j1)
912 for (
unsigned i2 = 0; i2 <= deg2; ++i2)
913 for (
unsigned j2 = 0; j2 <= deg2 - i2; ++j2)
922 powers[0].coeff(0, 0) = 1L;
923 for (
unsigned k = 1; k <= maxP; ++k) powers.
push_back(product(powers[k - 1], polyXY));
932 computePowers(polyX, pdeg, pXPowers);
933 computePowers(polyY, pdeg, pYPowers);
934 for (
unsigned px = 0; px <= pdeg; ++px)
935 for (
unsigned py = 0; py <= pdeg - px; ++py)
936 result += polyXY.
coeff(px, py) * product(pXPowers.
at(px), pYPowers.
at(py));
952 PolyXY rx(composition(plx, prx, pry));
953 PolyXY ry(composition(ply, prx, pry));
957 for (
unsigned px = 0; px <= result.
_degree; ++px)
958 for (
unsigned py = 0; py <= result.
_degree - px; ++py) {
968 for (
unsigned i = 0; i <= right.
_degree; ++i)
969 for (
unsigned j = 0; j <= right.
_degree - i; ++j) {
975 return (right + (*
this));
980 for (
unsigned i = 0; i <= res.
_degree; ++i)
981 for (
unsigned j = 0; j <= res.
_degree - i; ++j) {
989 s <<
" GtransfoPoly 1" <<
endl;
990 s <<
"degree " <<
_degree << endl;
993 for (
unsigned k = 0; k < 2 *
_nterms; ++k) s <<
_coeffs[k] <<
' ';
995 s << setprecision(oldprec);
1006 if (degree !=
"degree")
1008 " GtransfoPoly::read : expecting \"degree\" and found " + degree);
1010 for (
unsigned k = 0; k < 2 * _nterms; ++k) s >>
_coeffs[k];
1017 double stepx = frame.
getWidth() / (nx + 1);
1019 double stepy = frame.
getHeight() / (ny + 1);
1020 for (
unsigned i = 0; i < nx; ++i)
1021 for (
unsigned j = 0; j < ny; ++j) {
1022 Point in((i + 0.5) * stepx, (j + 0.5) * stepy);
1026 unsigned npairs = sm.
size();
1030 for (degree = 1; degree <= maxdeg; ++
degree) {
1035 for (
auto const &i : sm) chi2 += i.point2.computeDist2(poly->apply((i.point1)));
1036 if (chi2 / npairs < precision * precision)
break;
1038 if (degree > maxdeg)
1039 LOGLS_WARN(_log,
"inversePolyTransfo: Reached max degree without reaching requested precision: " 1050 const double A21,
const double A22)
1063 "Trying to build a GtransfoLin from a higher order transfo. Aborting. ");
1084 derivative.
coeff(0, 0, 0) = 0;
1085 derivative.
coeff(0, 0, 1) = 0;
1101 double d = (a11 * a22 - a12 *
a21);
1104 "GtransfoLin::invert singular transformation: transfo contents will be dumped to stderr.");
1108 GtransfoLin result(0, 0, a22 / d, -a12 / d, -a21 / d, a11 / d);
1125 int npairs = starMatchList.
size();
1127 LOGLS_FATAL(_log,
"GtransfoLinShift::fit trying to fit a linear transfo with only " << npairs
1134 Eigen::VectorXd B(2);
1136 Eigen::MatrixXd A(2, 2);
1139 for (
auto const &it : starMatchList) {
1140 const FatPoint &point1 = it.point1;
1141 const FatPoint &point2 = it.point2;
1142 double deltax = point2.
x - point1.
x;
1143 double deltay = point2.
y - point1.
y;
1144 double vxx = point1.
vx + point2.
vx;
1145 double vyy = point1.
vy + point2.
vy;
1146 double vxy = point1.
vxy + point2.
vxy;
1147 double det = vxx * vyy - vxy * vxy;
1148 double wxx = vyy / det;
1149 double wyy = vxx / det;
1150 double wxy = -vxy / det;
1151 B(0) += deltax * wxx + wxy * deltay;
1152 B(1) += deltay * wyy + wxy * deltax;
1156 sumr2 += deltax * deltax * wxx + deltay * deltay * wyy + 2. * wxy * deltax * deltay;
1158 double det = A(0, 0) * A(1, 1) - A(0, 1) * A(1, 0);
1159 if (det <= 0)
return -1;
1160 double tmp = A(0, 0);
1161 A(0, 0) = A(1, 1) / det;
1162 A(1, 1) = tmp / det;
1163 A(0, 1) = A(1, 0) = -A(0, 1) / det;
1164 Eigen::VectorXd sol = A * B;
1166 return (sumr2 - sol.dot(B));
1170 double c = scaleFactor *
cos(angleRad);
1171 double s = scaleFactor *
sin(angleRad);
1177 Point a_point(0., 0.);
1178 if (center) a_point = *center;
1182 dx() = a_point.
x -
Dx();
1183 dy() = a_point.
y -
dy();
1186 static double deg2rad(
double degree) {
return degree *
M_PI / 180.; }
1188 static double rad2deg(
double rad) {
return rad * 180. /
M_PI; }
1212 linPix2Tan = pix2Tan;
1213 ra0 = deg2rad(tangentPoint.
x);
1214 dec0 = deg2rad(tangentPoint.
y);
1218 if (corrections) corr.reset(
new GtransfoPoly(*corrections));
1251 LOGL_WARN(_log,
"No sidereal coordinates at pole!");
1260 if (rat < 0.0) rat += (2. *
M_PI);
1262 xOut = rad2deg(rat);
1263 yOut = rad2deg(dect);
1281 return Point(inverse.
Dx(), inverse.
Dy());
1291 xOut = outCoord[0].asDegrees();
1292 yOut = outCoord[1].asDegrees();
1296 stream <<
"GtransfoSkyWcs(" << *
_skyWcs <<
")";
1311 :
BaseTanWcs(pix2Tan, tangentPoint, corrections) {}
1329 if (
corr !=
nullptr) {
1330 LOGL_WARN(_log,
"You are inverting a TanPix2RaDec with corrections.");
1331 LOGL_WARN(_log,
"The inverse you get ignores the corrections!");
1358 double xtmp = xTangentPlane;
1359 double ytmp = yTangentPlane;
1360 corr->apply(xtmp, ytmp, xTangentPlane, yTangentPlane);
1371 stream <<
" tangent point " << tp.
x <<
' ' << tp.
y <<
endl;
1373 stream <<
" crpix " << crpix.
x <<
' ' << crpix.
y <<
endl;
1374 if (
corr) stream <<
"PV correction: " <<
endl << *
corr;
1387 "TanPix2RaDec::fit is NOT implemented (although it is doable)) ");
1395 :
BaseTanWcs(pix2Tan, tangentPoint, corrections) {}
1423 double &yTangentPlane)
const {
1427 corr->apply(xPixel, yPixel, xtmp, ytmp);
1440 stream <<
" tangent point " << tp.
x <<
' ' << tp.
y <<
endl;
1442 stream <<
" crpix " << crpix.
x <<
' ' << crpix.
y <<
endl;
1443 if (
corr) stream <<
"PV correction: " <<
endl << *
corr;
1456 "TanSipPix2RaDec::fit is NOT implemented (although it is doable)) ");
1469 ra0 = deg2rad(tangentPoint.
x);
1470 dec0 = deg2rad(tangentPoint.
y);
1502 double ra = deg2rad(in.
x);
1503 double dec = deg2rad(in.
y);
1509 double coss =
cos(dec);
1510 double sins =
sin(dec);
1511 double sinda =
sin(ra -
ra0);
1512 double cosda =
cos(ra -
ra0);
1513 double l = sinda * coss;
1514 double m = sins *
sin0 + coss *
cos0 * cosda;
1516 m = (sins *
cos0 - coss *
sin0 * cosda) / m;
1520 sq(
sin0) - sq(coss) + sq(coss *
cos0) * (1 + sq(cosda)) + 2 * sins *
sin0 * coss * cos0 * cosda;
1521 double a11 = coss * (cosda * sins *
sin0 + coss *
cos0) / deno;
1522 double a12 = -sinda *
sin0 / deno;
1523 double a21 = coss * sinda * sins / deno;
1524 double a22 = cosda / deno;
1527 tmp.
vx = a11 * (a11 * in.
vx + 2 * a12 * in.
vxy) + a12 * a12 * in.
vy;
1528 tmp.
vy = a21 * a21 * in.
vx + a22 * a22 * in.
vy + 2. * a21 * a22 * in.
vxy;
1529 tmp.
vxy = a21 * a11 * in.
vx + a22 * a12 * in.
vy + (a21 * a12 + a11 * a22) * in.
vxy;
1539 double ra = deg2rad(xIn);
1540 double dec = deg2rad(yIn);
1545 double coss =
cos(dec);
1546 double sins =
sin(dec);
1547 double l =
sin(ra -
ra0) * coss;
1550 m = (sins *
cos0 - coss *
sin0 * cos(ra -
ra0)) / m;
1561 stream <<
" tan2pix " <<
linTan2Pix <<
" tangent point " << tp.
x <<
' ' << tp.
y <<
endl;
1578 "TanRaDec2Pix::fit is NOT implemented (although it is doable)) ");
1586 : _userFun(userFun), _userData(userData) {}
1598 "UserTransfo::fit is NOT implemented (and will never be)) ");
1627 "gtransfoRead : could not find a Gtransfotype");
1628 if (type ==
"GtransfoIdentity") {
1632 }
else if (type ==
"GtransfoPoly") {
1638 " 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 > roughInverse(const Frame ®ion) const
Overload the "generic routine" (available for all Gtransfo types.
void write(std::ostream &s) const
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.
implements the linear transformations (6 real coefficients).
TanPix2RaDec invert() const
exact typed inverse:
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const override
TanRaDec2Pix invert() const
approximate inverse : it ignores corrections;
std::unique_ptr< Gtransfo > inverseTransfo(const double precision, const Frame ®ion) const
Inverse transfo: returns a TanPix2RaDec.
std::unique_ptr< Gtransfo > gtransfoCompose(const Gtransfo *left, const Gtransfo *right)
Returns a pointer to a composition.
void computeDerivative(const Point &where, GtransfoLin &derivative, const double step=0.01) const
specialised analytic routine
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
double fit(const StarMatchList &starMatchList)
fits a transfo to a std::list of Point pairs (p1,p2, the Point fields in StarMatch).
void computeDerivative(const Point &where, GtransfoLin &derivative, const double step=0.01) const
Computes the local Derivative of a transfo, w.r.t.
std::unique_ptr< Gtransfo > _direct
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...
the transformation that handles pix to sideral transfos (Gnomonic, possibly with polynomial distortio...
void setCorrections(std::unique_ptr< GtransfoPoly > corrections)
Assign the correction polynomial (what it means is left to derived classes)
long double & coeff(const unsigned powX, const unsigned powY)
GtransfoLin invert() const
returns the inverse: T1 = T2.invert();
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.
void paramDerivatives(const Point &where, double *dx, double *dy) const
Derivative w.r.t parameters.
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
void write(std::ostream &s) const
void computeMonomials(double xIn, double yIn, double *monomial) const
bool isIdentity(const Gtransfo *gtransfo)
Shorthand test to tell if a transfo belongs to the GtransfoIdentity class.
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))
double computeFit(const StarMatchList &starMatchList, const Gtransfo &InTransfo, const bool UseErrors)
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
Transform pixels to ICRS RA, Dec in degrees.
double fit(const StarMatchList &starMatchList)
Not implemented yet, because we do it otherwise.
double xMin
coordinate of boundary.
GtransfoLin linearApproximation(const Point &where, const double step=0.01) const
linear (local) approximation.
#define LOGL_ERROR(logger, message...)
Log a error-level message using a varargs/printf style interface.
double paramRef(const int i) const
table::Key< table::Array< int > > degree
void dump(std::ostream &stream) const
dumps the transfo coefficients to stream.
Polynomial transformation class.
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)
GtransfoPoly getPix2TangentPlane() const
the transformation from pixels to tangent plane (degrees)
A Point with uncertainties.
std::ostream & operator<<(std::ostream &os, CameraSysPrefix const &detSysPrefix)
double fit(const StarMatchList &starMatchList)
fits a transfo to a std::list of Point pairs (p1,p2, the Point fields in StarMatch).
LSST DM logging module built on log4cxx.
std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
Include files required for standard LSST Exception handling.
GtransfoComposition(const Gtransfo *second, const Gtransfo *first)
will pipe transfos
std::unique_ptr< Gtransfo > roughInverse(const Frame ®ion) const
Overload the "generic routine" (available for all Gtransfo types.
GtransfoPoly operator*(const GtransfoPoly &right) const
Composition (internal stuff in quadruple precision)
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.
std::unique_ptr< GtransfoPoly > inversePolyTransfo(const Gtransfo &Direct, const Frame &frame, const double Prec)
approximates the inverse by a polynomial, up to required precision.
double getHeight() const
size along y axis
double coeffOrZero(const unsigned powX, const unsigned powY, const unsigned whichCoord) const
read access, zero if beyond degree
void computeDerivative(const Point &where, GtransfoLin &derivative, const double step=0.01) const
specialised analytic routine
#define LOGL_FATAL(logger, message...)
Log a fatal-level message using a varargs/printf style interface.
unsigned getDegree() const
void read(std::istream &s)
rectangle with sides parallel to axes.
A base class for image defects.
std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
GtransfoPoly operator-(const GtransfoPoly &right) const
Subtraction.
Point getCrPix() const
Get the pixel origin of the WCS (CRPIX in FITS WCS terminology, but zero-based)
std::unique_ptr< Gtransfo > _roughInverse
GtransfoLin getLinPart() const
The Linear part (corresponding to CD's and CRPIX's)
std::unique_ptr< Gtransfo > reduceCompo(const Gtransfo *right) const
to be overloaded by derived classes if they can really "reduce" the composition (e.g.
std::unique_ptr< Gtransfo > inverseTransfo(const double precision, const Frame ®ion) const
returns an inverse transfo. Numerical if not overloaded.
std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
double fit(const StarMatchList &starMatchList)
guess what
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
void dump(ostream &stream=cout) const
dumps the transfo coefficients to stream.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
void read(std::istream &s)
double fit(const StarMatchList &starMatchList)
fits a transfo to a std::list of Point pairs (p1,p2, the Point fields in StarMatch).
Point getTangentPoint() const
tangent point coordinates (degrees)
std::shared_ptr< afw::geom::SkyWcs > getSkyWcs() const
double fit(const StarMatchList &starMatchList)
Not implemented yet, because we do it otherwise.
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.
void dump(std::ostream &stream=std::cout) const
print out of coefficients in a readable form.
double fit(const StarMatchList &starMatchList)
fits a transfo to a std::list of Point pairs (p1,p2, the Point fields in StarMatch).
#define LOGL_WARN(logger, message...)
Log a warn-level message using a varargs/printf style interface.
double getWidth() const
size along x axis
unsigned getDegree() const
returns degree
virtual void transformPosAndErrors(const FatPoint &in, FatPoint &out) const
a mix of apply and Derivative
std::vector< double > _coeffs
PolyXY(const GtransfoPoly >ransfoPoly, const unsigned whichCoord)
Point getCenter() const
Center of the frame.
A do-nothing transformation. It anyway has dummy routines to mimick a Gtransfo.
void setTangentPoint(const Point &tangentPoint)
Resets the projection (or tangent) point.
#define LSST_EXCEPT(type,...)
Create an exception with a given type and message and optionally other arguments (dependent on the ty...
just here to provide a specialized constructor, and fit.
virtual std::unique_ptr< Gtransfo > reduceCompo(const Gtransfo *right) const
to be overloaded by derived classes if they can really "reduce" the composition (e.g.
std::unique_ptr< Gtransfo > inverseTransfo(const double precision, const Frame ®ion) const
Inverse transfo: returns a TanRaDec2Pix if there are no corrections, or the iterative solver if there...
std::unique_ptr< Gtransfo > _second
std::unique_ptr< Gtransfo > clone() const
returns a copy (allocated by new) of the transformation.
This one is the Tangent Plane (called gnomonic) projection (from celestial sphere to tangent plane) ...
std::unique_ptr< Gtransfo > inverseTransfo(const double precision, const Frame ®ion) const
Inverse transfo: returns a TanRaDec2Pix if there are no corrections, or the iterative solver if there...
friend class GtransfoPoly
void transformPosAndErrors(const FatPoint &in, FatPoint &out) const
transform with analytical derivatives
GtransfoPoly operator+(const GtransfoPoly &right) const
Addition.
virtual char const * what(void) const
Return a character string summarizing this exception.
GtransfoLin getLinPart() const
The Linear part (corresponding to CD's and CRPIX's)
just here to provide specialized constructors. GtransfoLin fit routine.
a virtual (interface) class for geometric transformations.
void operator=(const GtransfoInverse &)
void dump(std::ostream &stream) const
dumps the transfo coefficients to stream.
GtransfoPoly(const unsigned degree=1)
Default transfo : identity for all degrees (>=1 ).
void setDegree(const unsigned degree)
Point getTangentPoint() const
Get the sky origin (CRVAL in FITS WCS terminology) in degrees.
std::unique_ptr< GtransfoPoly > corr
virtual void pix2TP(double xPixel, double yPixel, double &xTangentPlane, double &yTangentPlane) const
transforms from pixel space to tangent plane (degrees)
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.
BaseTanWcs(const GtransfoLin &pix2Tan, const Point &tangentPoint, const GtransfoPoly *corrections=nullptr)
GtransfoPoly getPix2TangentPlane() const
the transformation from pixels to tangent plane (degrees)
double fit(const StarMatchList &starMatchList)
guess what
virtual GtransfoLin linearApproximation(const Point &where, const double step=0.01) const
linear approximation.
TanPix2RaDec operator*(const GtransfoLin &right) const
composition with GtransfoLin
#define LOGLS_FATAL(logger, message)
Log a fatal-level message using an iostream-based interface.
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.
std::unique_ptr< Gtransfo > reduceCompo(const Gtransfo *right) const
to be overloaded by derived classes if they can really "reduce" the composition (e.g.
virtual void pix2TP(double xPixel, double yPixel, double &xTangentPlane, double &yTangentPlane) const
transforms from pixel space to tangent plane (degrees)
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.
double fit(const StarMatchList &starMatchList)
guess what
virtual void dump(std::ostream &stream=std::cout) const =0
dumps the transfo coefficients to stream.
UserTransfo(GtransfoFun &fun, const void *userData)
the transfo routine and extra data that it may need.
virtual void pix2TP(double xPixel, double yPixel, double &xTangentPlane, double &yTangentPlane) const =0
Transform from pixels to tangent plane (degrees)
double fit(const StarMatchList &starMatchList) override
Not implemented; throws pex::exceptions::LogicError.
vector< long double > coeffs
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!
double determinant() const
GtransfoLin operator*(const GtransfoLin &right) const
enables to combine linear tranformations: T1=T2*T3 is legal.
void dump(std::ostream &stream=std::cout) const override
dumps the transfo coefficients to stream.
std::shared_ptr< afw::geom::SkyWcs > _skyWcs