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
00031
00032
00033
00034
00035
00036
00037
00038 #include "fors_cpl_wcs.h"
00039
00040 #include "cpl.h"
00041
00042 #include <fitsio.h>
00043 #include <fitsio2.h>
00044 #include <wcslib.h>
00045
00046
00047
00048 cpl_propertylist *cpl_propertylist_from_fitsfile(fitsfile *file);
00049
00050
00051
00052
00053
00054
00055
00056
00057 cpl_error_code cpl_propertylist_to_fitsfile(fitsfile *file, const cpl_propertylist *self, const char *);
00058
00059
00060
00061
00062 #include <math.h>
00063 #include <string.h>
00064
00065
00082
00085
00086
00087
00088
00089 struct _fors_cpl_wcs_ {
00090 struct wcsprm *wcsptr;
00091 int naxis;
00092 int *dims;
00093 };
00094
00095
00096
00097 static fors_cpl_wcs *fors_cpl_wcs_init(void);
00098 static char *fors_cpl_wcs_plist2fitsstr(const cpl_propertylist *self, int *nkeys);
00099 static cpl_propertylist *fors_cpl_wcs_fitsstr2plist(char *fitsstr);
00100
00101
00102
00103 #define DEGRAD 57.2957795130823229
00104
00105
00106
00107 #define WCSLIB_ERRCODE_MAX 9
00108 static char *wcslib_errmsgs[WCSLIB_ERRCODE_MAX+1] = {
00109 "",
00110 "WCSLIB undefined input structure pointer",
00111 "WCSLIB unable to allocate required memory",
00112 "WCSLIB linear transformation matrix is singular",
00113 "WCSLIB invalid coordinate axis types",
00114 "WCSLIB invalid parameter value",
00115 "WCSLIB invalid coordinate transformation parameters",
00116 "WCSLIB Ill-conditioned coordinate transformation parameters",
00117 "WCSLIB One or more input coordinates invalid",
00118 "WCSLIB One or more input coordinates invalid"};
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 static int fors_ffhdr2str(
00131 fitsfile *fptr,
00132 int exclude_comm,
00133 char **exclist,
00134 int nexc,
00135 char **header,
00136 int *nkeys,
00137 int *status)
00138
00139
00140
00141
00142
00143
00144
00145
00146 {
00147 {
00148
00149
00150 float version;
00151 fits_get_version(&version);
00152
00153 if (version >= 3.030)
00154 return ffhdr2str(fptr, exclude_comm, exclist, nexc, header, nkeys, status);
00155 }
00156
00157 int casesn, match, exact, totkeys;
00158 long ii, jj;
00159 char keybuf[162], keyname[FLEN_KEYWORD], *headptr;
00160
00161 *nkeys = 0;
00162
00163 if (*status > 0)
00164 return(*status);
00165
00166
00167 if (ffghsp(fptr, &totkeys, NULL, status) > 0)
00168 return(*status);
00169
00170
00171 *header = (char *) calloc ( (totkeys + 1) * 80 + 1, 1);
00172 if (!(*header))
00173 {
00174 *status = MEMORY_ALLOCATION;
00175 ffpmsg("failed to allocate memory to hold all the header keywords");
00176 return(*status);
00177 }
00178
00179 headptr = *header;
00180 casesn = FALSE;
00181
00182
00183 for (ii = 1; ii <= totkeys; ii++)
00184 {
00185 ffgrec(fptr, ii, keybuf, status);
00186
00187 strcat(keybuf,
00188 " ");
00189
00190 keyname[0] = '\0';
00191 strncat(keyname, keybuf, 8);
00192
00193 if (exclude_comm)
00194 {
00195 if (!FSTRCMP("COMMENT ", keyname) ||
00196 !FSTRCMP("HISTORY ", keyname) ||
00197 !FSTRCMP(" ", keyname) )
00198 continue;
00199 }
00200
00201
00202 for (jj = 0; jj < nexc; jj++ )
00203 {
00204 ffcmps(exclist[jj], keyname, casesn, &match, &exact);
00205 if (match)
00206 break;
00207 }
00208
00209 if (jj == nexc)
00210 {
00211
00212 strcpy(headptr, keybuf);
00213 headptr += 80;
00214 (*nkeys)++;
00215 }
00216 }
00217
00218
00219 strcpy(headptr,
00220 "END ");
00221 headptr += 80;
00222 (*nkeys)++;
00223
00224 *headptr = '\0';
00225
00226 *header = realloc(*header, (*nkeys *80) + 1);
00227
00228 return(*status);
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 fors_cpl_wcs *fors_cpl_wcs_new_from_propertylist(const cpl_propertylist *plist) {
00278 const char *_id = "fors_cpl_wcs_new";
00279 char *shdr,nax[9];
00280 fors_cpl_wcs *wcs;
00281 int retval,nrej,nwcs,np,i;
00282 struct wcsprm *wwcs = NULL;
00283
00284
00285
00286 if (plist == NULL) {
00287 cpl_error_set(_id,CPL_ERROR_NULL_INPUT);
00288 return(NULL);
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298 if ((wcs = fors_cpl_wcs_init()) == NULL)
00299 return(NULL);
00300
00301
00302
00303 shdr = fors_cpl_wcs_plist2fitsstr(plist, &np);
00304 if (! shdr) {
00305 cpl_error_set_where(_id);
00306 fors_cpl_wcs_delete(wcs);
00307 return(NULL);
00308 }
00309
00310
00311 retval = wcspih(shdr,np,0,0,&nrej,&nwcs,&wwcs);
00312
00313 if (retval != 0) {
00314 cpl_msg_warning(_id,"Cannot parse WCS header");
00315 free(shdr);
00316 wcsvfree(&nwcs,&wwcs);
00317 fors_cpl_wcs_delete(wcs);
00318 return(NULL);
00319 }
00320 free(shdr);
00321
00322
00323
00324 wcs->wcsptr = (struct wcsprm *)cpl_calloc(1,sizeof(struct wcsprm));
00325 (wcs->wcsptr)->flag = -1;
00326 wcscopy(1,wwcs,wcs->wcsptr);
00327 wcsset(wcs->wcsptr);
00328 wcsvfree(&nwcs,&wwcs);
00329
00330
00331
00332 if (cpl_propertylist_has(plist,"NAXIS")) {
00333 wcs->naxis = cpl_propertylist_get_int(plist,"NAXIS");
00334 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00335 fors_cpl_wcs_delete(wcs);
00336 return(NULL);
00337 }
00338 wcs->dims = cpl_calloc(wcs->naxis,sizeof(int));
00339 for (i = 1; i <= wcs->naxis; i++) {
00340 (void)snprintf(nax,9,"NAXIS%d",i);
00341 wcs->dims[i-1] = cpl_propertylist_get_int(plist,nax);
00342 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00343 fors_cpl_wcs_delete(wcs);
00344 return(NULL);
00345 }
00346 }
00347 }
00348
00349
00350
00351 return(wcs);
00352 }
00353
00367 void fors_cpl_wcs_delete(fors_cpl_wcs *wcs) {
00368
00369
00370
00371 if (wcs == NULL)
00372 return;
00373 if (wcs->wcsptr != NULL) {
00374 (void)wcsfree(wcs->wcsptr);
00375 cpl_free(wcs->wcsptr);
00376 }
00377 if (wcs->dims != NULL)
00378 cpl_free(wcs->dims);
00379 cpl_free(wcs);
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 cpl_error_code fors_cpl_wcs_convert(const fors_cpl_wcs *wcs, const cpl_matrix *from,
00434 cpl_matrix **to, cpl_array **status,
00435 fors_cpl_wcs_trans_mode transform) {
00436 int nrows,ncols,*sdata,retval,i;
00437 cpl_matrix *x1;
00438 cpl_array *x2,*x3;
00439 cpl_error_code code;
00440 double *fdata,*tdata,*x1data,*x2data,*x3data;
00441 char *_id = "fors_cpl_wcs_convert";
00442
00443
00444
00445 *to = NULL;
00446 *status = NULL;
00447
00448
00449
00450 if (wcs == NULL || wcs->wcsptr == NULL || from == NULL) {
00451 cpl_error_set(_id,CPL_ERROR_NULL_INPUT);
00452 return(CPL_ERROR_NULL_INPUT);
00453 }
00454
00455
00456
00457 nrows = cpl_matrix_get_nrow(from);
00458 ncols = cpl_matrix_get_ncol(from);
00459 if (nrows == 0 || ncols == 0) {
00460 cpl_error_set(_id,CPL_ERROR_UNSPECIFIED);
00461 return(CPL_ERROR_UNSPECIFIED);
00462 }
00463
00464
00465
00466 *to = cpl_matrix_new(nrows,ncols);
00467 *status = cpl_array_new(nrows,CPL_TYPE_INT);
00468 x1 = cpl_matrix_new(nrows,ncols);
00469 x2 = cpl_array_new(nrows,CPL_TYPE_DOUBLE);
00470 x3 = cpl_array_new(nrows,CPL_TYPE_DOUBLE);
00471
00472
00473
00474 fdata = cpl_matrix_get_data(from);
00475 tdata = cpl_matrix_get_data(*to);
00476 sdata = cpl_array_get_data_int(*status);
00477 x1data = cpl_matrix_get_data(x1);
00478 x2data = cpl_array_get_data_double(x2);
00479 x3data = cpl_array_get_data_double(x3);
00480
00481
00482
00483
00484 switch (transform) {
00485 case FORS_CPL_WCS_PHYS2WORLD:
00486 retval = wcsp2s(wcs->wcsptr,nrows,wcs->naxis,fdata,x1data,x2data,
00487 x3data,tdata,sdata);
00488 break;
00489 case FORS_CPL_WCS_WORLD2PHYS:
00490 retval = wcss2p(wcs->wcsptr,nrows,wcs->naxis,fdata,x2data,x3data,
00491 x1data,tdata,sdata);
00492 break;
00493 case FORS_CPL_WCS_WORLD2STD:
00494 retval = wcss2p(wcs->wcsptr,nrows,wcs->naxis,fdata,x2data,x3data,
00495 tdata,x1data,sdata);
00496 break;
00497 case FORS_CPL_WCS_PHYS2STD:
00498 retval = wcsp2s(wcs->wcsptr,nrows,wcs->naxis,fdata,tdata,x2data,
00499 x3data,x1data,sdata);
00500 break;
00501 default:
00502 cpl_error_set(_id,CPL_ERROR_UNSUPPORTED_MODE);
00503 cpl_matrix_delete(*to);
00504 *to = NULL;
00505 cpl_array_delete(*status);
00506 *status = NULL;
00507 cpl_matrix_delete(x1);
00508 return(CPL_ERROR_UNSUPPORTED_MODE);
00509 }
00510
00511
00512
00513 cpl_matrix_delete(x1);
00514 cpl_array_delete(x2);
00515 cpl_array_delete(x3);
00516
00517
00518
00519 switch (retval) {
00520 case 0:
00521 code = CPL_ERROR_NONE;
00522 break;
00523 case 1:
00524 code = CPL_ERROR_NULL_INPUT;
00525 cpl_msg_warning(__func__,wcslib_errmsgs[1]);
00526 cpl_error_set(__func__,code);
00527 break;
00528 case 2:
00529 case 3:
00530 case 4:
00531 case 5:
00532 case 6:
00533 case 7:
00534 case 8:
00535 case 9:
00536 code = CPL_ERROR_UNSPECIFIED;
00537 cpl_error_set(__func__,code);
00538 cpl_msg_warning(__func__,wcslib_errmsgs[retval]);
00539 break;
00540 default:
00541 code = CPL_ERROR_UNSPECIFIED;
00542 cpl_error_set(__func__,code);
00543 cpl_msg_warning(__func__,"WCSLIB found an unspecified error: %d",
00544 retval);
00545 break;
00546 }
00547 return(code);
00548 }
00549
00550
00551
00554
00555
00569 static fors_cpl_wcs *fors_cpl_wcs_init(void) {
00570 fors_cpl_wcs *wcs = NULL;
00571
00572
00573
00574 wcs = cpl_malloc(sizeof(fors_cpl_wcs));
00575 if (wcs == NULL)
00576 return(NULL);
00577
00578
00579
00580 wcs->wcsptr = NULL;
00581 wcs->naxis = 0;
00582 wcs->dims = NULL;
00583
00584 return wcs;
00585 }
00586
00613 static char *fors_cpl_wcs_plist2fitsstr(const cpl_propertylist *self, int *nkeys) {
00614
00615 const char *_id = "fors_cpl_wcs_plist2fitsstr";
00616 char *header,*h,cval[2];
00617 int n,status;
00618 long lval,i;
00619 float fval;
00620 double dval;
00621 fitsfile *fptr;
00622 cpl_property *p;
00623
00624
00625
00626 if (self == NULL) {
00627 cpl_error_set(_id,CPL_ERROR_NULL_INPUT);
00628 return(NULL);
00629 }
00630
00631
00632
00633 n = cpl_propertylist_get_size(self);
00634
00635
00636
00637 status = 0;
00638 (void)fits_create_file(&fptr,"mem://",&status);
00639 (void)fits_create_img(fptr,BYTE_IMG,0,NULL,&status);
00640
00641
00642
00643 cpl_propertylist_to_fitsfile(fptr,self,NULL);
00644
00645
00646
00647
00648 (void)fors_ffhdr2str(fptr,1,NULL,0,&header,nkeys,&status);
00649 (void)fits_close_file(fptr,&status);
00650
00651
00652
00653 return(header);
00654
00655 }
00656
00682 static cpl_propertylist *fors_cpl_wcs_fitsstr2plist(char *fitsstr) {
00683 int i,status;
00684 fitsfile *fptr;
00685 char *f,*_id="fors_cpl_wcs_fitsstr2plist";
00686 cpl_propertylist *p;
00687
00688
00689
00690 if (fitsstr == NULL) {
00691 cpl_error_set(_id,CPL_ERROR_NULL_INPUT);
00692 return(NULL);
00693 }
00694
00695
00696
00697
00698 status = 0;
00699 (void)fits_create_file(&fptr,"mem://",&status);
00700 (void)fits_create_img(fptr,BYTE_IMG,0,NULL,&status);
00701
00702
00703
00704
00705 f = fitsstr;
00706 while (strncmp(f,"END ",8)) {
00707 (void)fits_insert_card(fptr,f,&status);
00708 f += (FLEN_CARD - 1);
00709 }
00710 (void)fits_insert_card(fptr,f,&status);
00711
00712
00713
00714 p = cpl_propertylist_from_fitsfile(fptr);
00715
00716
00717
00718 (void)fits_close_file(fptr,&status);
00719 return(p);
00720 }
00721