IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 10594


Ignore:
Timestamp:
Dec 8, 2006, 5:02:02 PM (20 years ago)
Author:
eugene
Message:

adding higher-order terms

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psastro/src/psastroWCS.c

    r10513 r10594  
    213213    // techinically, we can have a plate scale here (toTPA:dx,dy != 1)
    214214    if (!psPlaneDistortIsIdentity (toTPA)) psAbort ("psastro", "invalid TPA transformation");
     215   
     216    // XXX require toFPA->x->nX == toFPA->x->nY
     217    // XXX require toFPA->y->nX == toFPA->y->nY
     218    // XXX require toFPA->x->nX == toFPA->y->nX
     219    // XXX require toFPA->nX == 1,2,3
    215220
    216221    switch (toSky->type) {
     
    241246    // XXX need to handle the plateScale
    242247   
    243     // solve for CDELT1,2:
    244     cdelt1 = toSky->Xs*DEG_RAD*toTPA->x->coeff[1][0][0][0];
    245     cdelt2 = toSky->Ys*DEG_RAD*toTPA->y->coeff[0][1][0][0];
     248    /* discussion of the coord transformations:
     249    X,Y: coord on a chip in pixels
     250    L,M: coord on the focal plane (pixels)
     251    P,Q: coord in the tangent plane (microns or mm?)
     252    R,D: coord on the sky
     253   
     254    this function creates WCS terms which convert directly from chip to sky.
     255    this function requires a linear, unrotated toTPA distortion term
     256    toTPA->x,y->coeff[1][0],[0][1] defines the detector scale (microns / pixel)
     257    tpSky->Xs,Ys defines the plate scale (radians / micron)
     258    */
     259   
     260    // solve for CDELT1,2 (degrees / pixel)
     261    cdelt1 = DEG_RAD*toSky->Xs*toTPA->x->coeff[1][0][0][0];
     262    cdelt2 = DEG_RAD*toSky->Ys*toTPA->y->coeff[0][1][0][0];
    246263
    247264    // L,M = toFPA(X,Y)
    248265    // solve for CRPIX1,2 (Xo,Yo) : L,M(Xo,Yo) = 0,0
     266
    249267    // linear solution for Xo,Yo:
    250     R  = (xsum[1][0]*ysum[0][1] - xsum[0][1]*ysum[1][0]);
    251     Xo = det*(ysum[0][0]*xsum[0][1] - xsum[0][0]*ysum[0][1]);
    252     Yo = det*(xsum[0][0]*ysum[1][0] - ysum[0][0]*xsum[1][0]);
    253 
    254     if (
    255 # endif
     268    xcoeff = toFPA->x->coeff;
     269    ycoeff = toFPA->y->coeff;
     270    R  = (xcoeff[1][0]*ycoeff[0][1] - xcoeff[0][1]*ycoeff[1][0]);
     271    Xo = det*(ycoeff[0][0]*xcoeff[0][1] - xcoeff[0][0]*ycoeff[0][1]);
     272    Yo = det*(xcoeff[0][0]*ycoeff[1][0] - ycoeff[0][0]*xcoeff[1][0]);
     273
     274    if (toFPA->x->nX > 1) {
     275
     276        psPolynomial2D *XdX = psPolynomial2D_dX(toFPA->x);
     277        psPolynomial2D *XdY = psPolynomial2D_dY(toFPA->x);
     278
     279        psPolynomial2D *YdX = psPolynomial2D_dX(toFPA->y);
     280        psPolynomial2D *YdY = psPolynomial2D_dY(toFPA->y);
     281
     282        psImage *Alpha = psImageAlloc (2, 2, PS_DATA_F32);
     283        psVector *Beta = psVectorAlloc (2, PS_DATA_F32);
     284
     285        // XXX this loop is rather arbitrary in length...
     286        for (int i = 0; i < 10; i++) {
     287            // NOTE: order is: [y][x]
     288            Alpha->data.F32[0][0] = psPolynomial2DEval (XdX, Xo, Yo);
     289            Alpha->data.F32[1][0] = psPolynomial2DEval (XdY, Xo, Yo);
     290            Alpha->data.F32[0][1] = psPolynomial2DEval (YdX, Xo, Yo);
     291            Alpha->data.F32[1][1] = psPolynomial2DEval (YdY, Xo, Yo);
     292
     293            Beta->data.F32[0] = psPolynomial2DEval (toFPA->x, Xo, Yo);
     294            Beta->data.F32[1] = psPolynomial2DEval (toFPA->y, Xo, Yo);
     295
     296            psMatrixGJSolveF32 (Alpha, Beta);
     297       
     298            Xo += Beta->data.F32[0];
     299            Yo += Beta->data.F32[1];
     300        }
     301    }
     302    psMetadataAddF32 (header, PS_LIST_TAIL, "CRPIX1",   PS_META_REPLACE, "", Xo);
     303    psMetadataAddF32 (header, PS_LIST_TAIL, "CRPIX2",   PS_META_REPLACE, "", Yo);
     304
     305    switch (toFPA->x->nX) {
     306
     307      case 1:
     308        /* the linear solution can be analytically inverted */
     309        pc1_1 = xcoeff[1][0] / cdelt1;
     310        pc1_2 = xcoeff[0][1] / cdelt2;
     311        pc2_1 = ycoeff[1][0] / cdelt1;
     312        pc2_2 = ycoeff[0][1] / cdelt2;
     313
     314      case 2:
     315        a10 = xcoeff[1][0] + 2.0*xcoeff[2][0]*Xo + xcoeff[1][1]*Yo;
     316        a01 = xcoeff[0][1] + 2.0*xcoeff[0][2]*Yo + xcoeff[1][1]*Xo;
     317        a11 = xcoeff[1][1];
     318        a20 = xcoeff[2][0];
     319        a02 = xcoeff[0][2];
     320
     321        b10 = ycoeff[1][0] + 2.0*ycoeff[2][0]*Xo + ycoeff[1][1]*Yo;
     322        b01 = ycoeff[0][1] + 2.0*ycoeff[0][2]*Yo + ycoeff[1][1]*Xo;
     323        b20 = ycoeff[2][0];
     324        b11 = ycoeff[1][1];
     325        b02 = ycoeff[0][2];
     326
     327        coords[0].pc1_1 = a10 / coords[0].cdelt1;
     328        coords[0].pc1_2 = a01 / coords[0].cdelt2;
     329        coords[0].pc2_1 = b10 / coords[0].cdelt1;
     330        coords[0].pc2_2 = b01 / coords[0].cdelt2;
     331
     332        coords[0].polyterms[0][0] = a20 / SQ(coords[0].cdelt1);
     333        coords[0].polyterms[1][0] = a11 / (coords[0].cdelt1*coords[0].cdelt2);
     334        coords[0].polyterms[2][0] = a02 / SQ(coords[0].cdelt2);
     335
     336        coords[0].polyterms[0][1] = b20 / SQ(coords[0].cdelt1);
     337        coords[0].polyterms[1][1] = b11 / (coords[0].cdelt1*coords[0].cdelt2);
     338        coords[0].polyterms[2][1] = b02 / SQ(coords[0].cdelt2);
     339        for (i = 3; i < 7; i++) {
     340            coords[0].polyterms[i][0] = coords[0].polyterms[i][1] = 0.0;
     341        }
     342        break;
     343     
     344      case 3:
     345        a10 = xcoeff[1][0] + 2*xcoeff[2][0]*Xo +   xcoeff[1][1]*Yo + 3*xcoeff[3][0]*Xo*Xo + 2*xcoeff[2][1]*Xo*Yo + xcoeff[1][2]*Yo*Yo;
     346        a01 = xcoeff[0][1] + 2*xcoeff[0][2]*Yo +   xcoeff[1][1]*Xo + 3*xcoeff[0][3]*Yo*Yo + 2*xcoeff[1][2]*Xo*Yo + xcoeff[2][1]*Xo*Xo;
     347        a20 = xcoeff[2][0] + 3*xcoeff[3][0]*Xo +   xcoeff[2][1]*Yo;
     348        a11 = xcoeff[1][1] + 2*xcoeff[2][1]*Xo + 2*xcoeff[1][2]*Yo;
     349        a02 = xcoeff[0][2] + 3*xcoeff[0][3]*Yo +   xcoeff[1][2]*Xo;
     350        a30 = xcoeff[3][0];
     351        a21 = xcoeff[2][1];
     352        a12 = xcoeff[1][2];
     353        a03 = xcoeff[0][3];
     354
     355        b10 = ycoeff[1][0] + 2*ycoeff[2][0]*Xo +   ycoeff[1][1]*Yo + 3*ycoeff[3][0]*Xo*Xo + 2*ycoeff[2][1]*Xo*Yo + ycoeff[1][2]*Yo*Yo;
     356        b01 = ycoeff[0][1] + 2*ycoeff[0][2]*Yo +   ycoeff[1][1]*Xo + 3*ycoeff[0][3]*Yo*Yo + 2*ycoeff[1][2]*Xo*Yo + ycoeff[2][1]*Xo*Xo;
     357        b20 = ycoeff[2][0] + 3*ycoeff[3][0]*Xo +   ycoeff[2][1]*Yo;
     358        b11 = ycoeff[1][1] + 2*ycoeff[2][1]*Xo + 2*ycoeff[1][2]*Yo;
     359        b02 = ycoeff[0][2] + 3*ycoeff[0][3]*Yo +   ycoeff[1][2]*Xo;
     360        b30 = ycoeff[3][0];
     361        b21 = ycoeff[2][1];
     362        b12 = ycoeff[1][2];
     363        b03 = ycoeff[0][3];
     364
     365        coords[0].pc1_1 = a10 / coords[0].cdelt1;
     366        coords[0].pc1_2 = a01 / coords[0].cdelt2;
     367        coords[0].pc2_1 = b10 / coords[0].cdelt1;
     368        coords[0].pc2_2 = b01 / coords[0].cdelt2;
     369
     370        coords[0].polyterms[0][0] = a20 / SQ(coords[0].cdelt1);
     371        coords[0].polyterms[1][0] = a11 / (coords[0].cdelt1*coords[0].cdelt2);
     372        coords[0].polyterms[2][0] = a02 / SQ(coords[0].cdelt2);
     373
     374        coords[0].polyterms[3][0] = a30 / (SQ(coords[0].cdelt1)*coords[0].cdelt1);
     375        coords[0].polyterms[4][0] = a21 / (SQ(coords[0].cdelt1)*coords[0].cdelt2);
     376        coords[0].polyterms[5][0] = a12 / (SQ(coords[0].cdelt2)*coords[0].cdelt1);
     377        coords[0].polyterms[6][0] = a03 / (SQ(coords[0].cdelt2)*coords[0].cdelt2);
     378
     379        coords[0].polyterms[0][1] = b20 / SQ(coords[0].cdelt1);
     380        coords[0].polyterms[1][1] = b11 / (coords[0].cdelt1*coords[0].cdelt2);
     381        coords[0].polyterms[2][1] = b02 / SQ(coords[0].cdelt2);
     382
     383        coords[0].polyterms[3][1] = b30 / (SQ(coords[0].cdelt1)*coords[0].cdelt1);
     384        coords[0].polyterms[4][1] = b21 / (SQ(coords[0].cdelt1)*coords[0].cdelt2);
     385        coords[0].polyterms[5][1] = b12 / (SQ(coords[0].cdelt2)*coords[0].cdelt1);
     386        coords[0].polyterms[6][1] = b03 / (SQ(coords[0].cdelt2)*coords[0].cdelt2);
     387        break;
     388
     389      default:
     390        fprintf (stderr, "error: invalid order %d\n", coords[0].Npolyterms);
     391        exit (2);
     392    }
     393
     394    while (coords[0].crval1 < 0) coords[0].crval1 += 360.0;
     395    while (coords[0].crval1 > 360.0) coords[0].crval1 -= 360.0;
     396
     397
     398# else
    256399
    257400    psMetadataAddF32 (header, PS_LIST_TAIL, "CRVAL1",   PS_META_REPLACE, "", toSky->R*DEG_RAD);
     
    266409    psMetadataAddF32 (header, PS_LIST_TAIL, "PC002001", PS_META_REPLACE, "", toFPA->y->coeff[1][0]/plateScale);
    267410    psMetadataAddF32 (header, PS_LIST_TAIL, "PC002002", PS_META_REPLACE, "", toFPA->y->coeff[0][1]/plateScale);
     411
     412# endif
    268413
    269414    // alternative representations use
Note: See TracChangeset for help on using the changeset viewer.