Changeset 15897 for trunk/psModules/src/astrom/pmAstrometryTable.c
- Timestamp:
- Dec 22, 2007, 7:53:15 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/astrom/pmAstrometryTable.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/astrom/pmAstrometryTable.c
r15884 r15897 10 10 * 11 11 * @author EAM, IfA 12 * @version $Revision: 1. 6$ $Name: not supported by cvs2svn $13 * @date $Date: 2007-12- 19 18:57:05 $12 * @version $Revision: 1.7 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2007-12-22 17:53:15 $ 14 14 * 15 15 * Copyright 2007 Institute for Astronomy, University of Hawaii … … 120 120 } 121 121 122 if (!pmAstromWriteChips (file)) { 123 psError(PS_ERR_IO, false, "Failed to write Astrometry for chips"); 124 return false; 125 } 126 127 if (!pmAstromWriteFP (file)) { 128 psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry table"); 129 return false; 130 } 131 132 if (!pmAstromWriteTP (file)) { 133 psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry table"); 134 return false; 135 } 136 122 137 if (!pmAstromWriteSky (file)) { 123 138 psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry table"); … … 125 140 } 126 141 127 if (!pmAstromWriteTP (file)) {128 psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry table");129 return false;130 }131 132 if (!pmAstromWriteFP (file)) {133 psError(PS_ERR_IO, false, "Failed to write Sky for Astrometry table");134 return false;135 }136 137 if (!pmAstromWriteChips (file)) {138 psError(PS_ERR_IO, false, "Failed to write Astrometry for chips");139 return false;140 }141 142 return true; 142 143 } … … 174 175 psFree (outhead); 175 176 176 return true;177 }178 179 // first layer is the sky180 bool pmAstromWriteSky (pmFPAfile *file) {181 182 psMetadata *header = psMetadataAlloc();183 psMetadataAddStr(header, PS_LIST_TAIL, "COORD", PS_META_REPLACE, "name of this layer", "SKY");184 psMetadataAddStr(header, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "NONE");185 psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region", "NONE");186 psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent", "NONE");187 188 psArray *table = psArrayAllocEmpty (1);189 psMetadata *row = psMetadataAlloc ();190 psMetadataAddStr(row, PS_LIST_TAIL, "SEGMENT", PS_META_REPLACE, "name of this segment", "SKY");191 psMetadataAddStr(row, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "NONE");192 193 psArrayAdd (table, 100, row);194 psFree (row);195 196 if (!psFitsWriteTable (file->fits, header, table, "SKY")) {197 psError(PS_ERR_IO, false, "writing sky data\n");198 psFree(table);199 return false;200 }201 202 psFree (table);203 psFree (header);204 return (true);205 }206 207 // second layer is the tangent plane208 bool pmAstromWriteTP (pmFPAfile *file) {209 210 psMetadata *header = psMetadataAlloc();211 psMetadataAddStr(header, PS_LIST_TAIL, "COORD", PS_META_REPLACE, "name of this layer", "TANGENT_PLANE");212 psMetadataAddStr(header, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "SKY");213 psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region", "RECTANGLE");214 psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent", "PROJECTION");215 216 psArray *table = psArrayAllocEmpty (1);217 psMetadata *row = psMetadataAlloc ();218 psMetadataAddStr(row, PS_LIST_TAIL, "SEGMENT", PS_META_REPLACE, "name of this segment", "TANGENT_PLANE");219 psMetadataAddStr(row, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "SKY");220 221 psRegion *region = pmAstromFPAExtent (file->fpa);222 psMetadataAddF32(row, PS_LIST_TAIL, "MINX", PS_META_REPLACE, "range", region->x0);223 psMetadataAddF32(row, PS_LIST_TAIL, "MAXX", PS_META_REPLACE, "range", region->x1);224 psMetadataAddF32(row, PS_LIST_TAIL, "MINY", PS_META_REPLACE, "range", region->y0);225 psMetadataAddF32(row, PS_LIST_TAIL, "MAXY", PS_META_REPLACE, "range", region->y1);226 227 psMetadataAddF32(row, PS_LIST_TAIL, "XSCALE", PS_META_REPLACE, "", file->fpa->toSky->Xs * PM_DEG_RAD);228 psMetadataAddF32(row, PS_LIST_TAIL, "YSCALE", PS_META_REPLACE, "", file->fpa->toSky->Ys * PM_DEG_RAD);229 psMetadataAddF32(row, PS_LIST_TAIL, "XREF", PS_META_REPLACE, "", file->fpa->toSky->R * PM_DEG_RAD);230 psMetadataAddF32(row, PS_LIST_TAIL, "YREF", PS_META_REPLACE, "", file->fpa->toSky->D * PM_DEG_RAD);231 232 psArrayAdd (table, 100, row);233 psFree (row);234 235 if (!psFitsWriteTable (file->fits, header, table, "TP")) {236 psError(PS_ERR_IO, false, "writing sky data\n");237 psFree (region);238 psFree (table);239 psFree (header);240 return false;241 }242 243 psFree (region);244 psFree (table);245 psFree (header);246 return (true);247 }248 249 // third layer is the focal plane250 bool pmAstromWriteFP (pmFPAfile *file) {251 252 psMetadata *header = psMetadataAlloc();253 psMetadataAddStr(header, PS_LIST_TAIL, "COORD", PS_META_REPLACE, "name of this layer", "FOCAL_PLANE");254 psMetadataAddStr(header, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "TANGENT_PLANE");255 psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region", "RECTANGLE");256 psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent", "POLYNOMIAL");257 258 psArray *table = psArrayAllocEmpty (1);259 260 // XXX is this or the tpa region correct?261 psRegion *region = pmAstromFPAExtent (file->fpa);262 263 for (int i = 0; i <= file->fpa->toTPA->x->nX; i++) {264 for (int j = 0; j <= file->fpa->toTPA->x->nY; j++) {265 psMetadata *row = psMetadataAlloc ();266 psMetadataAddStr(row, PS_LIST_TAIL, "SEGMENT", PS_META_REPLACE, "name of this segment", "FOCAL_PLANE");267 psMetadataAddStr(row, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "TANGENT_PLANE");268 psMetadataAddF32(row, PS_LIST_TAIL, "MINX", PS_META_REPLACE, "range", region->x0);269 psMetadataAddF32(row, PS_LIST_TAIL, "MAXX", PS_META_REPLACE, "range", region->x1);270 psMetadataAddF32(row, PS_LIST_TAIL, "MINY", PS_META_REPLACE, "range", region->y0);271 psMetadataAddF32(row, PS_LIST_TAIL, "MAXY", PS_META_REPLACE, "range", region->y1);272 273 psMetadataAddS32(row, PS_LIST_TAIL, "NX", PS_META_REPLACE, "", file->fpa->toTPA->x->nX);274 psMetadataAddS32(row, PS_LIST_TAIL, "NY", PS_META_REPLACE, "", file->fpa->toTPA->x->nY);275 psMetadataAddF32(row, PS_LIST_TAIL, "POLY_X", PS_META_REPLACE, "", file->fpa->toTPA->x->coeff[i][j]);276 psMetadataAddF32(row, PS_LIST_TAIL, "POLY_Y", PS_META_REPLACE, "", file->fpa->toTPA->y->coeff[i][j]);277 psMetadataAddF32(row, PS_LIST_TAIL, "ERROR_X", PS_META_REPLACE, "", file->fpa->toTPA->x->coeffErr[i][j]);278 psMetadataAddF32(row, PS_LIST_TAIL, "ERROR_Y", PS_META_REPLACE, "", file->fpa->toTPA->y->coeffErr[i][j]);279 280 psArrayAdd (table, 100, row);281 psFree (row);282 }283 }284 285 if (!psFitsWriteTable (file->fits, header, table, "FP")) {286 psError(PS_ERR_IO, false, "writing sky data\n");287 psFree(table);288 return false;289 }290 291 psFree (table);292 psFree (header);293 psFree (region);294 177 return true; 295 178 } … … 332 215 psMetadataAddF32(row, PS_LIST_TAIL, "MAXY", PS_META_REPLACE, "range", region->y1); 333 216 334 psMetadataAddS32(row, PS_LIST_TAIL, "NX", PS_META_REPLACE, "", i); 335 psMetadataAddS32(row, PS_LIST_TAIL, "NY", PS_META_REPLACE, "", j); 217 psMetadataAddS32(row, PS_LIST_TAIL, "XORDER", PS_META_REPLACE, "", i); 218 psMetadataAddS32(row, PS_LIST_TAIL, "YORDER", PS_META_REPLACE, "", j); 219 psMetadataAddS32(row, PS_LIST_TAIL, "NXORDER", PS_META_REPLACE, "", chip->toFPA->x->nX); 220 psMetadataAddS32(row, PS_LIST_TAIL, "NYORDER", PS_META_REPLACE, "", chip->toFPA->x->nY); 336 221 psMetadataAddF32(row, PS_LIST_TAIL, "POLY_X", PS_META_REPLACE, "", chip->toFPA->x->coeff[i][j]); 337 222 psMetadataAddF32(row, PS_LIST_TAIL, "POLY_Y", PS_META_REPLACE, "", chip->toFPA->y->coeff[i][j]); 338 223 psMetadataAddF32(row, PS_LIST_TAIL, "ERROR_X", PS_META_REPLACE, "", chip->toFPA->x->coeffErr[i][j]); 339 224 psMetadataAddF32(row, PS_LIST_TAIL, "ERROR_Y", PS_META_REPLACE, "", chip->toFPA->y->coeffErr[i][j]); 225 psMetadataAddU8 (row, PS_LIST_TAIL, "MASK_X", PS_META_REPLACE, "", chip->toFPA->x->coeffMask[i][j]); 226 psMetadataAddU8 (row, PS_LIST_TAIL, "MASK_Y", PS_META_REPLACE, "", chip->toFPA->y->coeffMask[i][j]); 340 227 psArrayAdd (table, 100, row); 341 228 psFree (row); … … 357 244 psFree (header); 358 245 return true; 246 } 247 248 // third layer is the focal plane 249 bool pmAstromWriteFP (pmFPAfile *file) { 250 251 bool status; 252 253 psMetadata *header = psMetadataAlloc(); 254 psMetadataAddStr(header, PS_LIST_TAIL, "COORD", PS_META_REPLACE, "name of this layer", "FOCAL_PLANE"); 255 psMetadataAddStr(header, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "TANGENT_PLANE"); 256 psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region", "RECTANGLE"); 257 psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent", "POLYNOMIAL"); 258 259 psArray *table = psArrayAllocEmpty (1); 260 261 // XXX is this or the tpa region correct? 262 psRegion *region = pmAstromFPAExtent (file->fpa); 263 264 // rotate the toTPA to have 0.0 posangle 265 float posangle = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.POSANGLE"); 266 267 // the to/from TPA transform currently has rotation of posangle; remove it & create the toTPA version 268 psPlaneTransform *fromTPA = psPlaneTransformRotate (NULL, file->fpa->fromTPA, -posangle); 269 psPlaneTransform *toTPA = psPlaneTransformInvert(NULL, fromTPA, *region, 50); 270 271 for (int i = 0; i <= toTPA->x->nX; i++) { 272 for (int j = 0; j <= toTPA->x->nY; j++) { 273 psMetadata *row = psMetadataAlloc (); 274 psMetadataAddStr(row, PS_LIST_TAIL, "SEGMENT", PS_META_REPLACE, "name of this segment", "FOCAL_PLANE"); 275 psMetadataAddStr(row, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "TANGENT_PLANE"); 276 psMetadataAddF32(row, PS_LIST_TAIL, "MINX", PS_META_REPLACE, "range", region->x0); 277 psMetadataAddF32(row, PS_LIST_TAIL, "MAXX", PS_META_REPLACE, "range", region->x1); 278 psMetadataAddF32(row, PS_LIST_TAIL, "MINY", PS_META_REPLACE, "range", region->y0); 279 psMetadataAddF32(row, PS_LIST_TAIL, "MAXY", PS_META_REPLACE, "range", region->y1); 280 281 psMetadataAddS32(row, PS_LIST_TAIL, "XORDER", PS_META_REPLACE, "", i); 282 psMetadataAddS32(row, PS_LIST_TAIL, "YORDER", PS_META_REPLACE, "", j); 283 psMetadataAddS32(row, PS_LIST_TAIL, "NXORDER", PS_META_REPLACE, "", toTPA->x->nX); 284 psMetadataAddS32(row, PS_LIST_TAIL, "NYORDER", PS_META_REPLACE, "", toTPA->x->nY); 285 psMetadataAddF32(row, PS_LIST_TAIL, "POLY_X", PS_META_REPLACE, "", toTPA->x->coeff[i][j]); 286 psMetadataAddF32(row, PS_LIST_TAIL, "POLY_Y", PS_META_REPLACE, "", toTPA->y->coeff[i][j]); 287 psMetadataAddF32(row, PS_LIST_TAIL, "ERROR_X", PS_META_REPLACE, "", toTPA->x->coeffErr[i][j]); 288 psMetadataAddF32(row, PS_LIST_TAIL, "ERROR_Y", PS_META_REPLACE, "", toTPA->y->coeffErr[i][j]); 289 psMetadataAddU8 (row, PS_LIST_TAIL, "MASK_X", PS_META_REPLACE, "", toTPA->x->coeffMask[i][j]); 290 psMetadataAddU8 (row, PS_LIST_TAIL, "MASK_Y", PS_META_REPLACE, "", toTPA->y->coeffMask[i][j]); 291 292 psArrayAdd (table, 100, row); 293 psFree (row); 294 } 295 } 296 297 if (!psFitsWriteTable (file->fits, header, table, "FP")) { 298 psError(PS_ERR_IO, false, "writing sky data\n"); 299 psFree(table); 300 psFree (header); 301 psFree (region); 302 return false; 303 } 304 305 psFree (table); 306 psFree (header); 307 psFree (region); 308 return true; 309 } 310 311 // second layer is the tangent plane 312 bool pmAstromWriteTP (pmFPAfile *file) { 313 314 bool status; 315 316 // get the boresite model parameters 317 float Xo = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.X0"); 318 float Yo = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.Y0"); 319 float RX = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.RX"); 320 float RY = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.RY"); 321 float To = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.T0"); 322 float Po = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.BORE.P0"); 323 float PosZero = psMetadataLookupF32 (&status, file->fpa->concepts, "FPA.POS_ZERO"); /// XXX be consistent with degrees v radians 324 char *refChip = psMetadataLookupStr (&status, file->fpa->concepts, "FPA.REF.CHIP"); 325 326 psMetadata *header = psMetadataAlloc(); 327 psMetadataAddStr(header, PS_LIST_TAIL, "COORD", PS_META_REPLACE, "name of this layer", "TANGENT_PLANE"); 328 psMetadataAddStr(header, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "SKY"); 329 psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region", "RECTANGLE"); 330 psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent", "PROJECTION"); 331 332 psArray *table = psArrayAllocEmpty (1); 333 psMetadata *row = psMetadataAlloc (); 334 psMetadataAddStr(row, PS_LIST_TAIL, "SEGMENT", PS_META_REPLACE, "name of this segment", "TANGENT_PLANE"); 335 psMetadataAddStr(row, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "SKY"); 336 337 psRegion *region = pmAstromFPAExtent (file->fpa); 338 psMetadataAddF32(row, PS_LIST_TAIL, "MINX", PS_META_REPLACE, "range", region->x0); 339 psMetadataAddF32(row, PS_LIST_TAIL, "MAXX", PS_META_REPLACE, "range", region->x1); 340 psMetadataAddF32(row, PS_LIST_TAIL, "MINY", PS_META_REPLACE, "range", region->y0); 341 psMetadataAddF32(row, PS_LIST_TAIL, "MAXY", PS_META_REPLACE, "range", region->y1); 342 343 // psMetadataAddF32(row, PS_LIST_TAIL, "XREF", PS_META_REPLACE, "", file->fpa->toSky->R * PM_DEG_RAD); 344 // psMetadataAddF32(row, PS_LIST_TAIL, "YREF", PS_META_REPLACE, "", file->fpa->toSky->D * PM_DEG_RAD); 345 346 psMetadataAddF32(row, PS_LIST_TAIL, "XSCALE", PS_META_REPLACE, "", file->fpa->toSky->Xs * PM_DEG_RAD); 347 psMetadataAddF32(row, PS_LIST_TAIL, "YSCALE", PS_META_REPLACE, "", file->fpa->toSky->Ys * PM_DEG_RAD); 348 psMetadataAddF32(row, PS_LIST_TAIL, "BORE_X0", PS_META_REPLACE, "boresite parameter", Xo); 349 psMetadataAddF32(row, PS_LIST_TAIL, "BORE_Y0", PS_META_REPLACE, "boresite parameter", Yo); 350 psMetadataAddF32(row, PS_LIST_TAIL, "BORE_RX", PS_META_REPLACE, "boresite parameter", RX); 351 psMetadataAddF32(row, PS_LIST_TAIL, "BORE_RY", PS_META_REPLACE, "boresite parameter", RY); 352 psMetadataAddF32(row, PS_LIST_TAIL, "BORE_T0", PS_META_REPLACE, "boresite parameter", To); 353 psMetadataAddF32(row, PS_LIST_TAIL, "BORE_P0", PS_META_REPLACE, "boresite parameter", Po); 354 psMetadataAddF32(row, PS_LIST_TAIL, "POS_ZERO", PS_META_REPLACE, "boresite parameter", PosZero); 355 psMetadataAddStr(row, PS_LIST_TAIL, "REF_CHIP", PS_META_REPLACE, "boresite parameter", refChip); 356 357 psArrayAdd (table, 100, row); 358 psFree (row); 359 360 if (!psFitsWriteTable (file->fits, header, table, "TP")) { 361 psError(PS_ERR_IO, false, "writing sky data\n"); 362 psFree (region); 363 psFree (table); 364 psFree (header); 365 return false; 366 } 367 368 psFree (region); 369 psFree (table); 370 psFree (header); 371 return (true); 372 } 373 374 // first layer is the sky 375 bool pmAstromWriteSky (pmFPAfile *file) { 376 377 psMetadata *header = psMetadataAlloc(); 378 psMetadataAddStr(header, PS_LIST_TAIL, "COORD", PS_META_REPLACE, "name of this layer", "SKY"); 379 psMetadataAddStr(header, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "NONE"); 380 psMetadataAddStr(header, PS_LIST_TAIL, "BOUNDARY", PS_META_REPLACE, "validity region", "NONE"); 381 psMetadataAddStr(header, PS_LIST_TAIL, "TRANSFRM", PS_META_REPLACE, "mapping to parent", "NONE"); 382 383 psArray *table = psArrayAllocEmpty (1); 384 psMetadata *row = psMetadataAlloc (); 385 psMetadataAddStr(row, PS_LIST_TAIL, "SEGMENT", PS_META_REPLACE, "name of this segment", "SKY"); 386 psMetadataAddStr(row, PS_LIST_TAIL, "PARENT", PS_META_REPLACE, "next layer up", "NONE"); 387 388 psArrayAdd (table, 100, row); 389 psFree (row); 390 391 if (!psFitsWriteTable (file->fits, header, table, "SKY")) { 392 psError(PS_ERR_IO, false, "writing sky data\n"); 393 psFree(table); 394 return false; 395 } 396 397 psFree (table); 398 psFree (header); 399 return (true); 359 400 } 360 401 … … 504 545 chip->toFPA->x->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_X"); 505 546 chip->toFPA->y->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_Y"); 547 chip->toFPA->x->coeffMask[ix][iy] = psMetadataLookupU8(&status, row, "MASK_X"); 548 chip->toFPA->y->coeffMask[ix][iy] = psMetadataLookupU8(&status, row, "MASK_Y"); 506 549 } 507 550 … … 509 552 for (int i = 0; i < file->fpa->chips->n; i++) { 510 553 pmChip *chip = file->fpa->chips->data[i]; 554 if (!chip->toFPA) continue; 511 555 psRegion *region = pmChipPixels (chip); 512 556 psFree (chip->fromFPA); … … 533 577 if (!header) psAbort("cannot read table header"); 534 578 535 // there is only one transformation in this table; the order is defined in the header 536 int nX = psMetadataLookupS32(&status, header, "NXORDER"); REQUIRE (status, "missing NXORDER"); 537 int nY = psMetadataLookupS32(&status, header, "NYORDER"); REQUIRE (status, "missing NYORDER"); 538 539 // allocate the new transformation 579 // free the old 540 580 psFree (file->fpa->toTPA); 541 file->fpa->toTPA = psPlaneTransformAlloc(nX, nY); 542 543 // free & DON'T allocate the new transformation fromTPA; this is created after the boresite 544 // is applied in pmAstromReadTP 545 psFree (file->fpa->fromTPA); 546 file->fpa->fromTPA = NULL; 581 file->fpa->toTPA = NULL; 547 582 548 583 // read the complete table data at one shot … … 553 588 for (int i = 0; i < table->n; i++) { 554 589 psMetadata *row = table->data[i]; 590 591 // there is only one transformation in this table; the order is defined in the header 592 int nX = psMetadataLookupS32(&status, row, "NXORDER"); REQUIRE (status, "missing NXORDER"); 593 int nY = psMetadataLookupS32(&status, row, "NYORDER"); REQUIRE (status, "missing NYORDER"); 594 if (file->fpa->toTPA == NULL) { 595 // allocate the new transformation 596 file->fpa->toTPA = psPlaneTransformAlloc(nX, nY); 597 } else { 598 REQUIRE (file->fpa->toTPA->x->nX == nX, "mismatch in chip order"); 599 REQUIRE (file->fpa->toTPA->x->nY == nY, "mismatch in chip order"); 600 REQUIRE (file->fpa->toTPA->y->nX == nX, "mismatch in chip order"); 601 REQUIRE (file->fpa->toTPA->y->nY == nY, "mismatch in chip order"); 602 } 603 555 604 int ix = psMetadataLookupS32(&status, row, "XORDER"); REQUIRE (status, "missing XORDER"); 556 605 int iy = psMetadataLookupS32(&status, row, "YORDER"); REQUIRE (status, "missing YORDER"); 557 file->fpa->toTPA->x->coeff[ix][iy] = psMetadataLookupF32(&status, row, "POLY_X"); REQUIRE (status, "missing POLY_X"); 558 file->fpa->toTPA->y->coeff[ix][iy] = psMetadataLookupF32(&status, row, "POLY_Y"); REQUIRE (status, "missing POLY_Y"); 559 file->fpa->toTPA->x->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_X"); REQUIRE (status, "missing ERROR_X"); 560 file->fpa->toTPA->y->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_Y"); REQUIRE (status, "missing ERROR_Y"); 561 } 606 file->fpa->toTPA->x->coeff[ix][iy] = psMetadataLookupF32(&status, row, "POLY_X"); REQUIRE (status, "missing POLY_X"); 607 file->fpa->toTPA->y->coeff[ix][iy] = psMetadataLookupF32(&status, row, "POLY_Y"); REQUIRE (status, "missing POLY_Y"); 608 file->fpa->toTPA->x->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_X"); REQUIRE (status, "missing ERROR_X"); 609 file->fpa->toTPA->y->coeffErr[ix][iy] = psMetadataLookupF32(&status, row, "ERROR_Y"); REQUIRE (status, "missing ERROR_Y"); 610 file->fpa->toTPA->x->coeffMask[ix][iy] = psMetadataLookupU8 (&status, row, "MASK_X"); REQUIRE (status, "missing MASK_X"); 611 file->fpa->toTPA->y->coeffMask[ix][iy] = psMetadataLookupU8 (&status, row, "MASK_Y"); REQUIRE (status, "missing MASK_Y"); 612 } 613 614 psRegion *region = pmAstromFPAExtent (file->fpa); 615 psFree (file->fpa->fromTPA); 616 file->fpa->fromTPA = psPlaneTransformInvert(NULL, file->fpa->toTPA, *region, 50); 562 617 563 618 psFree (table); 564 619 psFree (header); 565 return true; 566 } 620 psFree (region); 621 return true; 622 } 623 624 # define TRANSFER(TO,FROM,NAME) { \ 625 psMetadataItem *item = psMetadataLookup(FROM,NAME); \ 626 if (!item) psAbort ("cannot find %s", NAME); \ 627 psMetadataItem *newItem = psMetadataItemCopy(item); \ 628 if (!psMetadataAddItem(TO, newItem, PS_LIST_TAIL, PS_META_REPLACE)) { \ 629 psAbort ("cannot copy %s", NAME); \ 630 } \ 631 psFree (newItem); } 567 632 568 633 // third layer applies boresite corrections and converts tangent plane to sky 569 634 bool pmAstromReadTP (pmFPAfile *file) { 570 635 571 bool status;572 573 // these externally supplied values are used to set the final transformation terms574 double RA = psMetadataLookupF64 (&status, file->fpa->concepts, "FPA.RA"); REQUIRE (status, "missing FPA.RA");575 double DEC = psMetadataLookupF64 (&status, file->fpa->concepts, "FPA.DEC"); REQUIRE (status, "missing FPA.DEC");576 double POS = psMetadataLookupF64 (&status, file->fpa->concepts, "FPA.POSANGLE"); REQUIRE (status, "missing FPA.POSANGLE");577 double ROT = psMetadataLookupF64 (&status, file->fpa->concepts, "FPA.ROTANGLE"); REQUIRE (status, "missing FPA.ROTANGLE");578 579 636 if (!psFitsMoveExtName (file->fits, "TP")) { 580 637 psError(PS_ERR_IO, false, "missing TP extension in astrometry table\n"); … … 591 648 psMetadata *row = table->data[0]; 592 649 593 // get projection scale; center is supplied 594 float Xs = psMetadataLookupF32(&status, row, "XSCALE") * PM_RAD_DEG; REQUIRE (status, "missing XSCALE"); 595 float Ys = psMetadataLookupF32(&status, row, "YSCALE") * PM_RAD_DEG; REQUIRE (status, "missing YSCALE"); 596 597 // allocate a new toSky projection 598 psFree (file->fpa->toSky); 599 file->fpa->toSky = psProjectionAlloc (RA, DEC, Xs, Ys, PS_PROJ_WRP); 600 601 // get boresite correction terms. L,M,T define an ellipse along which the boresite travels 602 double R_L = psMetadataLookupF32(&status, row, "ROTATOR_L"); REQUIRE (status, "missing ROTATOR_L"); 603 double R_M = psMetadataLookupF32(&status, row, "ROTATOR_M"); REQUIRE (status, "missing ROTATOR_M"); 604 double R_T = psMetadataLookupF32(&status, row, "ROTATOR_T"); REQUIRE (status, "missing ROTATOR_T"); 605 606 // the position of the boresite on the ellipse is the ROTANGLE - ROT_ZERO 607 double R_0 = psMetadataLookupF32(&status, row, "ROT_ZERO"); REQUIRE (status, "missing ROT_ZERO"); 608 609 // find the current position of the boresite for this image 610 double Lo = R_L*cos(ROT - R_0)*cos(R_T) + R_M*sin(ROT - R_0)*sin(R_T); 611 double Mo = R_M*sin(ROT - R_0)*cos(R_T) - R_L*cos(ROT - R_0)*sin(R_T); 612 613 // apply new reference pixel to transformation 614 psPlaneTransform *tmpToTPA = psPlaneTransformSetCenter (NULL, file->fpa->toTPA, Lo, Mo); 615 psFree (file->fpa->toTPA); 616 617 // apply POSANGLE 618 double Po = psMetadataLookupF32(&status, row, "POS_ZERO"); REQUIRE (status, "missing POS_ZERO"); 619 file->fpa->toTPA = psPlaneTransformRotate (NULL, tmpToTPA, POS - Po); 620 psFree (tmpToTPA); 621 622 psRegion *region = pmAstromFPAExtent (file->fpa); 623 psFree (file->fpa->fromTPA); 624 file->fpa->fromTPA = psPlaneTransformInvert(NULL, file->fpa->toTPA, *region, 50); 625 626 psFree (region); 650 // move needed items to the concepts 651 TRANSFER (file->fpa->concepts, row, "XSCALE"); 652 TRANSFER (file->fpa->concepts, row, "XSCALE"); 653 TRANSFER (file->fpa->concepts, row, "YSCALE"); 654 TRANSFER (file->fpa->concepts, row, "BORE_X0"); 655 TRANSFER (file->fpa->concepts, row, "BORE_Y0"); 656 TRANSFER (file->fpa->concepts, row, "BORE_RX"); 657 TRANSFER (file->fpa->concepts, row, "BORE_RY"); 658 TRANSFER (file->fpa->concepts, row, "BORE_T0"); 659 TRANSFER (file->fpa->concepts, row, "BORE_P0"); 660 TRANSFER (file->fpa->concepts, row, "POS_ZERO"); 661 TRANSFER (file->fpa->concepts, row, "REF_CHIP"); 662 627 663 psFree (table); 628 664 psFree (header); … … 652 688 } 653 689 690 // third layer applies boresite corrections and converts tangent plane to sky 691 bool pmAstromSetTP (pmFPAfile *file, psMetadata *concepts) { 692 693 bool status; 694 695 // these externally supplied values are used to set the final transformation terms 696 double RA = psMetadataLookupF64 (&status, concepts, "FPA.RA"); REQUIRE (status, "missing FPA.RA"); 697 double DEC = psMetadataLookupF64 (&status, concepts, "FPA.DEC"); REQUIRE (status, "missing FPA.DEC"); 698 double POS = PM_RAD_DEG * psMetadataLookupF64 (&status, concepts, "FPA.POSANGLE"); REQUIRE (status, "missing FPA.POSANGLE"); 699 // double ROT = psMetadataLookupF64 (&status, concepts, "FPA.ROTANGLE"); REQUIRE (status, "missing FPA.ROTANGLE"); 700 701 // get projection scale; center is supplied 702 float Xs = psMetadataLookupF32(&status, file->fpa->concepts, "XSCALE") * PM_RAD_DEG; REQUIRE (status, "missing XSCALE"); 703 float Ys = psMetadataLookupF32(&status, file->fpa->concepts, "YSCALE") * PM_RAD_DEG; REQUIRE (status, "missing YSCALE"); 704 705 // allocate a new toSky projection using the reported position 706 psFree (file->fpa->toSky); 707 file->fpa->toSky = psProjectionAlloc (RA, DEC, Xs, Ys, PS_PROJ_WRP); 708 709 // get boresite correction terms. RX,RY,To,Po define an ellipse along which the boresite travels 710 double Xo = psMetadataLookupF32(&status, file->fpa->concepts, "BORE_X0"); REQUIRE (status, "missing "); 711 double Yo = psMetadataLookupF32(&status, file->fpa->concepts, "BORE_Y0"); REQUIRE (status, "missing "); 712 double RX = psMetadataLookupF32(&status, file->fpa->concepts, "BORE_RX"); REQUIRE (status, "missing "); 713 double RY = psMetadataLookupF32(&status, file->fpa->concepts, "BORE_RY"); REQUIRE (status, "missing "); 714 double To = psMetadataLookupF32(&status, file->fpa->concepts, "BORE_T0"); REQUIRE (status, "missing "); 715 double Po = psMetadataLookupF32(&status, file->fpa->concepts, "BORE_P0"); REQUIRE (status, "missing "); 716 717 // the true rotation of the instrument is POSANGLE - POS_ZERO 718 double PosZero = PM_RAD_DEG * psMetadataLookupF32(&status, file->fpa->concepts, "POS_ZERO"); REQUIRE (status, "missing POS_ZERO"); 719 char *refChip = psMetadataLookupStr(&status, file->fpa->concepts, "REF_CHIP"); REQUIRE (status, "missing REF_CHIP"); 720 721 // apply true posangle = -(POS - POS_ZERO) 722 psPlaneTransform *fromTPA = psPlaneTransformRotate (NULL, file->fpa->fromTPA, (POS - PosZero)); 723 psFree (file->fpa->fromTPA); 724 file->fpa->fromTPA = fromTPA; 725 726 psRegion *region = pmAstromFPAExtent (file->fpa); 727 psFree (file->fpa->toTPA); 728 file->fpa->toTPA = psPlaneTransformInvert(NULL, file->fpa->fromTPA, *region, 50); 729 730 // current position of the nominal boresite in refChip coordinates 731 double X = Xo + RX*cos(POS - To)*cos(Po) + RY*sin(POS - To)*sin(Po); 732 double Y = Yo + RY*sin(POS - To)*cos(Po) - RX*cos(POS - To)*sin(Po); 733 734 // get reference chip from name 735 pmChip *chip = pmConceptsChipFromName (file->fpa, refChip); 736 if (!chip) psAbort ("invalid chip name for reference"); 737 738 psPlane *boreCH = psPlaneAlloc(); 739 psPlane *boreFP = psPlaneAlloc(); 740 psPlane *boreTP = psPlaneAlloc(); 741 psSphere *boreSky = psSphereAlloc(); 742 743 // find the true RA,DEC coord of the mirror of the reported boresite 744 boreCH->x = -X; 745 boreCH->y = -Y; 746 psPlaneTransformApply (boreFP, chip->toFPA, boreCH); 747 psPlaneTransformApply (boreTP, file->fpa->toTPA, boreFP); 748 psDeproject (boreSky, boreTP, file->fpa->toSky); 749 750 // modify the projection to account for offset between true and reported boresite 751 file->fpa->toSky->R = boreSky->r; 752 file->fpa->toSky->D = boreSky->d; 753 754 psFree (boreCH); 755 psFree (boreFP); 756 psFree (boreTP); 757 psFree (boreSky); 758 759 psFree (region); 760 return (true); 761 } 762
Note:
See TracChangeset
for help on using the changeset viewer.
