IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 9, 2006, 6:14:45 PM (20 years ago)
Author:
magnier
Message:

adding higher-order terms to astrometry

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/astrom/pmAstrometryWCS.c

    r10603 r10606  
    11/** @file  pmAstrometryWCS.c
    2 *
    3 *  @brief functions to convert FITS WCS keywords to / from pmFPA structures
    4 *
    5 *  @ingroup Astrometry
    6 *
    7 *  @author EAM, IfA
    8 *
    9 *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    10 *  @date $Date: 2006-12-10 02:06:47 $
    11 *
    12 *  Copyright 2006 Institute for Astronomy, University of Hawaii
    13 */
     2 *
     3 *  @brief functions to convert FITS WCS keywords to / from pmFPA structures
     4 *
     5 *  @ingroup Astrometry
     6 *
     7 *  @author EAM, IfA
     8 *
     9 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2006-12-10 04:14:45 $
     11 *
     12 *  Copyright 2006 Institute for Astronomy, University of Hawaii
     13 */
    1414
    1515#ifdef HAVE_CONFIG_H
     
    2525bool pmAstromReadWCS (pmFPA *fpa, pmChip *chip, psMetadata *header, double plateScale, bool isMosaic)
    2626{
    27 
    28     # if (0)
    29         psProjectionType type;
    30     bool status, pcKeys, cdKeys;
     27    psProjectionType type;
     28    psPlaneTransform *toFPA;
     29    bool status, pcKeys, cdKeys, isPoly;
    3130    float crval1, crval2, crpix1, crpix2, cdelt1, cdelt2;
    32     float pc1_1, pc1_2, pc2_1, pc2_2;
     31    char name[16]; // used to store FITS keyword below (always < 8, so 16 should be safe!)
    3332
    3433    // interpret header data, convert to crval(i), etc
     
    7372        psError(PS_ERR_UNKNOWN, true, "polynomial terms defined, but missing PC00i00j WCS terms");
    7473        return false;
    75         if (fitOrder = 0)
     74        if (fitOrder == 0)
    7675            fitOrder = 1;
    7776        if ((fitOrder > 3) || (fitOrder < 1)) {
     
    102101        double rotate = psMetadataLookupF32 (&status, header, "CROTA2");
    103102        if (status) {
    104             double Lambda = cdelt2 / cdelt1;
    105             wcsTrans->x->coeff[1][0] = +cos(rotate*PS_RAD_DEG); // == PC1_1
    106             wcsTrans->x->coeff[0][1] = -sin(rotate*PS_RAD_DEG) * Lambda; // == PC1_2
    107             wcsTrans->y->coeff[1][0] = +sin(rotate*PS_RAD_DEG) / Lambda; // == PC2_1
    108             wcsTrans->y->coeff[1][0] = +cos(rotate*PS_RAD_DEG); // == PC2_2
     103            wcsTrans->x->coeff[1][0] = +cdelt1 * cos(rotate*PS_RAD_DEG); // == PC1_1
     104            wcsTrans->x->coeff[0][1] = -cdelt2 * sin(rotate*PS_RAD_DEG); // == PC1_2
     105            wcsTrans->y->coeff[1][0] = +cdelt1 * sin(rotate*PS_RAD_DEG); // == PC2_1
     106            wcsTrans->y->coeff[1][0] = +cdelt2 * cos(rotate*PS_RAD_DEG); // == PC2_2
    109107            goto got_matrix;
    110108        }
    111109
    112110        // test the PC00i00j varient:
    113         wcsTrans->x->coeff[1][0] = psMetadataLookupF32 (&status, header, "PC001001"); // == PC1_1
    114         wcsTrans->x->coeff[0][1] = psMetadataLookupF32 (&status, header, "PC001002"); // == PC1_2
    115         wcsTrans->y->coeff[1][0] = psMetadataLookupF32 (&status, header, "PC002001"); // == PC2_1
    116         wcsTrans->y->coeff[0][1] = psMetadataLookupF32 (&status, header, "PC002002"); // == PC2_2
     111        wcsTrans->x->coeff[1][0] = cdelt1 * psMetadataLookupF32 (&status, header, "PC001001"); // == PC1_1
     112        wcsTrans->x->coeff[0][1] = cdelt2 * psMetadataLookupF32 (&status, header, "PC001002"); // == PC1_2
     113        wcsTrans->y->coeff[1][0] = cdelt1 * psMetadataLookupF32 (&status, header, "PC002001"); // == PC2_1
     114        wcsTrans->y->coeff[0][1] = cdelt2 * psMetadataLookupF32 (&status, header, "PC002002"); // == PC2_2
    117115
    118116        if (isPoly) {
     
    125123                        continue;
    126124                    sprintf (name, "PCA1dX%1dY%1d", i, j);
    127                     wcsTrans->x->coeff[i][j] = psMetadataLookupF32 (&status, header, name);
     125                    wcsTrans->x->coeff[i][j] = pow(cdelt1, i) * pow(cdelt2, j) * psMetadataLookupF32 (&status, header, name);
    128126                }
    129127            }
     
    136134                        continue;
    137135                    sprintf (name, "PCA2dX%1dY%1d", i, j);
    138                     wcsTrans->y->coeff[i][j] = psMetadataLookupF32 (&status, header, name);
     136                    wcsTrans->y->coeff[i][j] = pow(cdelt1, i) * pow(cdelt2, j) * psMetadataLookupF32 (&status, header, name);
    139137                }
    140138            }
    141             goto got_matrix;
    142         }
    143         psLogMsg ("psastro", 2, "warning: missing rotation matrix?\n");
    144         return false;
     139        }
     140        goto got_matrix;
    145141    }
    146142
     
    151147        wcsTrans->y->coeff[1][0] = psMetadataLookupF32 (&status, header, "CD2_1"); // == PC2_1
    152148        wcsTrans->y->coeff[0][1] = psMetadataLookupF32 (&status, header, "CD2_2"); // == PC2_2
    153 
    154         // normalize rotation matrix, generate cdelt1, cdelt2
    155         double scale = hypot (wcsTrans->x->coeff[1][0], wcsTrans->y->coeff[0][1]);
    156         cdelt1 = cdelt2 = scale;
    157         wcsTrans->x->coeff[1][0] /= scale;
    158         wcsTrans->x->coeff[0][1] /= scale;
    159         wcsTrans->y->coeff[1][0] /= scale;
    160         wcsTrans->y->coeff[0][1] /= scale;
    161149        goto got_matrix;
    162150    }
     
    166154got_matrix:
    167155
    168     /*****
    169 
    170     For mosaic astrometry, we need to have a starting set of projection terms in which the
    171     chip-to-FPA terms result in a fixed physical unit on the focal plane (eg, pixels or
    172     microns).  This set of projections, coupled with an identity toTPA (ie, no distortion) will
    173     result in substantial errors between the observed and predicted star positions on the focal
    174     plane: this is the measurement of the optical distortion in the camera.  At the same time,
    175     we need to carry around the transformations which allow us to make an accurate calculation
    176     of the position of the stars based on the input (per-chip) astrometry.  These
    177     transformations will allow us to match the raw and ref stars robustly.  To convert the
    178     per-chip astrometry (which may have been calculated with a different plate scale for each
    179     chip) to a collection of astrometry terms for chips in a single mosaic, we need to adjust
    180     the chip-to-FPA scaling (eg, pc11) to match the variations in the effective plate scale for
    181     each chip (eg, cdelt1).  Thus, we need to carry around both the
    182 
    183     *****/
    184 
    185156    /* at this point, we have extracted from the header the WCS terms in the form of a polynomial,
    186        wcsTrans, which will con
    187        along with the addition
    188        PC00i00j representation:
     157     * wcsTrans, which will convert X,Y in pixels to L,M in degrees.  we also have the following
     158     * elements defined:
    189159     * type (CTYPE)
    190160     * crval1,2 (in RA,DEC degrees)
    191161     * crpix1,2
    192162     * cdelt1,2 (in degrees / pixel)
    193      * pci,j (normalized)
     163     * plateScale (radians / physical TPA units)
    194164     *
    195      * we also have plateScale (radians / physical TPA units)
    196      * now we convert to pmFPA terms
     165     * now we convert wcsTrans to toFPA, which is different from wcsTrans in 3 important ways:
     166     * 1) the output is in pixel (not degrees): divide by cdelt1,2 raised to an appropriate power
     167     * 2) X,Y are applied directly, without an applied Xo,Yo offset
     168     * 3) there is an allowed Lo,Mo term ([0][0] coefficients)
    197169     */
    198170
    199171    /*** XXXX need to extend these formulae to higher-order terms ***/
    200172
    201     {
    202         // XXX free an existing toFPA?
    203         psPlaneTransform *toFPA = psPlaneTransformAlloc (1, 1);
    204 
    205         //
    206 
     173    // XXX free an existing toFPA?
     174    toFPA = psPlaneTransformAlloc(fitOrder, fitOrder);
     175
     176    /* given two equivalent polynomial representations L(x,y) = \sum_i \sum_j A_{i,j} x^i y^j
     177     * we can transform L(x,y) into L'(x+xo,y+yo) by taking the derivatives of both sides and
     178     * noting that the constant term in each is the coefficient in the case of L(x,y) and is the
     179     * value of L'(xo,yo) in the second case.  in this case, xo,yo = crpix1,2
     180     */
     181
     182    psPolynomial2D *xPx = psPolynomial2DCopy (NULL, wcsTrans->x);
     183    psPolynomial2D *yPx = psPolynomial2DCopy (NULL, wcsTrans->y);
     184
     185    for (int i = 0; i <= fitOrder; i++) {
     186        psPolynomial2D *xPy = psPolynomial2DCopy (NULL, xPx);
     187        psPolynomial2D *yPy = psPolynomial2DCopy (NULL, yPx);
     188        for (int j = 0; j <= fitOrder; j++) {
     189            toFPA->x->mask[i][j] = wcsTrans->x->mask[i][j];
     190            toFPA->y->mask[i][j] = wcsTrans->y->mask[i][j];
     191            toFPA->x->coeff[i][j] = (toFPA->x->mask[i][j]) ? 0 : psPolynomial2DEval (xPy, crpix1, crpix2) / tgamma(i+1) / tgamma(j+1) / cdelt1;
     192            toFPA->y->coeff[i][j] = (toFPA->y->mask[i][j]) ? 0 : psPolynomial2DEval (yPy, crpix1, crpix2) / tgamma(i+1) / tgamma(j+1) / cdelt2;
     193
     194            // take the next derivative wrt y
     195            psPolynomial2D_dY(xPy, xPy);
     196            psPolynomial2D_dY(yPy, yPy);
     197        }
     198        psFree (xPy);
     199        psFree (yPy);
     200        // take the next derivative wrt x
     201        psPolynomial2D_dX(xPx, xPx);
     202        psPolynomial2D_dX(yPx, yPx);
     203    }
     204    psFree (xPx);
     205    psFree (yPx);
     206
     207    // save until we verify the transformation
     208    # if (0)
    207209        // basic transformation from chip to FPA (FPA in pixels)
    208210        toFPA->x->coeff[0][0] = -(pc1_1*crpix1 + pc1_2*crpix2);
    209         toFPA->x->coeff[1][0] = pc1_1;
    210         toFPA->x->coeff[0][1] = pc1_2;
    211         toFPA->x->mask[1][1]  = 1;
    212 
    213         toFPA->y->coeff[0][0] = -(pc2_1*crpix1 + pc2_2*crpix2);
    214         toFPA->y->coeff[1][0] = pc2_1;
    215         toFPA->y->coeff[0][1] = pc2_2;
    216         toFPA->y->mask[1][1]  = 1;
    217 
    218         // scale from FPA to TPA (microns / pixel)
    219         double pdelt1 = cdelt1*PS_RAD_DEG / plateScale;
    220         double pdelt2 = cdelt2*PS_RAD_DEG / plateScale;
    221         float rX = 1.0;
    222         float rY = 1.0;
    223 
    224         // projection from TPA to SKY
    225         psProjection *toSky = psProjectionAlloc (crval1*PS_RAD_DEG, crval2*PS_RAD_DEG, plateScale, plateScale, type);
    226 
    227         if (fpa->toSky == NULL)
    228         {
    229             fpa->toTPA = psPlaneDistortIdentity (1);
    230             fpa->fromTPA = psPlaneDistortIdentity (1);
    231             fpa->toTPA->x->coeff[1][0][0][0] = pdelt1;
    232             fpa->toTPA->y->coeff[0][1][0][0] = pdelt2;
    233             fpa->fromTPA->x->coeff[1][0][0][0] = 1.0 / pdelt1;
    234             fpa->fromTPA->y->coeff[0][1][0][0] = 1.0 / pdelt2;
    235             fpa->toSky = toSky;
    236         } else
    237         {
    238             if (fpa->toTPA == NULL)
    239                 psAbort ("wcs", "projection defined, tangent-plane not defined");
    240             if (fpa->fromTPA == NULL)
    241                 psAbort ("wcs", "projection defined, tangent-plane not defined");
    242 
    243             // convert from pixels on this chip to pixels on reference chip
    244             // rX has units of refpixels / pixel
    245             rX = pdelt1 / fpa->toTPA->x->coeff[1][0][0][0];
    246             rY = pdelt2 / fpa->toTPA->y->coeff[0][1][0][0];
    247 
    248             // correct to common plate scale (output is in refpixel units)
    249             toFPA->x->coeff[0][0] *= rX;
    250             toFPA->x->coeff[1][0] *= rX;
    251             toFPA->x->coeff[0][1] *= rX;
    252             toFPA->y->coeff[0][0] *= rY;
    253             toFPA->y->coeff[1][0] *= rY;
    254             toFPA->y->coeff[0][1] *= rY;
    255 
    256             // adjust for common toSky, toTPA for mosaic:
    257             // find the FPA coordinate of 0,0 for this chip.
    258             psPlane *chip = psPlaneAlloc();
    259             psPlane *fp = psPlaneAlloc();
    260             psPlane *tp = psPlaneAlloc();
    261             psSphere *sky = psSphereAlloc();
    262             chip->x = chip->y = 0;
    263 
    264             psPlaneTransformApply (fp, toFPA, chip); // find the focal-plane coordinate of this chip's 0,0 coordinate
    265             psPlaneDistortApply (tp, fpa->toTPA, fp, 0.0, 0.0);
    266             p_psDeproject (sky, tp, toSky); // find the RA,DEC coord of the focal-plane coordinate
    267             p_psProject (tp, sky, fpa->toSky); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
    268             psPlaneDistortApply (fp, fpa->fromTPA, tp, 0.0, 0.0);
    269 
    270             toFPA->x->coeff[0][0] = fp->x;
    271             toFPA->y->coeff[0][0] = fp->y;
    272 
    273             psFree (fp);
    274             psFree (sky);
    275             psFree (chip);
    276             psFree (toSky);
    277         }
    278 
    279         chip->toFPA = toFPA;
    280         chip->fromFPA = p_psPlaneTransformLinearInvert(toFPA);
    281 
    282         // this can take a very long time...
    283         while (fpa->toSky->R < 0)
    284             fpa->toSky->R += 2.0*M_PI;
    285         while (fpa->toSky->R > 2.0*M_PI)
    286             fpa->toSky->R -= 2.0*M_PI;
    287 
    288         // remove the correction to the common plate scale
    289         // NOTE: this assumes 1) we are reading in headers generated using per-chip astrometry
    290         // and 2) we are going to measure the mosaic distortion in the next step.
    291         // XXX perhaps make this its own function? (I'll need to store rX somewhere).
    292         if (isMosaic)
    293         {
    294             chip->toFPA->x->coeff[0][0] /= rX;
    295             chip->toFPA->x->coeff[1][0] /= rX;
    296             chip->toFPA->x->coeff[0][1] /= rX;
    297             chip->toFPA->y->coeff[0][0] /= rY;
    298             chip->toFPA->y->coeff[1][0] /= rY;
    299             chip->toFPA->y->coeff[0][1] /= rY;
    300         }
    301 
    302         psTrace ("psastro", 5, "toFPA: %f %f  (%f,%f),(%f,%f)\n",
    303                  chip->toFPA->x->coeff[0][0], chip->toFPA->y->coeff[0][0],
    304                  chip->toFPA->x->coeff[1][0], chip->toFPA->x->coeff[0][1],
    305                  chip->toFPA->y->coeff[1][0], chip->toFPA->y->coeff[0][1]);
    306 
    307         psTrace ("psastro", 5, "frFPA: %f %f  (%f,%f),(%f,%f)\n",
    308                  chip->fromFPA->x->coeff[0][0], chip->fromFPA->y->coeff[0][0],
    309                  chip->fromFPA->x->coeff[1][0], chip->fromFPA->x->coeff[0][1],
    310                  chip->fromFPA->y->coeff[1][0], chip->fromFPA->y->coeff[0][1]);
    311 
    312         psLogMsg ("psastro", 3, "field center: %f,%f, plate scale: %f,%f (arcsec/pixel)\n",
    313                   PS_DEG_RAD*fpa->toSky->R, PS_DEG_RAD*fpa->toSky->D,
    314                   3600*PS_DEG_RAD*fpa->toSky->Xs, 3600*PS_DEG_RAD*fpa->toSky->Ys);
    315     }
     211    toFPA->x->coeff[1][0] = pc1_1;
     212    toFPA->x->coeff[0][1] = pc1_2;
     213    toFPA->x->mask[1][1]  = 1;
     214
     215    toFPA->y->coeff[0][0] = -(pc2_1*crpix1 + pc2_2*crpix2);
     216    toFPA->y->coeff[1][0] = pc2_1;
     217    toFPA->y->coeff[0][1] = pc2_2;
     218    toFPA->y->mask[1][1]  = 1;
    316219    # endif
     220
     221    // scale from FPA to TPA (microns / pixel)
     222    double pdelt1 = cdelt1*PS_RAD_DEG / plateScale;
     223    double pdelt2 = cdelt2*PS_RAD_DEG / plateScale;
     224    float rX = 1.0;
     225    float rY = 1.0;
     226
     227    // projection from TPA to SKY
     228    psProjection *toSky = psProjectionAlloc (crval1*PS_RAD_DEG, crval2*PS_RAD_DEG, plateScale, plateScale, type);
     229
     230    if (fpa->toSky == NULL) {
     231        fpa->toTPA = psPlaneDistortIdentity (1);
     232        fpa->fromTPA = psPlaneDistortIdentity (1);
     233        fpa->toTPA->x->coeff[1][0][0][0] = pdelt1;
     234        fpa->toTPA->y->coeff[0][1][0][0] = pdelt2;
     235        fpa->fromTPA->x->coeff[1][0][0][0] = 1.0 / pdelt1;
     236        fpa->fromTPA->y->coeff[0][1][0][0] = 1.0 / pdelt2;
     237        fpa->toSky = toSky;
     238    } else {
     239        if (fpa->toTPA == NULL)
     240            psAbort ("wcs", "projection defined, tangent-plane not defined");
     241        if (fpa->fromTPA == NULL)
     242            psAbort ("wcs", "projection defined, tangent-plane not defined");
     243
     244        // convert from pixels on this chip to pixels on reference chip
     245        // rX has units of refpixels / pixel
     246        rX = pdelt1 / fpa->toTPA->x->coeff[1][0][0][0];
     247        rY = pdelt2 / fpa->toTPA->y->coeff[0][1][0][0];
     248        for (int i = 0; i <= fitOrder; i++) {
     249            for (int j = 0; j <= fitOrder; j++) {
     250                toFPA->x->coeff[i][j] *= rX;
     251                toFPA->y->coeff[i][j] *= rY;
     252            }
     253        }
     254
     255        // adjust for common toSky, toTPA for mosaic:
     256        // find the FPA coordinate of 0,0 for this chip.
     257        psPlane *chip = psPlaneAlloc();
     258        psPlane *fp = psPlaneAlloc();
     259        psPlane *tp = psPlaneAlloc();
     260        psSphere *sky = psSphereAlloc();
     261        chip->x = chip->y = 0;
     262
     263        psPlaneTransformApply (fp, toFPA, chip); // find the focal-plane coordinate of this chip's 0,0 coordinate
     264        psPlaneDistortApply (tp, fpa->toTPA, fp, 0.0, 0.0);
     265        p_psDeproject (sky, tp, toSky); // find the RA,DEC coord of the focal-plane coordinate
     266        p_psProject (tp, sky, fpa->toSky); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
     267        psPlaneDistortApply (fp, fpa->fromTPA, tp, 0.0, 0.0);
     268
     269        toFPA->x->coeff[0][0] = fp->x;
     270        toFPA->y->coeff[0][0] = fp->y;
     271
     272        psFree (fp);
     273        psFree (sky);
     274        psFree (chip);
     275        psFree (toSky);
     276    }
     277
     278    chip->toFPA = toFPA;
     279    // XXX this needs to perform the full (non-linear) inversion
     280    chip->fromFPA = p_psPlaneTransformLinearInvert(toFPA);
     281
     282    // this can take a very long time...
     283    while (fpa->toSky->R < 0)
     284        fpa->toSky->R += 2.0*M_PI;
     285    while (fpa->toSky->R > 2.0*M_PI)
     286        fpa->toSky->R -= 2.0*M_PI;
     287
     288    // remove the correction to the common plate scale
     289    // NOTE: this assumes 1) we are reading in headers generated using per-chip astrometry
     290    // and 2) we are going to measure the mosaic distortion in the next step.
     291    // XXX perhaps make this its own function? (I'll need to store rX somewhere).
     292    if (isMosaic) {
     293        chip->toFPA->x->coeff[0][0] /= rX;
     294        chip->toFPA->x->coeff[1][0] /= rX;
     295        chip->toFPA->x->coeff[0][1] /= rX;
     296        chip->toFPA->y->coeff[0][0] /= rY;
     297        chip->toFPA->y->coeff[1][0] /= rY;
     298        chip->toFPA->y->coeff[0][1] /= rY;
     299    }
     300
     301    psTrace ("psastro", 5, "toFPA: %f %f  (%f,%f),(%f,%f)\n",
     302             chip->toFPA->x->coeff[0][0], chip->toFPA->y->coeff[0][0],
     303             chip->toFPA->x->coeff[1][0], chip->toFPA->x->coeff[0][1],
     304             chip->toFPA->y->coeff[1][0], chip->toFPA->y->coeff[0][1]);
     305
     306    psTrace ("psastro", 5, "frFPA: %f %f  (%f,%f),(%f,%f)\n",
     307             chip->fromFPA->x->coeff[0][0], chip->fromFPA->y->coeff[0][0],
     308             chip->fromFPA->x->coeff[1][0], chip->fromFPA->x->coeff[0][1],
     309             chip->fromFPA->y->coeff[1][0], chip->fromFPA->y->coeff[0][1]);
     310
     311    psLogMsg ("psastro", 3, "field center: %f,%f, plate scale: %f,%f (arcsec/pixel)\n",
     312              PS_DEG_RAD*fpa->toSky->R, PS_DEG_RAD*fpa->toSky->D,
     313              3600*PS_DEG_RAD*fpa->toSky->Xs, 3600*PS_DEG_RAD*fpa->toSky->Ys);
     314
     315    psFree (wcsTrans);
     316
    317317    return true;
    318318}
     
    361361
    362362        /* discussion of the coord transformations:
    363         X,Y: coord on a chip in pixels
    364         L,M: coord on the focal plane (pixels)
    365         P,Q: coord in the tangent plane (microns or mm?)
    366         R,D: coord on the sky
    367 
    368         this function creates WCS terms which convert directly from chip to sky.
    369         this function requires a linear, unrotated toTPA distortion term
    370         toTPA->x,y->coeff[1][0],[0][1] defines the detector scale (microns / pixel)
    371         tpSky->Xs,Ys defines the plate scale (radians / micron)
     363           X,Y: coord on a chip in pixels
     364           L,M: coord on the focal plane (pixels)
     365           P,Q: coord in the tangent plane (microns or mm?)
     366           R,D: coord on the sky
     367         
     368           this function creates WCS terms which convert directly from chip to sky.
     369           this function requires a linear, unrotated toTPA distortion term
     370           toTPA->x,y->coeff[1][0],[0][1] defines the detector scale (microns / pixel)
     371           tpSky->Xs,Ys defines the plate scale (radians / micron)
    372372        */
    373373
     
    720720    return status;
    721721}
     722
     723/*****
     724 
     725For mosaic astrometry, we need to have a starting set of projection terms in which the
     726chip-to-FPA terms result in a fixed physical unit on the focal plane (eg, pixels or
     727microns).  This set of projections, coupled with an identity toTPA (ie, no distortion) will
     728result in substantial errors between the observed and predicted star positions on the focal
     729plane: this is the measurement of the optical distortion in the camera.  At the same time,
     730we need to carry around the transformations which allow us to make an accurate calculation
     731of the position of the stars based on the input (per-chip) astrometry.  These
     732transformations will allow us to match the raw and ref stars robustly.  To convert the
     733per-chip astrometry (which may have been calculated with a different plate scale for each
     734chip) to a collection of astrometry terms for chips in a single mosaic, we need to adjust
     735the chip-to-FPA scaling (eg, pc11) to match the variations in the effective plate scale for
     736each chip (eg, cdelt1).  Thus, we need to carry around both the
     737 
     738*****/
     739
Note: See TracChangeset for help on using the changeset viewer.