00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033
00034 #include <cpl.h>
00035 #include <math.h>
00036
00037 #include "vircam_wcsutils.h"
00038 #include "vircam_pfits.h"
00039 #include "vircam_utils.h"
00040
00041 #define WCS_FATAL_ERR(_p) {cpl_msg_error(fctid,"Unable to find keyword %s",_p); cpl_error_reset(); return(wcs);}
00042
00043
00044
00045 #define NNOTABKEYS 6
00046 static const char *notabkeys[NNOTABKEYS] = {"^CRVAL[1-2]*$","^CRPIX[1-2]*",
00047 "^CD[1-2]*_[1-2]*","^CDELT[1-2]*",
00048 "^CTYPE[1-2]*","^PV2_[1-5]*"};
00049
00050
00051
00052 #define NWCSKEYS 15
00053 static const char *vir_wcskeys[NWCSKEYS] = {"CTYPE1","CTYPE2","CRVAL1",
00054 "CRVAL2","CRPIX1","CRPIX2","CD1_1",
00055 "CD1_2","CD2_1","CD2_2","PV2_1",
00056 "PV2_2","PV2_3","PV2_4","PV2_5"};
00057
00058 #define SZKEY 9
00059
00075
00101
00102
00103 extern void vircam_xytoradec(cpl_wcs *wcs, double x, double y, double *ra,
00104 double *dec) {
00105 double *xy,*radec;
00106 cpl_matrix *from,*to;
00107 cpl_array *status;
00108 int stat;
00109
00110
00111
00112 from = cpl_matrix_new(1,2);
00113 xy = cpl_matrix_get_data(from);
00114 xy[0] = x;
00115 xy[1] = y;
00116
00117
00118
00119 cpl_wcs_convert(wcs,from,&to,&status,CPL_WCS_PHYS2WORLD);
00120
00121
00122
00123 radec = cpl_matrix_get_data(to);
00124 *ra = radec[0];
00125 *dec = radec[1];
00126
00127
00128
00129 cpl_matrix_delete(from);
00130 cpl_matrix_delete(to);
00131 cpl_array_delete(status);
00132 return;
00133 }
00134
00135
00160
00161
00162 extern void vircam_radectoxy(cpl_wcs *wcs, double ra, double dec, double *x,
00163 double *y) {
00164 double *xy,*radec;
00165 cpl_matrix *from,*to;
00166 cpl_array *status;
00167 int stat;
00168
00169
00170
00171 from = cpl_matrix_new(1,2);
00172 radec = cpl_matrix_get_data(from);
00173 radec[0] = ra;
00174 radec[1] = dec;
00175
00176
00177
00178 cpl_wcs_convert(wcs,from,&to,&status,CPL_WCS_WORLD2PHYS);
00179
00180
00181
00182 xy = cpl_matrix_get_data(to);
00183 *x = xy[0];
00184 *y = xy[1];
00185
00186
00187
00188 cpl_matrix_delete(from);
00189 cpl_matrix_delete(to);
00190 cpl_array_delete(status);
00191 }
00192
00193
00219
00220
00221 extern void vircam_radectoxieta(cpl_wcs *wcs, double ra, double dec,
00222 double *xi, double *eta) {
00223
00224 double *xy,*radec;
00225 cpl_matrix *from,*to;
00226 cpl_array *status;
00227 int stat;
00228
00229
00230
00231 from = cpl_matrix_new(1,2);
00232 radec = cpl_matrix_get_data(from);
00233 radec[0] = ra;
00234 radec[1] = dec;
00235
00236
00237
00238 cpl_wcs_convert(wcs,from,&to,&status,CPL_WCS_WORLD2STD);
00239
00240
00241
00242 xy = cpl_matrix_get_data(to);
00243 *xi = xy[0]/DEGRAD;
00244 *eta = xy[1]/DEGRAD;
00245
00246
00247
00248 cpl_matrix_delete(from);
00249 cpl_matrix_delete(to);
00250 cpl_array_delete(status);
00251 }
00252
00253
00284
00285
00286 extern int vircam_coverage(cpl_propertylist *plist, int fudge, double *ra1,
00287 double *ra2, double *dec1, double *dec2,
00288 int *status) {
00289
00290 cpl_wcs *wcs;
00291 double ra,dec,x,y,dra,ddec,boxfudge,min_4q,max_1q;
00292 int first_quad,fourth_quad,*naxes;
00293 long i,j;
00294 cpl_array *a;
00295
00296
00297
00298 *ra1 = 0.0;
00299 *ra2 = 0.0;
00300 *dec1 = 0.0;
00301 *dec2 = 0.0;
00302 if (*status != VIR_OK)
00303 return(*status);
00304
00305
00306
00307 wcs = cpl_wcs_new_from_propertylist(plist);
00308 if (wcs == NULL)
00309 FATAL_ERROR
00310
00311
00312
00313 a = cpl_wcs_get_image_dims(wcs);
00314 naxes = cpl_array_get_data_int(a);
00315
00316
00317
00318 *ra1 = 370.0;
00319 *ra2 = -370.0;
00320 *dec1 = 95.0;
00321 *dec2 = -95.0;
00322 first_quad = 0;
00323 fourth_quad = 0;
00324 min_4q = 370.0;
00325 max_1q = 0.0;
00326 for (j = 1; j < naxes[1]; j += 10) {
00327 j = min(j,naxes[1]);
00328 y = (double)j;
00329 for (i = 1; i < naxes[0]; i += 10) {
00330 i = min(i,naxes[0]);
00331 x = (double)i;
00332 vircam_xytoradec(wcs,x,y,&ra,&dec);
00333 if (ra >= 0.0 && ra <= 90.0) {
00334 first_quad = 1;
00335 max_1q = max(ra,max_1q);
00336 } else if (ra >= 270.0 && ra <= 360.0) {
00337 fourth_quad = 1;
00338 min_4q = min((ra-360.0),min_4q);
00339 }
00340 *ra1 = min(*ra1,ra);
00341 *ra2 = max(*ra2,ra);
00342 *dec1 = min(*dec1,dec);
00343 *dec2 = max(*dec2,dec);
00344 }
00345 }
00346 cpl_wcs_delete(wcs);
00347
00348
00349
00350
00351
00352
00353 if (first_quad && fourth_quad) {
00354 *ra1 = min_4q;
00355 *ra2 = max_1q;
00356 }
00357
00358
00359
00360 if (fudge) {
00361 boxfudge = 0.01*(float)fudge;
00362 dra = 0.5*boxfudge*(*ra2 - *ra1);
00363 *ra1 -= dra;
00364 *ra2 += dra;
00365 ddec = 0.5*boxfudge*(*dec2 - *dec1);
00366 *dec1 -= ddec;
00367 *dec2 += ddec;
00368 }
00369
00370
00371
00372 GOOD_STATUS
00373 }
00374
00375
00401
00402
00403 extern int vircam_crpixshift(cpl_propertylist *p, double scalefac,
00404 double sh[]) {
00405 int i;
00406 double val;
00407 char key[SZKEY];
00408 cpl_type type;
00409 const char *fctid = "vircam_crpixshift";
00410
00411
00412
00413 if (scalefac == 0.0) {
00414 cpl_msg_error(fctid,"Scale factor is zero!");
00415 return(VIR_FATAL);
00416 }
00417
00418
00419
00420 for (i = 1; i <= 2; i++) {
00421 snprintf(key,SZKEY,"CRPIX%d",i);
00422
00423
00424
00425 if (cpl_propertylist_has(p,key) == 0) {
00426 cpl_msg_error(fctid,"Header is missing WCS key %s",key);
00427 return(VIR_FATAL);
00428 }
00429
00430
00431
00432 type = cpl_propertylist_get_type(p,key);
00433
00434
00435
00436
00437 switch (type) {
00438 case CPL_TYPE_FLOAT:
00439 val = (double)cpl_propertylist_get_float(p,key);
00440 break;
00441 case CPL_TYPE_DOUBLE:
00442 val = cpl_propertylist_get_double(p,key);
00443 break;
00444 default:
00445 cpl_msg_error(fctid,"Header has WCS key %s as non-floating point!",
00446 key);
00447 return(VIR_FATAL);
00448 }
00449
00450
00451
00452 val = (val - sh[i-1])/scalefac - 1.0;
00453
00454
00455
00456 switch (type) {
00457 case CPL_TYPE_FLOAT:
00458 cpl_propertylist_update_float(p,key,(float)val);
00459 break;
00460 case CPL_TYPE_DOUBLE:
00461 cpl_propertylist_update_double(p,key,val);
00462 break;
00463 default:
00464 break;
00465 }
00466 }
00467 return(VIR_OK);
00468 }
00469
00470
00492
00493
00494 extern int vircam_rescalecd(cpl_propertylist *p, double scalefac) {
00495 int i,j;
00496 cpl_type type;
00497 char key[SZKEY];
00498 const char *fctid = "vircam_rescalecd";
00499 double val;
00500
00501
00502
00503 if (scalefac == 0.0) {
00504 cpl_msg_error(fctid,"Scale factor is zero!");
00505 return(VIR_FATAL);
00506 }
00507
00508
00509
00510 for (i = 1; i <= 2; i++) {
00511 for (j = 1; j <= 2; j++) {
00512 snprintf(key,SZKEY,"CD%d_%d",i,j);
00513
00514
00515
00516 if (cpl_propertylist_has(p,key) == 0) {
00517 cpl_msg_error(fctid,"Header is missing WCS key %s",key);
00518 return(VIR_FATAL);
00519 }
00520
00521
00522
00523 type = cpl_propertylist_get_type(p,key);
00524
00525
00526
00527
00528 switch (type) {
00529 case CPL_TYPE_FLOAT:
00530 val = (double)cpl_propertylist_get_float(p,key);
00531 break;
00532 case CPL_TYPE_DOUBLE:
00533 val = cpl_propertylist_get_double(p,key);
00534 break;
00535 default:
00536 cpl_msg_error(fctid,"Header has WCS key %s as non-floating point!",
00537 key);
00538 return(VIR_FATAL);
00539 }
00540
00541
00542
00543 val *= scalefac;
00544
00545
00546
00547 switch (type) {
00548 case CPL_TYPE_FLOAT:
00549 cpl_propertylist_update_float(p,key,(float)val);
00550 break;
00551 case CPL_TYPE_DOUBLE:
00552 cpl_propertylist_update_double(p,key,val);
00553 break;
00554 default:
00555 break;
00556 }
00557 }
00558 }
00559 return(VIR_OK);
00560 }
00561
00562
00588
00589
00590 extern int vircam_diffxywcs(cpl_wcs *wcs, cpl_wcs *wcsref, float *xoff,
00591 float *yoff, int *status) {
00592 double xc,yc,ra,dec,xnew,ynew;
00593 cpl_array *a;
00594 int *dims;
00595 const char *fctid = "vircam_diffxywcs";
00596
00597
00598
00599 *xoff = 0.0;
00600 *yoff = 0.0;
00601 if (*status != VIR_OK)
00602 return(*status);
00603
00604
00605
00606 if (wcs == NULL || wcsref == NULL) {
00607 cpl_msg_error(fctid,"NULL wcs information");
00608 FATAL_ERROR
00609 }
00610
00611
00612
00613 a = cpl_wcs_get_image_dims(wcsref);
00614 dims = cpl_array_get_data_int(a);
00615 xc = 0.5*(double)dims[0];
00616 yc = 0.5*(double)dims[1];
00617 vircam_xytoradec(wcsref,xc,yc,&ra,&dec);
00618
00619
00620
00621
00622 vircam_radectoxy(wcs,ra,dec,&xnew,&ynew);
00623
00624
00625
00626 *xoff = (float)(xc - xnew);
00627 *yoff = (float)(yc - ynew);
00628 GOOD_STATUS
00629 }
00630
00631
00651
00652
00653 extern int vircam_removewcs(cpl_propertylist *p, int *status) {
00654 int i;
00655 const char *fctid = "vircam_removewcs";
00656
00657
00658
00659 if (*status != VIR_OK)
00660 return(*status);
00661 if (p == NULL) {
00662 cpl_msg_error(fctid,"Propertylist passed is NULL\nProgramming error");
00663 FATAL_ERROR
00664 }
00665
00666
00667
00668 for (i = 0; i < NNOTABKEYS; i++)
00669 cpl_propertylist_erase_regexp(p,notabkeys[i],0);
00670
00671 GOOD_STATUS
00672 }
00673
00674
00699
00700
00701 extern int vircam_tabwcs(cpl_propertylist *p, int xcol, int ycol,
00702 int *status) {
00703 int i;
00704 char key[9],key2[9],*fctid="vircam_tabwcs";
00705
00706
00707
00708 if (*status != VIR_OK)
00709 return(*status);
00710 if (p == NULL) {
00711 cpl_msg_error(fctid,"Propertylist passed is NULL\nProgramming error");
00712 FATAL_ERROR
00713 }
00714
00715
00716
00717
00718 if (xcol == -1 || ycol == -1) {
00719 vircam_removewcs(p,status);
00720 GOOD_STATUS
00721 }
00722
00723
00724
00725
00726 (void)snprintf(key,8,"TCTYP%d",xcol);
00727 vircam_rename_property(p,"CTYPE1",key);
00728 (void)snprintf(key,8,"TCTYP%d",ycol);
00729 vircam_rename_property(p,"CTYPE2",key);
00730
00731
00732
00733
00734 (void)snprintf(key,8,"TCRVL%d",xcol);
00735 vircam_rename_property(p,"CRVAL1",key);
00736 (void)snprintf(key,8,"TCRVL%d",ycol);
00737 vircam_rename_property(p,"CRVAL2",key);
00738
00739
00740
00741 (void)snprintf(key,8,"TCRPX%d",xcol);
00742 vircam_rename_property(p,"CRPIX1",key);
00743 (void)snprintf(key,8,"TCRPX%d",ycol);
00744 vircam_rename_property(p,"CRPIX2",key);
00745
00746
00747
00748 for (i = 1; i <= 5; i++) {
00749 (void)snprintf(key2,8,"PV2_%d",i);
00750 (void)snprintf(key,8,"TV%d_%d",ycol,i);
00751 if (cpl_propertylist_has(p,key2))
00752 vircam_rename_property(p,key2,key);
00753 }
00754
00755
00756
00757 (void)snprintf(key,8,"TC%d_%d",xcol,xcol);
00758 vircam_rename_property(p,"CD1_1",key);
00759 (void)snprintf(key,8,"TC%d_%d",xcol,ycol);
00760 vircam_rename_property(p,"CD1_2",key);
00761 (void)snprintf(key,8,"TC%d_%d",ycol,xcol);
00762 vircam_rename_property(p,"CD2_1",key);
00763 (void)snprintf(key,8,"TC%d_%d",ycol,ycol);
00764 vircam_rename_property(p,"CD2_2",key);
00765
00766
00767
00768 GOOD_STATUS
00769
00770 }
00771
00772
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864