int main() { char infile[] = "pih.fits"; char devtyp[16], idents[3][80], nlcprm[1], opt[2]; int c0[] = {-1, -1, -1, -1, -1, -1, -1}; int i, ic, gcode[2], naxis[2], nkeyrec, nreject, nwcs, relax, status; float blc[2], trc[2]; double cache[257][4], grid1[1], grid2[1], nldprm[1]; struct wcsprm *wcs; nlfunc_t pgwcsl_; #if defined HAVE_CFITSIO && defined DO_CFITSIO char *header; fitsfile *fptr; #else char keyrec[81], header[28801]; int gotend, j, k; FILE *fptr; #endif /* Set line buffering in case stdout is redirected to a file, otherwise * stdout and stderr messages will be jumbled (stderr is unbuffered). */ setvbuf(stdout, NULL, _IOLBF, 0); printf("Testing WCSLIB parser for FITS image headers (tpih2.c)\n" "------------------------------------------------------\n\n"); /* Read in the FITS header, excluding COMMENT and HISTORY keyrecords. */ #if defined HAVE_CFITSIO && defined DO_CFITSIO status = 0; if (fits_open_file(&fptr, infile, READONLY, &status)) { fits_report_error(stderr, status); return 1; } if (fits_hdr2str(fptr, 1, NULL, 0, &header, &nkeyrec, &status)) { fits_report_error(stderr, status); return 1; } fits_close_file(fptr, &status); #else if ((fptr = fopen(infile, "r")) == 0x0) { printf("ERROR opening %s\n", infile); return 1; } k = 0; nkeyrec = 0; gotend = 0; for (j = 0; j < 10; j++) { for (i = 0; i < 36; i++) { if (fgets(keyrec, 81, fptr) == 0) { break; } if (strncmp(keyrec, " ", 8) == 0) continue; if (strncmp(keyrec, "COMMENT ", 8) == 0) continue; if (strncmp(keyrec, "HISTORY ", 8) == 0) continue; strncpy(header+k, keyrec, 80); k += 80; nkeyrec++; if (strncmp(keyrec, "END ", 8) == 0) { /* An END keyrecord was read, but read the rest of the block. */ gotend = 1; } } if (gotend) break; } fclose(fptr); #endif fprintf(stderr, "Found %d non-comment header keyrecords.\n", nkeyrec); relax = WCSHDR_all; if ((status = wcspih(header, nkeyrec, relax, 2, &nreject, &nwcs, &wcs))) { fprintf(stderr, "wcspih ERROR %d: %s.\n", status, wcs_errmsg[status]); } #if defined HAVE_CFITSIO && defined DO_CFITSIO free(header); #endif /* Plot setup. */ naxis[0] = 1024; naxis[1] = 1024; blc[0] = 0.5f; blc[1] = 0.5f; trc[0] = naxis[0] + 0.5f; trc[1] = naxis[1] + 0.5f; strcpy(devtyp, "/XWINDOW"); cpgbeg(0, devtyp, 1, 1); cpgvstd(); cpgwnad(0.0f, 1.0f, 0.0f, 1.0f); cpgask(1); cpgpage(); /* Annotation. */ strcpy(idents[0], "Right ascension"); strcpy(idents[1], "Declination"); opt[0] = 'G'; opt[1] = 'E'; /* Compact lettering. */ cpgsch(0.8f); /* Draw full grid lines. */ cpgsci(1); gcode[0] = 2; gcode[1] = 2; grid1[0] = 0.0; grid2[0] = 0.0; for (i = 0; i < nwcs; i++) { 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); printf("\n%s\n", idents[2]); /* Draw the celestial grid. The grid density is set for each world */ /* coordinate by specifying LABDEN = 1224. */ ic = -1; cpgsbox(blc, trc, idents, opt, 0, 1224, c0, gcode, 0.0, 0, grid1, 0, grid2, 0, pgwcsl_, 1, WCSLEN, 1, nlcprm, (int *)(wcs+i), nldprm, 256, &ic, cache, &status); /* Draw the frame. */ cpgbox("BC", 0.0f, 0, "BC", 0.0f, 0); cpgpage(); } status = wcsvfree(&nwcs, &wcs); return 0; }
int main() { char *header; int i, nkeyrec, nreject, nwcs, stat[NWCSFIX], status = 0; fitsfile *fptr; struct wcsprm *wcs; /* Set line buffering in case stdout is redirected to a file, otherwise * stdout and stderr messages will be jumbled (stderr is unbuffered). */ setvbuf(stdout, NULL, _IOLBF, 0); printf("Testing -TAB interpreter (twcstab.c)\n" "------------------------------------\n\n"); /* Create the input FITS test file. */ if (create_input()) { fprintf(stderr, "Failed to create FITS test file."); return 1; } /* Open the FITS test file and read the primary header. */ fits_open_file(&fptr, "wcstab.fits", 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. */ /*-----------------------------------------------------------------------*/ /* Do something with it. */ do_wcs_stuff(fptr, wcs); /* Finished with the FITS file. */ fits_close_file(fptr, &status); free(header); /* Clean up. */ status = wcsvfree(&nwcs, &wcs); return 0; }
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(int argc, char *argv[]) { char *infile = "TPV7.fits"; char keyrec[81], header[288001], *disfn; int dopoly, gotend, iblock, ikeyrec, inc, itest, j, k, n, naxis[2], naxis1, naxis2, nClosure, nFail, nkeyrec, nsamp, nreject, nTest, nwcs, p1, p2, status; clock_t t0, tp2x, tx2p; double absmax, dp1, dp2, *img, *img1, *img2, pix[8], pixblc[2], pixsamp[2], pixtrc[2], px, *px0, *px1, pxi[8], rel, resid, relmax; double *avgdis, *avgtot, *maxdis, *maxtot, *rmsdis, *rmstot, stats[9]; FILE *fptr; struct linprm affine, *lin, *linpol, *lintpv; struct wcsprm *wcs, wcspol; wcserr_enable(1); wcsprintf_set(stdout); /* Set line buffering in case stdout is redirected to a file, otherwise * stdout and stderr messages will be jumbled (stderr is unbuffered). */ setvbuf(stdout, NULL, _IOLBF, 0); wcsprintf("Testing closure of WCSLIB distortion routines (tdis1.c)\n" "-------------------------------------------------------\n"); /* List status return messages. */ wcsprintf("\nList of dis status return values:\n"); for (status = 1; status <= 5; status++) { wcsprintf("%4d: %s.\n", status, dis_errmsg[status]); } wcsprintf("\n"); /* Optional file name specified? */ if (1 < argc) { infile = argv[1]; } /* Read in the FITS header, excluding COMMENT and HISTORY keyrecords. */ if ((fptr = fopen(infile, "r")) == 0) { wcsprintf("ERROR opening %s\n", infile); return 1; } memset(naxis, 0, 2*sizeof(int)); k = 0; nkeyrec = 0; gotend = 0; for (iblock = 0; iblock < 100; iblock++) { for (ikeyrec = 0; ikeyrec < 36; ikeyrec++) { if (fgets(keyrec, 81, fptr) == 0) { break; } if (strncmp(keyrec, " ", 8) == 0) continue; if (strncmp(keyrec, "COMMENT ", 8) == 0) continue; if (strncmp(keyrec, "HISTORY ", 8) == 0) continue; if (strncmp(keyrec, "NAXIS", 5) == 0) { if (keyrec[5] == ' ') { sscanf(keyrec+10, "%d", &n); if (n != 2) { wcsprintf("ERROR, expecting a 2D image.\n"); return 1; } continue; } sscanf(keyrec+5, "%d = %d", &j, &n); naxis[j-1] = n; continue; } strncpy(header+k, keyrec, 80); k += 80; nkeyrec++; if (strncmp(keyrec, "END ", 10) == 0) { /* An END keyrecord was read, but read the rest of the block. */ gotend = 1; } } if (gotend) break; } fclose(fptr); /* Parse the header. */ if ((wcspih(header, nkeyrec, WCSHDR_none, 2, &nreject, &nwcs, &wcs))) { wcsperr(wcs, 0x0); return 1; } /* Is it TPV? */ dopoly = 0; if (strcmp(wcs->ctype[0], "RA---TPV") == 0) { /* Copy it and translate to Polynomial for later use. */ wcspol.flag = -1; if (wcscopy(1, wcs, &wcspol)) { wcsperr(wcs, 0x0); return 1; } /* Translate TPV to Polynomial. */ tpv2poly(&wcspol); wcspol.flag = -1; if (wcsset(&wcspol)) { wcsperr(&wcspol, 0x0); return 1; } dopoly = 1; } /* wcsset() translates the TPV "projection" into a sequent distortion. */ if (wcsset(wcs)) { wcsperr(wcs, 0x0); return 1; } /* Henceforth, we will work with linprm. */ lin = &(wcs->lin); /* Get statistics on the distortion in the inner quarter of the image. */ maxdis = stats; maxtot = maxdis + 2; avgdis = maxtot + 1; avgtot = avgdis + 2; rmsdis = avgtot + 1; rmstot = rmsdis + 2; pixblc[0] = 0.25 * naxis[0]; pixblc[1] = 0.25 * naxis[1]; pixtrc[0] = 0.75 * naxis[0]; pixtrc[1] = 0.75 * naxis[1]; pixsamp[0] = (pixtrc[0] - pixblc[0])/512.0; pixsamp[1] = (pixtrc[1] - pixblc[1])/512.0; if (pixsamp[0] < 1.0) pixsamp[0] = 1.0; if (pixsamp[1] < 1.0) pixsamp[1] = 1.0; if (linwarp(lin, pixblc, pixtrc, pixsamp, &nsamp, maxdis, maxtot, avgdis, avgtot, rmsdis, rmstot)) { linperr(lin, 0x0); return 1; } for (k = 0; k < 9; k++) { if (fabs(stats[k]) < 0.0005) stats[k] = 0.0; } wcsprintf("linwarp() statistics computed over %d sample points:\n" " Max distortion, axis 1: %8.3f pixels\n" " axis 2: %8.3f pixels\n" " total: %8.3f pixels\n" " Mean distortion, axis 1: %8.3f pixels\n" " axis 2: %8.3f pixels\n" " total: %8.3f pixels\n" " RMS distortion, axis 1: %8.3f pixels\n" " axis 2: %8.3f pixels\n" " total: %8.3f pixels\n", nsamp, maxdis[0], maxdis[1], *maxtot, avgdis[0], avgdis[1], *avgtot, rmsdis[0], rmsdis[1], *rmstot); if (lin->disseq) { /* Exercise diswarp() as well. */ wcsprintf("\n"); /* Define a rectangle in intermediate pixel coordinates that just */ /* encompasses the inner quarter of the image. For this we need */ /* to switch off CDELTia scaling and all distortions. */ affine.flag = -1; if ((status = lincpy(1, lin, &affine))) { linperr(lin, 0x0); return 1; } affine.cdelt[0] = 1.0; affine.cdelt[1] = 1.0; if ((status = (lindis(1, &affine, 0x0) || lindis(2, &affine, 0x0) || linset(&affine)))) { linperr(&affine, 0x0); return 1; } pix[0] = pixblc[0]; pix[1] = pixblc[1]; pix[2] = pixtrc[0]; pix[3] = pixblc[1]; pix[4] = pixtrc[0]; pix[5] = pixtrc[1]; pix[6] = pixblc[0]; pix[7] = pixtrc[1]; if (linp2x(&affine, 4, 2, pix, pxi)) { linperr(&affine, 0x0); return 1; } linfree(&affine); pixblc[0] = pxi[0]; pixblc[1] = pxi[1]; pixtrc[0] = pxi[0]; pixtrc[1] = pxi[1]; k = 2; for (j = 1; j < 4; j++) { if (pixblc[0] > pxi[k]) pixblc[0] = pxi[k]; if (pixtrc[0] < pxi[k]) pixtrc[0] = pxi[k]; k++; if (pixblc[1] > pxi[k]) pixblc[1] = pxi[k]; if (pixtrc[1] < pxi[k]) pixtrc[1] = pxi[k]; k++; } pixsamp[0] = (pixtrc[0] - pixblc[0])/512.0; pixsamp[1] = (pixtrc[1] - pixblc[1])/512.0; if (diswarp(lin->disseq, pixblc, pixtrc, pixsamp, &nsamp, maxdis, maxtot, avgdis, avgtot, rmsdis, rmstot)) { wcserr_prt(lin->disseq->err, 0x0); return 1; } for (k = 0; k < 9; k++) { if (fabs(stats[k]) < 0.0005) stats[k] = 0.0; } wcsprintf("diswarp() statistics computed over %d sample points:\n" " Max distortion, axis 1: %8.3f units\n" " axis 2: %8.3f units\n" " total: %8.3f units\n" " Mean distortion, axis 1: %8.3f units\n" " axis 2: %8.3f units\n" " total: %8.3f units\n" " RMS distortion, axis 1: %8.3f units\n" " axis 2: %8.3f units\n" " total: %8.3f units\n", nsamp, maxdis[0], maxdis[1], *maxtot, avgdis[0], avgdis[1], *avgtot, rmsdis[0], rmsdis[1], *rmstot); } /* The image size determines the test domain. */ if ((naxis1 = naxis[0]) == 0) { naxis1 = 2*wcs->crpix[0] + 1; } if ((naxis2 = naxis[1]) == 0) { naxis2 = 2*wcs->crpix[1] + 1; } /* Limit the number of tests. */ inc = 1; while ((naxis1/inc)*(naxis2/inc) > 800000) { inc *= 2; } n = naxis1 / inc; px0 = calloc(4*(2*n), sizeof(double)); px1 = px0 + 2*n ; img = px1 + 2*n ; img1 = img; img2 = img + 2*n; for (itest = 0; itest < 2; itest++) { if (itest) { if (!dopoly) break; lin = &(wcspol.lin); } if (lin->dispre) { disfn = lin->dispre->dtype[0]; } else if (lin->disseq) { disfn = lin->disseq->dtype[0]; } wcsprintf("\n"); /* Now the closure test. */ tp2x = 0; tx2p = 0; nTest = 0; nFail = 0; nClosure = 0; absmax = 0.0; relmax = 0.0; for (p2 = 1; p2 <= naxis2; p2 += inc) { k = 0; for (p1 = 1; p1 <= naxis1; p1 += inc) { px0[k++] = (double)p1; px0[k++] = (double)p2; } t0 = clock(); if (linp2x(lin, n, 2, px0, img)) { linperr(lin, 0x0); nFail = 1; break; } tp2x += clock() - t0; t0 = clock(); if (linx2p(lin, n, 2, img, px1)) { linperr(lin, 0x0); nFail = 1; break; } tx2p += clock() - t0; /* Check closure. */ k = 0; for (k = 0; k < 2*n ; k += 2) { dp1 = fabs(px1[k] - px0[k]); dp2 = fabs(px1[k+1] - px0[k+1]); resid = (dp1 > dp2) ? dp1 : dp2; if (resid > absmax) absmax = resid; if (resid > ATOL) { nClosure++; wcsprintf("Absolute closure error:\n"); wcsprintf(" pix: %18.12f %18.12f\n", px0[k], px0[k+1]); wcsprintf(" -> img: %18.12f %18.12f\n", img[k], img[k+1]); wcsprintf(" -> pix: %18.12f %18.12f\n", px1[k], px1[k+1]); wcsprintf("\n"); continue; } resid = 0.0; if ((px = fabs(px0[k])) > 1.0) resid = dp1/px; if ((px = fabs(px0[k+1])) > 1.0) { if ((rel = dp2/px) > resid) resid = rel; } if (resid > relmax) relmax = resid; if (resid > FTOL) { nClosure++; wcsprintf("Relative closure error:\n"); wcsprintf(" pix: %18.12f %18.12f\n", px0[k], px0[k+1]); wcsprintf(" -> img: %18.12f %18.12f\n", img[k], img[k+1]); wcsprintf(" -> pix: %18.12f %18.12f\n", px1[k], px1[k+1]); wcsprintf("\n"); } } nTest += n; } if (nFail) { wcsprintf("\nFAIL: The %s test failed to complete.\n", disfn); } else { wcsprintf("linp2x/linx2p with %s distortions:\n" " Completed %d closure tests.\n" " Maximum absolute closure residual = %.2e pixel.\n" " Maximum relative closure residual = %.2e.\n", disfn, nTest, absmax, relmax); wcsprintf("\n"); wcsprintf(" linp2x time (ns): %6.0f\n linx2p time (ns): %6.0f\n\n", 1.0e9*((double)tp2x/CLOCKS_PER_SEC)/nTest, 1.0e9*((double)tx2p/CLOCKS_PER_SEC)/nTest); if (nClosure) { wcsprintf("FAIL: %d closure residuals exceed reporting tolerance.\n", nClosure); } else { wcsprintf("PASS: All %s closure residuals are within reporting " "tolerance.\n", disfn); } } } /* Compare TPV with Polynomial over the test domain. */ if (dopoly) { wcsprintf("\n"); nTest = 0; nFail = 0; absmax = 0.0; lintpv = &(wcs->lin); linpol = &(wcspol.lin); for (p2 = 1; p2 <= naxis2; p2 += inc) { k = 0; for (p1 = 1; p1 <= naxis1; p1 += inc) { px0[k++] = (double)p1; px0[k++] = (double)p2; } if (linp2x(lintpv, n, 2, px0, img1)) { linperr(lintpv, 0x0); break; } if (linp2x(linpol, n, 2, px0, img2)) { linperr(linpol, 0x0); break; } /* Check agreement. */ k = 0; for (k = 0; k < 2*n ; k += 2) { dp1 = fabs(img2[k] - img1[k]); dp2 = fabs(img2[k+1] - img1[k+1]); resid = (dp1 > dp2) ? dp1 : dp2; if (resid > absmax) absmax = resid; if (resid > ATOL) { nFail++; wcsprintf("TPV - Polynomial disagreement:\n"); wcsprintf(" pix: %18.12f %18.12f\n", px0[k], px0[k+1]); wcsprintf(" -> TPV: %18.12f %18.12f\n", img1[k], img1[k+1]); wcsprintf(" -> Pol: %18.12f %18.12f\n", img2[k], img2[k+1]); wcsprintf("\n"); continue; } } nTest += n; } wcsprintf("linp2x, TPV vs Polynomial distortions:\n" " Completed %d comparisons.\n" " Maximum absolute disagreement = %.2e units.\n", nTest, absmax); wcsprintf("\n"); if (nFail) { wcsprintf("FAIL: %d comparisons exceed reporting tolerance.\n", nFail); } else { wcsprintf("PASS: All TPV vs Polynomial comparisons are within " "reporting tolerance.\n"); } } free(px0); wcsvfree(&nwcs, &wcs); wcsfree(&wcspol); return nFail || nClosure; }
int main(int argc, char *argv[]) { char *infile = "SIP.fits"; char keyrec[81], header[288001]; int axes[4], gotend, iblock, ikeyrec, j, k, n, naxis[4], nkeyrec, nreject, nsamp, nsub, nwcs, status; double pixblc[4], pixsamp[4], pixtrc[4]; double *avgdis, *avgtot, *maxdis, *maxtot, *rmsdis, *rmstot, stats[15]; FILE *fptr; struct linprm *lin; struct wcsprm *wcs, wcsext; wcserr_enable(1); wcsprintf_set(stdout); /* Set line buffering in case stdout is redirected to a file, otherwise * stdout and stderr messages will be jumbled (stderr is unbuffered). */ setvbuf(stdout, NULL, _IOLBF, 0); wcsprintf("Testing wcssub() with distortions (tdis2.c)\n" "-------------------------------------------\n"); /* Optional file name specified? */ if (1 < argc) { infile = argv[1]; } /* Read in the FITS header, excluding COMMENT and HISTORY keyrecords. */ if ((fptr = fopen(infile, "r")) == 0) { wcsprintf("ERROR opening %s\n", infile); return 1; } memset(naxis, 0, 2*sizeof(int)); k = 0; nkeyrec = 0; gotend = 0; for (iblock = 0; iblock < 100; iblock++) { for (ikeyrec = 0; ikeyrec < 36; ikeyrec++) { if (fgets(keyrec, 81, fptr) == 0) { break; } if (strncmp(keyrec, " ", 8) == 0) continue; if (strncmp(keyrec, "COMMENT ", 8) == 0) continue; if (strncmp(keyrec, "HISTORY ", 8) == 0) continue; if (strncmp(keyrec, "NAXIS", 5) == 0) { if (keyrec[5] == ' ') { sscanf(keyrec+10, "%d", &n); if (4 < n) { wcsprintf("ERROR, can't handle more than 4 axes.\n"); return 1; } continue; } sscanf(keyrec+5, "%d = %d", &j, &n); naxis[j-1] = n; continue; } strncpy(header+k, keyrec, 80); k += 80; nkeyrec++; if (strncmp(keyrec, "END ", 10) == 0) { /* An END keyrecord was read, but read the rest of the block. */ gotend = 1; } } if (gotend) break; } fclose(fptr); /* Parse the header. */ if ((wcspih(header, nkeyrec, WCSHDR_none, 2, &nreject, &nwcs, &wcs))) { wcsperr(wcs, 0x0); return 1; } /* Extract the coordinate description for a transposed subimage and prepend a new axis. Also tests wcssub() on a struct that hasn't been set up. */ nsub = 3; axes[0] = 0; axes[1] = WCSSUB_LATITUDE; axes[2] = WCSSUB_LONGITUDE; wcsext.flag = -1; if ((status = wcssub(1, wcs, &nsub, axes, &wcsext))) { wcsperr(&wcsext, ""); goto cleanup; } else if (nsub == 0) { printf("None of the requested subimage axes were found.\n"); goto cleanup; } /* Print the original and extracted structs. */ printf("\nInitial contents of wcsprm struct:\n"); if ((status = wcsset(wcs))) { wcsperr(wcs, ""); goto cleanup; }; wcsprt(wcs); printf("\n\nExtracted contents of wcsprm struct:\n"); if ((status = wcsset(&wcsext))) { wcsperr(&wcsext, ""); goto cleanup; } wcsprt(&wcsext); /* Compute distortion statistics in the initial struct. */ maxdis = stats; maxtot = maxdis + 4; avgdis = maxtot + 1; avgtot = avgdis + 4; rmsdis = avgtot + 1; rmstot = rmsdis + 4; pixblc[0] = 1.0; pixblc[1] = 1.0; pixblc[2] = 1.0; pixblc[3] = 1.0; pixtrc[0] = 256.0; pixtrc[1] = 256.0; pixtrc[2] = 1.0; pixtrc[3] = 1.0; pixsamp[0] = 1.0; pixsamp[1] = 1.0; pixsamp[2] = 1.0; pixsamp[3] = 1.0; lin = &(wcs->lin); if (linwarp(lin, pixblc, pixtrc, pixsamp, &nsamp, maxdis, maxtot, avgdis, avgtot, rmsdis, rmstot)) { linperr(lin, 0x0); return 1; } for (k = 0; k < 12; k++) { if (fabs(stats[k]) < 0.0005) stats[k] = 0.0; } wcsprintf("\n\n" "Initial linwarp() statistics computed over %d sample points:\n" " Max distortion, axis 1: %10.5f pixels\n" " axis 2: %10.5f pixels\n" " axis 3: %10.5f pixels\n" " axis 4: %10.5f pixels\n" " total: %10.5f pixels\n" " Mean distortion, axis 1: %10.5f pixels\n" " axis 2: %10.5f pixels\n" " axis 3: %10.5f pixels\n" " axis 4: %10.5f pixels\n" " total: %10.5f pixels\n" " RMS distortion, axis 1: %10.5f pixels\n" " axis 2: %10.5f pixels\n" " axis 3: %10.5f pixels\n" " axis 4: %10.5f pixels\n" " total: %10.5f pixels\n", nsamp, maxdis[0], maxdis[1], maxdis[2], maxdis[3], *maxtot, avgdis[0], avgdis[1], avgdis[2], avgdis[3], *avgtot, rmsdis[0], rmsdis[1], rmsdis[2], rmsdis[3], *rmstot); /* Compute distortion statistics in the extracted struct. */ pixtrc[0] = 1.0; pixtrc[1] = 256.0; pixtrc[2] = 256.0; lin = &(wcsext.lin); if (linwarp(lin, pixblc, pixtrc, pixsamp, &nsamp, maxdis, maxtot, avgdis, avgtot, rmsdis, rmstot)) { linperr(lin, 0x0); return 1; } for (k = 0; k < 12; k++) { if (fabs(stats[k]) < 0.0005) stats[k] = 0.0; } wcsprintf("\n" "linwarp() statistics for extract computed over the same %d points:\n" " Max distortion, axis 1: %10.5f pixels\n" " axis 2: %10.5f pixels\n" " axis 3: %10.5f pixels\n" " total: %10.5f pixels\n" " Mean distortion, axis 1: %10.5f pixels\n" " axis 2: %10.5f pixels\n" " axis 3: %10.5f pixels\n" " total: %10.5f pixels\n" " RMS distortion, axis 1: %10.5f pixels\n" " axis 2: %10.5f pixels\n" " axis 3: %10.5f pixels\n" " total: %10.5f pixels\n", nsamp, maxdis[0], maxdis[1], maxdis[2], *maxtot, avgdis[0], avgdis[1], avgdis[2], *avgtot, rmsdis[0], rmsdis[1], rmsdis[2], *rmstot); cleanup: wcsvfree(&nwcs, &wcs); wcsfree(&wcsext); return status; }
int main() { char infile[] = "test.fits"; char text[80]; int i, j, k, ncards, nkeyids, nreject, status; struct fitskey *keys, *kptr; struct fitskeyid keyids[8]; #if defined HAVE_CFITSIO && defined DO_CFITSIO char *header; fitsfile *fptr; #else char card[81], header[288001]; int end; FILE *fptr; #endif #ifdef DO_WCSHDR struct wcsprm *wcs; int ctrl, nwcs, relax; #endif printf("Testing FITS image header parser (tfitshdr.c)\n" "---------------------------------------------\n\n"); /* Read in the FITS header. */ #if defined HAVE_CFITSIO && defined DO_CFITSIO status = 0; if (fits_open_file(&fptr, infile, READONLY, &status)) { fits_report_error(stderr, status); return 1; } if (fits_hdr2str(fptr, 0, NULL, 0, &header, &ncards, &status)) { fits_report_error(stderr, status); return 1; } fits_close_file(fptr, &status); #else if ((fptr = fopen(infile, "r")) == 0) { printf("ERROR opening %s\n", infile); return 1; } k = 0; end = 0; ncards = 0; for (j = 0; j < 100; j++) { for (i = 0; i < 36; i++) { if (fgets(card, 81, fptr) == 0) { break; } strncpy(header+k, card, 80); k += 80; ncards++; if (strncmp(card, "END ", 8) == 0) { /* An END card was read, but read the rest of the block. */ end = 1; } } if (end) break; } fclose(fptr); #endif printf("Found %d header cards.\n", ncards); #ifdef DO_WCSHDR /* Cull all recognized, syntactically valid WCS cards from the header. */ relax = WCSHDR_all; ctrl = -1; if (status = wcspih(header, ncards, relax, ctrl, &nreject, &nwcs, &wcs)) { fprintf(stderr, "wcspih ERROR %d: %s.\n", status, wcs_errmsg[status]); return 1; } /* Number remaining. */ ncards = strlen(header) / 80; #endif /* Specific keywords to be located or culled. */ strcpy(keyids[0].name, "SIMPLE "); strcpy(keyids[1].name, "BITPIX "); strcpy(keyids[2].name, "NAXIS "); strcpy(keyids[3].name, "COMMENT "); strcpy(keyids[4].name, "HISTORY "); strcpy(keyids[5].name, " "); strcpy(keyids[6].name, "END "); nkeyids = 7; if (nkeyids) { printf("\nThe following cards will not be listed:\n"); for (i = 0; i < nkeyids; i++) { printf(" \"%8s\"\n", keyids[i].name); } } /* Parse the header. */ if (status = fitshdr(header, ncards, nkeyids, keyids, &nreject, &keys)) { printf("fitskey ERROR %d: %s.\n", status, fitshdr_errmsg[status]); } #if defined HAVE_CFITSIO && defined DO_CFITSIO free(header); #endif /* Report the results. */ printf("\n%d header cards parsed by fitshdr(), %d rejected:\n\n", ncards, nreject); kptr = keys; for (i = 0; i < ncards; i++, kptr++) { /* Skip syntactically valid cards that were indexed. */ if (kptr->keyno < 0 && !kptr->status) continue; /* Basic card info. */ printf("%4d%5d %-8s%3d", kptr->keyno, kptr->status, kptr->keyword, kptr->type); /* Format the keyvalue for output. */ switch (abs(kptr->type)%10) { case 1: /* Logical. */ sprintf(text, "%c", kptr->keyvalue.i?'T':'F'); break; case 2: /* 32-bit signed integer. */ sprintf(text, "%d", kptr->keyvalue.i); break; case 3: /* 64-bit signed integer. */ #ifdef WCS_INT64 sprintf(text, "%+Ld", kptr->keyvalue.k); #else if (kptr->keyvalue.k[2]) { sprintf(text, "%+d%09d%09d", kptr->keyvalue.k[2], abs(kptr->keyvalue.k[1]), abs(kptr->keyvalue.k[0])); } else { sprintf(text, "%+d%09d", kptr->keyvalue.k[1], abs(kptr->keyvalue.k[0])); } #endif break; case 4: /* Very long integer. */ k = 0; for (j = 7; j > 0; j--) { if (kptr->keyvalue.l[j]) { k = j; break; } } sprintf(text, "%+d", kptr->keyvalue.l[k]); for (j = k-1; j >= 0; j--) { sprintf(text+strlen(text), "%09d", abs(kptr->keyvalue.l[j])); } break; case 5: /* Float. */ sprintf(text, "%+13.6E", kptr->keyvalue.f); break; case 6: /* Int complex. */ sprintf(text, "%.0f %.0f", kptr->keyvalue.c[0], kptr->keyvalue.c[1]); break; case 7: /* Float complex. */ sprintf(text, "%+13.6E %+13.6E", kptr->keyvalue.c[0], kptr->keyvalue.c[1]); break; case 8: /* String. */ sprintf(text, "\"%s\"", kptr->keyvalue.s); break; default: /* No value. */ *text = '\0'; break; } if (kptr->type > 0) { /* Keyvalue successfully extracted. */ printf(" %s", text); } else if (kptr->type < 0) { /* Syntax error of some type while extracting the keyvalue. */ printf(" (%s)", text); } /* Units? */ if (kptr->ulen) { printf(" %.*s", kptr->ulen-2, kptr->comment+1); } /* Comment text or reject card. */ printf("\n%s\n", kptr->comment); } /* Print indexes. */ printf("\n\nIndexes of selected keywords:\n"); for (i = 0; i < nkeyids; i++) { printf("%-8s%5d%5d%5d", keyids[i].name, keyids[i].count, keyids[i].idx[0], keyids[i].idx[1]); /* Print logical (SIMPLE) and integer (BITPIX, NAXIS) values. */ if (keyids[i].count) { kptr = keys + keyids[i].idx[0]; printf("%4d", kptr->type); if (kptr->type == 1) { printf("%5c", kptr->keyvalue.i?'T':'F'); } else if (kptr->type == 2) { printf("%5d", kptr->keyvalue.i); } } printf("\n"); } free(keys); return 0; }
int main(int argc, char **argv) { char alt = '\0', *header, idents[3][80], *infile, keyword[16], nlcprm[1], opt[2], pgdev[16]; int c0[] = {-1, -1, -1, -1, -1, -1, -1}; int alts[27], gcode[2], hdunum = 1, hdutype, i, ic, naxes, naxis[2], nkeyrec, nreject, nwcs, stat[NWCSFIX], status; float blc[2], trc[2]; double cache[257][4], grid1[3], grid2[3], nldprm[1]; struct wcsprm *wcs; nlfunc_t pgwcsl_; fitsfile *fptr; /* Parse options. */ strcpy(pgdev, "/XWINDOW"); 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 'd': if (argv[i][2] == '?') { cpgldev(); return 0; } if (argv[i][2] == '/') { strncpy(pgdev+1, argv[i]+3, 15); } else { strncpy(pgdev+1, argv[i]+2, 15); } break; case 'h': hdunum = atoi(argv[i]+2); 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("wcsgrid: Cannot access %s.\n", infile); return 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; } /* Check that we have at least two image axes. */ if (fits_read_key(fptr, TINT, "NAXIS", &naxes, NULL, &status)) { goto fitserr; } if (naxes < 2) { fprintf(stderr, "ERROR, HDU number %d does not contain a 2-D image.\n", hdunum); return 1; } else if (naxes > 2) { printf("HDU number %d contains a %d-D image array.\n", hdunum, naxes); } /* 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); /* Read -TAB arrays from the binary table extension (if necessary). */ if (fits_read_wcstab(fptr, wcs->nwtb, (wtbarr *)wcs->wtb, &status)) { goto fitserr; } /* Translate non-standard WCS keyvalues. */ if ((status = wcsfix(7, 0, wcs, stat))) { status = 0; for (i = 0; i < NWCSFIX; i++) { if (stat[i] > 0) { fprintf(stderr, "wcsfix ERROR %d: %s.\n", stat[i], wcsfix_errmsg[stat[i]]); /* Ignore problems with CDi_ja and DATE-OBS. */ if (!(i == CDFIX || i == DATFIX)) status = 1; } } if (status) return 1; } /* Sort out alternates. */ if (alt) { wcsidx(nwcs, &wcs, alts); if (alt == ' ') { if (alts[0] == -1) { fprintf(stderr, "WARNING, no primary coordinate representation, " "doing all.\n"); alt = '\0'; } } else if (alt < 'A' || alt > 'Z') { fprintf(stderr, "WARNING, alternate specifier \"%c\" is invalid, " "doing all.\n", alt); alt = '\0'; } else { if (alts[alt - 'A' + 1] == -1) { fprintf(stderr, "WARNING, no alternate coordinate representation " "\"%c\", doing all.\n", alt); alt = '\0'; } } } /* Get image dimensions from the header. */ sprintf(keyword, "NAXIS%d", wcs->lng + 1); fits_read_key(fptr, TINT, "NAXIS1", naxis, NULL, &status); sprintf(keyword, "NAXIS%d", wcs->lat + 1); fits_read_key(fptr, TINT, "NAXIS2", naxis+1, NULL, &status); if ((naxis[0] < 2) || (naxis[1] < 2)) { fprintf(stderr, "ERROR, HDU number %d contains degenerate image axes.\n", hdunum); return 1; } fits_close_file(fptr, &status); /* Plot setup. */ blc[0] = 0.5f; blc[1] = 0.5f; trc[0] = naxis[0] + 0.5f; trc[1] = naxis[1] + 0.5f; if (cpgbeg(0, pgdev, 1, 1) != 1) { fprintf(stderr, "ERROR, failed to open PGPLOT device %s.\n", pgdev); return 1; } cpgvstd(); cpgwnad(blc[0], trc[0], blc[0], trc[1]); cpgask(1); cpgpage(); /* Compact lettering. */ cpgsch(0.8f); /* Draw full grid lines. */ gcode[0] = 2; gcode[1] = 2; grid1[0] = 0.0; grid2[0] = 0.0; /* These are for the projection boundary. */ grid1[1] = -180.0; grid1[2] = 180.0; grid2[1] = -90.0; grid2[2] = 90.0; cpgsci(1); for (i = 0; i < nwcs; i++) { if (alt && (wcs+i)->alt[0] != alt) { continue; } if ((status = wcsset(wcs+i))) { fprintf(stderr, "wcsset ERROR %d: %s.\n", status, wcs_errmsg[status]); continue; } /* Draw the frame. */ cpgbox("BC", 0.0f, 0, "BC", 0.0f, 0); /* Axis labels; use CNAMEia in preference to CTYPEia. */ if ((wcs+i)->cname[0][0]) { strcpy(idents[0], (wcs+i)->cname[0]); } else { strcpy(idents[0], (wcs+i)->ctype[0]); } if ((wcs+i)->cname[1][0]) { strcpy(idents[1], (wcs+i)->cname[1]); } else { strcpy(idents[1], (wcs+i)->ctype[1]); } /* Title; use WCSNAME. */ strcpy(idents[2], (wcs+i)->wcsname); if (strlen(idents[2])) { printf("\n%s\n", idents[2]); } /* Formatting control for celestial coordinates. */ if (strncmp((wcs+i)->ctype[0], "RA", 2) == 0) { /* Right ascension in HMS, declination in DMS. */ opt[0] = 'G'; opt[1] = 'E'; } else { /* Other angles in decimal degrees. */ opt[0] = 'A'; opt[1] = 'B'; } /* Draw the celestial grid. The grid density is set for each world */ /* coordinate by specifying LABDEN = 1224. */ ic = -1; cpgsbox(blc, trc, idents, opt, 0, 1224, c0, gcode, 0.0, 0, grid1, 0, grid2, 0, pgwcsl_, 1, WCSLEN, 1, nlcprm, (int *)(wcs+i), nldprm, 256, &ic, cache, &status); /* Delimit the projection boundary. */ if ((wcs+i)->cel.prj.category != ZENITHAL) { /* Reset to the native coordinate graticule. */ (wcs+i)->crval[0] = (wcs+i)->cel.prj.phi0; (wcs+i)->crval[1] = (wcs+i)->cel.prj.theta0; (wcs+i)->lonpole = 999.0; (wcs+i)->latpole = 999.0; status = wcsset(wcs+i); ic = -1; cpgsbox(blc, trc, idents, opt, -1, 0, c0, gcode, 0.0, 2, grid1, 2, grid2, 0, pgwcsl_, 1, WCSLEN, 1, nlcprm, (int *)(wcs+i), nldprm, 256, &ic, cache, &status); } cpgpage(); } status = wcsvfree(&nwcs, &wcs); return 0; fitserr: fits_report_error(stderr, status); fits_close_file(fptr, &status); return 1; }
int main() { char infile[] = "pih.fits"; char a, *hptr; int alts[27], ctrl, ialt, iblock, ifix, ikeyrec, iwcs, nkeyrec, nreject, nwcs, relax, stat[NWCSFIX], status; struct wcsprm *wcs; #if defined HAVE_CFITSIO && defined DO_CFITSIO char *header; fitsfile *fptr; #else char keyrec[81], header[288001]; int gotend, k; FILE *fptr; #endif /* Set line buffering in case stdout is redirected to a file, otherwise * stdout and stderr messages will be jumbled (stderr is unbuffered). */ setvbuf(stdout, NULL, _IOLBF, 0); printf("Testing WCSLIB parser for FITS image headers (tpih1.c)\n" "------------------------------------------------------\n\n"); /* Read in the FITS header, excluding COMMENT and HISTORY keyrecords. */ #if defined HAVE_CFITSIO && defined DO_CFITSIO status = 0; if (fits_open_file(&fptr, infile, READONLY, &status)) { fits_report_error(stderr, status); return 1; } if (fits_hdr2str(fptr, 1, NULL, 0, &header, &nkeyrec, &status)) { fits_report_error(stderr, status); return 1; } fits_close_file(fptr, &status); #else if ((fptr = fopen(infile, "r")) == 0) { fprintf(stderr, "ERROR opening %s\n", infile); return 1; } k = 0; nkeyrec = 0; gotend = 0; for (iblock = 0; iblock < 100; iblock++) { for (ikeyrec = 0; ikeyrec < 36; ikeyrec++) { if (fgets(keyrec, 81, fptr) == 0) { break; } if (strncmp(keyrec, " ", 8) == 0) continue; if (strncmp(keyrec, "COMMENT ", 8) == 0) continue; if (strncmp(keyrec, "HISTORY ", 8) == 0) continue; strncpy(header+k, keyrec, 80); k += 80; nkeyrec++; if (strncmp(keyrec, "END ", 8) == 0) { /* An END keyrecord was read, but read the rest of the block. */ gotend = 1; } } if (gotend) break; } fclose(fptr); #endif fprintf(stderr, "Found %d non-comment header keyrecords.\n\n", nkeyrec); /* Parse the header, allowing all recognized non-standard WCS keywords and * usage. All WCS keyrecords are culled from the header, illegal ones are * reported. */ relax = WCSHDR_all; ctrl = -2; fprintf(stderr, "\nIllegal or extraneous WCS header keyrecords rejected " "by wcspih():\n"); if ((status = wcspih(header, nkeyrec, relax, ctrl, &nreject, &nwcs, &wcs))) { fprintf(stderr, "wcspih ERROR %d: %s.\n", status, wcs_errmsg[status]); } if (!nreject) fprintf(stderr, "(none)\n"); /* List the remaining keyrecords. */ printf("\n\nNon-WCS header keyrecords ignored by wcspih():\n"); hptr = header; while (*hptr) { printf("%.80s\n", hptr); hptr += 80; } #if defined HAVE_CFITSIO && defined DO_CFITSIO free(header); #endif /* Summarize what was found. */ status = wcsidx(nwcs, &wcs, alts); printf("\n\nFound %d alternate coordinate descriptions with indices:\n ", nwcs); for (a = 'A'; a <= 'Z'; a++) { printf("%2c", a); } printf("\n"); for (ialt = 0; ialt < 27; ialt++) { if (alts[ialt] < 0) { printf(" -"); } else { printf("%2d", alts[ialt]); } } printf("\n"); /* Fix non-standard usage and print each of the wcsprm structs. The output * from wcsprt() will be written to an internal buffer and then printed just * to show that it can be done. */ wcsprintf_set(0x0); for (iwcs = 0; iwcs < nwcs; iwcs++) { wcsprintf("\n------------------------------------" "------------------------------------\n"); /* Fix non-standard WCS keyvalues. */ if ((status = wcsfix(7, 0, wcs+iwcs, stat))) { printf("wcsfix ERROR, status returns: ("); for (ifix = 0; ifix < NWCSFIX; ifix++) { printf(ifix ? ", %d" : "%d", stat[ifix]); } printf(")\n\n"); } if ((status = wcsset(wcs+iwcs))) { fprintf(stderr, "wcsset ERROR %d: %s.\n", status, wcs_errmsg[status]); continue; } if ((status = wcsprt(wcs+iwcs))) { fprintf(stderr, "wcsprt ERROR %d: %s.\n", status, wcs_errmsg[status]); } } printf("%s", wcsprintf_buf()); status = wcsvfree(&nwcs, &wcs); return 0; }
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; }
/* Read the WCS information from the header. Unfortunately, WCS lib is not thread safe, so it needs a mutex. In case you are not using multiple threads, just pass a NULL pointer as the mutex. After you finish with this WCS, you should free the space with: status = wcsvfree(&nwcs,&wcs); If the WCS structure is not recognized, then this function will return a NULL pointer for the wcsprm structure and a zero for nwcs. It will also report the fact to the user in stderr. =================================== WARNING: wcspih IS NOT THREAD SAFE! =================================== Don't call this function within a thread or use a mutex. */ struct wcsprm * gal_wcs_read_fitsptr(fitsfile *fptr, size_t hstartwcs, size_t hendwcs, int *nwcs) { /* Declaratins: */ int nkeys=0, status=0; struct wcsprm *wcs=NULL; char *fullheader, *to, *from; int relax = WCSHDR_all; /* Macro: use all informal WCS extensions. */ int ctrl = 0; /* Don't report why a keyword wasn't used. */ int nreject = 0; /* Number of keywords rejected for syntax. */ /* CFITSIO function: */ if( fits_hdr2str(fptr, 1, NULL, 0, &fullheader, &nkeys, &status) ) gal_fits_io_error(status, NULL); /* Only consider the header keywords in the current range: */ if(hendwcs>hstartwcs) { /* Mark the last character in the desired region. */ fullheader[hendwcs*(FLEN_CARD-1)]='\0'; /*******************************************************/ /****************************************************** printf("%s\n", fullheader); ******************************************************/ /*******************************************************/ /* Shift all the characters to the start of the string. */ if(hstartwcs) /* hstartwcs!=0 */ { to=fullheader; from=&fullheader[hstartwcs*(FLEN_CARD-1)-1]; while(*from++!='\0') *to++=*from; } nkeys=hendwcs-hstartwcs; /*******************************************************/ /****************************************************** printf("\n\n\n###############\n\n\n\n\n\n"); printf("%s\n", &fullheader[1*(FLEN_CARD-1)]); exit(0); ******************************************************/ /*******************************************************/ } /* WCSlib function to parse the FITS headers. */ status=wcspih(fullheader, nkeys, relax, ctrl, &nreject, nwcs, &wcs); if(status) { fprintf(stderr, "\n##################\n" "WCSLIB Warning: wcspih ERROR %d: %s.\n" "##################\n", status, wcs_errmsg[status]); wcs=NULL; *nwcs=0; } if (fits_free_memory(fullheader, &status) ) gal_fits_io_error(status, "problem in fitsarrayvv.c for freeing " "the memory used to keep all the headers"); /* Set the internal structure: */ if(wcs) { /* CTYPE is a mandatory WCS keyword, so if it hasn't been given (its '\0'), then the headers didn't have a WCS structure. However, WCSLIB still fills in the basic information (for example the dimensionality of the dataset). */ if(wcs->ctype[0][0]=='\0') { wcsfree(wcs); wcs=NULL; *nwcs=0; } else { /* Set the WCS structure. */ status=wcsset(wcs); if(status) { fprintf(stderr, "\n##################\n" "WCSLIB Warning: wcsset ERROR %d: %s.\n" "##################\n", status, wcs_errmsg[status]); wcsfree(wcs); wcs=NULL; *nwcs=0; } else /* A correctly useful WCS is present. When no PC matrix elements were present in the header, the default PC matrix (a unity matrix) is used. In this case WCSLIB doesn't set `altlin' (and gives it a value of 0). In Gnuastro, later on, we might need to know the type of the matrix used, so in such a case, we will set `altlin' to 1. */ if(wcs->altlin==0) wcs->altlin=1; } } /* Return the WCS structure. */ return wcs; }