IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 27461


Ignore:
Timestamp:
Mar 26, 2010, 11:21:55 AM (16 years ago)
Author:
bills
Message:

Improve fit to bi-level astrometry for postage stamps by making astrometry terms that are centered on the output chip center

Location:
trunk
Files:
3 edited

Legend:

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

    r26492 r27461  
    865865    }
    866866
     867#define noCOMPARE_TRANS
    867868#ifdef COMPARE_TRANS
    868869    // compare the computed coordintes from this transform with the original
    869870    psPlane *new = psPlaneAlloc();
    870     printf("   i     chip_x  fpa_x     fpa_x_fit     dx         chip_y    fpa_y     fpa_y_fit     dy     dx > 0.5 || dy > 0.5\n");
     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");
    871872    for (int i=0; i<psArrayLength(dst); i++) {
    872873        psPlane *d = (psPlane *) psArrayGet(dst, i);
     
    878879        double yerr = new->y - d->y;
    879880        bool bigerr = (fabs(xerr) > .5) || (fabs(yerr) > .5);
    880         printf("%4d %9.2f %9.2f %9.2f %9.2f     %9.2f %9.2f %9.2f %9.2f   %s\n"
     881        printf("%4d %9.2f %9.2f %9.2f %9.4f     %9.2f %9.2f %9.2f %9.4f   %s\n"
    881882        , i, s->x, new->x, d->x, xerr, s->y, new->y, d->y, yerr, bigerr ? "BIGERR" : "");
    882883    }
     
    891892}
    892893
    893 bool pmAstromLinearizeTransforms(pmFPA *fpa, pmChip *chip)
    894 {
    895     psRegion    *chipBounds = pmChipPixels(chip);
    896 
    897 #ifdef TESTING_CAMRUN_14728
    898     chipBounds->y0 = 1874.;
    899     chipBounds->x1 = 2387.;
    900 #endif
    901 
    902     // First combine the chip to FPA and FPA to TPA into a single transformation
    903     psPlaneTransform *chipToTPA = psPlaneTransformCombine(NULL, chip->toFPA, fpa->toTPA, *chipBounds, 50);
     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);
    904911    if (!chipToTPA) {
    905         psFree(chipBounds);
    906912        psError(PS_ERR_UNKNOWN, false, "failed to create chipToTPA");
    907913        return false;
    908914    }
    909915
    910     // Next do a linear fit
    911     psPlaneTransform *newToFPA = linearFitToTransform(chipToTPA, chipBounds);
     916    // Next do the linear fit within the output boundary pixels
     917    psPlaneTransform *chipToFPA = linearFitToTransform(chipToTPA, outputBounds);
    912918    psFree(chipToTPA);
    913     if (!newToFPA) {
    914         psFree(chipBounds);
     919    if (!chipToFPA) {
    915920        psError(PS_ERR_UNKNOWN, false, "linear fit of chip to TPA transform failed");
    916921        return false;
    917922    }
    918923
    919     psPlaneTransform *newFromFPA = psPlaneTransformInvert(NULL, newToFPA, *chipBounds, 50);
    920     psFree(chipBounds);
     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);
    9211047    if (!newFromFPA) {
    9221048        psFree(newToFPA);
    923         psError(PS_ERR_UNKNOWN, false, "inversion of fit of chip to TPA transform failed");
     1049        psError(PS_ERR_UNKNOWN, false, "inversion of fit of output chip toFPA failed");
    9241050        return false;
    9251051    }
    9261052
    9271053    // Success. Now set the fpa's toTPA and fromTPA to identity and replace the chip's transforms.
    928 
    929     psPlaneTransform *newToTPA   = psPlaneTransformIdentity(1);
    930     psFree(fpa->toTPA);
    931     fpa->toTPA = newToTPA;
    932 
    933     psPlaneTransform *newFromTPA = psPlaneTransformIdentity(1);
    934     psFree(fpa->fromTPA);
    935     fpa->fromTPA = newFromTPA;
    936 
    937     psFree(chip->toFPA);
    938     chip->toFPA = newToFPA;
    939 
    940     psFree(chip->fromFPA);
    941     chip->fromFPA = newFromFPA;
    942 
    943     // Finally change the type for the projection.
    944     fpa->toSky->type = PS_PROJ_TAN;
     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);
    9451065
    9461066    return true;
  • trunk/psModules/src/astrom/pmAstrometryWCS.h

    r25299 r27461  
    6363bool pmAstromWriteBilevelMosaic (psMetadata *header, const pmFPA *fpa, double tol);
    6464
    65 bool pmAstromLinearizeTransforms(pmFPA *fpa, pmChip *);
     65bool pmAstromLinearizeTransforms(pmFPA *inFPA, pmChip *inChip, pmFPA *outFPA, pmChip *outChip, psRegion *outputBounds, double offset_x, double offset_y);
     66bool pmAstromLinearizeToSky(pmFPA *inFPA, pmChip *inChip, pmFPA *outFPA, pmChip *outChip, psRegion *bounds);
    6667
    6768// move to pslib
  • trunk/pstamp/src/ppstampMakeStamp.c

    r27117 r27461  
    1717
    1818static void skyToChip(pmAstromObj *pt, pmFPA *fpa, pmChip *chip);
     19static void chipToSky(pmAstromObj *pt, pmFPA *fpa, pmChip *chip);
    1920static bool setMaskedToNAN(pmConfig *config, psImage *image, psImage *mask, psImage *variance);
    2021
    2122// convert the input chip's transforms to the output
    22 static bool convertWCS(pmHDU *outHDU, pmFPA *outFPA, pmChip *outChip, pmChip *inChip, psRegion *roi)
    23 {
    24     pmHDU *hdu = pmHDUFromChip(inChip);
    25     PS_ASSERT_PTR_NON_NULL(hdu, 1)
    26     PS_ASSERT_PTR_NON_NULL(hdu->header, 1)
    27 
    28     // Change the reference pixel to account for the change in origin between the stamp and
    29     // the original image
    30     // XXX: shouldn't we be using the center of the stamp instead of the corner?
    31     outChip->toFPA   = psPlaneTransformSetCenter(NULL, inChip->toFPA, (int) roi->x0, (int) roi->y0);
    32 
    33     outChip->fromFPA = psPlaneTransformInvert(NULL, outChip->toFPA, *roi, 50);
     23static bool convertWCS(pmHDU *outHDU, pmFPA *inFPA, pmChip *inChip, pmFPA *outFPA, pmChip *outChip, psRegion *roi)
     24{
     25    PS_ASSERT_PTR_NON_NULL(outHDU, 1);
     26    PS_ASSERT_PTR_NON_NULL(outHDU->header, 1);
     27
     28    // Center of stamp in chip coordinates
     29    double center_x = (roi->x0 + roi->x1) / 2;
     30    double center_y = (roi->y0 + roi->y1) / 2;
     31    pmAstromObj *check = pmAstromObjAlloc();
     32    check->chip->x = center_x;
     33    check->chip->y = center_y;
     34    chipToSky(check, inFPA, inChip);
     35    double r_before = check->sky->r;
     36    double d_before = check->sky->d;
     37    psLogMsg("ppstampMakeStamp", 2, "Before fit  Center Pixel RA: %f   DEC: %f (degrees)\n",
     38             r_before * PS_DEG_RAD, d_before * PS_DEG_RAD);
    3439
    3540    if (outFPA->toSky->type != PS_PROJ_TAN) {
    36         if (!pmAstromLinearizeTransforms(outFPA, outChip)) {
     41        // we need to make astrometry terms for the output which are centered on the output chip center,
     42        // but we keep the original plate scale
     43        psFree(outFPA->toSky);
     44        outFPA->toSky = psProjectionAlloc (r_before, d_before, inFPA->toSky->Xs, inFPA->toSky->Ys, PS_PROJ_TAN);
     45
     46        if (!pmAstromLinearizeToSky(inFPA, inChip, outFPA, outChip, roi)) {
     47            psFree(check);
    3748            psError(PS_ERR_UNKNOWN, false, "Failed to linearize astrometry\n");
    3849            return false;
    3950        }
    40     }
     51        check->chip->x = (roi->x1 - roi->x0) / 2;
     52        check->chip->y = (roi->y1 - roi->y0) / 2;
     53        chipToSky(check, outFPA, outChip);
     54        double r_after = check->sky->r;
     55        double d_after = check->sky->d;
     56
     57        psLogMsg("ppstampMakeStamp", 2, "After fit:  Center Pixel RA: %f   DEC: %f (degrees)\n",
     58                 r_after * PS_DEG_RAD, d_after * PS_DEG_RAD);
     59        psLogMsg("ppstampMakeStamp", 2, "Error in fit to astrometry %.2f    %.2f (arcseconds)\n",
     60                 (r_after - r_before) *  PS_DEG_RAD * 3600, (d_after - d_before) * PS_DEG_RAD * 3600);
     61
     62        // XXX: should we fail if the fit is bad ??
     63
     64    } else {
     65        outChip->toFPA     = psPlaneTransformSetCenter(NULL, inChip->toFPA, (int) roi->x0, (int) roi->y0);
     66        outChip->fromFPA   = psPlaneTransformInvert(NULL, outChip->toFPA, *roi, 50);
     67        if (!outChip->fromFPA) {
     68            psError(PS_ERR_UNKNOWN, false, "inversion of toFPA transform failed");
     69            return false;
     70        }
     71    }
     72    psFree(check);
    4173
    4274    if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_NONLIN_TOL)) {
     
    92124    // If input had WCS convert it for stamp
    93125    if (input->fpa->toSky) {
    94         // steal the input fpa's transforms
    95         output->fpa->toTPA   = input->fpa->toTPA;
    96         output->fpa->fromTPA = input->fpa->fromTPA;
    97         output->fpa->toSky   = input->fpa->toSky;
    98 
    99         // drop the references
    100         input->fpa->toTPA   = 0;
    101         input->fpa->fromTPA = 0;
    102         input->fpa->toSky   = 0;
    103 
    104         if (!convertWCS(outHDU, output->fpa, outChip, inChip, &options->roi)) {
     126        // copy the input fpa's transforms
     127        // XXX: if we change to making multiple stamps per process we'll need to copy
     128        // the transformations
     129        output->fpa->toTPA   = psMemIncrRefCounter(input->fpa->toTPA);
     130        output->fpa->fromTPA = psMemIncrRefCounter(input->fpa->fromTPA);
     131        output->fpa->toSky   = psMemIncrRefCounter(input->fpa->toSky);
     132
     133        if (!convertWCS(outHDU, input->fpa, inChip, output->fpa, outChip, &options->roi)) {
    105134            return false;
    106135        }
Note: See TracChangeset for help on using the changeset viewer.