Changeset 15323 for trunk/ppstamp/src/ppstampMakeStamp.c
- Timestamp:
- Oct 16, 2007, 4:00:33 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/ppstamp/src/ppstampMakeStamp.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppstamp/src/ppstampMakeStamp.c
r15318 r15323 16 16 } ppstampOverlap; 17 17 18 static bool regionContainsPoint(psRegion *region, psPlane *point); 19 static bool regionContainsRegion(psRegion *outer, psRegion *inner); 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; 52 } 18 // convert the input chip's transforms to the output 19 static bool convertWCS(pmHDU *outHDU, pmFPA *outFPA, pmChip *outChip, pmChip *inChip, psRegion *roi) 20 { 21 pmHDU *hdu = pmHDUFromChip(inChip); 22 PS_ASSERT_PTR_NON_NULL(hdu, 1) 23 PS_ASSERT_PTR_NON_NULL(hdu->header, 1) 24 25 outChip->toFPA = psPlaneTransformSetCenter(NULL, inChip->toFPA, roi->x0, roi->y0); 26 outChip->fromFPA = psPlaneTransformInvert(NULL, outChip->toFPA, *roi, 50); 27 28 if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_NONLIN_TOL)) { 29 psError(PS_ERR_UNKNOWN, false, "Failed to write WCS\n"); 30 return false; 31 } 32 33 return true; 34 } 35 36 static bool copyMetadata(pmFPAfile *output, pmFPAfile *input, pmChip *inChip, pmCell *inCell, psRegion *roi) 37 { 38 pmChip *outChip; 39 pmFPAview *view = pmFPAviewAlloc(0); 40 41 // our output file has a single chip 42 view->chip = 0; 43 outChip = pmFPAviewThisChip(view, output->fpa); 44 psFree(view); 45 46 // XXX we probably should copy some concepts from the chip (skipping those that don't apply) 47 outChip->parent->concepts = psMetadataCopy(outChip->parent->concepts, inChip->parent->concepts); 48 49 pmHDU *inHDU = pmHDUGetHighest(input->fpa, inChip, NULL); 50 pmHDU *outHDU = pmHDUGetHighest(output->fpa, outChip, NULL); 51 52 if (inHDU->header) { 53 outHDU->header = psMetadataCopy(outHDU->header, inHDU->header); 54 } else if (!outHDU->header) { 55 outHDU->header = psMetadataAlloc(); 56 } 57 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 } 71 72 return true; 73 } 74 75 // Build the postage stamp output file 53 76 54 77 static bool makeStamp(pmConfig *config, ppstampOptions *options, pmFPAfile *input, … … 82 105 while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) { 83 106 if (!readout->data_exists) { 84 // XXX if this happens something is wrong85 107 continue; 86 108 } … … 92 114 } 93 115 94 // XXX Do we have to do somethign to deal with negative parity95 116 psImage *subsetImage = psImageSubset(readout->image, options->roi); 96 117 if (subsetImage) { … … 99 120 psFree(subsetImage); 100 121 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. 101 124 // XXX put this into a function in psImage 102 125 // (What I really needed was a function to "create a copy of this portion of an image") … … 126 149 127 150 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); 151 152 static bool regionContainsPoint(psRegion *r, psPlane *pt) 153 { 154 if (pt->x < r->x0) 155 return false; 156 if (pt->x >= r->x1) 157 return false; 158 if (pt->y < r->y0) 159 return false; 160 if (pt->y >= r->y1) 161 return false; 162 163 return true; 164 } 165 166 // true if the inner region is equal to or completely contained in 167 // the outer region 168 static bool regionContainsRegion(psRegion *outer, psRegion *inner) 169 { 170 if ((outer->x0 <= inner->x0) && 171 (outer->y0 <= inner->y0) && 172 (outer->x1 >= inner->x1) && 173 (outer->y1 >= inner->y1)) { 174 return true; 183 175 } 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) 200 { 201 pmChip *outChip; 202 pmFPAview *view = pmFPAviewAlloc(0); 203 204 // our output file has a single chip 205 view->chip = 0; 206 outChip = pmFPAviewThisChip(view, output->fpa); 207 psFree(view); 208 209 outChip->parent->concepts = psMetadataCopy(outChip->parent->concepts, inChip->parent->concepts); 210 211 pmHDU *inHDU = pmHDUGetHighest(input->fpa, inChip, NULL); 212 pmHDU *outHDU = pmHDUGetHighest(output->fpa, outChip, NULL); 213 214 if (inHDU->header) { 215 outHDU->header = psMetadataCopy(outHDU->header, inHDU->header); 216 } else if (!outHDU->header) { 217 outHDU->header = psMetadataAlloc(); 218 } 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 233 return true; 234 } 235 236 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) 241 { 242 psRegion *chipExtent = pmChipPixels(chip); 176 return false; 177 } 178 } 179 180 181 static void skyToChip(pmAstromObj *pt, pmFPA *fpa, pmChip *chip) 182 { 183 // convert from sky to FP 184 psProject(pt->TP, pt->sky, fpa->toSky); 185 psPlaneTransformApply(pt->FP, fpa->fromTPA, pt->TP); 186 // convert from FP to chip 187 psPlaneTransformApply(pt->chip, chip->fromFPA, pt->FP); 188 } 189 190 static void chipToSky(pmAstromObj *pt, pmFPA *fpa, pmChip *chip) 191 { 192 psPlaneTransformApply(pt->FP, chip->toFPA, pt->chip); 193 psPlaneTransformApply(pt->TP, fpa->toTPA, pt->FP); 194 psDeproject(pt->sky, pt->TP, fpa->toSky); 195 196 } 197 198 static void compareToBox(psRegion *region, psPlane *pt) 199 { 200 if (pt->x < region->x0) 201 region->x0 = pt->x; 202 if (pt->x > region->x1) 203 region->x1 = pt->x; 204 if (pt->y < region->y0) 205 region->y0 = pt->y; 206 if (pt->y > region->y1) 207 region->y1 = pt->y; 208 } 209 210 static void findBoundingBox(ppstampOptions *options, pmFPA *fpa, pmChip *chip, pmAstromObj *center) 211 { 212 pmAstromObj *pt = pmAstromObjAlloc(); 213 214 if (!options->celestialCenter) { 215 // Center was specified in chip coordinates, transform to the sky 216 chipToSky(center, fpa, chip); 217 } 218 219 // calculate the four corners of the bounding box in sky coordinates, translate them to 220 // chip coordinates and build the ROI by comparison. 221 222 options->roi.x0 = INFINITY; 223 options->roi.x1 = -INFINITY; 224 options->roi.y0 = INFINITY; 225 options->roi.y1 = -INFINITY; 226 227 pt->sky->rErr = 0; 228 pt->sky->dErr = 0; 229 230 pt->sky->r = center->sky->r - options->dRA/2; 231 pt->sky->d = center->sky->d - options->dDEC/2; 232 skyToChip(pt, fpa, chip); 233 compareToBox(&options->roi, pt->chip); 234 235 pt->sky->r = center->sky->r + options->dRA/2; 236 pt->sky->d = center->sky->d - options->dDEC/2; 237 skyToChip(pt, fpa, chip); 238 compareToBox(&options->roi, pt->chip); 239 240 pt->sky->r = center->sky->r + options->dRA/2; 241 pt->sky->d = center->sky->d + options->dDEC/2; 242 skyToChip(pt, fpa, chip); 243 compareToBox(&options->roi, pt->chip); 244 245 pt->sky->r = center->sky->r - options->dRA/2; 246 pt->sky->d = center->sky->d + options->dDEC/2; 247 skyToChip(pt, fpa, chip); 248 compareToBox(&options->roi, pt->chip); 249 250 psFree(pt); 251 } 252 253 254 // find cell on given chip that contains the region of interest 255 // return the status of the overlap and if the cell completely contains the ROI 256 // set a pointer to reference the cell 257 258 static ppstampOverlap findCell(pmFPAview *view, ppstampOptions *options, pmFPAfile *input, 259 pmAstromObj *center, pmCell **ppCell) 260 { 261 pmCell *cell; 262 263 view->cell = -1; 264 while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) { 265 psRegion *cellExtent = ppstampCellRegion(cell); 266 if (regionContainsPoint(cellExtent, center->chip)) { 267 if (regionContainsRegion(cellExtent, &options->roi)) { 268 *ppCell = cell; 269 psFree(cellExtent); 270 return PPSTAMP_ON; 271 } else { 272 fprintf(stderr, "ROI must be confined to single cell. Partial overlap cell %d\n", 273 view->cell); 274 fprintf(stderr, "Partial Overlap cell %d\n", view->cell); 275 fprintf(stderr, " ROI: %s\n", psRegionToString(options->roi)); 276 fprintf(stderr, " Cell Extent: %s\n", psRegionToString(*cellExtent)); 277 psFree(cellExtent); 278 return PPSTAMP_PARTIALLY_ON; 279 } 280 } 281 psFree(cellExtent); 282 } 283 284 // This shouldn't ever happen since ROI is on the chip, it must at least partially overlap 285 // one of the cells 286 psError(PS_ERR_PROGRAMMING, false, "findCell couldn't find a cell containing the center\n"); 287 288 return PPSTAMP_OFF; 289 } 290 291 // findROI 292 // 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. 294 295 static ppstampOverlap findROI(ppstampOptions *options, pmFPAview *view, pmFPAfile *input, pmChip *chip, 296 pmAstromObj *center, pmCell **ppCell) 297 { 298 psString chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); 299 psRegion *chipExtent = ppstampChipRegion(chip); 243 300 bool onChip = false; 244 301 ppstampOverlap returnval = PPSTAMP_OFF; 245 psString chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");246 302 247 303 // set up the astrometry … … 253 309 psError(PS_ERR_UNKNOWN, false, "Failed to Read WCS\n"); 254 310 psFree(chipExtent); 255 psFree(center);256 311 return PPSTAMP_ERROR; 257 312 } … … 259 314 if (options->celestialCenter) { 260 315 261 // convert from sky to FP262 316 center->sky->r = options->centerRA; 263 317 center->sky->d = options->centerDEC; 264 center->sky->rErr = 0; // TODO: is this right?318 center->sky->rErr = 0; 265 319 center->sky->dErr = 0; 266 320 267 psProject(center->TP, center->sky, input->fpa->toSky); 268 psPlaneTransformApply(center->FP, input->fpa->fromTPA, center->TP); 269 270 // convert from FP to chip 321 skyToChip(center, input->fpa, chip); 271 322 psPlaneTransformApply(center->chip, chip->fromFPA, center->FP); 272 323 … … 277 328 } 278 329 } else { 279 // center specified in pixels, user needs to have specified the chip 280 if (chipName == NULL) { 281 psError(PS_ERR_UNKNOWN, true, "Failed to find CHIP.NAME\n"); 282 returnval = PPSTAMP_ERROR; 283 } 284 // ppstampArguments insures that options->chipName is not null 285 if (!strcmp(chipName, options->chipName)) { 330 // center specified in pixels. 331 // If the user specified a name of a chip name wait until we get to that one. 332 // If no chip name was specified, select this one (the first one that had data) 333 if ((options->chipName == NULL) || !strcmp(chipName, options->chipName)) { 286 334 psLogMsg("ppstampMakeStamp", 3, "Center on chip: %s\n", chipName); 287 onChip = true;288 onChip = true;289 335 center->chip->x = options->centerX; 290 336 center->chip->y = options->centerY; 337 center->chip->xErr = 0; 338 center->chip->yErr = 0; 339 onChip = true; 291 340 } 292 341 } … … 294 343 if (onChip) { 295 344 if (options->celestialRange) { 296 // Protect against unimplemented feature 297 psError(PS_ERR_PROGRAMMING, true, "not ready for Range in celestial coordinates yet.\n"); 298 exit(PS_EXIT_PROG_ERROR); 299 // find the bounding box in pixel space that encloses the ROI 345 findBoundingBox(options, input->fpa, chip, center); 300 346 } else { 301 347 int width = options->dX; … … 303 349 304 350 // calculate the ROI in chip coordinates 305 roi->x0 = center->chip->x - width / 2;306 roi->x1 = roi->x0 +width;307 roi->y0 = center->chip->y - height / 2;308 roi->y1 = roi->y0 + height;309 310 if (regionContainsRegion(chipExtent, roi)) { 311 returnval = findCell(view, options, input, center, ppCell);312 } else {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; 318 }351 options->roi.x0 = center->chip->x - width / 2; 352 options->roi.x1 = options->roi.x0 + width; 353 options->roi.y0 = center->chip->y - height / 2; 354 options->roi.y1 = options->roi.y0 + height; 355 } 356 357 if (regionContainsRegion(chipExtent, &options->roi)) { 358 returnval = findCell(view, options, input, center, ppCell); 359 } else { 360 fprintf(stderr, "Partial Overlap chip %s\n", chipName); 361 fprintf(stderr, "ROI: %s\n", psRegionToString(options->roi)); 362 fprintf(stderr, "Chip Extent: %s\n", psRegionToString(*chipExtent)); 363 364 returnval = PPSTAMP_PARTIALLY_ON; 319 365 } 320 366 } … … 363 409 364 410 pmCell *cell; 365 ppstampOverlap overlap = findROI(options, view, input, chip, center, & options->roi, &cell);411 ppstampOverlap overlap = findROI(options, view, input, chip, center, &cell); 366 412 367 413 if (overlap == PPSTAMP_ON) { … … 409 455 410 456 411 static bool regionContainsPoint(psRegion *r, psPlane *pt)412 {413 // TODO: should this comparison be done with integers since we414 // are dealing with pixels?415 // Maybe we should round and truncate before we get here.416 if (pt->x < r->x0)417 return false;418 if (pt->x >= r->x1)419 return false;420 if (pt->y < r->y0)421 return false;422 if (pt->y >= r->y1)423 return false;424 425 return true;426 }427 428 // true if the inner region is equal to or completely contained in429 // the outer region430 static bool regionContainsRegion(psRegion *outer, psRegion *inner)431 {432 if ((outer->x0 <= inner->x0) &&433 (outer->y0 <= inner->y0) &&434 (outer->x1 >= inner->x1) &&435 (outer->y1 >= inner->y1)) {436 return true;437 } else {438 return false;439 }440 }
Note:
See TracChangeset
for help on using the changeset viewer.
