IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 8, 2006, 3:50:18 PM (20 years ago)
Author:
eugene
Message:

substantial work to correctly handle higher order polynomial.
conversions between the internal fitting model (R = sum (Aij xi yj))
and the header representation were incorrect: they did not correctly
handle the shift to the CRPIXi value (ie, x -> (x - xo)). i fixed this
by making the fit explicitly work on the fit to the tangent-plane
coordinates, instead of fitting corrections, and calculating the correct
change of polynomial coefficients. this is not as simple as it seems at
first glance: the header version of the coefficients does not have a
zero-order term, and instead has the CRPIX value. to convert from one to
the other requires solving the equation L(Xo,Yo),M(Xo,Yo) = (0,0). I do
this using the Newton-Raphson method.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/gastro2/src/gfit2.c

    r2442 r8241  
    11# include "gastro2.h"
    2 
    3 static int NPAIR, Npair;
    4 static int *idx1, *idx2;
    52
    63void gfit (CmpCatalog *Target, RefCatalog *Ref, int order) {
    74
    85  int i, j, j0;
     6  int Npair, *idx1, *idx2;
    97  double Radius, Radius2;
    108  double dX, dY, dR;
     
    1210  StarData *st, *sr;
    1311
     12  /* XXX why is this hardwired here? */
    1413  NFIELD = 0.1;
    1514  gproject (Target, Ref, &Subset);
     
    2524  sort_stars_X (Subset.stars, Subset.N);
    2625
    27   Radius = MAX (2.0 * Target[0].answer.dR, 0.5);
     26  Radius = MAX (2.5 * Target[0].answer.dR, 0.5);
    2827  Radius2 = Radius*Radius;
    2928
     
    6362  }
    6463 
    65 # if (0)
    66   pair_init ();
    67   for (i = 0; i < Target[0].N; i++) {
    68     pair_add (i, i);
    69   }
    70 # endif
    71 
    72   fit_init (order);
    73   fit_norm ();
    74 
    75   plot_resid_init (0, (double) Target[0].header.Naxis[0]);
    76   plot_resid_init (1, (double) Target[0].header.Naxis[1]);
    77   if (PLOTSTUFF) plot_resid (st, sr);
    78 
     64  Npair = pair_lists (&idx1, &idx2);
    7965  /* find fit for matched pairs */
    8066  fit_init (order);
    8167  for (i = 0; i < Npair; i++) {
    82     fit_add (st[idx1[i]].X, st[idx1[i]].Y, sr[idx2[i]].X, sr[idx2[i]].Y, 1.0);
     68    fit_add (st[idx1[i]].X, st[idx1[i]].Y, sr[idx2[i]].P, sr[idx2[i]].Q, 1.0);
    8369  }
    8470  fit_eval ();
    8571
    86   Target[0].answer.dR = fit_scat (st, sr);
     72  /* XXX this is weak: the fit_scat call requires the coords from the fit_adjust call */
    8773  Target[0].answer.N  = fit_adjust (&Target[0].coords);
     74  Target[0].answer.dR = fit_scat (st, sr, &Target[0].coords);
    8875
     76  if (PLOTSTUFF) fprintf (stderr, "ploting resid (2)\n");
    8977  plot_resid_init (0, (double) Target[0].header.Naxis[0]);
    9078  plot_resid_init (1, (double) Target[0].header.Naxis[1]);
    91   if (PLOTSTUFF) plot_resid (st, sr);
     79  if (PLOTSTUFF) plot_resid (st, sr, &Target[0].coords);
    9280  free (idx1);
    9381  free (idx2);
    9482}
    95 
    96 static int NTERM, NPOWR, NPARS, NORDER, Npts;
    97 static double **sum, **xsum, **ysum;
    98 static double **matrix, **vector;
    99 
    100 void fit_init (int order) {
    101 
    102   int i;
    103 
    104   NORDER = order;
    105   NPOWR = NORDER + 1;
    106   NTERM = 2*NORDER + 1;
    107   NPARS = (NORDER + 1)*(NORDER + 2) / 2;
    108   Npts  = 0;
    109 
    110   /* allocate arrays for fit solution */
    111   ALLOCATE (sum, double *, NTERM);
    112   ALLOCATE (xsum, double *, NTERM);
    113   ALLOCATE (ysum, double *, NTERM);
    114   for (i = 0; i < NTERM; i++) {
    115     ALLOCATE (sum[i], double, NTERM);
    116     bzero (sum[i], NTERM*sizeof(double));
    117     ALLOCATE (xsum[i], double, NTERM);
    118     bzero (xsum[i], NTERM*sizeof(double));
    119     ALLOCATE (ysum[i], double, NTERM);
    120     bzero (ysum[i], NTERM*sizeof(double));
    121   }
    122   ALLOCATE (matrix, double *, NPARS);
    123   ALLOCATE (vector, double *, NPARS);
    124   for (i = 0; i < NPARS; i++) {
    125     ALLOCATE (matrix[i], double, NPARS);
    126     ALLOCATE (vector[i], double, 2);
    127     bzero (vector[i], 2*sizeof(double));
    128     bzero (matrix[i], NPARS*sizeof(double));
    129   }
    130 
    131 }
    132 
    133 void fit_add (double x1, double y1, double x2, double y2, double wt) {
    134 
    135   int n, m;
    136   double xterm, yterm, term;
    137 
    138   xterm = 1;
    139   for (n = 0; n < NTERM; n++) {
    140     yterm = 1;
    141     for (m = 0; m < NTERM; m++) {
    142       term = xterm*yterm;
    143       if (n+m < NTERM) {
    144         sum[n][m] += term;
    145       }
    146       if (n+m < NPOWR) {
    147         xsum[n][m] += x2*term;
    148         ysum[n][m] += y2*term;
    149       }
    150       yterm *= y1;
    151     }
    152     xterm *= x1;
    153   }
    154   Npts ++;
    155 
    156 }
    157 
    158 void fit_eval () {
    159 
    160   int i, j, n, m, M, N;
    161   double max;
    162 
    163   fprintf (stderr, "npts: %d\n", Npts);
    164 
    165   i = 0;
    166   for (m = 0; m < NPOWR; m++) {
    167     for (n = 0; n < NPOWR - m; n++, i++) {
    168       vector[i][0] = xsum[n][m];
    169       vector[i][1] = ysum[n][m];
    170     }   
    171   }
    172   j = 0;
    173   for (M = 0; M < NPOWR; M++) {
    174     for (N = 0; N < NPOWR - M; N++, j++) {
    175       i = 0;
    176       for (m = 0; m < NPOWR; m++) {
    177         for (n = 0; n < NPOWR - m; n++, i++) {
    178           matrix[i][j] = sum[n+N][m+M];
    179         }       
    180       }
    181     }
    182   }       
    183   max = 0.0;
    184   for (i = 0; i < NPARS; i++) {
    185     for (j = 0; j < NPARS; j++) {
    186       max = MAX (max, fabs(matrix[i][j]));
    187     }
    188     max = MAX (max, fabs(vector[i][0]));
    189     max = MAX (max, fabs(vector[i][1]));
    190   }
    191   for (i = 0; i < NPARS; i++) {
    192     for (j = 0; j < NPARS; j++) {
    193       matrix[i][j] /= max;
    194     }
    195     vector[i][0] /= max;
    196     vector[i][1] /= max;
    197   }
    198 # if (0)
    199   for (i = 0; i < NPARS; i++) {
    200     for (j = 0; j < NPARS; j++) {
    201       fprintf (stderr, "%10.4e  ", matrix[i][j]);
    202     }
    203     fprintf (stderr, "  %10.4e  ", vector[i][0]);
    204     fprintf (stderr, "  %10.4e  \n", vector[i][1]);
    205   }
    206 # endif
    207   gaussj (matrix, NPARS, vector, 2);
    208 # if (0)
    209   fprintf (stderr, "\n\n");
    210   for (i = 0; i < NPARS; i++) {
    211     for (j = 0; j < NPARS; j++) {
    212       fprintf (stderr, "%11.4e  ", matrix[i][j]);
    213     }
    214     fprintf (stderr, "  %11.4e  ", vector[i][0]);
    215     fprintf (stderr, "  %11.4e  \n", vector[i][1]);
    216   }
    217 # endif
    218   i = 0;
    219   for (m = 0; m < NPOWR; m++) {
    220     for (n = 0; n < NPOWR - m; n++, i++) {
    221       xsum[n][m] = vector[i][0];
    222       ysum[n][m] = vector[i][1];
    223     }   
    224   }
    225   i = 0;
    226   for (m = 0; m < NPOWR; m++) {
    227     for (n = 0; n < NPOWR - m; n++, i++) {
    228       fprintf (stderr, "RA x^%dy^%d: %10.4g    DEC x^%dy^%d: %10.4g \n",
    229                n, m, vector[i][0], n, m, vector[i][1]);
    230     }   
    231   }
    232 }
    233 
    234 void fit_norm () {
    235 
    236   xsum[0][0] = 0;
    237   xsum[1][0] = 1;
    238   xsum[0][1] = 0;
    239 
    240   ysum[0][0] = 0;
    241   ysum[1][0] = 0;
    242   ysum[0][1] = 1;
    243 }
    244 
    245 void fit_apply (double *x, double *y, double X, double Y) {
    246 
    247   int m, n;
    248   double xterm, yterm;
    249   double Xo, Yo;
    250 
    251   Xo = Yo = 0;
    252   yterm = 1;
    253   for (m = 0; m < NPOWR; m++) {
    254     xterm = 1;
    255     for (n = 0; n < NPOWR - m; n++) {
    256       Xo += xterm*yterm*xsum[n][m];
    257       Yo += xterm*yterm*ysum[n][m];
    258       xterm *= X;
    259     }   
    260     yterm *= Y;
    261   }
    262  
    263   *x = Xo;
    264   *y = Yo;
    265 }
    266 
    267 
    268 void pair_init () {
    269 
    270   Npair = 0;
    271   NPAIR = 100;
    272   ALLOCATE (idx1, int, NPAIR);
    273   ALLOCATE (idx2, int, NPAIR);
    274 
    275 }
    276 
    277 void pair_add (int i1, int i2) {
    278 
    279   idx1[Npair] = i1;
    280   idx2[Npair] = i2;
    281 
    282   Npair ++;
    283 
    284   if (Npair == NPAIR) {
    285     NPAIR += 100;
    286     REALLOCATE (idx1, int, NPAIR);
    287     REALLOCATE (idx2, int, NPAIR);
    288   }
    289 
    290 }
    291 
    292 double fit_scat (StarData *st, StarData *sr) {
    293 
    294   int i;
    295   double x, y, dx, dy, dX, dY, dX2, dY2, dR;
    296  
    297   dX = dY = dX2 = dY2 = 0;
    298   for (i = 0; i < Npair; i++) {
    299 
    300     fit_apply (&x, &y, sr[idx2[i]].X, sr[idx2[i]].Y);
    301    
    302     dx = x - st[idx1[i]].X;
    303     dy = y - st[idx1[i]].Y;
    304    
    305     dX += dx;
    306     dY += dy;
    307     dX2 += dx*dx;
    308     dY2 += dy*dy;
    309    
    310   }
    311 
    312   dX = dX / Npair;
    313   dY = dY / Npair;
    314   fprintf (stderr, "scatter: %f, %f\n", sqrt(dX2/Npair - dX*dX), sqrt(dY2/Npair - dY*dY));
    315   fprintf (stderr, "precise: %f, %f\n", sqrt((dX2/Npair - dX*dX) / Npair), sqrt((dY2/Npair - dY*dY)/Npair));
    316 
    317   dR = 0.5 * sqrt(fabs(dX2/Npair - dX*dX)) + 0.5 * sqrt (fabs(dY2/Npair - dY*dY));
    318   return (dR);
    319 }
    320 
    321 /* convert new terms to adjustments in coords and to polyterms */
    322 int fit_adjust (Coords *coords) {
    323 
    324   int i, j, N;
    325   double S1, S2, p11, p12, p21, p22;
    326   double a0, a1, a2, b0, b1, b2, det;
    327   double X, Y;
    328   int Np, Nv;
    329    
    330   S1 = coords[0].cdelt1;
    331   S2 = coords[0].cdelt2;
    332   p11 = coords[0].pc1_1;    p12 = coords[0].pc1_2;
    333   p21 = coords[0].pc2_1;    p22 = coords[0].pc2_2;
    334    
    335   /* get the correct vector entries for the linear terms */
    336   N = mk_vector (0, 0, NORDER);
    337   a0 = vector[N][0];  b0 = vector[N][1];
    338   N = mk_vector (1, 0, NORDER);
    339   a1 = vector[N][0];  b1 = vector[N][1];
    340   N = mk_vector (0, 1, NORDER);
    341   a2 = vector[N][0];  b2 = vector[N][1];
    342 
    343   det = 1.0 / (a1*b2 - a2*b1);
    344 
    345   coords[0].pc1_1 = p11*a1 + p12*b1*(S2/S1);
    346   coords[0].pc2_1 = p21*a1 + p22*b1*(S2/S1);
    347    
    348   coords[0].pc1_2 = p12*b2 + p11*a2*(S1/S2);
    349   coords[0].pc2_2 = p22*b2 + p21*a2*(S1/S2);
    350    
    351   X = (coords[0].crpix1 - a0);
    352   Y = (coords[0].crpix2 - b0);
    353   coords[0].crpix1 = det*(X*b2 - Y*a2);
    354   coords[0].crpix2 = det*(Y*a1 - X*b1);
    355 
    356   coords[0].Npolyterms = NORDER;
    357   if (NORDER > 1) strcpy (coords[0].ctype, "DEC--PLY");
    358 
    359   /* generate higher order terms from vector */
    360   for (i = 0; i < NORDER + 1; i++) {
    361     for (j = 0; j < (NORDER - i + 1); j++) {
    362       if (i + j < 2) continue;
    363       Np = mk_polyterm (i, j, NORDER);
    364       Nv = mk_vector (i, j, NORDER);
    365       coords[0].polyterms[Np][0] = det*(vector[Nv][0]*b2  - vector[Nv][1]*a2);  /* x2 y0 */
    366       coords[0].polyterms[Np][1] = det*(vector[Nv][1]*a1  - vector[Nv][0]*b1);  /* x2 y0 */
    367     }
    368   }
    369   while (coords[0].crval1 < 0) coords[0].crval1 += 360.0;
    370   while (coords[0].crval1 > 360.0) coords[0].crval1 -= 360.0;
    371 
    372   /* test for valid solution */
    373   return (Npts);
    374 
    375 }
    376 
    377 int mk_polyterm (int n, int m, int norder) {
    378  
    379   int i, nt, N;
    380  
    381   N = 0;
    382   nt = n + m;
    383   for (i = 2; i < nt; i++) {
    384     N += i + 1;
    385   }
    386   N += m;
    387   return (N);
    388 }
    389 
    390 int mk_vector (int n, int m, int norder) {
    391  
    392   int i, N;
    393  
    394   N = 0;
    395   for (i = 0; i < m; i++) {
    396     N += (norder - i + 1);
    397   }
    398   N += n;
    399   return (N);
    400 }
    401 
    402 void plot_resid (StarData *st, StarData *sr) {
    403 
    404   int i;
    405   double x, y, dx, dy;
    406   float *xvect0, *yvect0, *xvect1, *yvect1, *xvect2, *yvect2;
    407   int Nvect;
    408 
    409   Nvect = Npair;
    410   ALLOCATE (xvect0, float, Nvect);
    411   ALLOCATE (yvect0, float, Nvect);
    412   ALLOCATE (xvect1, float, Nvect);
    413   ALLOCATE (yvect1, float, Nvect);
    414 
    415   ALLOCATE (xvect2, float, 2*Nvect);
    416   ALLOCATE (yvect2, float, 2*Nvect);
    417  
    418   for (i = 0; i < Npair; i++) {
    419     fit_apply (&x, &y, st[idx1[i]].X, st[idx1[i]].Y);
    420    
    421     dx = x - sr[idx2[i]].X;
    422     dy = y - sr[idx2[i]].Y;
    423    
    424     xvect0[i] = sr[idx2[i]].X;
    425     xvect1[i] = sr[idx2[i]].Y;
    426     yvect0[i] = dx;
    427     yvect1[i] = dy;
    428 
    429     xvect2[2*i+0] = sr[idx2[i]].X;
    430     yvect2[2*i+0] = sr[idx2[i]].Y;
    431     xvect2[2*i+1] = x;
    432     yvect2[2*i+1] = y;
    433   }
    434 
    435   plot_resid_plot (0, xvect0, yvect0, Nvect);
    436   plot_resid_plot (1, xvect1, yvect1, Nvect);
    437   plot_fullfield_pairs (xvect2, yvect2, 2*Nvect);
    438 
    439   free (xvect2);
    440   free (yvect2);
    441   free (xvect0);
    442   free (yvect0);
    443   free (xvect1);
    444   free (yvect1);
    445 
    446 }
Note: See TracChangeset for help on using the changeset viewer.