Changeset 15318
- Timestamp:
- Oct 15, 2007, 4:49:27 PM (19 years ago)
- Location:
- trunk/ppstamp/src
- Files:
-
- 2 edited
-
ppstampCleanup.c (modified) (1 diff)
-
ppstampMakeStamp.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppstamp/src/ppstampCleanup.c
r15280 r15318 20 20 21 21 // psMemCheckLeaks (0, NULL, stderr, false); 22 //fprintf (stderr, "Found %d leaks in %s\n", psMemCheckLeaks (0, NULL, NULL, false), "ppstamp");22 fprintf (stderr, "Found %d leaks in %s\n", psMemCheckLeaks (0, NULL, NULL, false), "ppstamp"); 23 23 24 24 return; -
trunk/ppstamp/src/ppstampMakeStamp.c
r15280 r15318 5 5 #include "ppstamp.h" 6 6 #include "pmFPAAstrometry.h" 7 8 #define USE_MOSAIC 7 #include "pmAstrometryUtils.h" 8 9 #define WCS_NONLIN_TOL 0.001 // Non-linear tolerance for header WCS 9 10 10 11 typedef enum { 11 PPSTAMP_OFF _CHIP,12 PPSTAMP_PARTIALLY_ON _CHIP,13 PPSTAMP_ON _CHIP,12 PPSTAMP_OFF, 13 PPSTAMP_PARTIALLY_ON, 14 PPSTAMP_ON, 14 15 PPSTAMP_ERROR 15 16 } ppstampOverlap; … … 17 18 static bool regionContainsPoint(psRegion *region, psPlane *point); 18 19 static bool regionContainsRegion(psRegion *outer, psRegion *inner); 19 static bool copyMetadata(pmFPAfile *output, pmFPAfile *input, pmChip *inChip); 20 21 static pmFPAfile *buildMosaic(pmConfig *config, pmFPAfile *input, pmFPAview *view, pmFPAview *mosaicView) 22 { 23 bool status; 24 25 pmFPAfile *mosaic = psMetadataLookupPtr(&status, config->files, "PPSTAMP.CHIP"); 26 if (!status) { 27 psErrorStackPrint(stderr, "can't find mosaic i/o file\n"); 28 exit(EXIT_FAILURE); 29 } 30 31 pmChip *mChip = pmFPAviewThisChip(mosaicView, mosaic->fpa); 32 pmChip *inChip = pmFPAviewThisChip(view, input->fpa); 33 if (!mChip->hdu && !mChip->parent->hdu) { 34 const char *name = psMetadataLookupStr(&status, input->fpa->concepts, "FPA.NAME"); // Name of FPA 35 pmFPAAddSourceFromView(mosaic->fpa, name, mosaicView, mosaic->format); 36 } 37 38 psMaskType blankMask = pmConfigMask("BLANK", config); 39 40 status = pmChipMosaic(mChip, inChip, true, blankMask); 41 if (status) { 42 return mosaic; 43 } else { 44 return NULL; 45 } 20 static bool copyMetadata(pmFPAfile *output, pmFPAfile *input, pmChip *inChip, pmCell *inCell, 21 psRegion *roi); 22 23 24 static ppstampOverlap findCell(pmFPAview *view, ppstampOptions *options, pmFPAfile *input, 25 pmAstromObj *center, pmCell **ppCell) 26 { 27 pmCell *cell; 28 29 view->cell = -1; 30 while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) { 31 psRegion *cellExtent = pmCellExtent(cell); 32 if (regionContainsPoint(cellExtent, center->chip)) { 33 if (regionContainsRegion(cellExtent, &options->roi)) { 34 *ppCell = cell; 35 psFree(cellExtent); 36 return PPSTAMP_ON; 37 } else { 38 fprintf(stderr, "ROI must be confined to single cell. Partial overlap cell %d\n", 39 view->cell); 40 psFree(cellExtent); 41 return PPSTAMP_PARTIALLY_ON; 42 } 43 } 44 psFree(cellExtent); 45 } 46 47 // This shouldn't ever happen since ROI is on the chip, it must at least partially overlap 48 // one of the cells 49 psError(PS_ERR_PROGRAMMING, false, "findCell couldn't find a cell containing the center\n"); 50 51 return PPSTAMP_OFF; 46 52 } 47 53 48 54 static bool makeStamp(pmConfig *config, ppstampOptions *options, pmFPAfile *input, 49 pmChip * chip, pmFPAview *view)55 pmChip *inChip, pmCell *inCell, pmFPAview *view) 50 56 { 51 57 int status = false; 58 52 59 pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, "PPSTAMP.OUTPUT"); 53 60 if (!output) { … … 66 73 outview = NULL; 67 74 75 // psMetadataPrint(stderr, inChip->concepts, 0); 76 // psMetadataPrint(stderr, inCell->concepts, 0); 68 77 // these default to zero would that be ok? 69 78 psMetadataAddS32(target->concepts, PS_LIST_TAIL, "CELL.XBIN", PS_META_REPLACE, "Binning in x", 1); 70 79 psMetadataAddS32(target->concepts, PS_LIST_TAIL, "CELL.YBIN", PS_META_REPLACE, "Binning in y", 1); 71 80 72 // we extract our postage stamp from a mosaic so that73 // pmChipMosaic can handle all of the complexities of parity, binning, etc.74 pmFPAview *mosaicView = pmFPAviewAlloc(0);75 mosaicView->chip = 0;76 pmFPAfile *mosaic = buildMosaic(config, input, view, mosaicView);77 if (mosaic == NULL) {78 psFree(mosaicView);79 return false;80 }81 82 mosaicView->cell = 0;83 81 pmReadout *readout; 84 while ((readout = pmFPAviewNextReadout ( mosaicView, mosaic->fpa, 1)) != NULL) {82 while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) { 85 83 if (!readout->data_exists) { 86 // HMM, this probably means something is wrong84 // XXX if this happens something is wrong 87 85 continue; 88 86 } … … 94 92 } 95 93 96 // define a subset of the mosaic's readout94 // XXX Do we have to do somethign to deal with negative parity 97 95 psImage *subsetImage = psImageSubset(readout->image, options->roi); 98 96 if (subsetImage) { … … 101 99 psFree(subsetImage); 102 100 if (outReadout->image) { 103 // TODO:put this into a function in psImage104 // (What I really needed was a function to "create a copy of this portion of an image )101 // XXX put this into a function in psImage 102 // (What I really needed was a function to "create a copy of this portion of an image") 105 103 P_PSIMAGE_SET_COL0(outReadout->image, 0); 106 104 P_PSIMAGE_SET_ROW0(outReadout->image, 0); … … 121 119 } 122 120 123 psFree(mosaicView);124 125 121 if (status) { 126 status = copyMetadata(output, input, chip);122 status = copyMetadata(output, input, inChip, inCell, &options->roi); 127 123 } 128 124 return status; 129 125 } 130 126 131 static bool copyMetadata(pmFPAfile *output, pmFPAfile *input, pmChip *inChip) 127 128 static bool copyWCS(pmHDU *outHDU, pmFPA *outFPA, pmChip *outChip, pmChip *inChip, psRegion *roi) 129 { 130 pmHDU *hdu = pmHDUFromChip(inChip); 131 PS_ASSERT_PTR_NON_NULL(hdu, 1) 132 PS_ASSERT_PTR_NON_NULL(hdu->header, 1) 133 134 #ifdef BRUTE_FORCE 135 outChip->toFPA = inChip->toFPA; 136 outChip->fromFPA = inChip->fromFPA; 137 inChip->toFPA = 0; 138 inChip->fromFPA = 0; 139 140 // This gets us within one pixel of the correct answer 141 psMetadataItemSupplement(outHDU->header, hdu->header, "CD1_1"); 142 psMetadataItemSupplement(outHDU->header, hdu->header, "CD1_2"); 143 psMetadataItemSupplement(outHDU->header, hdu->header, "CD2_1"); 144 psMetadataItemSupplement(outHDU->header, hdu->header, "CD2_2"); 145 psMetadataItemSupplement(outHDU->header, hdu->header, "CRVAL1"); 146 psMetadataItemSupplement(outHDU->header, hdu->header, "CRVAL2"); 147 148 double crpix1 = psMetadataLookupF64(NULL, hdu->header, "CRPIX1"); 149 double crpix2 = psMetadataLookupF64(NULL, hdu->header, "CRPIX2"); 150 151 crpix1 -= roi->x0; 152 crpix2 -= roi->y0; 153 psMetadataAddF64(outHDU->header, PS_LIST_TAIL, "CRPIX1", PS_META_REPLACE, "", crpix1); 154 psMetadataAddF64(outHDU->header, PS_LIST_TAIL, "CRPIX2", PS_META_REPLACE, "", crpix2); 155 156 157 #else 158 159 bool combineTransform = false; 160 if (combineTransform) { 161 // translation from output chip coordinates to input chip coordinates 162 psPlaneTransform *trans = psPlaneTransformAlloc(1, 1); 163 164 trans->x->coeff[0][0] = roi->x0; 165 trans->x->coeff[0][1] = 0; 166 trans->x->coeff[1][0] = 1.0; 167 trans->x->coeff[1][1] = 0; 168 169 trans->y->coeff[0][0] = roi->y0; 170 trans->y->coeff[0][1] = 1.0; 171 trans->y->coeff[1][0] = 0; 172 trans->y->coeff[1][1] = 0; 173 174 // combine the translation with the input's transform 175 // Note: the region and magic number are not actually used by psPlaneTransformCombine 176 outChip->toFPA = psPlaneTransformCombine(NULL, trans, inChip->toFPA, *roi, 50); 177 178 // for completeness we set fromFPA, but since we don't use it ... 179 outChip->fromFPA = psPlaneTransformInvert(NULL, outChip->toFPA, *roi, 50); 180 181 // psFree(region); 182 psFree(trans); 183 } else { 184 outChip->toFPA = psPlaneTransformSetCenter(NULL, inChip->toFPA, roi->x0, roi->y0); 185 outChip->fromFPA = psPlaneTransformInvert(NULL, outChip->toFPA, *roi, 50); 186 } 187 188 189 if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_NONLIN_TOL)) { 190 psError(PS_ERR_UNKNOWN, false, "Failed to write WCS\n"); 191 return false; 192 } 193 #endif 194 195 return true; 196 } 197 198 199 static bool copyMetadata(pmFPAfile *output, pmFPAfile *input, pmChip *inChip, pmCell *inCell, psRegion *roi) 132 200 { 133 201 pmChip *outChip; … … 141 209 outChip->parent->concepts = psMetadataCopy(outChip->parent->concepts, inChip->parent->concepts); 142 210 143 pmHDU *inHDU = pmHDUGetHighest(input->fpa, inChip, NULL);211 pmHDU *inHDU = pmHDUGetHighest(input->fpa, inChip, NULL); 144 212 pmHDU *outHDU = pmHDUGetHighest(output->fpa, outChip, NULL); 145 213 … … 149 217 outHDU->header = psMetadataAlloc(); 150 218 } 151 // TODO set up the astrometry related information 219 220 // steal the input fpa's transforms 221 output->fpa->toTPA = input->fpa->toTPA; 222 output->fpa->fromTPA = input->fpa->fromTPA; 223 output->fpa->toSky = input->fpa->toSky; 224 // drop references 225 input->fpa->toTPA = 0; 226 input->fpa->fromTPA = 0; 227 input->fpa->toSky = 0; 228 229 if (!copyWCS(outHDU, output->fpa, outChip, inChip, roi)) { 230 return false; 231 } 232 152 233 return true; 153 234 } 154 235 155 236 156 ppstampOverlap findROI(ppstampOptions *options, pmFPAfile *input, pmChip *chip, 157 pmAstromObj *center, psRegion *roi) 237 // findROI: find whether the region of interest is completely contained in a cell on a given chip. 238 // If so return the cell 239 ppstampOverlap findROI(ppstampOptions *options, pmFPAview *view, pmFPAfile *input, pmChip *chip, 240 pmAstromObj *center, psRegion *roi, pmCell **ppCell) 158 241 { 159 242 psRegion *chipExtent = pmChipPixels(chip); 160 243 bool onChip = false; 161 ppstampOverlap returnval = PPSTAMP_OFF _CHIP;244 ppstampOverlap returnval = PPSTAMP_OFF; 162 245 psString chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); 163 246 164 if (options->celestialCenter || options->celestialRange) { 165 // set up the astrometry 166 pmHDU *hdu = pmHDUFromChip(chip); 167 PS_ASSERT_PTR_NON_NULL(hdu, 1) 168 PS_ASSERT_PTR_NON_NULL(hdu->header, 1) 169 170 if (!pmAstromReadWCS(input->fpa, chip, hdu->header, 1.0)) { 171 psError(PS_ERR_UNKNOWN, false, "Failed to Read WCS\n"); 172 psFree(chipExtent); 173 psFree(center); 174 return PPSTAMP_ERROR; 175 } 247 // set up the astrometry 248 pmHDU *hdu = pmHDUFromChip(chip); 249 PS_ASSERT_PTR_NON_NULL(hdu, 1) 250 PS_ASSERT_PTR_NON_NULL(hdu->header, 1) 251 252 if (!pmAstromReadWCS(input->fpa, chip, hdu->header, 1.0)) { 253 psError(PS_ERR_UNKNOWN, false, "Failed to Read WCS\n"); 254 psFree(chipExtent); 255 psFree(center); 256 return PPSTAMP_ERROR; 176 257 } 177 258 … … 191 272 192 273 if (regionContainsPoint(chipExtent, center->chip)) { 193 psLogMsg("ppstampMakeStamp", 3, "Found center on chip: %s\n", chipName); 274 psLogMsg("ppstampMakeStamp", 3, "Found center (%f %f) on chip: %s\n", 275 center->chip->x, center->chip->y, chipName); 194 276 onChip = true; 195 277 } … … 227 309 228 310 if (regionContainsRegion(chipExtent, roi)) { 229 returnval = PPSTAMP_ON_CHIP;311 returnval = findCell(view, options, input, center, ppCell); 230 312 } else { 231 returnval = PPSTAMP_PARTIALLY_ON_CHIP; 313 fprintf(stderr, "Partial Overlap chip %s\n", chipName); 314 fprintf(stderr, "ChipExtent: %s\n", psRegionToString(*chipExtent)); 315 fprintf(stderr, "ROI: %s\n", psRegionToString(*roi)); 316 317 returnval = PPSTAMP_PARTIALLY_ON; 232 318 } 233 319 } … … 255 341 // files associated with the science image 256 342 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 257 // TODO log error258 343 psError(PS_ERR_UNKNOWN, false, "Failed to load input."); 259 344 psFree(center); … … 272 357 273 358 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 274 // TODO log error275 359 psError(PS_ERR_UNKNOWN, false, "failed to load chip"); 276 360 status = false; … … 278 362 } 279 363 280 ppstampOverlap overlap = findROI(options, input, chip, center, &options->roi); 281 282 if (overlap == PPSTAMP_ON_CHIP) { 283 284 returnval = makeStamp(config, options, input, chip, view); 364 pmCell *cell; 365 ppstampOverlap overlap = findROI(options, view, input, chip, center, &options->roi, &cell); 366 367 if (overlap == PPSTAMP_ON) { 368 369 returnval = makeStamp(config, options, input, chip, cell, view); 285 370 286 371 allDone = true; 287 } else if (overlap == PPSTAMP_PARTIALLY_ON _CHIP) {288 psError(PS_ERR_UNKNOWN, false, "Region of interest must be confined to a single c hip\n");372 } else if (overlap == PPSTAMP_PARTIALLY_ON) { 373 psError(PS_ERR_UNKNOWN, false, "Region of interest must be confined to a single cell\n"); 289 374 // XXX: perhaps print a helpful message about what coordinates would be valid 290 375 returnval = false; … … 301 386 view->cell = -1; 302 387 break; 388 } else { 389 // Remove the transformations from the fpa so that they will be 390 // recalculated from scratch for the next chip. 391 // If I don't do this the calculation of the astrometry parameters for the output file 392 // don't come out correctly. See the code on the false side of the test 393 // if (fpa->toSky == NULL) in the function pmAstromWCStoFPA 394 psFree(input->fpa->fromTPA); 395 psFree(input->fpa->toTPA); 396 psFree(input->fpa->toSky); 397 input->fpa->fromTPA = NULL; 398 input->fpa->toTPA = NULL; 399 input->fpa->toSky = NULL; 303 400 } 304 401 }
Note:
See TracChangeset
for help on using the changeset viewer.
