IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 23, 2007, 11:50:52 AM (19 years ago)
Author:
bills
Message:

Extract postage stamp from chip mosaic image. Changed -celcenter to -skycenter
Range in celestial coordinates not specified with -arcrange (arcseconds)
Better error handling.
Allow files without WCS if we don't need it

Location:
trunk/ppstamp/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppstamp/src

    • Property svn:ignore
      •  

        old new  
        66config.h.in
        77stamp-h1
         8ppstampErrorCodes.c
         9ppstampErrorCodes.h
  • trunk/ppstamp/src/ppstampMakeStamp.c

    r15323 r15363  
    1616} ppstampOverlap;
    1717
     18static void skyToChip(pmAstromObj *pt, pmFPA *fpa, pmChip *chip);
     19
    1820// convert the input chip's transforms to the output
    1921static bool convertWCS(pmHDU *outHDU, pmFPA *outFPA, pmChip *outChip, pmChip *inChip, psRegion *roi)
     
    2426
    2527    outChip->toFPA   = psPlaneTransformSetCenter(NULL, inChip->toFPA, roi->x0, roi->y0);
     28
    2629    outChip->fromFPA = psPlaneTransformInvert(NULL, outChip->toFPA, *roi, 50);
    2730
    2831    if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_NONLIN_TOL)) {
    29         psError(PS_ERR_UNKNOWN, false, "Failed to write WCS\n");
     32        psError(PS_ERR_UNKNOWN, false, "Failed to write WCS to output\n");
    3033        return false;
    3134    }
     
    3437}
    3538
    36 static bool copyMetadata(pmFPAfile *output, pmFPAfile *input, pmChip *inChip, pmCell *inCell, psRegion *roi)
     39static bool copyMetadata(pmFPAfile *output, pmFPAfile *input, pmChip *inChip, ppstampOptions *options)
    3740{
    3841    pmChip    *outChip;
     
    4447    psFree(view);
    4548
    46     // XXX we probably should copy some concepts from the chip (skipping those that don't apply)
     49    // copy data from the input chip header to the output.
     50    // since some of the keywords might be duplicated we may not want to copy both
     51
     52    // copy the fpa concepts
    4753    outChip->parent->concepts = psMetadataCopy(outChip->parent->concepts, inChip->parent->concepts);
    4854
    49     pmHDU *inHDU  = pmHDUGetHighest(input->fpa, inChip, NULL);
     55    pmHDU *inHDU  = pmHDUFromChip(inChip);
    5056    pmHDU *outHDU = pmHDUGetHighest(output->fpa, outChip, NULL);
    5157
     
    5662    }
    5763
    58     // steal the input fpa's transforms
    59     output->fpa->toTPA = input->fpa->toTPA;
    60     output->fpa->fromTPA = input->fpa->fromTPA;
    61     output->fpa->toSky = input->fpa->toSky;
    62 
    63     // drop the references
    64     input->fpa->toTPA = 0;
    65     input->fpa->fromTPA = 0;
    66     input->fpa->toSky = 0;
    67 
    68     if (!convertWCS(outHDU, output->fpa, outChip, inChip, roi)) {
    69         return false;
    70     }
     64    // If input had WCS convert it for stamp
     65    if (input->fpa->toSky) {
     66        // steal the input fpa's transforms
     67        output->fpa->toTPA   = input->fpa->toTPA;
     68        output->fpa->fromTPA = input->fpa->fromTPA;
     69        output->fpa->toSky   = input->fpa->toSky;
     70
     71        // drop the references
     72        input->fpa->toTPA   = 0;
     73        input->fpa->fromTPA = 0;
     74        input->fpa->toSky   = 0;
     75
     76        if (!convertWCS(outHDU, output->fpa, outChip, inChip, &options->roi)) {
     77            return false;
     78        }
     79    } else {
     80        psWarning("No WCS present in input\n");
     81    }
     82
     83    ppstampVersionMetadata(outHDU->header, options);
    7184
    7285    return true;
    7386}
    7487
     88#ifdef notdef
     89// update the ROI to account for any change in the coordinate system in the
     90// mosaic process
     91// THERE isn't any change. This is something I was trying to make the megacam
     92// transforms come out correctly.
     93static bool updateROI(ppstampOptions *options, pmFPAfile *mosaic, pmChip *mosaicChip)
     94{
     95    // set up the astrometry
     96    pmHDU *hdu = pmHDUFromChip(mosaicChip);
     97    PS_ASSERT_PTR_NON_NULL(hdu, 1)
     98    PS_ASSERT_PTR_NON_NULL(hdu->header, 1)
     99
     100
     101    if (!pmAstromReadWCS(mosaic->fpa, mosaicChip, hdu->header, 1.0)) {
     102        psError(PS_ERR_UNKNOWN, false, "Failed to Read WCS from mosaic, cannot proceed\n");
     103        return false;
     104    }
     105    pmAstromObj *center = pmAstromObjAlloc();
     106
     107    center->sky->r = options->centerRA;
     108    center->sky->d = options->centerDEC;
     109    center->sky->rErr = 0;
     110    center->sky->dErr = 0;
     111
     112    skyToChip(center, mosaic->fpa, mosaicChip);
     113
     114    int width = options->dX;
     115    int height = options->dY;
     116
     117    fprintf(stderr, "ROI before: %s\n", psRegionToString(options->roi));
     118
     119    options->roi.x0 = center->chip->x - width/2;
     120    options->roi.x1 = options->roi.x0 + width;
     121    options->roi.y0 = center->chip->y - height/2;
     122    options->roi.y1 = options->roi.y0 + height;
     123
     124    fprintf(stderr, "ROI after:  %s\n", psRegionToString(options->roi));
     125
     126
     127    return true;
     128}
     129#endif
     130
    75131// Build the postage stamp output file
    76132
    77133static bool makeStamp(pmConfig *config, ppstampOptions *options, pmFPAfile *input,
    78                 pmChip *inChip, pmCell *inCell, pmFPAview *view)
     134                pmChip *inChip, pmFPAview *view)
    79135{
    80136    int status = false;
     
    91147    outview->chip = 0;
    92148    outview->cell = 0;
    93     outview->readout = 0;
    94149    pmCell *target =  pmFPAviewThisCell(outview, output->fpa); // Target cell
    95150    psFree(outview);
    96151    outview = NULL;
    97152
    98     //    psMetadataPrint(stderr, inChip->concepts, 0);
    99     //   psMetadataPrint(stderr, inCell->concepts, 0);
    100     // these default to zero would that be ok?
     153    //   psMetadataPrint(stderr, inChip->concepts, 0);
     154   
     155    // These default to zero. would that be ok?
    101156    psMetadataAddS32(target->concepts, PS_LIST_TAIL, "CELL.XBIN", PS_META_REPLACE, "Binning in x", 1);
    102157    psMetadataAddS32(target->concepts, PS_LIST_TAIL, "CELL.YBIN", PS_META_REPLACE, "Binning in y", 1);
    103158
     159
     160    // we extract our postage stamp from a mosaic so that
     161    // pmChipMosaic can handle the tricky bits of parity, binning, etc.
     162    pmFPAfile *mosaic = ppstampBuildMosaic(config, input, view);
     163    if (mosaic == NULL) {
     164        return false;
     165    }
     166
     167    // one cell one chip
     168    pmFPAview *mosaicView = pmFPAviewAlloc(0);
     169    mosaicView->chip = 0;
     170    mosaicView->cell = 0;
     171
    104172    pmReadout *readout;
    105     while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
     173    while ((readout = pmFPAviewNextReadout (mosaicView, mosaic->fpa, 1)) != NULL) {
    106174        if (!readout->data_exists) {
     175            psError(PS_ERR_UNKNOWN, false, "no data in mosaic readout!\n");
    107176            continue;
    108177        }
     
    113182            break;
    114183        }
    115 
     184   
    116185        psImage *subsetImage = psImageSubset(readout->image, options->roi);
    117186        if (subsetImage) {
     
    120189            psFree(subsetImage);
    121190            if (outReadout->image) {
    122                 // The image has inherited the source's col0 and row0. We don't want this in
    123                 // our output so override it.
     191                // The image has inherited the subset's col0 and row0. We don't want this in
     192                // our output so override the values.
    124193                // XXX put this into a function in psImage
    125                 // (What I really needed was a function to "create a copy of this portion of an image")
     194                // (What I really needed was a function that does
     195                //     "create a copy of this portion of an image and return it as a new image with
     196                //      origin 0,0 ")
    126197                P_PSIMAGE_SET_COL0(outReadout->image, 0);
    127198                P_PSIMAGE_SET_ROW0(outReadout->image, 0);
    128199
    129200                outReadout->data_exists = true;
    130                 outReadout->parent->data_exists = true;         // cell
    131                 outReadout->parent->parent->data_exists = true; // chip
     201                outReadout->parent->data_exists = true;
     202                outReadout->parent->parent->data_exists = true;
    132203                status = true;
    133204            } else {
     
    142213    }
    143214
     215    // XXXX remove this or make writing the mosaic to a file a valid option
     216    static bool writeMosaic = false;
     217    if (writeMosaic) {
     218        mosaic->save = true;
     219        mosaicView->cell = -1;
     220        pmFPAfileIOChecks(config, mosaicView, PM_FPA_AFTER);
     221    }
     222
     223    psFree(mosaicView);
     224
    144225    if (status) {
    145         status = copyMetadata(output, input, inChip, inCell, &options->roi);
     226        status = copyMetadata(output, input, inChip, options);
    146227    }
    147228    return status;
     
    181262static void skyToChip(pmAstromObj *pt, pmFPA *fpa, pmChip *chip)
    182263{
    183     // convert from sky to FP
     264    // convert from sky to TP to FP
    184265    psProject(pt->TP, pt->sky, fpa->toSky);
    185266    psPlaneTransformApply(pt->FP, fpa->fromTPA, pt->TP);
     
    190271static void chipToSky(pmAstromObj *pt, pmFPA *fpa, pmChip *chip)
    191272{
     273    // chip to FP
    192274    psPlaneTransformApply(pt->FP, chip->toFPA, pt->chip);
     275    // FP to TP to sky
    193276    psPlaneTransformApply(pt->TP, fpa->toTPA, pt->FP);
    194277    psDeproject(pt->sky, pt->TP, fpa->toSky);
     
    208291}
    209292
     293// For roi width and height given in sky coordinates find a bounding box in chip coordinates
     294// that encloses the requested range
    210295static void findBoundingBox(ppstampOptions *options, pmFPA *fpa, pmChip *chip, pmAstromObj *center)
    211296{
     
    249334
    250335    psFree(pt);
    251 }
    252 
    253 
     336
     337    // save the width and height in case we need them later
     338    options->dX = options->roi.x1 - options->roi.x0;
     339    options->dY = options->roi.y1 - options->roi.y0;
     340}
     341
     342#ifdef notdef
     343// I'm not using this any more. We mosaic the chip before extracting the pixels
     344// so we don't need to deal with cells at this level.
     345
     346// findCell
    254347// find cell on given chip that contains the region of interest
    255348// return the status of the overlap and if the cell completely contains the ROI
     
    263356    view->cell = -1;
    264357    while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
    265         psRegion *cellExtent = ppstampCellRegion(cell);
     358        psRegion *cellExtent = pmCellExtent(cell);
    266359        if (regionContainsPoint(cellExtent, center->chip)) {
    267360            if (regionContainsRegion(cellExtent, &options->roi)) {
     
    288381    return PPSTAMP_OFF;
    289382}
     383#endif
     384
     385
    290386
    291387// findROI
    292388// calculate the region of interest in chip coordinates and determine whether that region
    293 // whether the region of interest is completely contained in a cell on a given chip.
     389// is completely contained on a single chip
    294390
    295391static ppstampOverlap findROI(ppstampOptions *options, pmFPAview *view, pmFPAfile *input, pmChip *chip,
    296                        pmAstromObj *center, pmCell **ppCell)
     392                       pmAstromObj *center)
    297393{
    298394    psString chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
    299     psRegion    *chipExtent = ppstampChipRegion(chip);
     395    psRegion    *chipBounds = ppstampChipRegion(chip);
    300396    bool        onChip = false;
    301397    ppstampOverlap   returnval = PPSTAMP_OFF;
     398
     399//    fprintf(stderr, "ppstampChipBounds: %s\n", psRegionToString(*chipBounds));
    302400
    303401    // set up the astrometry
     
    307405
    308406    if (!pmAstromReadWCS(input->fpa, chip, hdu->header, 1.0)) {
    309         psError(PS_ERR_UNKNOWN, false, "Failed to Read WCS\n");
    310         psFree(chipExtent);
    311         return PPSTAMP_ERROR;
     407        // we can live without WCS if the ROI is specified in pixels
     408
     409        if (options->celestialCenter || options->celestialRange) {
     410            psError(PPSTAMP_ERR_DATA, false, "Failed to Read WCS, cannot proceed\n");
     411            psFree(chipBounds);
     412            return PPSTAMP_ERROR;
     413        }
    312414    }
    313415
     
    320422
    321423        skyToChip(center, input->fpa, chip);
    322         psPlaneTransformApply(center->chip, chip->fromFPA, center->FP);
    323 
    324         if (regionContainsPoint(chipExtent, center->chip)) {
    325             psLogMsg("ppstampMakeStamp", 3, "Found center (%f %f) on chip: %s\n",
     424
     425        if (regionContainsPoint(chipBounds, center->chip)) {
     426            psLogMsg("ppstampMakeStamp", 2, "Found center (%f %f) on chip: %s\n",
    326427                center->chip->x, center->chip->y, chipName);
    327428            onChip = true;
     
    332433        // If no chip name was specified, select this one (the first one that had data)
    333434        if ((options->chipName == NULL) || !strcmp(chipName, options->chipName)) {
    334             psLogMsg("ppstampMakeStamp", 3, "Center on chip: %s\n", chipName);
     435            psLogMsg("ppstampMakeStamp", 2, "Center on chip: %s\n", chipName);
    335436            center->chip->x = options->centerX;
    336437            center->chip->y = options->centerY;
     
    355456        }
    356457
    357         if (regionContainsRegion(chipExtent, &options->roi)) {
    358             returnval = findCell(view, options, input, center, ppCell);
     458
     459        if (regionContainsRegion(chipBounds, &options->roi)) {
     460            // returnval = findCell(view, options, input, center, ppCell);
     461            psLogMsg("ppstampMakeStamp", 2, "ROI contained on: %s\n", chipName);
     462            returnval = PPSTAMP_ON;
    359463        } else {
    360464            fprintf(stderr, "Partial Overlap chip %s\n", chipName);
    361465            fprintf(stderr, "ROI:         %s\n", psRegionToString(options->roi));
    362             fprintf(stderr, "Chip Extent: %s\n", psRegionToString(*chipExtent));
     466            fprintf(stderr, "Chip Extent: %s\n", psRegionToString(*chipBounds));
    363467
    364468            returnval = PPSTAMP_PARTIALLY_ON;
    365         }
    366     }
    367     psFree(chipExtent);
     469
     470        }
     471    }
     472    psFree(chipBounds);
    368473
    369474    return returnval;
     
    374479    bool        status = false;
    375480    bool        returnval = false;;
     481    bool        foundOverlap = false;
    376482    pmAstromObj *center = pmAstromObjAlloc();
    377483
     
    408514        }
    409515
    410         pmCell *cell;
    411         ppstampOverlap overlap = findROI(options, view, input, chip, center, &cell);
    412 
    413         if (overlap == PPSTAMP_ON) {
    414 
    415             returnval = makeStamp(config, options, input, chip, cell, view);
    416 
     516        ppstampOverlap overlap = findROI(options, view, input, chip, center);
     517
     518        switch (overlap) {
     519        case PPSTAMP_OFF:
     520            // keep looking
     521            break;
     522        case PPSTAMP_ON:
     523            returnval = makeStamp(config, options, input, chip, view);
    417524            allDone = true;
    418         } else if (overlap == PPSTAMP_PARTIALLY_ON) {
    419             psError(PS_ERR_UNKNOWN, false, "Region of interest must be confined to a single cell\n");
     525            foundOverlap = true;
     526            break;
     527        case PPSTAMP_PARTIALLY_ON:
     528            psError(PS_ERR_UNKNOWN, false, "Region of interest must be confined to a single chip\n");
    420529            // XXX: perhaps print a helpful message about what coordinates would be valid
    421530            returnval = false;
    422531            allDone = true;
    423         } else if (overlap == PPSTAMP_ERROR) {
     532            foundOverlap = true;
     533            break;
     534        case PPSTAMP_ERROR:
    424535            returnval = false;
    425536            allDone = true;
     537            break;
     538        default:
     539            psError(PS_ERR_PROGRAMMING, false, "findROI returned unexpected value %d\n", overlap);
     540            break;
    426541        }
    427542
     
    430545        if (allDone) {
    431546            view->chip = -1;
    432             view->cell = -1;
    433             break;
    434         } else {
    435             // Remove the transformations from the fpa so that they will be
    436             // recalculated from scratch for the next chip.
    437             // If I don't do this the calculation of the astrometry parameters for the output file
    438             // don't come out correctly. See the code on the false side of the test
    439             // if (fpa->toSky == NULL) in the function pmAstromWCStoFPA
    440             psFree(input->fpa->fromTPA);
    441             psFree(input->fpa->toTPA);
    442             psFree(input->fpa->toSky);
    443             input->fpa->fromTPA = NULL;
    444             input->fpa->toTPA = NULL;
    445             input->fpa->toSky = NULL;
     547            break;
    446548        }
    447549    }
     
    451553    psFree(view);
    452554
     555    if (!foundOverlap) {
     556        fprintf(stderr, "ROI not found in input\n");
     557    }
     558
    453559    return returnval;
    454560}
Note: See TracChangeset for help on using the changeset viewer.