IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 3, 2010, 8:45:22 AM (16 years ago)
Author:
eugene
Message:

updates from trunk

Location:
branches/simmosaic_branches
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/simmosaic_branches

  • branches/simmosaic_branches/psModules

  • branches/simmosaic_branches/psModules/src/astrom/pmAstrometryWCS.c

    r24052 r27839  
    289289    // test the CDELTi varient
    290290    if (pcKeys) {
     291        wcs->wcsCDkeys = 0;
    291292        wcs->cdelt1 = psMetadataLookupF64 (&status, header, "CDELT1");
    292293        wcs->cdelt2 = psMetadataLookupF64 (&status, header, "CDELT2");
     
    334335    // test the CDi_j varient
    335336    if (cdKeys) {
     337        wcs->wcsCDkeys = 1;
     338
    336339        wcs->trans->x->coeff[1][0] = psMetadataLookupF64 (&status, header, "CD1_1"); // == PC1_1
    337340        wcs->trans->x->coeff[0][1] = psMetadataLookupF64 (&status, header, "CD1_2"); // == PC1_2
     
    375378    // XXX make it optional to write out CDi_j terms, or other versions
    376379    // apply CDELT1,2 (degrees / pixel) to yield PCi,j terms of order unity
    377     double cdelt1 = wcs->cdelt1;
    378     double cdelt2 = wcs->cdelt2;
    379     psMetadataAddF64 (header, PS_LIST_TAIL, "CDELT1", PS_META_REPLACE, "", cdelt1);
    380     psMetadataAddF64 (header, PS_LIST_TAIL, "CDELT2", PS_META_REPLACE, "", cdelt2);
    381 
    382     // test the PC00i00j varient:
    383     psMetadataAddF64 (header, PS_LIST_TAIL, "PC001001", PS_META_REPLACE, "", wcs->trans->x->coeff[1][0] / cdelt1); // == PC1_1
    384     psMetadataAddF64 (header, PS_LIST_TAIL, "PC001002", PS_META_REPLACE, "", wcs->trans->x->coeff[0][1] / cdelt2); // == PC1_2
    385     psMetadataAddF64 (header, PS_LIST_TAIL, "PC002001", PS_META_REPLACE, "", wcs->trans->y->coeff[1][0] / cdelt1); // == PC2_1
    386     psMetadataAddF64 (header, PS_LIST_TAIL, "PC002002", PS_META_REPLACE, "", wcs->trans->y->coeff[0][1] / cdelt2); // == PC2_2
    387 
    388     // Elixir-style polynomial terms
    389     // XXX currently, Elixir/DVO cannot accept mixed orders
    390     // XXX need to respect the masks
    391     // XXX is wcs->cdelt1,2 always consistent?
    392     int fitOrder = wcs->trans->x->nX;
    393     if (fitOrder > 1) {
     380    if (!wcs->wcsCDkeys) {
     381
     382      double cdelt1 = wcs->cdelt1;
     383      double cdelt2 = wcs->cdelt2;
     384      psMetadataAddF64 (header, PS_LIST_TAIL, "CDELT1", PS_META_REPLACE, "", cdelt1);
     385      psMetadataAddF64 (header, PS_LIST_TAIL, "CDELT2", PS_META_REPLACE, "", cdelt2);
     386     
     387      // test the PC00i00j varient:
     388      psMetadataAddF64 (header, PS_LIST_TAIL, "PC001001", PS_META_REPLACE, "", wcs->trans->x->coeff[1][0] / cdelt1); // == PC1_1
     389      psMetadataAddF64 (header, PS_LIST_TAIL, "PC001002", PS_META_REPLACE, "", wcs->trans->x->coeff[0][1] / cdelt2); // == PC1_2
     390      psMetadataAddF64 (header, PS_LIST_TAIL, "PC002001", PS_META_REPLACE, "", wcs->trans->y->coeff[1][0] / cdelt1); // == PC2_1
     391      psMetadataAddF64 (header, PS_LIST_TAIL, "PC002002", PS_META_REPLACE, "", wcs->trans->y->coeff[0][1] / cdelt2); // == PC2_2
     392     
     393      // Elixir-style polynomial terms
     394      // XXX currently, Elixir/DVO cannot accept mixed orders
     395      // XXX need to respect the masks
     396      // XXX is wcs->cdelt1,2 always consistent?
     397      int fitOrder = wcs->trans->x->nX;
     398      if (fitOrder > 1) {
    394399        for (int i = 0; i <= fitOrder; i++) {
    395             for (int j = 0; j <= fitOrder; j++) {
    396                 if (i + j < 2)
    397                     continue;
    398                 if (i + j > fitOrder)
    399                     continue;
    400                 sprintf (name, "PCA1X%1dY%1d", i, j);
    401                 psMetadataAddF64 (header, PS_LIST_TAIL, name, PS_META_REPLACE, "", wcs->trans->x->coeff[i][j] / pow(cdelt1, i) / pow(cdelt2, j));
    402                 sprintf (name, "PCA2X%1dY%1d", i, j);
    403                 psMetadataAddF64 (header, PS_LIST_TAIL, name, PS_META_REPLACE, "", wcs->trans->y->coeff[i][j] / pow(cdelt1, i) / pow(cdelt2, j));
    404             }
     400          for (int j = 0; j <= fitOrder; j++) {
     401            if (i + j < 2)
     402              continue;
     403            if (i + j > fitOrder)
     404              continue;
     405            sprintf (name, "PCA1X%1dY%1d", i, j);
     406            psMetadataAddF64 (header, PS_LIST_TAIL, name, PS_META_REPLACE, "", wcs->trans->x->coeff[i][j] / pow(cdelt1, i) / pow(cdelt2, j));
     407            sprintf (name, "PCA2X%1dY%1d", i, j);
     408            psMetadataAddF64 (header, PS_LIST_TAIL, name, PS_META_REPLACE, "", wcs->trans->y->coeff[i][j] / pow(cdelt1, i) / pow(cdelt2, j));
     409          }
    405410        }
    406411        psMetadataAddS32 (header, PS_LIST_TAIL, "NPLYTERM", PS_META_REPLACE, "", fitOrder);
    407     }
    408 
    409     // remove any existing 'CDi_j style' wcs keywords
    410     if (psMetadataLookup(header, "CD1_1")) {
     412      }
     413     
     414      // remove any existing 'CDi_j style' wcs keywords
     415      if (psMetadataLookup(header, "CD1_1")) {
    411416        psMetadataRemoveKey(header, "CD1_1");
    412417        psMetadataRemoveKey(header, "CD1_2");
    413418        psMetadataRemoveKey(header, "CD2_1");
    414419        psMetadataRemoveKey(header, "CD2_2");
     420      }
     421    } else {
     422
     423      psMetadataAddF64 (header, PS_LIST_TAIL, "CD1_1", PS_META_REPLACE, "", wcs->trans->x->coeff[1][0]);
     424      psMetadataAddF64 (header, PS_LIST_TAIL, "CD1_2", PS_META_REPLACE, "", wcs->trans->x->coeff[0][1]);
     425      psMetadataAddF64 (header, PS_LIST_TAIL, "CD2_1", PS_META_REPLACE, "", wcs->trans->y->coeff[1][0]);
     426      psMetadataAddF64 (header, PS_LIST_TAIL, "CD2_2", PS_META_REPLACE, "", wcs->trans->y->coeff[0][1]);
     427
     428      if (psMetadataLookup(header, "PC001001")) {
     429        psMetadataRemoveKey(header, "PC001001");
     430        psMetadataRemoveKey(header, "PC001002");
     431        psMetadataRemoveKey(header, "PC002001");
     432        psMetadataRemoveKey(header, "PC002002");
     433      }
    415434    }
    416435
     
    535554        fpa->toSky->R -= 2.0*M_PI;
    536555
     556    fpa->wcsCDkeys = wcs->wcsCDkeys;
     557
    537558    psTrace ("psastro", 5, "toFPA: %f %f  (%f,%f),(%f,%f)\n",
    538559             chip->toFPA->x->coeff[0][0], chip->toFPA->y->coeff[0][0],
     
    648669    wcs->crval2 = fpa->toSky->D*PS_DEG_RAD;
    649670
     671    // generate a transform that has 0.0 rotation:
     672    // get the current posangle of the ref chip
     673    // XXX average angles for x and y...
     674    float angle = atan2 (toTPA->y->coeff[1][0], toTPA->x->coeff[1][0]);
     675    // fprintf (stderr, "angle: %f\n", angle*PS_DEG_RAD);
     676    psPlaneTransform *tpa1 = psPlaneTransformRotate (NULL, toTPA, angle);
     677
    650678    // given transformation, solve for coordinates which yields output coordinates of 0,0
    651     psPlane *center = psPlaneTransformGetCenter (toTPA, tol);
     679    psPlane *center = psPlaneTransformGetCenter (tpa1, tol);
    652680    if (!center) {
    653681        psError(PS_ERR_UNKNOWN, false, "Unable to solve for TPA center.");
     
    657685    }
    658686
     687    // generate transform with the original orientation (does this rotate about 'center'?)
     688    psPlaneTransform *tpa2 = psPlaneTransformRotate (NULL, tpa1, -1.0*angle);
     689
     690    // prove that the center coordinates give 0,0:
     691    // float Xo = psPolynomial2DEval (tpa1->x, center->x, center->y);
     692    // float Yo = psPolynomial2DEval (tpa1->x, center->x, center->y);
     693    // fprintf (stderr, "tpa1: Xo, Yo: %f, %f\n", Xo, Yo);
     694
     695    // prove that the center coordinates give 0,0:
     696    // Xo = psPolynomial2DEval (tpa2->x, center->x, center->y);
     697    // Yo = psPolynomial2DEval (tpa2->x, center->x, center->y);
     698    // fprintf (stderr, "tpa2: Xo, Yo: %f, %f\n", Xo, Yo);
     699
    659700    // create wcs transform from toFPA, resulting transformation has units of microns/pixel
    660701    // adjust wcs transform to use center as reference coordinate
    661     psPlaneTransformSetCenter (wcs->trans, toTPA, center->x, center->y);
     702    psPlaneTransformSetCenter (wcs->trans, tpa2, center->x, center->y);
    662703
    663704    // calculated center is crpix1,2
     
    665706    wcs->crpix2 = center->y;
    666707    psFree (center);
     708    psFree (tpa1);
     709    psFree (tpa2);
    667710
    668711    // pdelt1,2 has units of degrees/micron
     
    682725    wcs->cdelt2 = hypot (wcs->trans->y->coeff[1][0], wcs->trans->y->coeff[0][1]);
    683726
     727    wcs->wcsCDkeys = fpa->wcsCDkeys;
    684728    psFree (toTPA);
    685729
     
    800844    int k=0;
    801845    for (int j=0; j<nSamples; j++) {
    802         double y = j * deltaY / nSamples;
     846        double y = bounds->y0 + (j * deltaY / nSamples);
    803847        for (int i=0; i<nSamples; i++) {
    804848            psPlane *s = psPlaneAlloc();
    805             s->x = i * deltaX / nSamples;
     849            s->x = bounds->x0 + (i * deltaX / nSamples);
    806850            s->y = y;
    807851            psArraySet(src, k, s);
    808852            psPlane *d = psPlaneTransformApply(NULL, trans, s);
    809853            psArraySet(dst, k, d);
    810             psFree(s);
     854            psFree(s);  // drop our refs to s and d
    811855            psFree(d);
    812856            ++k;
     
    821865    }
    822866
     867#define noCOMPARE_TRANS
    823868#ifdef COMPARE_TRANS
    824869    // compare the computed coordintes from this transform with the original
    825870    psPlane *new = psPlaneAlloc();
     871    printf("   i     chip_x  tpa_x     tpa_x_fit     dx         chip_y    tpa_y     tpa_y_fit     dy     dx > 0.5 || dy > 0.5\n");
    826872    for (int i=0; i<psArrayLength(dst); i++) {
    827873        psPlane *d = (psPlane *) psArrayGet(dst, i);
     
    830876        new = psPlaneTransformApply(new, newTrans, s);
    831877
    832         printf("%4d %f %f\n", i, 100.*(new->x - d->x)/d->x, 100.*(new->y - d->y)/d->y);
     878        double xerr = new->x - d->x;
     879        double yerr = new->y - d->y;
     880        bool bigerr = (fabs(xerr) > .5) || (fabs(yerr) > .5);
     881        printf("%4d %9.2f %9.2f %9.2f %9.4f     %9.2f %9.2f %9.2f %9.4f   %s\n"
     882        , i, s->x, new->x, d->x, xerr, s->y, new->y, d->y, yerr, bigerr ? "BIGERR" : "");
    833883    }
    834884    psFree(new);
     
    842892}
    843893
    844 bool pmAstromLinearizeTransforms(pmFPA *fpa, pmChip *chip)
    845 {
    846     psRegion    *chipBounds = pmChipPixels(chip);
    847 
    848     psPlaneTransform *newToFPA = linearFitToTransform(chip->toFPA, chipBounds);
    849     if (!newToFPA) {
    850         psFree(chipBounds);
    851         psError(PS_ERR_UNKNOWN, false, "linear fit for toFPA failed");
    852         return false;
    853     }
    854 
    855     psFree(chip->toFPA);
    856     chip->toFPA = newToFPA;
    857 
    858     psFree(chip->fromFPA);
    859     chip->fromFPA = psPlaneTransformInvert(NULL, chip->toFPA, *chipBounds, 50);
    860     if (!chip->fromFPA) {
    861         psError(PS_ERR_UNKNOWN, false, "failed to invert linear fit for toFPA");
    862         return false;
    863     }
    864 
    865     psPlane *chip0 = psPlaneAlloc();
    866     chip0->x = 0;
    867     chip0->y = 0;
    868     psPlane *chip1 = psPlaneAlloc();
    869     chip1->x = chipBounds->x1;
    870     chip1->y = chipBounds->y1;
    871 
    872     // compute bounding region for fpa
    873     psPlane *fpa0 = psPlaneTransformApply(NULL, newToFPA, chip0);
    874     psPlane *fpa1 = psPlaneTransformApply(NULL, newToFPA, chip1);
    875 
    876     psRegion *fpaBounds = psRegionAlloc(fpa0->x, fpa1->x, fpa0->y, fpa1->y);
    877     psFree(chip0);
    878     psFree(chip1);
    879     psFree(fpa0);
    880     psFree(fpa1);
    881 
    882     psPlaneTransform *newToTPA = linearFitToTransform(fpa->toTPA, fpaBounds);
    883     if (!newToTPA) {
    884         psError(PS_ERR_UNKNOWN, false, "failed to perform linear fit to toTPA");
    885         psFree(fpaBounds);
    886         return false;
    887     }
    888     psFree(fpa->toTPA);
    889     fpa->toTPA = newToTPA;
    890 
    891     // XXX: is this region ok?
    892     psFree(fpa->fromTPA);
    893     fpa->fromTPA = psPlaneTransformInvert(NULL, fpa->toTPA, *fpaBounds, 50);
    894     if (!fpa->fromTPA) {
    895         psError(PS_ERR_UNKNOWN, false, "failed to invert linear fit to toTPA");
    896         return false;
    897     }
    898 
    899     fpa->toSky->type = PS_PROJ_TAN;
    900 
    901     psFree(chipBounds);
    902     psFree(fpaBounds);
     894bool pmAstromLinearizeTransforms(pmFPA *inFPA, pmChip *inChip, pmFPA *outFPA, pmChip *outChip, psRegion *outputBounds, double offset_x, double offset_y)
     895{
     896    PS_ASSERT_PTR_NON_NULL(inFPA, NULL);
     897    PS_ASSERT_PTR_NON_NULL(inChip, NULL);
     898
     899    if (outFPA == NULL) {
     900        outFPA = inFPA;
     901    }
     902    if (outChip == NULL) {
     903        outChip = inChip;
     904    }
     905    if (outputBounds == NULL) {
     906        outputBounds = pmChipPixels(outChip);
     907    }
     908
     909    // First combine the "chip to FPA" and "FPA to TPA" into a single transformation
     910    psPlaneTransform *chipToTPA = psPlaneTransformCombine(NULL, inChip->toFPA, inFPA->toTPA, *outputBounds, 50);
     911    if (!chipToTPA) {
     912        psError(PS_ERR_UNKNOWN, false, "failed to create chipToTPA");
     913        return false;
     914    }
     915
     916    // Next do the linear fit within the output boundary pixels
     917    psPlaneTransform *chipToFPA = linearFitToTransform(chipToTPA, outputBounds);
     918    psFree(chipToTPA);
     919    if (!chipToFPA) {
     920        psError(PS_ERR_UNKNOWN, false, "linear fit of chip to TPA transform failed");
     921        return false;
     922    }
     923
     924    // if requested,  change the center
     925    psPlaneTransform *outToFPA;
     926    if (offset_x != 0. && offset_y != 0.) {
     927        outToFPA = psPlaneTransformSetCenter(NULL, chipToFPA, offset_x, offset_y);
     928        psFree(chipToFPA);
     929    } else {
     930        outToFPA = chipToFPA;
     931    }
     932
     933    psPlaneTransform *outFromFPA = psPlaneTransformInvert(NULL, outToFPA, *outputBounds, 50);
     934    if (!outFromFPA) {
     935        psFree(outToFPA);
     936        psError(PS_ERR_UNKNOWN, false, "inversion of fit of output chip toFPA failed");
     937        return false;
     938    }
     939
     940    // Success. Now set the fpa's toTPA and fromTPA to identity and replace the chip's transforms.
     941
     942    psFree(outFPA->toTPA);
     943    outFPA->toTPA =  psPlaneTransformIdentity(1);
     944
     945    psFree(outFPA->fromTPA);
     946    outFPA->fromTPA = psPlaneTransformIdentity(1);
     947
     948    psFree(outChip->toFPA);
     949    outChip->toFPA = outToFPA;
     950
     951    psFree(outChip->fromFPA);
     952    outChip->fromFPA = outFromFPA;
     953
     954    // Finally, change the type for the projection.
     955    outFPA->toSky->type = PS_PROJ_TAN;
     956
     957    return true;
     958}
     959
     960bool pmAstromLinearizeToSky(pmFPA *inFPA, pmChip *inChip, pmFPA *outFPA, pmChip *outChip, psRegion *bounds)
     961{
     962    PS_ASSERT_PTR_NON_NULL(inFPA, NULL);
     963    PS_ASSERT_PTR_NON_NULL(inChip, NULL);
     964    PS_ASSERT_PTR_NON_NULL(outFPA, NULL);
     965    PS_ASSERT_PTR_NON_NULL(outChip, NULL);
     966    PS_ASSERT_PTR_NON_NULL(bounds, NULL);
     967
     968    // outFPA projection must be defined as the goal
     969   
     970    // the output transformations are:
     971    // chip -> FPA : standard linear trans with needed rotation, etc
     972    // FPA  -> TPA : identidy
     973
     974    int nSamples = 10;  // 10 samples in each dimension
     975
     976    double deltaX = (bounds->x1 - bounds->x0);
     977    double deltaY = (bounds->y1 - bounds->y0);
     978
     979    psArray *src = psArrayAllocEmpty(nSamples * nSamples);
     980    psArray *dst = psArrayAllocEmpty(nSamples * nSamples);
     981
     982    psPlane srcFP, srcTP;
     983
     984    for (int j = 0; j < nSamples; j++) {
     985        double y = bounds->y0 + (j * deltaY / nSamples);
     986        for (int i =  0; i < nSamples; i++) {
     987
     988            psSphere srcSky;
     989            psPlane *srcChip = psPlaneAlloc();
     990            psPlane *dstTP = psPlaneAlloc();
     991
     992            srcChip->x = bounds->x0 + (i * deltaX / nSamples);
     993            srcChip->y = y;
     994
     995            psPlaneTransformApply (&srcFP, inChip->toFPA, srcChip);
     996            psPlaneTransformApply (&srcTP, inFPA->toTPA, &srcFP);
     997            psDeproject (&srcSky, &srcTP, inFPA->toSky);
     998           
     999            // fprintf (stderr, "%f %f | %f %f | %f %f | %f %f\n", srcChip->x, srcChip->y, srcFP.x, srcFP.y, srcTP.x, srcTP.y, srcSky.r*PS_DEG_RAD, srcSky.d*PS_DEG_RAD);
     1000
     1001            psProject (dstTP, &srcSky, outFPA->toSky);
     1002
     1003            srcChip->x -= bounds->x0;
     1004            srcChip->y -= bounds->y0;
     1005            psArrayAdd (src, 100, srcChip);
     1006            psArrayAdd (dst, 100, dstTP);
     1007
     1008            psFree(srcChip);  // drop our refs to s and d
     1009            psFree(dstTP);
     1010        }
     1011    }
     1012
     1013    psPlaneTransform *newToFPA = psPlaneTransformAlloc(1, 1);
     1014    newToFPA->x->coeffMask[1][1] = 1;
     1015    newToFPA->y->coeffMask[1][1] = 1;
     1016
     1017    if (!psPlaneTransformFit(newToFPA, src, dst, 0, 0)) {
     1018        psError(PS_ERR_UNKNOWN, false, "linear fit to transform failed");
     1019        psFree(src);
     1020        psFree(dst);
     1021        return NULL;
     1022    }
     1023   
     1024# if (0)
     1025    for (int i = 0; i < src->n; i++) {
     1026       
     1027        psSphere srcSky, dstSky;
     1028        psPlane *srcChip = src->data[i];
     1029        psPlane *dstTP   = dst->data[i];
     1030
     1031        psPlaneTransformApply (&srcFP, newToFPA, srcChip);
     1032        psDeproject (&srcSky, &srcFP, outFPA->toSky);
     1033        psDeproject (&dstSky, dstTP, outFPA->toSky);
     1034
     1035        double dX = (srcSky.r*PS_DEG_RAD - dstSky.r*PS_DEG_RAD)*3600.0;
     1036        double dY = (srcSky.d*PS_DEG_RAD - dstSky.d*PS_DEG_RAD)*3600.0;
     1037        fprintf (stderr, "%f %f | %f %f | %f %f | %f %f | %f %f | %f %f\n", dX, dY, srcChip->x, srcChip->y, srcFP.x, srcFP.y, dstTP->x, dstTP->y, srcSky.r*PS_DEG_RAD, srcSky.d*PS_DEG_RAD, dstSky.r*PS_DEG_RAD, dstSky.d*PS_DEG_RAD);
     1038
     1039    }
     1040# endif
     1041
     1042    psFree(src);
     1043    psFree(dst);
     1044
     1045    // this is a linear transformation
     1046    psPlaneTransform *newFromFPA = psPlaneTransformInvert(NULL, newToFPA, *bounds, 1);
     1047    if (!newFromFPA) {
     1048        psFree(newToFPA);
     1049        psError(PS_ERR_UNKNOWN, false, "inversion of fit of output chip toFPA failed");
     1050        return false;
     1051    }
     1052
     1053    // Success. Now set the fpa's toTPA and fromTPA to identity and replace the chip's transforms.
     1054    psFree(outChip->toFPA);
     1055    outChip->toFPA = newToFPA;
     1056
     1057    psFree(outChip->fromFPA);
     1058    outChip->fromFPA = newFromFPA;
     1059
     1060    psFree(outFPA->toTPA);
     1061    outFPA->toTPA =  psPlaneTransformIdentity(1);
     1062
     1063    psFree(outFPA->fromTPA);
     1064    outFPA->fromTPA = psPlaneTransformIdentity(1);
    9031065
    9041066    return true;
     
    9221084    wcs->trans = psPlaneTransformAlloc (nXorder, nYorder);
    9231085    wcs->toSky = NULL;
     1086    wcs->wcsCDkeys = 0;
    9241087
    9251088    memset (wcs->ctype1, 0, PM_ASTROM_WCS_TYPE_SIZE);
Note: See TracChangeset for help on using the changeset viewer.