static int wcslib_pixelxy2radec(const anwcslib_t* anwcslib, double px, double py, double* ra, double* dec) { double pix[2]; double world[2]; double phi; double theta; double imgcrd[2]; int status = 0; int code; struct wcsprm* wcs = anwcslib->wcs; pix[0] = px; pix[1] = py; code = wcsp2s(wcs, 1, 0, pix, imgcrd, &phi, &theta, world, &status); /* int wcsp2s(struct wcsprm *wcs, int ncoord, int nelem, const double pixcrd[], double imgcrd[], double phi[], double theta[], double world[], int stat[]); */ if (code) { //ERROR("Wcslib's wcsp2s() failed: code=%i, status=%i (%s); (x,y)=(%g,%g)", code, status, wcs_errmsg[status], px, py); logverb("Wcslib's wcsp2s() failed: code=%i, status=%i (%s); (x,y)=(%g,%g)", code, status, wcs_errmsg[status], px, py); return -1; } if (ra) *ra = world[wcs->lng]; if (dec) *dec = world[wcs->lat]; return 0; }
/* Similar to `gal_wcs_world_to_img'. */ gal_data_t * gal_wcs_img_to_world(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, pixcrd, stat, wcs->naxis, 1); /* Use WCSLIB's wcsp2s for the conversion. */ status=wcsp2s(wcs, ncoord, nelem, pixcrd, imgcrd, phi, theta, world, stat); if(status) error(EXIT_FAILURE, 0, "%s: wcsp2s 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", pixcrd[i*2], pixcrd[i*2+1], world[i*2], world[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, world, 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 wcsp2s_( int *wcs, const int *ncoord, const int *nelem, const double pixcrd[], double imgcrd[], double phi[], double theta[], double world[], int stat[]) { return wcsp2s((struct wcsprm *)wcs, *ncoord, *nelem, pixcrd, imgcrd, phi, theta, world, stat); }
int cylfix(const int naxis[], struct wcsprm *wcs) { static const char *function = "cylfix"; unsigned short icnr, indx[NMAX], ncnr; int j, k, stat[4], status; double img[4][NMAX], lat, lng, phi[4], phi0, phimax, phimin, pix[4][NMAX], *pixj, theta[4], theta0, world[4][NMAX], x, y; struct wcserr **err; if (naxis == 0x0) return FIXERR_NO_CHANGE; if (wcs == 0x0) return FIXERR_NULL_POINTER; err = &(wcs->err); /* Initialize if required. */ if (wcs->flag != WCSSET) { if ((status = wcsset(wcs))) return status; } /* Check that we have a cylindrical projection. */ if (wcs->cel.prj.category != CYLINDRICAL) return FIXERR_NO_CHANGE; if (wcs->naxis < 2) return FIXERR_NO_CHANGE; /* Compute the native longitude in each corner of the image. */ ncnr = 1 << wcs->naxis; for (k = 0; k < NMAX; k++) { indx[k] = 1 << k; } phimin = 1.0e99; phimax = -1.0e99; for (icnr = 0; icnr < ncnr;) { /* Do four corners at a time. */ for (j = 0; j < 4; j++, icnr++) { pixj = pix[j]; for (k = 0; k < wcs->naxis; k++) { if (icnr & indx[k]) { *(pixj++) = naxis[k] + 0.5; } else { *(pixj++) = 0.5; } } } if (!(status = wcsp2s(wcs, 4, NMAX, pix[0], img[0], phi, theta, world[0], stat))) { for (j = 0; j < 4; j++) { if (phi[j] < phimin) phimin = phi[j]; if (phi[j] > phimax) phimax = phi[j]; } } } if (phimin > phimax) return status; /* Any changes needed? */ if (phimin >= -180.0 && phimax <= 180.0) return FIXERR_NO_CHANGE; /* Compute the new reference pixel coordinates. */ phi0 = (phimin + phimax) / 2.0; theta0 = 0.0; if ((status = prjs2x(&(wcs->cel.prj), 1, 1, 1, 1, &phi0, &theta0, &x, &y, stat))) { if (status == PRJERR_BAD_PARAM) { return wcserr_set(WCSFIX_ERRMSG(FIXERR_BAD_PARAM)); } return wcserr_set(WCSFIX_ERRMSG(FIXERR_NO_REF_PIX_COORD)); } for (k = 0; k < wcs->naxis; k++) { img[0][k] = 0.0; } img[0][wcs->lng] = x; img[0][wcs->lat] = y; if ((status = linx2p(&(wcs->lin), 1, 0, img[0], pix[0]))) { return wcserr_set(WCSFIX_ERRMSG(status)); } /* Compute celestial coordinates at the new reference pixel. */ if ((status = wcsp2s(wcs, 1, 0, pix[0], img[0], phi, theta, world[0], stat))) { if (wcs->err->status == WCSERR_BAD_PIX) { wcs->err->status = FIXERR_NO_REF_PIX_COORD; } return wcs->err->status; } /* Compute native coordinates of the celestial pole. */ lng = 0.0; lat = 90.0; (void)sphs2x(wcs->cel.euler, 1, 1, 1, 1, &lng, &lat, phi, theta); wcs->crpix[wcs->lng] = pix[0][wcs->lng]; wcs->crpix[wcs->lat] = pix[0][wcs->lat]; wcs->crval[wcs->lng] = world[0][wcs->lng]; wcs->crval[wcs->lat] = world[0][wcs->lat]; wcs->lonpole = phi[0] - phi0; return wcsset(wcs); }
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 do_wcs_stuff(fitsfile *fptr, struct wcsprm *wcs) { int i1, i2, i3, k, naxis1, naxis2, naxis3, stat[8], status; double phi[8], pixcrd[8][4], imgcrd[8][4], theta[8], world[8][4], x1, x2, x3; /* 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; } /* Print the struct. */ if ((status = wcsprt(wcs))) return status; /* Compute coordinates in the corners. */ fits_read_key(fptr, TINT, "NAXIS1", &naxis1, NULL, &status); fits_read_key(fptr, TINT, "NAXIS2", &naxis2, NULL, &status); fits_read_key(fptr, TINT, "NAXIS3", &naxis3, NULL, &status); k = 0; x3 = 1.0f; for (i3 = 0; i3 < 2; i3++) { x2 = 0.5f; for (i2 = 0; i2 < 2; i2++) { x1 = 0.5f; for (i1 = 0; i1 < 2; i1++) { pixcrd[k][0] = x1; pixcrd[k][1] = x2; pixcrd[k][2] = x3; pixcrd[k][3] = 1.0f; k++; x1 = naxis1 + 0.5f; } x2 = naxis2 + 0.5f; } x3 = naxis3; } if ((status = wcsp2s(wcs, 8, 4, pixcrd[0], imgcrd[0], phi, theta, world[0], stat))) { fprintf(stderr, "\n\nwcsp2s ERROR %d: %s.\n", status, wcs_errmsg[status]); /* Invalid pixel coordinates. */ if (status == 8) status = 0; } if (status == 0) { printf("\n\nCorner world coordinates:\n" " Pixel World\n"); for (k = 0; k < 8; k++) { printf(" (%5.1f,%6.1f,%4.1f,%4.1f) -> (%7.3f,%8.3f,%9g,%11.5f)", pixcrd[k][0], pixcrd[k][1], pixcrd[k][2], pixcrd[k][3], world[k][0], world[k][1], world[k][2], world[k][3]); if (stat[k]) printf(" (BAD)"); printf("\n"); } } return 0; }
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 pipeline_all_pixel2world( pipeline_t* pipeline, const unsigned int ncoord, const unsigned int nelem, const double* const pixcrd /* [ncoord][nelem] */, double* world /* [ncoord][nelem] */) { static const char* function = "pipeline_all_pixel2world"; const double* wcs_input = NULL; double* wcs_output = NULL; int has_det2im; int has_sip; int has_p4; int has_wcs; int status = 1; struct wcserr **err; /* Temporary buffer for performing WCS calculations */ unsigned char* buffer = NULL; unsigned char* mem = NULL; /*@null@*/ double* tmp; /*@null@*/ double* imgcrd; /*@null@*/ double* phi; /*@null@*/ double* theta; /*@null@*/ int* stat; if (pipeline == NULL || pixcrd == NULL || world == NULL) { return WCSERR_NULL_POINTER; } err = &(pipeline->err); has_det2im = pipeline->det2im[0] != NULL || pipeline->det2im[1] != NULL; has_sip = pipeline->sip != NULL; has_p4 = pipeline->cpdis[0] != NULL || pipeline->cpdis[1] != NULL; has_wcs = pipeline->wcs != NULL; if (has_det2im || has_sip || has_p4) { if (nelem != 2) { status = wcserr_set( PIP_ERRMSG(WCSERR_BAD_COORD_TRANS), "Data must be 2-dimensional when Paper IV lookup table or SIP transform is present."); goto exit; } } if (has_wcs) { buffer = mem = malloc( ncoord * nelem * sizeof(double) + /* imgcrd */ ncoord * sizeof(double) + /* phi */ ncoord * sizeof(double) + /* theta */ ncoord * nelem * sizeof(double) + /* tmp */ ncoord * nelem * sizeof(int) /* stat */ ); if (buffer == NULL) { status = wcserr_set( PIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed"); goto exit; } imgcrd = (double *)mem; mem += ncoord * nelem * sizeof(double); phi = (double *)mem; mem += ncoord * sizeof(double); theta = (double *)mem; mem += ncoord * sizeof(double); tmp = (double *)mem; mem += ncoord * nelem * sizeof(double); stat = (int *)mem; /* mem += ncoord * nelem * sizeof(int); */ if (has_det2im || has_sip || has_p4) { status = pipeline_pix2foc(pipeline, ncoord, nelem, pixcrd, tmp); if (status != 0) { goto exit; } wcs_input = tmp; wcs_output = world; } else { wcs_input = pixcrd; wcs_output = world; } if ((status = wcsp2s(pipeline->wcs, (int)ncoord, (int)nelem, wcs_input, imgcrd, phi, theta, wcs_output, stat))) { wcserr_copy(pipeline->wcs->err, pipeline->err); } if (status == 8) { set_invalid_to_nan((int)ncoord, (int)nelem, wcs_output, stat); } } else { if (has_det2im || has_sip || has_p4) { status = pipeline_pix2foc(pipeline, ncoord, nelem, pixcrd, world); } } exit: free(buffer); return status; }
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; }