int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst) { static const char *function = "tabcpy"; int k, m, M, n, N, status; double *dstp, *srcp; struct wcserr **err; if (tabsrc == 0x0) return TABERR_NULL_POINTER; if (tabdst == 0x0) return TABERR_NULL_POINTER; err = &(tabdst->err); M = tabsrc->M; if (M <= 0) { return wcserr_set(WCSERR_SET(TABERR_BAD_PARAMS), "M must be positive, got %d", M); } if ((status = tabini(alloc, M, tabsrc->K, tabdst))) { return status; } N = M; for (m = 0; m < M; m++) { tabdst->map[m] = tabsrc->map[m]; tabdst->crval[m] = tabsrc->crval[m]; N *= tabsrc->K[m]; } for (m = 0; m < M; m++) { if ((srcp = tabsrc->index[m])) { dstp = tabdst->index[m]; for (k = 0; k < tabsrc->K[m]; k++) { *(dstp++) = *(srcp++); } } } srcp = tabsrc->coord; dstp = tabdst->coord; for (n = 0; n < N; n++) { *(dstp++) = *(srcp++); } return 0; }
int main() { char nl; int i, j, K[2], K1, K2, k, k1, k2, M, m, map[2], n, nFail = 0, stat0[128], stat1[128], status, status0, status1; double crpix, crval[2], epsilon, *index[1], psi_0, psi_1, resid, residmax, s[16], world[11][11][2], xt0[16], xt1[16], x0[11][11][2], x1[11][11][2], z; struct tabprm tab; printf( "Testing closure of WCSLIB tabular coordinate routines (ttab1.c)\n" "---------------------------------------------------------------\n"); /* List status return messages. */ printf("\nList of tab status return values:\n"); for (status = 1; status <= 5; status++) { printf("%4d: %s.\n", status, tab_errmsg[status]); } printf("\nReporting tolerance %5.1G.\n", tol); /* First a 1-dimensional table without index. */ printf("\nOne-dimensional test without index:\n"); M = 1; K[0] = 10; tab.flag = -1; tab.index = index; if ((status = tabini(1, M, K, &tab))) { printf("tabini ERROR %d: %s.\n", status, tab_errmsg[status]); return 1; } tab.M = M; tab.K[0] = K[0]; tab.map[0] = 0; tab.crval[0] = 0.0; tab.index[0] = 0x0; tab.coord[0] = 101.0; tab.coord[1] = 102.0; tab.coord[2] = 104.0; tab.coord[3] = 107.0; tab.coord[4] = 111.0; tab.coord[5] = 116.0; tab.coord[6] = 122.0; tab.coord[7] = 129.0; tab.coord[8] = 137.0; tab.coord[9] = 146.0; xt0[0] = 1.0; xt0[1] = 2.0; xt0[2] = 3.0; xt0[3] = 4.0; xt0[4] = 5.0; xt0[5] = 6.0; xt0[6] = 7.0; xt0[7] = 8.0; xt0[8] = 9.0; xt0[9] = 10.0; xt0[10] = 0.5; xt0[11] = 1.1; xt0[12] = 2.5; xt0[13] = 4.7; xt0[14] = 8.125; xt0[15] = 10.5; status0 = tabx2s(&tab, 16, 1, (double *)xt0, (double *)s, stat0); status1 = tabs2x(&tab, 16, 1, (double *)s, (double *)xt1, stat1); printf(" x -> s -> x\n"); for (i = 0; i < 16; i++) { printf("%8.5f%12.5f%9.5f", xt0[i], s[i], xt1[i]); if (stat0[i] || stat1[i]) { printf(" ERROR\n"); } else { printf("\n"); } if (i == 9) printf("\n"); } nl = 1; if (status0) { if (nl) printf("\n"); printf("tabx2s ERROR %d: %s.\n", status0, tab_errmsg[status0]); nl = 0; } if (status1) { if (nl) printf("\n"); printf("tabs2x ERROR %d: %s.\n", status1, tab_errmsg[status1]); } /* Test closure. */ nl = 1; residmax = 0.0; for (i = 0; i < 16; i++) { if (stat0[i]) { printf("\n tabx2s: x = %6.1f, stat = %d\n", xt0[i], stat0[i]); nl = 1; continue; } if (stat1[i]) { printf("\n tabs2x: s = %6.1f, stat = %d\n", s[i], stat1[i]); nl = 1; continue; } resid = fabs(xt1[i] - xt0[i]); if (resid > residmax) residmax = resid; if (resid > tol) { nFail++; if (nl) printf("\n"); printf(" Closure error:\n"); printf(" x = %20.15f\n", xt0[i]); printf(" -> s = %20.15f\n", s[i]); printf(" -> x = %20.15f\n", xt1[i]); nl = 0; } } tabfree(&tab); tab.index = 0x0; /* Now the 1-dimensional table from Sect. 6.2.3 of Paper III. */ printf("\n\nOne-dimensional test with index:\n"); M = 1; K[0] = 8; tab.flag = -1; if ((status = tabini(1, M, K, &tab))) { printf("tabini ERROR %d: %s.\n", status, tab_errmsg[status]); return 1; } tab.M = M; tab.K[0] = K[0]; tab.map[0] = 0; tab.crval[0] = 0.0; tab.index[0][0] = 0.0; tab.index[0][1] = 1.0; tab.index[0][2] = 1.0; tab.index[0][3] = 2.0; tab.index[0][4] = 2.0; tab.index[0][5] = 3.0; tab.index[0][6] = 3.0; tab.index[0][7] = 4.0; tab.coord[0] = 1997.84512; tab.coord[1] = 1997.84631; tab.coord[2] = 1993.28451; tab.coord[3] = 1993.28456; tab.coord[4] = 2001.59234; tab.coord[5] = 2001.59239; tab.coord[6] = 2002.18265; tab.coord[7] = 2002.18301; epsilon = 1e-3; crpix = 0.5; xt0[0] = 0.5 + epsilon - crpix; xt0[1] = 1.0 - crpix; xt0[2] = 1.5 - epsilon - crpix; xt0[3] = 1.5 + epsilon - crpix; xt0[4] = 2.0 - crpix; xt0[5] = 2.5 - epsilon - crpix; xt0[6] = 2.5 + epsilon - crpix; xt0[7] = 3.0 - crpix; xt0[8] = 3.5 - epsilon - crpix; xt0[9] = 3.5 + epsilon - crpix; xt0[10] = 4.0 - crpix; xt0[11] = 4.5 - epsilon - crpix; status0 = tabx2s(&tab, 12, 1, (double *)xt0, (double *)s, stat0); status1 = tabs2x(&tab, 12, 1, (double *)s, (double *)xt1, stat1); printf(" x -> time -> x\n"); for (i = 0; i < 12; i++) { printf("%8.5f%12.5f%9.5f", xt0[i], s[i], xt1[i]); if (stat0[i] || stat1[i]) { printf(" ERROR\n"); } else { printf("\n"); } } nl = 1; if (status0) { if (nl) printf("\n"); printf("tabx2s ERROR %d: %s.\n", status0, tab_errmsg[status0]); nl = 0; } if (status1) { if (nl) printf("\n"); printf("tabs2x ERROR %d: %s.\n", status1, tab_errmsg[status1]); } /* Test closure. */ nl = 1; residmax = 0.0; for (i = 0; i < 12; i++) { if (stat0[i]) { printf("\n tabx2s: x = %6.1f, stat = %d\n", xt0[i], stat0[i]); nl = 1; continue; } if (stat1[i]) { printf("\n tabs2x: s = %6.1f, stat = %d\n", s[i], stat1[i]); nl = 1; continue; } resid = fabs(xt1[i] - xt0[i]); if (resid > residmax) residmax = resid; if (resid > tol) { nFail++; if (nl) printf("\n"); printf(" Closure error:\n"); printf(" x = %20.15f\n", xt0[i]); printf(" -> s = %20.15f\n", s[i]); printf(" -> x = %20.15f\n", xt1[i]); nl = 0; } } tabfree(&tab); /* Now a 2-dimensional table. */ printf("\n\nTwo-dimensional test with index:\n"); M = 2; K[0] = K1 = 32; K[1] = K2 = 16; map[0] = 0; map[1] = 1; crval[0] = 4.0; crval[1] = -1.0; tab.flag = -1; if ((status = tabini(1, M, K, &tab))) { printf("tabini ERROR %d: %s.\n", status, tab_errmsg[status]); return 1; } /* Set up the tabprm struct. */ tab.M = M; for (m = 0; m < tab.M; m++) { tab.K[m] = K[m]; tab.map[m] = map[m]; tab.crval[m] = crval[m]; /* Construct a trivial 0-relative index. */ for (k = 0; k < tab.K[m]; k++) { tab.index[m][k] = (double)k; } } /* Construct a coordinate table. */ n = 0; z = 1.0 / (double)((K1-1) * (K2-1)); for (k2 = 0; k2 < K2; k2++) { for (k1 = 0; k1 < K1; k1++) { tab.coord[n++] = 3.0*k1*k2*z; tab.coord[n++] = -1.0*(K1-k1-1)*k2*z + 0.01*k1; } } /* Construct an array of intermediate world coordinates to transform. */ for (i = 0; i < 11; i++) { for (j = 0; j < 11; j++) { /* Compute psi_m within bounds... */ psi_0 = i*(K1-1)/10.0; psi_1 = j*(K2-1)/10.0; /* ...then compute x from it. */ x0[i][j][0] = psi_0 - crval[0]; x0[i][j][1] = psi_1 - crval[1]; } } /* Transform them to and fro. */ status0 = tabx2s(&tab, 121, 2, (double *)x0, (double *)world, stat0); status1 = tabs2x(&tab, 121, 2, (double *)world, (double *)x1, stat1); /* Print the results. */ printf(" x -> s -> x \n"); n = 0; for (i = 0; i < 11; i++) { for (j = 0; j < 11; j++, n++) { /* Print every sixth one only. */ if (n%6) continue; printf("(%4.1f,%4.1f) (%4.2f,%6.3f) (%4.1f,%4.1f)", x0[i][j][0], x0[i][j][1], world[i][j][0], world[i][j][1], x1[i][j][0], x1[i][j][1]); if (stat0[n] || stat1[n]) { printf(" ERROR\n"); } else { printf("\n"); } } } nl = 1; if (status0) { if (nl) printf("\n"); printf("tabx2s ERROR %d: %s.\n", status0, tab_errmsg[status0]); nl = 0; } if (status1) { if (nl) printf("\n"); printf("tabs2x ERROR %d: %s.\n", status1, tab_errmsg[status1]); } /* Check for closure. */ n = 0; nl = 1; residmax = 0.0; for (i = 0; i < 11; i++) { for (j = 0; j < 11; j++, n++) { if (stat0[n]) { printf(" tabx2s: x = (%6.1f,%6.1f), stat = %d\n", x0[i][j][0], x0[i][j][1], stat0[n]); nl = 1; continue; } if (stat1[n]) { printf(" tabs2x: s = (%6.1f,%6.1f), stat = %d\n", world[i][j][0], world[i][j][1], stat1[n]); nl = 1; continue; } for (m = 0; m < M; m++) { resid = fabs(x1[i][j][m] - x0[i][j][m]); if (resid > residmax) residmax = resid; if (resid > tol) { nFail++; if (nl) printf("\n"); printf(" Closure error:\n"); printf(" x = (%20.15f,%20.15f)\n", x0[i][j][0], x0[i][j][1]); printf(" -> w = (%20.15f,%20.15f)\n", world[i][j][0], world[i][j][1]); printf(" -> x = (%20.15f,%20.15f)\n", x1[i][j][0], x1[i][j][1]); nl = 0; break; } } } } printf("\ntabx2s/tabs2x: Maximum closure residual = %.1e\n", residmax); tabfree(&tab); if (nFail) { printf("\nFAIL: %d closure residuals exceed reporting tolerance.\n", nFail); } else { printf("\nPASS: All closure residuals are within reporting tolerance.\n"); } return nFail; }
int main() { /* Set up a 2 x 2 lookup table. */ const int M = 2; const int K[] = {K1, K2}; const int map[] = {0, 1}; const double crval[] = {0.0, 0.0}; char text[80]; int i, j, k, l, l1, l2, l3, lstep, m, stat[NP*NP], status; float array[NP][NP], clev[31], v0, v1, w; const float scl = 2.0f/(NP-1); float ltm[6]; double x[NP][NP][2], world[NP][NP][2]; struct tabprm tab; printf("Testing WCSLIB coordinate lookup table routines (ttab2.c)\n" "---------------------------------------------------------\n"); /* List status return messages. */ printf("\nList of tab status return values:\n"); for (status = 1; status <= 5; status++) { printf("%4d: %s.\n", status, tab_errmsg[status]); } printf("\n"); /* PGPLOT initialization. */ strcpy(text, "/xwindow"); cpgbeg(0, text, 1, 1); cpgvstd(); cpgsch(0.7f); /* The viewport is slightly oversized. */ cpgwnad(-0.65f, 1.65f, -0.65f, 1.65f); for (l = 0; l <= 30; l++) { clev[l] = 0.2f*(l-10); } ltm[0] = -scl*(1.0f + (NP-1)/4.0f); ltm[1] = scl; ltm[2] = 0.0f; ltm[3] = -scl*(1.0f + (NP-1)/4.0f); ltm[4] = 0.0f; ltm[5] = scl; /* Set up the lookup table. */ tab.flag = -1; if ((status = tabini(1, M, K, &tab))) { printf("tabini ERROR %d: %s.\n", status, tab_errmsg[status]); return 1; } tab.M = M; for (m = 0; m < tab.M; m++) { tab.K[m] = K[m]; tab.map[m] = map[m]; tab.crval[m] = crval[m]; for (k = 0; k < tab.K[m]; k++) { tab.index[m][k] = (double)k; } } /* Subdivide the interpolation element. */ for (i = 0; i < NP; i++) { for (j = 0; j < NP; j++) { x[i][j][0] = j*(K1-1.0)*scl - 0.5 - crval[0]; x[i][j][1] = i*(K2-1.0)*scl - 0.5 - crval[1]; } } /* The first coordinate element is static. */ tab.coord[0] = 0.0; tab.coord[2] = 0.0; tab.coord[4] = 0.0; tab.coord[6] = 0.0; /* (k1,k2) = (0,0). */ tab.coord[1] = 0.0; /* The second coordinate element varies in three of the corners. */ for (l3 = 0; l3 <= 100; l3 += 20) { /* (k1,k2) = (1,1). */ tab.coord[7] = 0.01 * l3; for (l2 = 0; l2 <= 100; l2 += 20) { /* (k1,k2) = (0,1). */ tab.coord[5] = 0.01 * l2; cpgpage(); for (l1 = 0; l1 <= 100; l1 += 2) { /* (k1,k2) = (1,0). */ tab.coord[3] = 0.01 * l1; /* Compute coordinates within the interpolation element. */ tab.flag = 0; if ((status = tabx2s(&tab, NP*NP, 2, (double *)x, (double *)world, stat))) { printf("tabx2s ERROR %d: %s.\n", status, tab_errmsg[status]); } /* Start a new plot. */ cpgbbuf(); cpgeras(); cpgsci(1); cpgslw(3); cpgbox("BCNST", 0.0f, 0, "BCNSTV", 0.0f, 0); cpgmtxt("T", 0.7f, 0.5f, 0.5f, "-TAB coordinates: " "linear interpolation / extrapolation in 2-D"); /* Draw the boundary of the interpolation element in red. */ cpgsci(2); cpgmove(-0.5f, 0.0f); cpgdraw( 1.5f, 0.0f); cpgmove( 1.0f, -0.5f); cpgdraw( 1.0f, 1.5f); cpgmove( 1.5f, 1.0f); cpgdraw(-0.5f, 1.0f); cpgmove( 0.0f, 1.5f); cpgdraw( 0.0f, -0.5f); /* Label the value of the coordinate element in each corner. */ sprintf(text, "%.1f", tab.coord[1]); cpgtext(-0.09f, -0.05f, text); sprintf(text, "%.2f", tab.coord[3]); cpgtext( 1.02f, -0.05f, text); sprintf(text, "%.1f", tab.coord[5]); cpgtext(-0.13f, 1.02f, text); sprintf(text, "%.1f", tab.coord[7]); cpgtext( 1.02f, 1.02f, text); cpgsci(1); /* Contour labelling: bottom. */ v0 = world[0][0][1]; v1 = world[0][NP-1][1]; if (v0 != v1) { lstep = (abs((int)((v1-v0)/0.2f)) < 10) ? 20 : 40; for (l = -200; l <= 300; l += lstep) { w = -0.5f + 2.0f * (l*0.01f - v0) / (v1 - v0); if (w < -0.5 || w > 1.5) continue; sprintf(text, "%4.1f", l*0.01f); cpgptxt(w+0.04f, -0.56f, 0.0f, 1.0f, text); } } /* Contour labelling: left. */ v0 = world[0][0][1]; v1 = world[NP-1][0][1]; if (v0 != v1) { lstep = (abs((int)((v1-v0)/0.2f)) < 10) ? 20 : 40; for (l = -200; l <= 300; l += lstep) { w = -0.5f + 2.0f * (l*0.01f - v0) / (v1 - v0); if (w < -0.5 || w > 1.5) continue; sprintf(text, "%4.1f", l*0.01f); cpgptxt(-0.52f, w-0.02f, 0.0f, 1.0f, text); } } /* Contour labelling: right. */ v0 = world[0][NP-1][1]; v1 = world[NP-1][NP-1][1]; if (v0 != v1) { lstep = (abs((int)((v1-v0)/0.2f)) < 10) ? 20 : 40; for (l = -200; l <= 300; l += lstep) { w = -0.5f + 2.0f * (l*0.01f - v0) / (v1 - v0); if (w < -0.5 || w > 1.5) continue; sprintf(text, "%.1f", l*0.01f); cpgptxt(1.52f, w-0.02f, 0.0f, 0.0f, text); } } /* Contour labelling: top. */ v0 = world[NP-1][0][1]; v1 = world[NP-1][NP-1][1]; if (v0 != v1) { lstep = (abs((int)((v1-v0)/0.2f)) < 10) ? 20 : 40; for (l = -200; l <= 300; l += lstep) { w = -0.5f + 2.0f * (l*0.01f - v0) / (v1 - v0); if (w < -0.5 || w > 1.5) continue; sprintf(text, "%4.1f", l*0.01f); cpgptxt(w+0.04f, 1.52f, 0.0f, 1.0f, text); } } /* Draw contours for the second coordinate element. */ for (i = 0; i < NP; i++) { for (j = 0; j < NP; j++) { array[i][j] = world[i][j][1]; } } cpgsci(4); cpgslw(2); cpgcont(array[0], NP, NP, 1, NP, 1, NP, clev, 10, ltm); cpgsci(7); cpgcont(array[0], NP, NP, 1, NP, 1, NP, clev+10, 1, ltm); cpgsci(5); cpgcont(array[0], NP, NP, 1, NP, 1, NP, clev+11, 20, ltm); cpgebuf(); } } } cpgend(); tabfree(&tab); return 0; }
int wcstab(struct wcsprm *wcs) { static const char *function = "wcstab"; char (*PSi_0a)[72] = 0x0, (*PSi_1a)[72] = 0x0, (*PSi_2a)[72] = 0x0; int *PVi_1a = 0x0, *PVi_2a = 0x0, *PVi_3a = 0x0, *tabax, *tabidx = 0x0; int getcrd, i, ip, itab, itabax, j, jtabax, m, naxis, ntabax, status; struct wtbarr *wtbp; struct tabprm *tabp; struct wcserr **err; if (wcs == 0x0) return WCSHDRERR_NULL_POINTER; err = &(wcs->err); /* Free memory previously allocated by wcstab(). */ if (wcs->flag != -1 && wcs->m_flag == WCSSET) { if (wcs->wtb == wcs->m_wtb) wcs->wtb = 0x0; if (wcs->tab == wcs->m_tab) wcs->tab = 0x0; if (wcs->m_wtb) free(wcs->m_wtb); if (wcs->m_tab) { for (j = 0; j < wcs->ntab; j++) { tabfree(wcs->m_tab + j); } free(wcs->m_tab); } } wcs->ntab = 0; wcs->nwtb = 0; wcs->wtb = 0x0; wcs->tab = 0x0; /* Determine the number of -TAB axes. */ naxis = wcs->naxis; if (!(tabax = calloc(naxis, sizeof(int)))) { return wcserr_set(WCSHDR_ERRMSG(WCSHDRERR_MEMORY)); } ntabax = 0; for (i = 0; i < naxis; i++) { /* Null fill. */ wcsutil_null_fill(72, wcs->ctype[i]); if (!strcmp(wcs->ctype[i]+4, "-TAB")) { tabax[i] = ntabax++; } else { tabax[i] = -1; } } if (ntabax == 0) { /* No lookup tables. */ status = 0; goto cleanup; } /* Collect information from the PSi_ma and PVi_ma keyvalues. */ if (!((PSi_0a = calloc(ntabax, sizeof(char[72]))) && (PVi_1a = calloc(ntabax, sizeof(int))) && (PVi_2a = calloc(ntabax, sizeof(int))) && (PSi_1a = calloc(ntabax, sizeof(char[72]))) && (PSi_2a = calloc(ntabax, sizeof(char[72]))) && (PVi_3a = calloc(ntabax, sizeof(int))) && (tabidx = calloc(ntabax, sizeof(int))))) { status = wcserr_set(WCSHDR_ERRMSG(WCSHDRERR_MEMORY)); goto cleanup; } for (itabax = 0; itabax < ntabax; itabax++) { /* Remember that calloc() zeroes allocated memory. */ PVi_1a[itabax] = 1; PVi_2a[itabax] = 1; PVi_3a[itabax] = 1; } for (ip = 0; ip < wcs->nps; ip++) { itabax = tabax[wcs->ps[ip].i - 1]; if (itabax >= 0) { switch (wcs->ps[ip].m) { case 0: /* EXTNAME. */ strcpy(PSi_0a[itabax], wcs->ps[ip].value); wcsutil_null_fill(72, PSi_0a[itabax]); break; case 1: /* TTYPEn for coordinate array. */ strcpy(PSi_1a[itabax], wcs->ps[ip].value); wcsutil_null_fill(72, PSi_1a[itabax]); break; case 2: /* TTYPEn for index vector. */ strcpy(PSi_2a[itabax], wcs->ps[ip].value); wcsutil_null_fill(72, PSi_2a[itabax]); break; } } } for (ip = 0; ip < wcs->npv; ip++) { itabax = tabax[wcs->pv[ip].i - 1]; if (itabax >= 0) { switch (wcs->pv[ip].m) { case 1: /* EXTVER. */ PVi_1a[itabax] = (int)(wcs->pv[ip].value + 0.5); break; case 2: /* EXTLEVEL. */ PVi_2a[itabax] = (int)(wcs->pv[ip].value + 0.5); break; case 3: /* Table axis number. */ PVi_3a[itabax] = (int)(wcs->pv[ip].value + 0.5); break; } } } /* Determine the number of independent tables. */ for (itabax = 0; itabax < ntabax; itabax++) { /* These have no defaults. */ if (!PSi_0a[itabax][0] || !PSi_1a[itabax][0]) { status = wcserr_set(WCSERR_SET(WCSHDRERR_BAD_TABULAR_PARAMS), "Invalid tabular parameters: PSi_0a and PSi_1a must be specified"); goto cleanup; } tabidx[itabax] = -1; for (jtabax = 0; jtabax < i; jtabax++) { /* EXTNAME, EXTVER, EXTLEVEL, and TTYPEn for the coordinate array */ /* must match for each axis of a multi-dimensional lookup table. */ if (strcmp(PSi_0a[itabax], PSi_0a[jtabax]) == 0 && strcmp(PSi_1a[itabax], PSi_1a[jtabax]) == 0 && PVi_1a[itabax] == PVi_1a[jtabax] && PVi_2a[itabax] == PVi_2a[jtabax]) { tabidx[itabax] = tabidx[jtabax]; break; } } if (jtabax == itabax) { tabidx[itabax] = wcs->ntab; wcs->ntab++; } } if (!(wcs->tab = calloc(wcs->ntab, sizeof(struct tabprm)))) { status = wcserr_set(WCSHDR_ERRMSG(WCSHDRERR_MEMORY)); goto cleanup; } wcs->m_tab = wcs->tab; /* Table dimensionality; find the largest axis number. */ for (itabax = 0; itabax < ntabax; itabax++) { tabp = wcs->tab + tabidx[itabax]; /* PVi_3a records the 1-relative table axis number. */ if (PVi_3a[itabax] > tabp->M) { tabp->M = PVi_3a[itabax]; } } for (itab = 0; itab < wcs->ntab; itab++) { if ((status = tabini(1, wcs->tab[itab].M, 0, wcs->tab + itab))) { if (status == 3) status = 5; wcserr_set(WCSHDR_ERRMSG(status)); goto cleanup; } } /* Copy parameters into the tabprm structs. */ for (i = 0; i < naxis; i++) { if ((itabax = tabax[i]) < 0) { /* Not a -TAB axis. */ continue; } /* PVi_3a records the 1-relative table axis number. */ m = PVi_3a[itabax] - 1; tabp = wcs->tab + tabidx[itabax]; tabp->map[m] = i; tabp->crval[m] = wcs->crval[i]; } /* Check for completeness. */ for (itab = 0; itab < wcs->ntab; itab++) { for (m = 0; m < wcs->tab[itab].M; m++) { if (wcs->tab[itab].map[m] < 0) { status = wcserr_set(WCSERR_SET(WCSHDRERR_BAD_TABULAR_PARAMS), "Invalid tabular parameters: the axis mapping is undefined"); goto cleanup; } } } /* Set up for reading the arrays; how many arrays are there? */ for (itabax = 0; itabax < ntabax; itabax++) { /* Does this -TAB axis have a non-degenerate index array? */ if (PSi_2a[itabax][0]) { wcs->nwtb++; } } /* Add one coordinate array for each table. */ wcs->nwtb += wcs->ntab; /* Allocate memory for structs to be returned. */ if (!(wcs->wtb = calloc(wcs->nwtb, sizeof(struct wtbarr)))) { wcs->nwtb = 0; status = wcserr_set(WCSHDR_ERRMSG(WCSHDRERR_MEMORY)); goto cleanup; } wcs->m_wtb = wcs->wtb; /* Set pointers for the index and coordinate arrays. */ wtbp = wcs->wtb; for (itab = 0; itab < wcs->ntab; itab++) { getcrd = 1; for (itabax = 0; itabax < ntabax; itabax++) { if (tabidx[itabax] != itab) continue; if (getcrd) { /* Coordinate array. */ wtbp->i = itabax + 1; wtbp->m = PVi_3a[itabax]; wtbp->kind = 'c'; strcpy(wtbp->extnam, PSi_0a[itabax]); wtbp->extver = PVi_1a[itabax]; wtbp->extlev = PVi_2a[itabax]; strcpy(wtbp->ttype, PSi_1a[itabax]); wtbp->row = 1L; wtbp->ndim = wcs->tab[itab].M + 1; wtbp->dimlen = wcs->tab[itab].K; wtbp->arrayp = &(wcs->tab[itab].coord); /* Signal for tabset() to take this memory. */ wcs->tab[itab].m_coord = (double *)0x1; wtbp++; getcrd = 0; } if (PSi_2a[itabax][0]) { /* Index array. */ wtbp->i = itabax + 1; wtbp->m = PVi_3a[itabax]; wtbp->kind = 'i'; m = wtbp->m - 1; strcpy(wtbp->extnam, PSi_0a[itabax]); wtbp->extver = PVi_1a[itabax]; wtbp->extlev = PVi_2a[itabax]; strcpy(wtbp->ttype, PSi_2a[itabax]); wtbp->row = 1L; wtbp->ndim = 1; wtbp->dimlen = wcs->tab[itab].K + m; wtbp->arrayp = wcs->tab[itab].index + m; /* Signal for tabset() to take this memory. */ wcs->tab[itab].m_indxs[m] = (double *)0x1; wtbp++; } } } status = 0; cleanup: if (tabax) free(tabax); if (tabidx) free(tabidx); if (PSi_0a) free(PSi_0a); if (PVi_1a) free(PVi_1a); if (PVi_2a) free(PVi_2a); if (PSi_1a) free(PSi_1a); if (PSi_2a) free(PSi_2a); if (PVi_3a) free(PVi_3a); if (status) { if (wcs->tab) free(wcs->tab); if (wcs->wtb) free(wcs->wtb); } return status; }
int main() { /* Set up the lookup table. */ const int M = 2; const int K[] = {K1, K2}; const int map[] = {0, 1}; const double crval[] = {135.0, 95.0}; char text[80]; int ci, i, ilat, ilng, j, k, m, stat[K2][K1], status; float xr[361], yr[361]; double *dp, world[361][2], x[K1], xy[361][2], y[K2]; struct tabprm tab; struct prjprm prj; printf( "Testing WCSLIB inverse coordinate lookup table routines (ttab3.c)\n" "-----------------------------------------------------------------\n"); /* List status return messages. */ printf("\nList of tab status return values:\n"); for (status = 1; status <= 5; status++) { printf("%4d: %s.\n", status, tab_errmsg[status]); } printf("\n"); /* PGPLOT initialization. */ strcpy(text, "/xwindow"); cpgbeg(0, text, 1, 1); cpgvstd(); cpgsch(0.7f); cpgwnad(-135.0f, 135.0f, -95.0f, 140.0f); cpgbox("BC", 0.0f, 0, "BC", 0.0f, 0); cpgscr(0, 0.00f, 0.00f, 0.00f); cpgscr(1, 1.00f, 1.00f, 0.00f); cpgscr(2, 1.00f, 1.00f, 1.00f); cpgscr(3, 0.50f, 0.50f, 0.80f); cpgscr(4, 0.80f, 0.50f, 0.50f); cpgscr(5, 0.80f, 0.80f, 0.80f); cpgscr(6, 0.50f, 0.50f, 0.80f); cpgscr(7, 0.80f, 0.50f, 0.50f); cpgscr(8, 0.30f, 0.50f, 0.30f); /* Set up the lookup table. */ tab.flag = -1; if ((status = tabini(1, M, K, &tab))) { printf("tabini ERROR %d: %s.\n", status, tab_errmsg[status]); return 1; } tab.M = M; for (m = 0; m < tab.M; m++) { tab.K[m] = K[m]; tab.map[m] = map[m]; tab.crval[m] = crval[m]; for (k = 0; k < tab.K[m]; k++) { tab.index[m][k] = (double)k; } } /* Set up the lookup table to approximate Bonne's projection. */ for (i = 0; i < K1; i++) { x[i] = 135 - i; } for (j = 0; j < K2; j++) { y[j] = j - 95; } prjini(&prj); prj.pv[1] = 35.0; status = bonx2s(&prj, K1, K2, 1, 2, x, y, tab.coord, tab.coord+1, (int *)stat); dp = tab.coord; for (j = 0; j < K2; j++) { for (i = 0; i < K1; i++) { if (stat[j][i]) { *dp = 999.0; *(dp+1) = 999.0; } dp += 2; } } /* Draw meridians. */ ci = 1; for (ilng = -180; ilng <= 180; ilng += 15) { if (++ci > 7) ci = 2; cpgsci(ilng?ci:1); for (j = 0, ilat = -90; ilat <= 90; ilat++, j++) { world[j][0] = (double)ilng; world[j][1] = (double)ilat; } /* A fudge to account for the singularity at the poles. */ world[0][0] = 0.0; world[180][0] = 0.0; status = tabs2x(&tab, 181, 2, (double *)world, (double *)xy, (int *)stat); k = 0; for (j = 0; j < 181; j++) { if (stat[0][j]) { if (k > 1) cpgline(k, xr, yr); k = 0; continue; } xr[k] = xy[j][0]; yr[k] = xy[j][1]; k++; } cpgline(k, xr, yr); } /* Draw parallels. */ ci = 1; for (ilat = -75; ilat <= 75; ilat += 15) { if (++ci > 7) ci = 2; cpgsci(ilat?ci:1); for (j = 0, ilng = -180; ilng <= 180; ilng++, j++) { world[j][0] = (double)ilng; world[j][1] = (double)ilat; } status = tabs2x(&tab, 361, 2, (double *)world, (double *)xy, (int *)stat); k = 0; for (j = 0; j < 361; j++) { if (stat[0][j]) { if (k > 1) cpgline(k, xr, yr); k = 0; continue; } xr[k] = xy[j][0]; yr[k] = xy[j][1]; k++; } cpgline(k, xr, yr); } cpgend(); return 0; }