IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 27025


Ignore:
Timestamp:
Feb 21, 2010, 11:27:48 AM (16 years ago)
Author:
eugene
Message:

use Newton-Raphson inverter for non-linear astrometry terms

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/libdvo/src/coordops.c

    r25757 r27025  
    2020int XY_to_LM (double *L, double *M, double x, double y, Coords *coords) {
    2121
    22   double X, Y;
     22  double X, Y, X2, XY, Y2, X3, Y3;
    2323
    2424  /** convert pixel coordinates to cartesian system **/
     
    3131  /** extra polynomial terms **/
    3232  if (coords[0].Npolyterms > 1) {
    33     *L += X*X*coords[0].polyterms[0][0] + X*Y*coords[0].polyterms[1][0] + Y*Y*coords[0].polyterms[2][0];
    34     *M += X*X*coords[0].polyterms[0][1] + X*Y*coords[0].polyterms[1][1] + Y*Y*coords[0].polyterms[2][1];
     33    X2 = X*X;
     34    Y2 = Y*Y;
     35    XY = X*Y;
     36    *L += X2*coords[0].polyterms[0][0] + XY*coords[0].polyterms[1][0] + Y2*coords[0].polyterms[2][0];
     37    *M += X2*coords[0].polyterms[0][1] + XY*coords[0].polyterms[1][1] + Y2*coords[0].polyterms[2][1];
    3538  }
    3639  if (coords[0].Npolyterms > 2) {
    37     *L += X*X*X*coords[0].polyterms[3][0] + X*X*Y*coords[0].polyterms[4][0] + X*Y*Y*coords[0].polyterms[5][0] + Y*Y*Y*coords[0].polyterms[6][0];
    38     *M += X*X*X*coords[0].polyterms[3][1] + X*X*Y*coords[0].polyterms[4][1] + X*Y*Y*coords[0].polyterms[5][1] + Y*Y*Y*coords[0].polyterms[6][1];
     40    X3 = X2*X;
     41    Y3 = Y2*Y;
     42    *L += X3*coords[0].polyterms[3][0] + X2*Y*coords[0].polyterms[4][0] + X*Y2*coords[0].polyterms[5][0] + Y3*coords[0].polyterms[6][0];
     43    *M += X3*coords[0].polyterms[3][1] + X2*Y*coords[0].polyterms[4][1] + X*Y2*coords[0].polyterms[5][1] + Y3*coords[0].polyterms[6][1];
    3944  }
    4045
     
    301306
    302307  int i;
    303   double determ;
    304   double X, Y, Lo, Mo, dL, dM;
     308  double Ro, Xo, Yo;
     309  double dX, dY, X, Y, Lo, Mo, dL, dM;
     310  double dLdX, dLdY, dMdX, dMdY, Do;
    305311
    306312  *x = 0;
    307313  *y = 0;
    308314
    309   /* convert L,M to X,Y */
    310   determ = 1.0 / (coords[0].pc1_1*coords[0].pc2_2 - coords[0].pc1_2*coords[0].pc2_1);
    311   X = determ * (coords[0].pc2_2*L - coords[0].pc1_2*M);
    312   Y = determ * (coords[0].pc1_1*M - coords[0].pc2_1*L);
     315  /* start with linear solution for X,Y */
     316  Ro = (coords[0].pc1_1*coords[0].pc2_2 - coords[0].pc1_2*coords[0].pc2_1);
     317  Xo = (coords[0].pc2_2*L - coords[0].pc1_2*M) / Ro;
     318  Yo = (coords[0].pc1_1*M - coords[0].pc2_1*L) / Ro;
    313319
    314320  /** extra polynomial terms **/
    315321  if (coords[0].Npolyterms > 1) {
    316322    for (i = 0; i < 10; i++) {
    317       Lo = (X*coords[0].pc1_1 + Y*coords[0].pc1_2);
    318       Mo = (X*coords[0].pc2_1 + Y*coords[0].pc2_2);
     323      // find derivatives at Xo, Yo
     324      dLdX = coords[0].pc1_1 + 2.0*Xo*coords[0].polyterms[0][0] + Yo*coords[0].polyterms[1][0];
     325      dLdY = coords[0].pc1_2 + 2.0*Yo*coords[0].polyterms[2][0] + Xo*coords[0].polyterms[1][0];
     326      dMdX = coords[0].pc2_1 + 2.0*Xo*coords[0].polyterms[0][1] + Yo*coords[0].polyterms[1][1];
     327      dMdY = coords[0].pc2_2 + 2.0*Yo*coords[0].polyterms[2][1] + Yo*coords[0].polyterms[1][1];
     328
     329      if (coords[0].Npolyterms > 2) {
     330        dLdX += 3.0*Xo*Xo*coords[0].polyterms[3][0] + 2*Xo*Yo*coords[0].polyterms[4][0] + Yo*Yo*coords[0].polyterms[5][0];
     331        dLdY += 3.0*Yo*Yo*coords[0].polyterms[6][0] + 2*Xo*Yo*coords[0].polyterms[5][0] + Xo*Xo*coords[0].polyterms[4][0];
     332        dMdX += 3.0*Xo*Xo*coords[0].polyterms[3][1] + 2*Xo*Yo*coords[0].polyterms[4][1] + Yo*Yo*coords[0].polyterms[5][1];
     333        dMdY += 3.0*Yo*Yo*coords[0].polyterms[6][1] + 2*Xo*Yo*coords[0].polyterms[5][1] + Xo*Xo*coords[0].polyterms[4][1];
     334      }
     335
     336      // find Lo,Mo for Xo,Yo:
     337      Lo = (Xo*coords[0].pc1_1 + Yo*coords[0].pc1_2);
     338      Mo = (Xo*coords[0].pc2_1 + Yo*coords[0].pc2_2);
    319339      if (coords[0].Npolyterms > 1) {
    320         Lo += X*X*coords[0].polyterms[0][0] + X*Y*coords[0].polyterms[1][0] + Y*Y*coords[0].polyterms[2][0];
    321         Mo += X*X*coords[0].polyterms[0][1] + X*Y*coords[0].polyterms[1][1] + Y*Y*coords[0].polyterms[2][1];
     340        Lo += Xo*Xo*coords[0].polyterms[0][0] + Xo*Yo*coords[0].polyterms[1][0] + Yo*Yo*coords[0].polyterms[2][0];
     341        Mo += Xo*Xo*coords[0].polyterms[0][1] + Xo*Yo*coords[0].polyterms[1][1] + Yo*Yo*coords[0].polyterms[2][1];
    322342      }
    323343      if (coords[0].Npolyterms > 2) {
    324         Lo += X*X*X*coords[0].polyterms[3][0] + X*X*Y*coords[0].polyterms[4][0] + X*Y*Y*coords[0].polyterms[5][0] + Y*Y*Y*coords[0].polyterms[6][0];
    325         Mo += X*X*X*coords[0].polyterms[3][1] + X*X*Y*coords[0].polyterms[4][1] + X*Y*Y*coords[0].polyterms[5][1] + Y*Y*Y*coords[0].polyterms[6][1];
     344        Lo += Xo*Xo*Xo*coords[0].polyterms[3][0] + Xo*Xo*Yo*coords[0].polyterms[4][0] + Xo*Yo*Yo*coords[0].polyterms[5][0] + Yo*Yo*Yo*coords[0].polyterms[6][0];
     345        Mo += Xo*Xo*Xo*coords[0].polyterms[3][1] + Xo*Xo*Yo*coords[0].polyterms[4][1] + Xo*Yo*Yo*coords[0].polyterms[5][1] + Yo*Yo*Yo*coords[0].polyterms[6][1];
    326346      }
     347
    327348      dL = (L - Lo);
    328349      dM = (M - Mo);
    329350
    330       X += determ * (coords[0].pc2_2*dL - coords[0].pc1_2*dM);
    331       Y += determ * (coords[0].pc1_1*dM - coords[0].pc2_1*dM);
     351      Do = 1.0 / (dLdX * dMdY - dLdY * dMdX);
     352      dX = (dL*dMdY - dM*dLdY) * Do;
     353      dY = (dM*dLdX - dL*dMdX) * Do;
     354
     355      // fprintf (stderr, "X,Y + dX,dY : %f, %f : %f, %f\n", X, Y, dX, dY);
     356
     357      Xo += dX;
     358      Yo += dY;
    332359    }
    333360  }
    334361  /* check for correct size (iterate?) */
    335362
    336   *x = X / coords[0].cdelt1 + coords[0].crpix1;
    337   *y = Y / coords[0].cdelt2 + coords[0].crpix2;
     363  *x = Xo / coords[0].cdelt1 + coords[0].crpix1;
     364  *y = Yo / coords[0].cdelt2 + coords[0].crpix2;
    338365
    339366  return (TRUE);
Note: See TracChangeset for help on using the changeset viewer.