static int wcslib_radec2pixelxy(const anwcslib_t* anwcslib, double ra, double dec, double* px, double* py) { double pix[2]; double world[2]; double phi; double theta; double imgcrd[2]; int status = 0; int code; struct wcsprm* wcs = anwcslib->wcs; world[wcs->lng] = ra; world[wcs->lat] = dec; code = wcss2p(wcs, 1, 0, world, &phi, &theta, imgcrd, pix, &status); /* int wcss2p(struct wcsprm *wcs, int ncoord, int nelem, const double world[], double phi[], double theta[], double imgcrd[], double pixcrd[], int stat[]); */ if (code) { ERROR("Wcslib's wcss2p() failed: code=%i, status=%i", code, status); return -1; } if (px) *px = pix[0]; if (py) *py = pix[1]; return 0; }
/* Convert world coordinates to image coordinates given the input WCS structure. The input must be a linked list of data structures of float64 (`double') type. The top element of the linked list must be the first coordinate and etc. If `inplace' is non-zero, then the output will be written into the input's allocated space. */ gal_data_t * gal_wcs_world_to_img(gal_data_t *coords, struct wcsprm *wcs, int inplace) { gal_data_t *out; int status, *stat=NULL, ncoord=coords->size, nelem=wcs->naxis; double *phi=NULL, *theta=NULL, *world=NULL, *pixcrd=NULL, *imgcrd=NULL; /* Some sanity checks. */ wcs_convert_sanity_check_alloc(coords, wcs, __func__, &stat, &phi, &theta, &world, &pixcrd, &imgcrd); /* Write the values from the input list of separate columns into a single array (WCSLIB input). */ wcs_convert_list_to_array(coords, world, stat, wcs->naxis, 1); /* Use WCSLIB's wcsp2s for the conversion. */ status=wcss2p(wcs, ncoord, nelem, world, phi, theta, imgcrd, pixcrd, stat); if(status) error(EXIT_FAILURE, 0, "%s: wcss2p ERROR %d: %s", __func__, status, wcs_errmsg[status]); /* For a sanity check. { size_t i; printf("\n\n%s sanity check:\n", __func__); for(i=0;i<coords->size;++i) printf("(%g, %g) --> (%g, %g), [stat: %d]\n", world[i*2], world[i*2+1], pixcrd[i*2], pixcrd[i*2+1], stat[i]); } */ /* Allocate the output arrays if they were not already allocated. */ out=wcs_convert_prepare_out(coords, wcs, inplace); /* Write the output from a single array (WCSLIB output) into the output list of this function. */ wcs_convert_list_to_array(out, pixcrd, stat, wcs->naxis, 0); /* Clean up. */ free(phi); free(stat); free(theta); free(world); free(pixcrd); /* Return the output list of coordinates. */ return out; }
int wcss2p_( int* wcs, const int *ncoord, const int *nelem, const double world[], double phi[], double theta[], double imgcrd[], double pixcrd[], int stat[]) { return wcss2p((struct wcsprm *)wcs, *ncoord, *nelem, world, phi, theta, imgcrd, pixcrd, stat); }
int default_wcsmap_init(struct wcsmap_param_t* m, pipeline_t* input, pipeline_t* output, int nx, int ny, double factor, struct driz_error_t* error) { int n; int table_size; double *pixcrd = NULL; double *ptr = NULL; double *tmp = NULL; double *phi = NULL; double *theta = NULL; double *imgcrd = NULL; int *stat = NULL; int snx; int sny; int i; int j; int status = 1; int istat; assert(m); assert(input); assert(output); assert(m->input_wcs == NULL); assert(m->output_wcs == NULL); assert(m->table == NULL); if (factor > 0) { snx = (int)((double)nx / factor) + 2; sny = (int)((double)ny / factor) + 2; n = (snx) * (sny); table_size = n << 1; pixcrd = malloc(table_size * sizeof(double)); if (pixcrd == NULL) { driz_error_set_message(error, "Out of memory"); goto exit; } m->table = malloc(table_size * sizeof(double)); if (m->table == NULL) { driz_error_set_message(error, "Out of memory"); goto exit; } tmp = malloc(table_size * sizeof(double)); if (tmp == NULL) { driz_error_set_message(error, "Out of memory"); goto exit; } phi = malloc(n * sizeof(double)); if (phi == NULL) { driz_error_set_message(error, "Out of memory"); goto exit; } theta = malloc(n * sizeof(double)); if (theta == NULL) { driz_error_set_message(error, "Out of memory"); goto exit; } imgcrd = malloc(table_size * sizeof(double)); if (imgcrd == NULL) { driz_error_set_message(error, "Out of memory"); goto exit; } stat = malloc(n * sizeof(int)); if (stat == NULL) { driz_error_set_message(error, "Out of memory"); goto exit; } ptr = pixcrd; for (j = 0; j < sny; ++j) { for (i = 0; i < snx; ++i) { *ptr++ = (double)i * factor; *ptr++ = (double)j * factor; } } wcsprm_python2c(input->wcs); istat = pipeline_all_pixel2world(input, n, 2, pixcrd, tmp); wcsprm_c2python(input->wcs); if (istat) { free(m->table); m->table = NULL; driz_error_set_message(error, wcslib_get_error_message(istat)); goto exit; } wcsprm_python2c(output->wcs); istat = wcss2p(output->wcs, n, 2, tmp, phi, theta, imgcrd, m->table, stat); wcsprm_c2python(output->wcs); if (istat) { free(m->table); m->table = NULL; driz_error_set_message(error, wcslib_get_error_message(istat)); goto exit; } } /* End if_then for factor > 0 */ m->input_wcs = input; m->output_wcs = output; m->nx = nx; m->ny = ny; m->snx = snx; m->sny = sny; m->factor = factor; status = 0; exit: free(pixcrd); free(tmp); free(phi); free(theta); free(imgcrd); free(stat); return status; }
static int default_wcsmap_direct(struct wcsmap_param_t* m, const double xd, const double yd, const integer_t n, double* xin /*[n]*/, double* yin /*[n]*/, /* Output parameters */ double* xout, double* yout, struct driz_error_t* error) { integer_t i; int status; int result = 1; double *memory = NULL; double *ptr = NULL; double *xyin = NULL; double *skyout = NULL; double *xyout = NULL; double *imgcrd = NULL; double *phi = NULL; double *theta = NULL; int *stat = NULL; /* Allocate memory for new 2-D array */ ptr = memory = (double *) malloc(n * 10 * sizeof(double)); if (memory == NULL) goto exit; xyin = ptr; ptr += n * 2; xyout = ptr; ptr += n * 2; skyout = ptr; ptr += n * 2; imgcrd = ptr; ptr += n * 2; phi = ptr; ptr += n; theta = ptr; stat = (int *)malloc(n * sizeof(int)); if (stat == NULL) goto exit; /* The input arrays need to be converted to 2-D arrays for input to the PyWCS (and related) functions. */ /* Populate new 2-D array with values from x and y input arrays */ for (i = 0; i < n; ++i) { xyin[2*i] = xin[i]; xyin[2*i+1] = yin[i]; } /* Apply pix2sky() transformation from PyWCS */ wcsprm_python2c(m->input_wcs->wcs); status = pipeline_all_pixel2world(m->input_wcs, n, 2, xyin, skyout); wcsprm_c2python(m->input_wcs->wcs); if (status) { goto exit; } /* Finally, call wcs_sky2pix() for the output object. */ wcsprm_python2c(m->output_wcs->wcs); status = wcss2p(m->output_wcs->wcs, n, 2, skyout, phi, theta, imgcrd, xyout, stat); wcsprm_c2python(m->output_wcs->wcs); if (status) { goto exit; } /* Transform results back to 2 1-D arrays, like the input. */ for (i = 0; i < n; ++i){ xout[i] = xyout[2*i]; yout[i] = xyout[2*i+1]; } result = 0; exit: /* Free memory allocated to internal 2-D arrays */ free(memory); free(stat); return result; }
int main(int argc, char **argv) { char alt = ' ', *header, idents[3][80], *infile; int alts[27], c, dofix = 0, doprt = 0, dopix = 0, doworld = 0, hdunum = 1, hdutype, i, j, nelem, nkeyrec, nreject, nwcs, *stat = 0x0, status; double *imgcrd = 0x0, phi, *pixcrd = 0x0, theta, *world = 0x0; struct wcsprm *wcs; fitsfile *fptr; /* Parse options. */ for (i = 1; i < argc && argv[i][0] == '-'; i++) { if (!argv[i][1]) break; switch (argv[i][1]) { case 'a': alt = toupper(argv[i][2]); break; case 'f': dofix = 1; break; case 'h': hdunum = atoi(argv[i]+2); break; case 'p': doprt = 1; break; case 'x': dopix = 1; break; case 'w': doworld = 1; break; default: fprintf(stderr, "%s", usage); return 1; } } if (i < argc) { infile = argv[i++]; if (i < argc) { fprintf(stderr, "%s", usage); return 1; } } else { infile = "-"; } /* Check accessibility of the input file. */ if (strcmp(infile, "-") && access(infile, R_OK) == -1) { printf("wcsware: Cannot access %s.\n", infile); return 1; } if (!dopix && !doworld) doprt = 1; /* Open the FITS file and move to the required HDU. */ status = 0; if (fits_open_file(&fptr, infile, READONLY, &status)) goto fitserr; if (fits_movabs_hdu(fptr, hdunum, &hdutype, &status)) goto fitserr; if (hdutype != IMAGE_HDU) { fprintf(stderr, "ERROR, HDU number %d does not contain an image array.\n", hdunum); return 1; } /* Read in the FITS header, excluding COMMENT and HISTORY keyrecords. */ if (fits_hdr2str(fptr, 1, NULL, 0, &header, &nkeyrec, &status)) { goto fitserr; } /* Interpret the WCS keywords. */ if ((status = wcspih(header, nkeyrec, WCSHDR_all, -3, &nreject, &nwcs, &wcs))) { fprintf(stderr, "wcspih ERROR %d: %s.\n", status, wcshdr_errmsg[status]); return 1; } free(header); if (wcs == 0x0) { fprintf(stderr, "No world coordinate systems found.\n"); return 1; } /* Read -TAB arrays from the binary table extension (if necessary). */ if (fits_read_wcstab(fptr, wcs->nwtb, (wtbarr *)wcs->wtb, &status)) { goto fitserr; } fits_close_file(fptr, &status); /* Translate non-standard WCS keyvalues? */ if (dofix) { stat = malloc(NWCSFIX * sizeof(int)); if ((status = wcsfix(7, 0, wcs, stat))) { for (i = 0; i < NWCSFIX; i++) { if (stat[i] > 0) { fprintf(stderr, "wcsfix ERROR %d: %s.\n", status, wcsfix_errmsg[stat[i]]); } } return 1; } } /* Sort out alternates. */ if (alt) { wcsidx(nwcs, &wcs, alts); if (alt == ' ') { if (alts[0] == -1) { fprintf(stderr, "WARNING, no primary coordinate representation.\n"); alt = '\0'; } } else if (alt < 'A' || alt > 'Z') { fprintf(stderr, "WARNING, alternate specifier \"%c\" is invalid.\n", alt); alt = '\0'; } else { if (alts[alt - 'A' + 1] == -1) { fprintf(stderr, "WARNING, no alternate coordinate representation " "\"%c\".\n", alt); alt = '\0'; } } } /* Initialize and possibly print the structs. */ for (i = 0; i < nwcs; i++) { if (alt && (wcs+i)->alt[0] != alt) { continue; } else if (i) { printf("\nType <CR> for next: "); fgetc(stdin); } if ((status = wcsset(wcs+i))) { fprintf(stderr, "wcsset ERROR %d: %s.\n", status, wcs_errmsg[status]); continue; } /* Get WCSNAME out of the wcsprm struct. */ strcpy(idents[2], (wcs+i)->wcsname); if (strlen(idents[2])) { printf("\n%s\n", idents[2]); } /* Print the struct. */ if (doprt) { wcsprt(wcs+i); } /* Transform coordinates? */ if (dopix || doworld) { nelem = (wcs+i)->naxis; world = realloc(world, nelem * sizeof(double)); imgcrd = realloc(imgcrd, nelem * sizeof(double)); pixcrd = realloc(pixcrd, nelem * sizeof(double)); stat = realloc(stat, nelem * sizeof(int)); if (dopix) { /* Transform pixel coordinates. */ while (1) { printf("\nEnter %d pixel coordinate element%s: ", nelem, (nelem==1)?"":"s"); c = fgetc(stdin); if (c == EOF || c == '\n') { if (c == EOF) printf("\n"); break; } ungetc(c, stdin); scanf("%lf", pixcrd); for (j = 1; j < nelem; j++) { scanf("%*[ ,]%lf", pixcrd+j); } while (fgetc(stdin) != '\n'); printf("Pixel: "); for (j = 0; j < nelem; j++) { printf("%s%14.9g", j?", ":"", pixcrd[j]); } if ((status = wcsp2s(wcs+i, 1, nelem, pixcrd, imgcrd, &phi, &theta, world, stat))) { fprintf(stderr, "wcsp2s ERROR %d: %s.\n", status, wcs_errmsg[status]); } else { printf("\nImage: "); for (j = 0; j < nelem; j++) { if (j == (wcs+i)->lng || j == (wcs+i)->lat) { /* Print angles in fixed format. */ printf("%s%14.6f", j?", ":"", imgcrd[j]); } else { printf("%s%14.9g", j?", ":"", imgcrd[j]); } } printf("\nWorld: "); for (j = 0; j < nelem; j++) { if (j == (wcs+i)->lng || j == (wcs+i)->lat) { /* Print angles in fixed format. */ printf("%s%14.6f", j?", ":"", world[j]); } else { printf("%s%14.9g", j?", ":"", world[j]); } } printf("\n"); } } } if (doworld) { /* Transform world coordinates. */ while (1) { printf("\nEnter %d world coordinate element%s: ", nelem, (nelem==1)?"":"s"); c = fgetc(stdin); if (c == EOF || c == '\n') { if (c == EOF) printf("\n"); break; } ungetc(c, stdin); scanf("%lf", world); for (j = 1; j < nelem; j++) { scanf("%*[ ,]%lf", world+j); } while (fgetc(stdin) != '\n'); printf("World: "); for (j = 0; j < nelem; j++) { if (j == (wcs+i)->lng || j == (wcs+i)->lat) { /* Print angles in fixed format. */ printf("%s%14.6f", j?", ":"", world[j]); } else { printf("%s%14.9g", j?", ":"", world[j]); } } if ((status = wcss2p(wcs+i, 1, nelem, world, &phi, &theta, imgcrd, pixcrd, stat))) { fprintf(stderr, "wcss2p ERROR %d: %s.\n", status, wcs_errmsg[status]); } else { printf("\nImage: "); for (j = 0; j < nelem; j++) { if (j == (wcs+i)->lng || j == (wcs+i)->lat) { /* Print angles in fixed format. */ printf("%s%14.6f", j?", ":"", imgcrd[j]); } else { printf("%s%14.9g", j?", ":"", imgcrd[j]); } } printf("\nPixel: "); for (j = 0; j < nelem; j++) { printf("%s%14.9g", j?", ":"", pixcrd[j]); } printf("\n"); } } } } } status = wcsvfree(&nwcs, &wcs); return 0; fitserr: fits_report_error(stderr, status); fits_close_file(fptr, &status); return 1; }
int main() { #define NELEM 9 char ok[] = "", mismatch[] = " (WARNING, mismatch)", *s; int i, k, lat, lng, nFail1 = 0, nFail2 = 0, stat[361], status; double freq, img[361][NELEM], lat1, lng1, phi[361], pixel1[361][NELEM], pixel2[361][NELEM], r, resid, residmax, theta[361], time, world1[361][NELEM], world2[361][NELEM]; struct wcsprm *wcs; printf("Testing closure of WCSLIB world coordinate transformation " "routines (twcs.c)\n" "----------------------------------------------------------" "-----------------\n"); /* List status return messages. */ printf("\nList of wcs status return values:\n"); for (status = 1; status <= 13; status++) { printf("%4d: %s.\n", status, wcs_errmsg[status]); } printf("\nSize of data types (bytes):\n"); printf(" char:%5"MODZ"u\n", sizeof(char)); printf(" short int:%5"MODZ"u\n", sizeof(short int)); printf(" int:%5"MODZ"u\n", sizeof(int)); printf(" long int:%5"MODZ"u\n", sizeof(long int)); printf(" float:%5"MODZ"u\n", sizeof(float)); printf(" double:%5"MODZ"u\n", sizeof(double)); printf(" char *:%5"MODZ"u\n", sizeof(char *)); printf(" char (*)[72]:%5"MODZ"u\n", sizeof(char (*)[72])); printf(" int *:%5"MODZ"u\n", sizeof(int *)); printf(" float *:%5"MODZ"u\n", sizeof(float *)); printf(" double *:%5"MODZ"u\n", sizeof(double *)); printf("struct pvcard *:%5"MODZ"u\n", sizeof(struct pvcard *)); printf("struct pscard *:%5"MODZ"u\n", sizeof(struct pscard *)); printf("\nSize of structs (bytes/ints):\n"); s = (sizeof(struct celprm) == sizeof(int)*CELLEN) ? ok : mismatch; printf(" celprm:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct celprm), CELLEN, s); s = (sizeof(struct fitskey) == sizeof(int)*KEYLEN) ? ok : mismatch; printf(" fitskey:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct fitskey), KEYLEN, s); s = (sizeof(struct fitskeyid) == sizeof(int)*KEYIDLEN) ? ok : mismatch; printf(" fitskeyid:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct fitskeyid), KEYIDLEN, s); s = (sizeof(struct linprm) == sizeof(int)*LINLEN) ? ok : mismatch; printf(" linprm:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct linprm), LINLEN, s); s = (sizeof(struct prjprm) == sizeof(int)*PRJLEN) ? ok : mismatch; printf(" prjprm:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct prjprm), PRJLEN, s); s = (sizeof(struct spcprm) == sizeof(int)*SPCLEN) ? ok : mismatch; printf(" spcprm:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct spcprm), SPCLEN, s); s = (sizeof(struct spxprm) == sizeof(int)*SPXLEN) ? ok : mismatch; printf(" spxprm:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct spxprm), SPXLEN, s); s = (sizeof(struct tabprm) == sizeof(int)*TABLEN) ? ok : mismatch; printf(" tabprm:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct tabprm), TABLEN, s); s = (sizeof(struct wcserr) == sizeof(int)*ERRLEN) ? ok : mismatch; printf(" wcserr:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct wcserr), ERRLEN, s); s = (sizeof(struct wcsprm) == sizeof(int)*WCSLEN) ? ok : mismatch; printf(" wcsprm:%5"MODZ"u /%4"MODZ"u%s\n", sizeof(struct wcsprm), WCSLEN, s); /* Set the PVi_ma keyvalues for the longitude axis. */ /*----------------------------------------------------------*/ /* For test purposes, these are set so that the fiducial */ /* native coordinates are at the native pole, i.e. so that */ /* (phi0,theta0) = (0,90), but without any fiducial offset, */ /* i.e. iwith PVi_0a == 0 (by default). */ /*----------------------------------------------------------*/ PV[0].i = 4; /* Longitude is on axis 4. */ PV[0].m = 1; /* Parameter number 1. */ PV[0].value = 0.0; /* Fiducial native longitude. */ PV[1].i = 4; /* Longitude is on axis 4. */ PV[1].m = 2; /* Parameter number 2. */ PV[1].value = 90.0; /* Fiducial native latitude. */ /* Set the PVi_m keyvaluess for the latitude axis. */ PV[2].i = 2; /* Latitude is on axis 2. */ PV[2].m = 1; /* Parameter number 1. */ PV[2].value = -30.0; /* PVi_1. */ /* The following routine simulates the actions of a FITS header parser. */ wcs = malloc(sizeof(struct wcsprm)); wcs->flag = -1; parser(wcs); printf("\nReporting tolerance %5.1g pixel.\n", tol); /* Initialize non-celestial world coordinates. */ time = 1.0; freq = 1.42040595e9 - 180.0 * 62500.0; for (k = 0; k < 361; k++) { world1[k][0] = 0.0; world1[k][1] = 0.0; world1[k][2] = 0.0; world1[k][3] = 0.0; world1[k][2] = time; time *= 1.01; world1[k][wcs->spec] = 2.99792458e8 / freq; freq += 62500.0; } residmax = 0.0; for (lat = 90; lat >= -90; lat--) { lat1 = (double)lat; for (lng = -180, k = 0; lng <= 180; lng++, k++) { lng1 = (double)lng; world1[k][wcs->lng] = lng1; world1[k][wcs->lat] = lat1; } if (wcss2p(wcs, 361, NELEM, world1[0], phi, theta, img[0], pixel1[0], stat)) { printf(" At wcss2p#1 with lat1 == %f\n", lat1); wcsperr(wcs, " "); continue; } if (wcsp2s(wcs, 361, NELEM, pixel1[0], img[0], phi, theta, world2[0], stat)) { printf(" At wcsp2s with lat1 == %f\n", lat1); wcsperr(wcs, " "); continue; } if (wcss2p(wcs, 361, NELEM, world2[0], phi, theta, img[0], pixel2[0], stat)) { printf(" At wcss2p#2 with lat1 == %f\n", lat1); wcsperr(wcs, " "); continue; } for (k = 0; k < 361; k++) { resid = 0.0; for (i = 0; i < NAXIS; i++) { r = pixel2[k][i] - pixel1[k][i]; resid += r*r; } resid = sqrt(resid); if (resid > residmax) residmax = resid; if (resid > tol) { nFail1++; printf("\nClosure error:\n" "world1:%18.12f%18.12f%18.12f%18.12f\n" "pixel1:%18.12f%18.12f%18.12f%18.12f\n" "world2:%18.12f%18.12f%18.12f%18.12f\n" "pixel2:%18.12f%18.12f%18.12f%18.12f\n", world1[k][0], world1[k][1], world1[k][2], world1[k][3], pixel1[k][0], pixel1[k][1], pixel1[k][2], pixel1[k][3], world2[k][0], world2[k][1], world2[k][2], world2[k][3], pixel2[k][0], pixel2[k][1], pixel2[k][2], pixel2[k][3]); } } } printf("wcsp2s/wcss2p: Maximum closure residual = %.1e pixel.\n", residmax); /* Test wcserr and wcsprintf() as well. */ nFail2 = 0; wcsprintf_set(stdout); wcsprintf("\n\nIGNORE messages marked with 'OK', they test wcserr " "(and wcsprintf):\n"); wcserr_enable(1); /* Test 1. */ wcs->pv[2].value = UNDEFINED; status = wcsset(wcs); nFail2 += check_error(wcs, status, WCSERR_BAD_PARAM, "Invalid parameter value"); nFail2 += test_errors(); if (nFail1 || nFail2) { if (nFail1) { printf("\nFAIL: %d closure residuals exceed reporting tolerance.\n", nFail1); } if (nFail2) { printf("FAIL: %d error messages differ from that expected.\n", nFail2); } } else { printf("\nPASS: All closure residuals are within reporting tolerance.\n"); printf("PASS: All error messages reported as expected.\n"); } /* Clean up. */ wcsfree(wcs); free(wcs); return nFail1 + nFail2; }
int main(int argc, char *argv[]) { char *header, *hptr; int dohdr = 0, dopixel = 0, doworld = 0; int i, nkeyrec, nreject, nwcs, stat[NWCSFIX], status = 0; double imgcrd[2], phi, pixcrd[2], theta, world[2]; fitsfile *fptr; struct wcsprm *wcs; /* Parse options. */ for (i = 1; i < argc && argv[i][0] == '-'; i++) { if (!argv[i][1]) break; switch (argv[i][1]) { case 'h': dohdr = 1; break; case 'p': dopixel = 1; break; case 'w': doworld = 1; break; default: fprintf(stderr, "Usage: twcshdr [-h | -p | -w] <file>\n"); return 1; } } if (i != (argc-1)) { fprintf(stderr, "Usage: twcshdr [-h | -p | -w] <file>\n"); return 1; } /* Open the FITS test file and read the primary header. */ fits_open_file(&fptr, argv[i], READONLY, &status); if ((status = fits_hdr2str(fptr, 1, NULL, 0, &header, &nkeyrec, &status))) { fits_report_error(stderr, status); return 1; } /*-----------------------------------------------------------------------*/ /* Basic steps required to interpret a FITS WCS header, including -TAB. */ /*-----------------------------------------------------------------------*/ /* Parse the primary header of the FITS file. */ if ((status = wcspih(header, nkeyrec, WCSHDR_all, 2, &nreject, &nwcs, &wcs))) { fprintf(stderr, "wcspih ERROR %d: %s.\n", status,wcshdr_errmsg[status]); } /* Read coordinate arrays from the binary table extension. */ if ((status = fits_read_wcstab(fptr, wcs->nwtb, (wtbarr *)wcs->wtb, &status))) { fits_report_error(stderr, status); return 1; } /* Translate non-standard WCS keyvalues. */ if ((status = wcsfix(7, 0, wcs, stat))) { for (i = 0; i < NWCSFIX; i++) { if (stat[i] > 0) { fprintf(stderr, "wcsfix ERROR %d: %s.\n", status, wcsfix_errmsg[stat[i]]); } } return 1; } /*-----------------------------------------------------------------------*/ /* The wcsprm struct is now ready for use. */ /*-----------------------------------------------------------------------*/ /* Finished with the FITS file. */ fits_close_file(fptr, &status); free(header); /* Initialize the wcsprm struct, also taking control of memory allocated by * fits_read_wcstab(). */ if ((status = wcsset(wcs))) { fprintf(stderr, "wcsset ERROR %d: %s.\n", status, wcs_errmsg[status]); return 1; } if (dohdr) { if ((status = wcshdo(WCSHDO_all, wcs, &nkeyrec, &header))) { return 1; } hptr = header; printf("\n\n"); for (i = 0; i < nkeyrec; i++, hptr += 80) { printf("%.80s\n", hptr); } free(header); } else if (dopixel) { while (1) { printf("Enter pixel coordinates: "); if (scanf("%lf%*[ ,]%lf", pixcrd, pixcrd+1) != wcs->naxis) break; status = wcsp2s(wcs, 1, 2, pixcrd, imgcrd, &phi, &theta, world, stat); printf(" (%20.15f, %20.15f) ->\n (%20.15f, %20.15f)\n\n", pixcrd[0], pixcrd[1], world[0], world[1]); } } else if (doworld) { while (1) { printf("Enter world coordinates: "); if (scanf("%lf%*[ ,]%lf", world, world+1) != wcs->naxis) break; status = wcss2p(wcs, 1, 2, world, &phi, &theta, imgcrd, pixcrd, stat); printf(" (%20.15f, %20.15f) ->\n (%20.15f, %20.15f)\n\n", world[0], world[1], pixcrd[0], pixcrd[1]); } } else { /* Print the struct. */ if ((status = wcsprt(wcs))) { return 1; } } /* Clean up. */ status = wcsvfree(&nwcs, &wcs); return 0; }