Changeset 10594
- Timestamp:
- Dec 8, 2006, 5:02:02 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psastro/src/psastroWCS.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psastro/src/psastroWCS.c
r10513 r10594 213 213 // techinically, we can have a plate scale here (toTPA:dx,dy != 1) 214 214 if (!psPlaneDistortIsIdentity (toTPA)) psAbort ("psastro", "invalid TPA transformation"); 215 216 // XXX require toFPA->x->nX == toFPA->x->nY 217 // XXX require toFPA->y->nX == toFPA->y->nY 218 // XXX require toFPA->x->nX == toFPA->y->nX 219 // XXX require toFPA->nX == 1,2,3 215 220 216 221 switch (toSky->type) { … … 241 246 // XXX need to handle the plateScale 242 247 243 // solve for CDELT1,2: 244 cdelt1 = toSky->Xs*DEG_RAD*toTPA->x->coeff[1][0][0][0]; 245 cdelt2 = toSky->Ys*DEG_RAD*toTPA->y->coeff[0][1][0][0]; 248 /* discussion of the coord transformations: 249 X,Y: coord on a chip in pixels 250 L,M: coord on the focal plane (pixels) 251 P,Q: coord in the tangent plane (microns or mm?) 252 R,D: coord on the sky 253 254 this function creates WCS terms which convert directly from chip to sky. 255 this function requires a linear, unrotated toTPA distortion term 256 toTPA->x,y->coeff[1][0],[0][1] defines the detector scale (microns / pixel) 257 tpSky->Xs,Ys defines the plate scale (radians / micron) 258 */ 259 260 // solve for CDELT1,2 (degrees / pixel) 261 cdelt1 = DEG_RAD*toSky->Xs*toTPA->x->coeff[1][0][0][0]; 262 cdelt2 = DEG_RAD*toSky->Ys*toTPA->y->coeff[0][1][0][0]; 246 263 247 264 // L,M = toFPA(X,Y) 248 265 // solve for CRPIX1,2 (Xo,Yo) : L,M(Xo,Yo) = 0,0 266 249 267 // linear solution for Xo,Yo: 250 R = (xsum[1][0]*ysum[0][1] - xsum[0][1]*ysum[1][0]); 251 Xo = det*(ysum[0][0]*xsum[0][1] - xsum[0][0]*ysum[0][1]); 252 Yo = det*(xsum[0][0]*ysum[1][0] - ysum[0][0]*xsum[1][0]); 253 254 if ( 255 # endif 268 xcoeff = toFPA->x->coeff; 269 ycoeff = toFPA->y->coeff; 270 R = (xcoeff[1][0]*ycoeff[0][1] - xcoeff[0][1]*ycoeff[1][0]); 271 Xo = det*(ycoeff[0][0]*xcoeff[0][1] - xcoeff[0][0]*ycoeff[0][1]); 272 Yo = det*(xcoeff[0][0]*ycoeff[1][0] - ycoeff[0][0]*xcoeff[1][0]); 273 274 if (toFPA->x->nX > 1) { 275 276 psPolynomial2D *XdX = psPolynomial2D_dX(toFPA->x); 277 psPolynomial2D *XdY = psPolynomial2D_dY(toFPA->x); 278 279 psPolynomial2D *YdX = psPolynomial2D_dX(toFPA->y); 280 psPolynomial2D *YdY = psPolynomial2D_dY(toFPA->y); 281 282 psImage *Alpha = psImageAlloc (2, 2, PS_DATA_F32); 283 psVector *Beta = psVectorAlloc (2, PS_DATA_F32); 284 285 // XXX this loop is rather arbitrary in length... 286 for (int i = 0; i < 10; i++) { 287 // NOTE: order is: [y][x] 288 Alpha->data.F32[0][0] = psPolynomial2DEval (XdX, Xo, Yo); 289 Alpha->data.F32[1][0] = psPolynomial2DEval (XdY, Xo, Yo); 290 Alpha->data.F32[0][1] = psPolynomial2DEval (YdX, Xo, Yo); 291 Alpha->data.F32[1][1] = psPolynomial2DEval (YdY, Xo, Yo); 292 293 Beta->data.F32[0] = psPolynomial2DEval (toFPA->x, Xo, Yo); 294 Beta->data.F32[1] = psPolynomial2DEval (toFPA->y, Xo, Yo); 295 296 psMatrixGJSolveF32 (Alpha, Beta); 297 298 Xo += Beta->data.F32[0]; 299 Yo += Beta->data.F32[1]; 300 } 301 } 302 psMetadataAddF32 (header, PS_LIST_TAIL, "CRPIX1", PS_META_REPLACE, "", Xo); 303 psMetadataAddF32 (header, PS_LIST_TAIL, "CRPIX2", PS_META_REPLACE, "", Yo); 304 305 switch (toFPA->x->nX) { 306 307 case 1: 308 /* the linear solution can be analytically inverted */ 309 pc1_1 = xcoeff[1][0] / cdelt1; 310 pc1_2 = xcoeff[0][1] / cdelt2; 311 pc2_1 = ycoeff[1][0] / cdelt1; 312 pc2_2 = ycoeff[0][1] / cdelt2; 313 314 case 2: 315 a10 = xcoeff[1][0] + 2.0*xcoeff[2][0]*Xo + xcoeff[1][1]*Yo; 316 a01 = xcoeff[0][1] + 2.0*xcoeff[0][2]*Yo + xcoeff[1][1]*Xo; 317 a11 = xcoeff[1][1]; 318 a20 = xcoeff[2][0]; 319 a02 = xcoeff[0][2]; 320 321 b10 = ycoeff[1][0] + 2.0*ycoeff[2][0]*Xo + ycoeff[1][1]*Yo; 322 b01 = ycoeff[0][1] + 2.0*ycoeff[0][2]*Yo + ycoeff[1][1]*Xo; 323 b20 = ycoeff[2][0]; 324 b11 = ycoeff[1][1]; 325 b02 = ycoeff[0][2]; 326 327 coords[0].pc1_1 = a10 / coords[0].cdelt1; 328 coords[0].pc1_2 = a01 / coords[0].cdelt2; 329 coords[0].pc2_1 = b10 / coords[0].cdelt1; 330 coords[0].pc2_2 = b01 / coords[0].cdelt2; 331 332 coords[0].polyterms[0][0] = a20 / SQ(coords[0].cdelt1); 333 coords[0].polyterms[1][0] = a11 / (coords[0].cdelt1*coords[0].cdelt2); 334 coords[0].polyterms[2][0] = a02 / SQ(coords[0].cdelt2); 335 336 coords[0].polyterms[0][1] = b20 / SQ(coords[0].cdelt1); 337 coords[0].polyterms[1][1] = b11 / (coords[0].cdelt1*coords[0].cdelt2); 338 coords[0].polyterms[2][1] = b02 / SQ(coords[0].cdelt2); 339 for (i = 3; i < 7; i++) { 340 coords[0].polyterms[i][0] = coords[0].polyterms[i][1] = 0.0; 341 } 342 break; 343 344 case 3: 345 a10 = xcoeff[1][0] + 2*xcoeff[2][0]*Xo + xcoeff[1][1]*Yo + 3*xcoeff[3][0]*Xo*Xo + 2*xcoeff[2][1]*Xo*Yo + xcoeff[1][2]*Yo*Yo; 346 a01 = xcoeff[0][1] + 2*xcoeff[0][2]*Yo + xcoeff[1][1]*Xo + 3*xcoeff[0][3]*Yo*Yo + 2*xcoeff[1][2]*Xo*Yo + xcoeff[2][1]*Xo*Xo; 347 a20 = xcoeff[2][0] + 3*xcoeff[3][0]*Xo + xcoeff[2][1]*Yo; 348 a11 = xcoeff[1][1] + 2*xcoeff[2][1]*Xo + 2*xcoeff[1][2]*Yo; 349 a02 = xcoeff[0][2] + 3*xcoeff[0][3]*Yo + xcoeff[1][2]*Xo; 350 a30 = xcoeff[3][0]; 351 a21 = xcoeff[2][1]; 352 a12 = xcoeff[1][2]; 353 a03 = xcoeff[0][3]; 354 355 b10 = ycoeff[1][0] + 2*ycoeff[2][0]*Xo + ycoeff[1][1]*Yo + 3*ycoeff[3][0]*Xo*Xo + 2*ycoeff[2][1]*Xo*Yo + ycoeff[1][2]*Yo*Yo; 356 b01 = ycoeff[0][1] + 2*ycoeff[0][2]*Yo + ycoeff[1][1]*Xo + 3*ycoeff[0][3]*Yo*Yo + 2*ycoeff[1][2]*Xo*Yo + ycoeff[2][1]*Xo*Xo; 357 b20 = ycoeff[2][0] + 3*ycoeff[3][0]*Xo + ycoeff[2][1]*Yo; 358 b11 = ycoeff[1][1] + 2*ycoeff[2][1]*Xo + 2*ycoeff[1][2]*Yo; 359 b02 = ycoeff[0][2] + 3*ycoeff[0][3]*Yo + ycoeff[1][2]*Xo; 360 b30 = ycoeff[3][0]; 361 b21 = ycoeff[2][1]; 362 b12 = ycoeff[1][2]; 363 b03 = ycoeff[0][3]; 364 365 coords[0].pc1_1 = a10 / coords[0].cdelt1; 366 coords[0].pc1_2 = a01 / coords[0].cdelt2; 367 coords[0].pc2_1 = b10 / coords[0].cdelt1; 368 coords[0].pc2_2 = b01 / coords[0].cdelt2; 369 370 coords[0].polyterms[0][0] = a20 / SQ(coords[0].cdelt1); 371 coords[0].polyterms[1][0] = a11 / (coords[0].cdelt1*coords[0].cdelt2); 372 coords[0].polyterms[2][0] = a02 / SQ(coords[0].cdelt2); 373 374 coords[0].polyterms[3][0] = a30 / (SQ(coords[0].cdelt1)*coords[0].cdelt1); 375 coords[0].polyterms[4][0] = a21 / (SQ(coords[0].cdelt1)*coords[0].cdelt2); 376 coords[0].polyterms[5][0] = a12 / (SQ(coords[0].cdelt2)*coords[0].cdelt1); 377 coords[0].polyterms[6][0] = a03 / (SQ(coords[0].cdelt2)*coords[0].cdelt2); 378 379 coords[0].polyterms[0][1] = b20 / SQ(coords[0].cdelt1); 380 coords[0].polyterms[1][1] = b11 / (coords[0].cdelt1*coords[0].cdelt2); 381 coords[0].polyterms[2][1] = b02 / SQ(coords[0].cdelt2); 382 383 coords[0].polyterms[3][1] = b30 / (SQ(coords[0].cdelt1)*coords[0].cdelt1); 384 coords[0].polyterms[4][1] = b21 / (SQ(coords[0].cdelt1)*coords[0].cdelt2); 385 coords[0].polyterms[5][1] = b12 / (SQ(coords[0].cdelt2)*coords[0].cdelt1); 386 coords[0].polyterms[6][1] = b03 / (SQ(coords[0].cdelt2)*coords[0].cdelt2); 387 break; 388 389 default: 390 fprintf (stderr, "error: invalid order %d\n", coords[0].Npolyterms); 391 exit (2); 392 } 393 394 while (coords[0].crval1 < 0) coords[0].crval1 += 360.0; 395 while (coords[0].crval1 > 360.0) coords[0].crval1 -= 360.0; 396 397 398 # else 256 399 257 400 psMetadataAddF32 (header, PS_LIST_TAIL, "CRVAL1", PS_META_REPLACE, "", toSky->R*DEG_RAD); … … 266 409 psMetadataAddF32 (header, PS_LIST_TAIL, "PC002001", PS_META_REPLACE, "", toFPA->y->coeff[1][0]/plateScale); 267 410 psMetadataAddF32 (header, PS_LIST_TAIL, "PC002002", PS_META_REPLACE, "", toFPA->y->coeff[0][1]/plateScale); 411 412 # endif 268 413 269 414 // alternative representations use
Note:
See TracChangeset
for help on using the changeset viewer.
