Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
Archivo: wcshdr.c Proyecto: MQQ/astropy
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;
}
Ejemplo n.º 5
0
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;
}