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 SZKEY 9
00046 #define NNOTABKEYS 6
00047 static const char *notabkeys[NNOTABKEYS] = {"^CRVAL[1-2]*$","^CRPIX[1-2]*",
00048 "^CD[1-2]*_[1-2]*","^CDELT[1-2]*",
00049 "^CTYPE[1-2]*","^PV2_[1-5]*"};
00050
00066
00092
00093
00094 extern void vircam_xytoradec(cpl_wcs *wcs, double x, double y, double *ra,
00095 double *dec) {
00096 double *xy,*radec;
00097 cpl_matrix *from,*to;
00098 cpl_array *status;
00099
00100
00101
00102 from = cpl_matrix_new(1,2);
00103 xy = cpl_matrix_get_data(from);
00104 xy[0] = x;
00105 xy[1] = y;
00106
00107
00108
00109 cpl_wcs_convert(wcs,from,&to,&status,CPL_WCS_PHYS2WORLD);
00110
00111
00112
00113 radec = cpl_matrix_get_data(to);
00114 *ra = radec[0];
00115 *dec = radec[1];
00116
00117
00118
00119 cpl_matrix_delete(from);
00120 cpl_matrix_delete(to);
00121 cpl_array_delete(status);
00122 return;
00123 }
00124
00125
00150
00151
00152 extern void vircam_radectoxy(cpl_wcs *wcs, double ra, double dec, double *x,
00153 double *y) {
00154 double *xy,*radec;
00155 cpl_matrix *from,*to;
00156 cpl_array *status;
00157
00158
00159
00160 from = cpl_matrix_new(1,2);
00161 radec = cpl_matrix_get_data(from);
00162 radec[0] = ra;
00163 radec[1] = dec;
00164
00165
00166
00167 cpl_wcs_convert(wcs,from,&to,&status,CPL_WCS_WORLD2PHYS);
00168
00169
00170
00171 xy = cpl_matrix_get_data(to);
00172 *x = xy[0];
00173 *y = xy[1];
00174
00175
00176
00177 cpl_matrix_delete(from);
00178 cpl_matrix_delete(to);
00179 cpl_array_delete(status);
00180 }
00181
00182
00208
00209
00210 extern void vircam_radectoxieta(cpl_wcs *wcs, double ra, double dec,
00211 double *xi, double *eta) {
00212
00213 double *xy,*radec;
00214 cpl_matrix *from,*to;
00215 cpl_array *status;
00216
00217
00218
00219 from = cpl_matrix_new(1,2);
00220 radec = cpl_matrix_get_data(from);
00221 radec[0] = ra;
00222 radec[1] = dec;
00223
00224
00225
00226 cpl_wcs_convert(wcs,from,&to,&status,CPL_WCS_WORLD2STD);
00227
00228
00229
00230 xy = cpl_matrix_get_data(to);
00231 *xi = xy[0]/DEGRAD;
00232 *eta = xy[1]/DEGRAD;
00233
00234
00235
00236 cpl_matrix_delete(from);
00237 cpl_matrix_delete(to);
00238 cpl_array_delete(status);
00239 }
00240
00241
00272
00273
00274 extern int vircam_coverage(cpl_propertylist *plist, int fudge, double *ra1,
00275 double *ra2, double *dec1, double *dec2,
00276 int *status) {
00277
00278 cpl_wcs *wcs;
00279 double ra,dec,x,y,dra,ddec,boxfudge,min_4q,max_1q;
00280 int first_quad,fourth_quad,ni,nj,istep;
00281 const int *naxes;
00282 long i,j;
00283 const cpl_array *a;
00284
00285
00286
00287 *ra1 = 0.0;
00288 *ra2 = 0.0;
00289 *dec1 = 0.0;
00290 *dec2 = 0.0;
00291 if (*status != VIR_OK)
00292 return(*status);
00293
00294
00295
00296 wcs = cpl_wcs_new_from_propertylist(plist);
00297 if (wcs == NULL)
00298 FATAL_ERROR
00299
00300
00301
00302 a = cpl_wcs_get_image_dims(wcs);
00303 naxes = cpl_array_get_data_int_const(a);
00304
00305
00306
00307 *ra1 = 370.0;
00308 *ra2 = -370.0;
00309 *dec1 = 95.0;
00310 *dec2 = -95.0;
00311 first_quad = 0;
00312 fourth_quad = 0;
00313 min_4q = 370.0;
00314 max_1q = 0.0;
00315 istep = 10;
00316 nj = naxes[1]/istep + 2;
00317 ni = naxes[0]/istep + 2;
00318 for (j = 1; j <= nj; j++) {
00319 y = (double)min(naxes[1],(istep*(j-1)+1));
00320 for (i = 1; i <= ni; i++) {
00321 x = (double)min(naxes[0],(istep*(i-1)+1));
00322 vircam_xytoradec(wcs,x,y,&ra,&dec);
00323 if (ra >= 0.0 && ra <= 90.0) {
00324 first_quad = 1;
00325 max_1q = max(ra,max_1q);
00326 } else if (ra >= 270.0 && ra <= 360.0) {
00327 fourth_quad = 1;
00328 min_4q = min((ra-360.0),min_4q);
00329 }
00330 *ra1 = min(*ra1,ra);
00331 *ra2 = max(*ra2,ra);
00332 *dec1 = min(*dec1,dec);
00333 *dec2 = max(*dec2,dec);
00334 }
00335 }
00336 cpl_wcs_delete(wcs);
00337
00338
00339
00340
00341
00342
00343 if (first_quad && fourth_quad) {
00344 *ra1 = min_4q;
00345 *ra2 = max_1q;
00346 }
00347
00348
00349
00350 if (fudge) {
00351 boxfudge = 0.01*(float)fudge;
00352 dra = 0.5*boxfudge*(*ra2 - *ra1);
00353 *ra1 -= dra;
00354 *ra2 += dra;
00355 ddec = 0.5*boxfudge*(*dec2 - *dec1);
00356 *dec1 -= ddec;
00357 *dec2 += ddec;
00358 }
00359
00360
00361
00362 GOOD_STATUS
00363 }
00364
00365
00391
00392
00393 extern int vircam_crpixshift(cpl_propertylist *p, double scalefac,
00394 double sh[]) {
00395 int i;
00396 double val;
00397 char key[SZKEY];
00398 cpl_type type;
00399 const char *fctid = "vircam_crpixshift";
00400
00401
00402
00403 if (scalefac == 0.0) {
00404 cpl_msg_error(fctid,"Scale factor is zero!");
00405 return(VIR_FATAL);
00406 }
00407
00408
00409
00410 for (i = 1; i <= 2; i++) {
00411 snprintf(key,SZKEY,"CRPIX%d",i);
00412
00413
00414
00415 if (cpl_propertylist_has(p,key) == 0) {
00416 cpl_msg_error(fctid,"Header is missing WCS key %s",key);
00417 return(VIR_FATAL);
00418 }
00419
00420
00421
00422 type = cpl_propertylist_get_type(p,key);
00423
00424
00425
00426
00427 switch (type) {
00428 case CPL_TYPE_FLOAT:
00429 val = (double)cpl_propertylist_get_float(p,key);
00430 break;
00431 case CPL_TYPE_DOUBLE:
00432 val = cpl_propertylist_get_double(p,key);
00433 break;
00434 default:
00435 cpl_msg_error(fctid,"Header has WCS key %s as non-floating point!",
00436 key);
00437 return(VIR_FATAL);
00438 }
00439
00440
00441
00442 val = (val - sh[i-1])/scalefac - 1.0;
00443
00444
00445
00446 switch (type) {
00447 case CPL_TYPE_FLOAT:
00448 cpl_propertylist_update_float(p,key,(float)val);
00449 break;
00450 case CPL_TYPE_DOUBLE:
00451 cpl_propertylist_update_double(p,key,val);
00452 break;
00453 default:
00454 break;
00455 }
00456 }
00457 return(VIR_OK);
00458 }
00459
00460
00482
00483
00484 extern int vircam_rescalecd(cpl_propertylist *p, double scalefac) {
00485 int i,j;
00486 cpl_type type;
00487 char key[SZKEY];
00488 const char *fctid = "vircam_rescalecd";
00489 double val;
00490
00491
00492
00493 if (scalefac == 0.0) {
00494 cpl_msg_error(fctid,"Scale factor is zero!");
00495 return(VIR_FATAL);
00496 }
00497
00498
00499
00500 for (i = 1; i <= 2; i++) {
00501 for (j = 1; j <= 2; j++) {
00502 snprintf(key,SZKEY,"CD%d_%d",i,j);
00503
00504
00505
00506 if (cpl_propertylist_has(p,key) == 0) {
00507 cpl_msg_error(fctid,"Header is missing WCS key %s",key);
00508 return(VIR_FATAL);
00509 }
00510
00511
00512
00513 type = cpl_propertylist_get_type(p,key);
00514
00515
00516
00517
00518 switch (type) {
00519 case CPL_TYPE_FLOAT:
00520 val = (double)cpl_propertylist_get_float(p,key);
00521 break;
00522 case CPL_TYPE_DOUBLE:
00523 val = cpl_propertylist_get_double(p,key);
00524 break;
00525 default:
00526 cpl_msg_error(fctid,"Header has WCS key %s as non-floating point!",
00527 key);
00528 return(VIR_FATAL);
00529 }
00530
00531
00532
00533 val *= scalefac;
00534
00535
00536
00537 switch (type) {
00538 case CPL_TYPE_FLOAT:
00539 cpl_propertylist_update_float(p,key,(float)val);
00540 break;
00541 case CPL_TYPE_DOUBLE:
00542 cpl_propertylist_update_double(p,key,val);
00543 break;
00544 default:
00545 break;
00546 }
00547 }
00548 }
00549 return(VIR_OK);
00550 }
00551
00552
00578
00579
00580 extern int vircam_diffxywcs(cpl_wcs *wcs, cpl_wcs *wcsref, float *xoff,
00581 float *yoff, int *status) {
00582 double xc,yc,ra,dec,xnew,ynew;
00583 const cpl_array *a;
00584 const int *dims;
00585 const char *fctid = "vircam_diffxywcs";
00586
00587
00588
00589 *xoff = 0.0;
00590 *yoff = 0.0;
00591 if (*status != VIR_OK)
00592 return(*status);
00593
00594
00595
00596 if (wcs == NULL || wcsref == NULL) {
00597 cpl_msg_error(fctid,"NULL wcs information");
00598 FATAL_ERROR
00599 }
00600
00601
00602
00603 a = cpl_wcs_get_image_dims(wcsref);
00604 dims = cpl_array_get_data_int_const(a);
00605 xc = 0.5*(double)dims[0];
00606 yc = 0.5*(double)dims[1];
00607 vircam_xytoradec(wcsref,xc,yc,&ra,&dec);
00608
00609
00610
00611
00612 vircam_radectoxy(wcs,ra,dec,&xnew,&ynew);
00613
00614
00615
00616 *xoff = (float)(xc - xnew);
00617 *yoff = (float)(yc - ynew);
00618 GOOD_STATUS
00619 }
00620
00621
00641
00642
00643 extern int vircam_removewcs(cpl_propertylist *p, int *status) {
00644 int i;
00645 const char *fctid = "vircam_removewcs";
00646
00647
00648
00649 if (*status != VIR_OK)
00650 return(*status);
00651 if (p == NULL) {
00652 cpl_msg_error(fctid,"Propertylist passed is NULL\nProgramming error");
00653 FATAL_ERROR
00654 }
00655
00656
00657
00658 for (i = 0; i < NNOTABKEYS; i++)
00659 cpl_propertylist_erase_regexp(p,notabkeys[i],0);
00660
00661 GOOD_STATUS
00662 }
00663
00664
00689
00690
00691 extern int vircam_tabwcs(cpl_propertylist *p, int xcol, int ycol,
00692 int *status) {
00693 int i;
00694 char key[9],key2[9];
00695 const char *fctid="vircam_tabwcs";
00696
00697
00698
00699 if (*status != VIR_OK)
00700 return(*status);
00701 if (p == NULL) {
00702 cpl_msg_error(fctid,"Propertylist passed is NULL\nProgramming error");
00703 FATAL_ERROR
00704 }
00705
00706
00707
00708
00709 if (xcol == -1 || ycol == -1) {
00710 vircam_removewcs(p,status);
00711 GOOD_STATUS
00712 }
00713
00714
00715
00716
00717 (void)snprintf(key,8,"TCTYP%d",xcol);
00718 vircam_rename_property(p,"CTYPE1",key);
00719 (void)snprintf(key,8,"TCTYP%d",ycol);
00720 vircam_rename_property(p,"CTYPE2",key);
00721
00722
00723
00724
00725 (void)snprintf(key,8,"TCRVL%d",xcol);
00726 vircam_rename_property(p,"CRVAL1",key);
00727 (void)snprintf(key,8,"TCRVL%d",ycol);
00728 vircam_rename_property(p,"CRVAL2",key);
00729
00730
00731
00732 (void)snprintf(key,8,"TCRPX%d",xcol);
00733 vircam_rename_property(p,"CRPIX1",key);
00734 (void)snprintf(key,8,"TCRPX%d",ycol);
00735 vircam_rename_property(p,"CRPIX2",key);
00736
00737
00738
00739 for (i = 1; i <= 5; i++) {
00740 (void)snprintf(key2,8,"PV2_%d",i);
00741 (void)snprintf(key,8,"TV%d_%d",ycol,i);
00742 if (cpl_propertylist_has(p,key2))
00743 vircam_rename_property(p,key2,key);
00744 }
00745
00746
00747
00748 (void)snprintf(key,8,"TC%d_%d",xcol,xcol);
00749 vircam_rename_property(p,"CD1_1",key);
00750 (void)snprintf(key,8,"TC%d_%d",xcol,ycol);
00751 vircam_rename_property(p,"CD1_2",key);
00752 (void)snprintf(key,8,"TC%d_%d",ycol,xcol);
00753 vircam_rename_property(p,"CD2_1",key);
00754 (void)snprintf(key,8,"TC%d_%d",ycol,ycol);
00755 vircam_rename_property(p,"CD2_2",key);
00756
00757
00758
00759 GOOD_STATUS
00760
00761 }
00762
00763
00766
00767
00768
00769
00770
00771
00772
00773
00774
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
00865
00866
00867
00868