int main() { char ctypeS[9]; int i, stat[NWCSFIX], status; struct wcsprm wcs; printf("Testing WCSLIB translator for non-standard usage (twcsfix.c)\n" "------------------------------------------------------------\n\n"); wcs.flag = -1; parser(&wcs); /* Print the unmodified struct. */ wcsprt(&wcs); printf("\n------------------------------------" "------------------------------------\n"); /* Fix non-standard WCS keyvalues. */ if ((status = wcsfix(7, 0, &wcs, stat))) { printf("wcsfix error, status returns: ("); for (i = 0; i < NWCSFIX; i++) { printf(i ? ", %d" : "%d", stat[i]); } printf(")\n"); return 1; } wcsprt(&wcs); printf("\n------------------------------------" "------------------------------------\n"); /* Should now have a 'VOPT-F2W' axis, translate it to frequency. */ strcpy(ctypeS, "FREQ-???"); i = -1; if ((status = wcssptr(&wcs, &i, ctypeS))) { printf("wcssptr ERROR %d: %s.n", status, wcs_errmsg[status]); return 1; } if ((status = wcsset(&wcs))) { printf("wcsset ERROR %d: %s.\n", status, wcs_errmsg[status]); return 1; } wcsprt(&wcs); wcsfree(&wcs); return 0; }
int wcsvfree(int *nwcs, struct wcsprm **wcs) { int a, status = 0; struct wcsprm *wcsp; if (wcs == 0) { return 1; } wcsp = *wcs; for (a = 0; a < *nwcs; a++, wcsp++) { status |= wcsfree(wcsp); } free(*wcs); *nwcs = 0; *wcs = 0; return status; }
int wcsvfree(int *nwcs, struct wcsprm **wcs) { int a, status = 0; struct wcsprm *wcsp; if (wcs == 0x0) { return WCSHDRERR_NULL_POINTER; } wcsp = *wcs; for (a = 0; a < *nwcs; a++, wcsp++) { status |= wcsfree(wcsp); } free(*wcs); *nwcs = 0; *wcs = 0x0; return status; }
static void wcslib_free(anwcslib_t* anwcslib) { wcsfree(anwcslib->wcs); free(anwcslib->wcs); free(anwcslib); }
static void wcstools_free(struct WorldCoor* wcs) { wcsfree(wcs); }
int main() { char ctypeS[9]; int i, stat[NWCSFIX], status; struct wcsprm wcs; struct wcserr info[NWCSFIX]; wcsprintf("Testing WCSLIB translator for non-standard usage (twcsfix.c)\n" "------------------------------------------------------------\n\n"); wcs.flag = -1; parser(&wcs); /* Note: to print the unfixed wcsprm struct using wcsprt() the struct would first have to be initialized by wcsset(). However, if the struct contains non-standard keyvalues then wcsset() will either fix them itself or else fail (e.g. for non-standard units). Thus, in general, wcsprt() cannot be used to print the unmodified struct. */ /* Fix non-standard WCS keyvalues. */ wcserr_enable(1); status = wcsfixi(7, 0, &wcs, stat, info); wcsprintf("wcsfix status returns: ("); for (i = 0; i < NWCSFIX; i++) { wcsprintf(i ? ", %d" : "%d", stat[i]); } wcsprintf(")\n"); for (i = 0; i < NWCSFIX; i++) { if (info[i].status < -1 || 0 < info[i].status) { wcsprintf("\n"); wcserr_prt(info+i, 0x0); } } if (status) { wcsprintf("\nwcsfix error %d", status); return 1; } /* Extract information from the FITS header. */ if (wcsset(&wcs)) { wcsprintf("\n"); wcserr_prt(wcs.err, 0x0); } wcsprintf("\n"); wcsprt(&wcs); wcsprintf("\n------------------------------------" "------------------------------------\n"); /* Should now have a 'VOPT-F2W' axis, translate it to frequency. */ strcpy(ctypeS, "FREQ-???"); i = -1; if (wcssptr(&wcs, &i, ctypeS)) { wcserr_prt(wcs.err, 0x0); return 1; } if (wcsset(&wcs)) { wcserr_prt(wcs.err, 0x0); return 1; } wcsprt(&wcs); wcsfree(&wcs); return 0; }
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() { #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 *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; }
gal_data_t * operands_pop(struct arithmeticparams *p, char *operator) { size_t i; gal_data_t *data; char *filename, *hdu; struct operand *operands=p->operands; /* If the operand linked list has finished, then give an error and exit. */ if(operands==NULL) error(EXIT_FAILURE, 0, "not enough operands for the \"%s\" operator", operator); /* Set the dataset. If filename is present then read the file and fill in the array, if not then just set the array. */ if(operands->filename) { hdu=operands->hdu; filename=operands->filename; /* Read the dataset. */ data=gal_fits_img_read(filename, hdu, p->cp.minmapsize, 0, 0); /* In case this is the first image that is read, then keep the WCS information in the `refdata' structure. Otherwise, the WCS is not necessary and we can safely free it. In any case, `data' must not have a WCS structure. */ if(p->popcounter==0) { p->refdata.wcs=data->wcs; p->refdata.nwcs=data->nwcs; } else wcsfree(data->wcs); data->wcs=NULL; data->nwcs=0; /* When the reference data structure's dimensionality is non-zero, it means that this is not the first image read. So, write its basic information into the reference data structure for future checks. */ if(p->refdata.ndim) { if(gal_data_dsize_is_different(&p->refdata, data)) error(EXIT_FAILURE, 0, "%s (hdu=%s): has a different size " "compared to previous images. All the images must be " "the same size in order for Arithmetic to work", filename, hdu); } else { /* Set the dimensionality. */ p->refdata.ndim=(data)->ndim; /* Allocate the dsize array. */ errno=0; p->refdata.dsize=malloc(p->refdata.ndim * sizeof *p->refdata.dsize); if(p->refdata.dsize==NULL) error(EXIT_FAILURE, errno, "%s: allocating %zu bytes for " "p->refdata.dsize", __func__, p->refdata.ndim * sizeof *p->refdata.dsize); /* Write the values into it. */ for(i=0;i<p->refdata.ndim;++i) p->refdata.dsize[i]=data->dsize[i]; } /* Report the read image if desired: */ if(!p->cp.quiet) printf(" - %s (hdu %s) is read.\n", filename, hdu); /* Free the HDU string: */ free(hdu); /* Add to the number of popped FITS images: */ ++p->popcounter; } else data=operands->data; /* Remove this node from the queue, return the data structure. */ p->operands=operands->next; free(operands); return data; }
int wcsfree_(int *wcs) { return wcsfree((struct wcsprm *)wcs); }
/* 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; }