static int
PyTabprm_cset(
    PyTabprm* self) {

  int status = 0;

  status = tabset(self->x);

  if (status == 0) {
    return 0;
  } else {
    wcslib_tab_to_python_exc(status);
    return -1;
  }
}
Exemple #2
0
char * tabspec(char const * string)

{
	char const * set;
	char const * tab;
	while (isdigit(* string))
	{
		for (set = string; isdigit(* string); string++);
		if (* string == '.')
		{
			string++;
		}
		for (tab = string; isdigit(* string); string++);
		if (* string == ',')
		{
			string++;
		}
		tabset (atoi(set), atoi(tab));
	}
	return ((char *) (string));
}
Exemple #3
0
int tabx2s(
    struct tabprm *tab,
    int ncoord,
    int nelem,
    const double x[],
    double world[],
    int stat[])

{
    static const char *function = "tabx2s";

    int i, iv, k, *Km, m, M, n, nv, offset, p1, status;
    double *coord, *Psi, psi_m, upsilon, wgt;
    register int *statp;
    register const double *xp;
    register double *wp;
    struct wcserr **err;

    if (tab == 0x0) return TABERR_NULL_POINTER;
    err = &(tab->err);

    /* Initialize if required. */
    if (tab->flag != TABSET) {
        if ((status = tabset(tab))) return status;
    }

    /* This is used a lot. */
    M = tab->M;

    status = 0;
    xp = x;
    wp = world;
    statp = stat;
    for (n = 0; n < ncoord; n++) {
        /* Determine the indexes. */
        Km = tab->K;
        for (m = 0; m < M; m++, Km++) {
            /* N.B. psi_m and Upsilon_m are 1-relative FITS indexes. */
            i = tab->map[m];
            psi_m = *(xp+i) + tab->crval[m];

            Psi = tab->index[m];
            if (Psi == 0x0) {
                /* Default indexing is simple. */
                upsilon = psi_m;

            } else {
                /* To ease confusion, decrement Psi so that we can use 1-relative
                   C array indexing to match the 1-relative FITS indexing. */
                Psi--;

                if (*Km == 1) {
                    /* Index vector is degenerate. */
                    if (Psi[1]-0.5 <= psi_m && psi_m <= Psi[1]+0.5) {
                        upsilon = psi_m;
                    } else {
                        *statp = 1;
                        status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X));
                        goto next;
                    }

                } else {
                    /* Interpolate in the indexing vector. */
                    if (tab->sense[m] == 1) {
                        /* Monotonic increasing index values. */
                        if (psi_m < Psi[1]) {
                            if (Psi[1] - 0.5*(Psi[2]-Psi[1]) <= psi_m) {
                                /* Allow minor extrapolation. */
                                k = 1;

                            } else {
                                /* Index is out of range. */
                                *statp = 1;
                                status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X));
                                goto next;
                            }

                        } else if (Psi[*Km] < psi_m) {
                            if (psi_m <= Psi[*Km] + 0.5*(Psi[*Km]-Psi[*Km-1])) {
                                /* Allow minor extrapolation. */
                                k = *Km - 1;

                            } else {
                                /* Index is out of range. */
                                *statp = 1;
                                status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X));
                                goto next;
                            }

                        } else {
                            for (k = 1; k < *Km; k++) {
                                if (psi_m < Psi[k]) {
                                    continue;
                                }
                                if (Psi[k] == psi_m && psi_m < Psi[k+1]) {
                                    break;
                                }
                                if (Psi[k] < psi_m && psi_m <= Psi[k+1]) {
                                    break;
                                }
                            }
                        }

                    } else {
                        /* Monotonic decreasing index values. */
                        if (psi_m > Psi[1]) {
                            if (Psi[1] + 0.5*(Psi[1]-Psi[2]) >= psi_m) {
                                /* Allow minor extrapolation. */
                                k = 1;

                            } else {
                                /* Index is out of range. */
                                *statp = 1;
                                status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X));
                                goto next;
                            }

                        } else if (psi_m < Psi[*Km]) {
                            if (Psi[*Km] - 0.5*(Psi[*Km-1]-Psi[*Km]) <= psi_m) {
                                /* Allow minor extrapolation. */
                                k = *Km - 1;

                            } else {
                                /* Index is out of range. */
                                *statp = 1;
                                status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X));
                                goto next;
                            }

                        } else {
                            for (k = 1; k < *Km; k++) {
                                if (psi_m > Psi[k]) {
                                    continue;
                                }
                                if (Psi[k] == psi_m && psi_m > Psi[k+1]) {
                                    break;
                                }
                                if (Psi[k] > psi_m && psi_m >= Psi[k+1]) {
                                    break;
                                }
                            }
                        }
                    }

                    upsilon = k + (psi_m - Psi[k]) / (Psi[k+1] - Psi[k]);
                }
            }

            if (upsilon < 0.5 || upsilon > *Km + 0.5) {
                /* Index out of range. */
                *statp = 1;
                status = wcserr_set(TAB_ERRMSG(TABERR_BAD_X));
                goto next;
            }

            /* Fiducial array indices and fractional offset.
               p1 is 1-relative while tab::p0 is 0-relative. */
            p1 = (int)floor(upsilon);
            tab->p0[m] = p1 - 1;
            tab->delta[m] = upsilon - p1;

            if (p1 == 0) {
                tab->p0[m] += 1;
                tab->delta[m] -= 1.0;
            } else if (p1 == *Km && *Km > 1) {
                tab->p0[m] -= 1;
                tab->delta[m] += 1.0;
            }
        }


        /* Now interpolate in the coordinate array; the M-dimensional linear  */
        /* interpolation algorithm is described in Sect. 3.4 of WCS Paper IV. */
        for (m = 0; m < M; m++) {
            i = tab->map[m];
            *(wp+i) = 0.0;
        }

        /* Loop over the 2^M vertices surrounding P. */
        nv = 1 << M;
        for (iv = 0; iv < nv; iv++) {
            /* Locate vertex in the coordinate array and compute its weight. */
            offset = 0;
            wgt = 1.0;
            for (m = M-1; m >= 0; m--) {
                offset *= tab->K[m];
                offset += tab->p0[m];
                if (iv & (1 << m)) {
                    if (tab->K[m] > 1) offset++;
                    wgt *= tab->delta[m];
                } else {
                    wgt *= 1.0 - tab->delta[m];
                }
            }

            if (wgt == 0.0) continue;

            /* Add the contribution from this vertex to each element. */
            coord = tab->coord + offset*M;
            for (m = 0; m < M; m++) {
                i = tab->map[m];
                *(wp+i) += *(coord++) * wgt;
            }

            if (wgt == 1.0) break;
        }

        *statp = 0;

next:
        xp += nelem;
        wp += nelem;
        statp++;
    }

    return status;
}
Exemple #4
0
int tabs2x(
    struct tabprm* tab,
    int ncoord,
    int nelem,
    const double world[],
    double x[],
    int stat[])

{
    static const char *function = "tabs2x";

    int tabedge(struct tabprm *);
    int tabrow(struct tabprm *, const double *);
    int tabvox(struct tabprm *, const double *, int, double **, unsigned int *);

    int edge, i, ic, iv, k, *Km, M, m, n, nv, offset, status;
    double *dcrd, delta, *Psi, psi_m, **tabcoord, upsilon;
    register int *statp;
    register const double *wp;
    register double *xp;
    struct wcserr **err;

    if (tab == 0x0) return TABERR_NULL_POINTER;
    err = &(tab->err);

    /* Initialize if required. */
    if (tab->flag != TABSET) {
        if ((status = tabset(tab))) return status;
    }

    /* This is used a lot. */
    M = tab->M;

    tabcoord = 0x0;
    nv = 0;
    if (M > 1) {
        nv = 1 << M;
        tabcoord = calloc(nv, sizeof(double *));
    }


    status = 0;
    wp = world;
    xp = x;
    statp = stat;
    for (n = 0; n < ncoord; n++) {
        /* Locate this coordinate in the coordinate array. */
        edge = 0;
        for (m = 0; m < M; m++) {
            tab->p0[m] = 0;
        }

        for (ic = 0; ic < tab->nc; ic++) {
            if (tab->p0[0] == 0) {
                /* New row, could it contain a solution? */
                if (edge || tabrow(tab, wp)) {
                    /* No, skip it. */
                    ic += tab->K[0];
                    tab->p0[1]++;
                    edge = tabedge(tab);

                    /* Because ic will be incremented when the loop is reentered. */
                    ic--;
                    continue;
                }
            }

            if (M == 1) {
                /* Deal with the one-dimensional case separately for efficiency. */
                if (*wp == tab->coord[0]) {
                    tab->p0[0] = 0;
                    tab->delta[0] = 0.0;
                    break;

                } else if (ic < tab->nc - 1) {
                    if (((tab->coord[ic] <= *wp && *wp <= tab->coord[ic+1]) ||
                            (tab->coord[ic] >= *wp && *wp >= tab->coord[ic+1])) &&
                            (tab->index[0] == 0x0 ||
                             tab->index[0][ic] != tab->index[0][ic+1])) {
                        tab->p0[0] = ic;
                        tab->delta[0] = (*wp - tab->coord[ic]) /
                                        (tab->coord[ic+1] - tab->coord[ic]);
                        break;
                    }
                }

            } else {
                /* Multi-dimensional tables are harder. */
                if (!edge) {
                    /* Addresses of the coordinates for each corner of the "voxel". */
                    for (iv = 0; iv < nv; iv++) {
                        offset = 0;
                        for (m = M-1; m >= 0; m--) {
                            offset *= tab->K[m];
                            offset += tab->p0[m];
                            if ((iv & (1 << m)) && (tab->K[m] > 1)) offset++;
                        }
                        tabcoord[iv] = tab->coord + offset*M;
                    }

                    if (tabvox(tab, wp, 0, tabcoord, 0x0) == 0) {
                        /* Found a solution. */
                        break;
                    }
                }

                /* Next voxel. */
                tab->p0[0]++;
                edge = tabedge(tab);
            }
        }


        if (ic == tab->nc) {
            /* Coordinate not found; allow minor extrapolation. */
            if (M == 1) {
                /* Should there be a solution? */
                if (tab->extrema[0] <= *wp && *wp <= tab->extrema[1]) {
                    dcrd = tab->coord;
                    for (i = 0; i < 2; i++) {
                        if (i) dcrd += tab->K[0] - 2;

                        delta = (*wp - *dcrd) / (*(dcrd+1) - *dcrd);

                        if (i == 0) {
                            if (-0.5 <= delta && delta <= 0.0) {
                                tab->p0[0] = 0;
                                tab->delta[0] = delta;
                                ic = 0;
                                break;
                            }
                        } else {
                            if (1.0 <= delta && delta <= 1.5) {
                                tab->p0[0] = tab->K[0] - 1;
                                tab->delta[0] = delta - 1.0;
                                ic = 0;
                            }
                        }
                    }
                }

            } else {
                /* Multi-dimensional tables. */
                /* >>> TBD <<< */
            }
        }


        if (ic == tab->nc) {
            /* Coordinate not found. */
            *statp = 1;
            status = wcserr_set(TAB_ERRMSG(TABERR_BAD_WORLD));
        } else {
            /* Determine the intermediate world coordinates. */
            Km = tab->K;
            for (m = 0; m < M; m++, Km++) {
                /* N.B. Upsilon_m and psi_m are 1-relative FITS indexes. */
                upsilon = (tab->p0[m] + 1) + tab->delta[m];

                if (upsilon < 0.5 || upsilon > *Km + 0.5) {
                    /* Index out of range. */
                    *statp = 1;
                    status = wcserr_set(TAB_ERRMSG(TABERR_BAD_WORLD));

                } else {
                    /* Do inverse lookup of the index vector. */
                    Psi = tab->index[m];
                    if (Psi == 0x0) {
                        /* Default indexing. */
                        psi_m = upsilon;

                    } else {
                        /* Decrement Psi and use 1-relative C array indexing to match the
                           1-relative FITS indexing. */
                        Psi--;

                        if (*Km == 1) {
                            /* Degenerate index vector. */
                            psi_m = Psi[1];
                        } else {
                            k = (int)(upsilon);
                            psi_m = Psi[k];
                            if (k < *Km) {
                                psi_m += (upsilon - k) * (Psi[k+1] - Psi[k]);
                            }
                        }
                    }

                    i = tab->map[m];
                    xp[i] = psi_m - tab->crval[m];
                }
            }
            *statp = 0;
        }

        wp += nelem;
        xp += nelem;
        statp++;
    }

    if (tabcoord) free(tabcoord);

    return status;
}