WCSLIB 4.20
tab.h
Go to the documentation of this file.
1 /*============================================================================
2 
3  WCSLIB 4.20 - an implementation of the FITS WCS standard.
4  Copyright (C) 1995-2013, Mark Calabretta
5 
6  This file is part of WCSLIB.
7 
8  WCSLIB is free software: you can redistribute it and/or modify it under the
9  terms of the GNU Lesser General Public License as published by the Free
10  Software Foundation, either version 3 of the License, or (at your option)
11  any later version.
12 
13  WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16  more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with WCSLIB. If not, see http://www.gnu.org/licenses.
20 
21  Direct correspondence concerning WCSLIB to mark@calabretta.id.au
22 
23  Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
24  http://www.atnf.csiro.au/people/Mark.Calabretta
25  $Id: tab_8h_source.html,v 1.1 2014/02/12 21:11:37 irby Exp $
26 *=============================================================================
27 *
28 * WCSLIB 4.20 - C routines that implement tabular coordinate systems as
29 * defined by the FITS World Coordinate System (WCS) standard. Refer to
30 *
31 * "Representations of world coordinates in FITS",
32 * Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (paper I)
33 *
34 * "Representations of spectral coordinates in FITS",
35 * Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L.
36 * 2006, A&A, 446, 747 (Paper III)
37 *
38 * Refer to the README file provided with WCSLIB for an overview of the
39 * library.
40 *
41 *
42 * Summary of the tab routines
43 * ---------------------------
44 * These routines implement the part of the FITS WCS standard that deals with
45 * tabular coordinates, i.e. coordinates that are defined via a lookup table.
46 * They define methods to be used for computing tabular world coordinates from
47 * intermediate world coordinates (a linear transformation of image pixel
48 * coordinates), and vice versa. They are based on the tabprm struct which
49 * contains all information needed for the computations. The struct contains
50 * some members that must be set by the user, and others that are maintained
51 * by these routines, somewhat like a C++ class but with no encapsulation.
52 *
53 * tabini(), tabmem(), tabcpy(), and tabfree() are provided to manage the
54 * tabprm struct, and another, tabprt(), to print its contents.
55 *
56 * A setup routine, tabset(), computes intermediate values in the tabprm struct
57 * from parameters in it that were supplied by the user. The struct always
58 * needs to be set up by tabset() but it need not be called explicitly - refer
59 * to the explanation of tabprm::flag.
60 *
61 * tabx2s() and tabs2x() implement the WCS tabular coordinate transformations.
62 *
63 * Accuracy:
64 * ---------
65 * No warranty is given for the accuracy of these routines (refer to the
66 * copyright notice); intending users must satisfy for themselves their
67 * adequacy for the intended purpose. However, closure effectively to within
68 * double precision rounding error was demonstrated by test routine ttab.c
69 * which accompanies this software.
70 *
71 *
72 * tabini() - Default constructor for the tabprm struct
73 * ----------------------------------------------------
74 * tabini() allocates memory for arrays in a tabprm struct and sets all members
75 * of the struct to default values.
76 *
77 * PLEASE NOTE: every tabprm struct should be initialized by tabini(), possibly
78 * repeatedly. On the first invokation, and only the first invokation, the
79 * flag member of the tabprm struct must be set to -1 to initialize memory
80 * management, regardless of whether tabini() will actually be used to allocate
81 * memory.
82 *
83 * Given:
84 * alloc int If true, allocate memory unconditionally for arrays in
85 * the tabprm struct.
86 *
87 * If false, it is assumed that pointers to these arrays
88 * have been set by the user except if they are null
89 * pointers in which case memory will be allocated for
90 * them regardless. (In other words, setting alloc true
91 * saves having to initalize these pointers to zero.)
92 *
93 * M int The number of tabular coordinate axes.
94 *
95 * K const int[]
96 * Vector of length M whose elements (K_1, K_2,... K_M)
97 * record the lengths of the axes of the coordinate array
98 * and of each indexing vector. M and K[] are used to
99 * determine the length of the various tabprm arrays and
100 * therefore the amount of memory to allocate for them.
101 * Their values are copied into the tabprm struct.
102 *
103 * It is permissible to set K (i.e. the address of the
104 * array) to zero which has the same effect as setting
105 * each element of K[] to zero. In this case no memory
106 * will be allocated for the index vectors or coordinate
107 * array in the tabprm struct. These together with the
108 * K vector must be set separately before calling
109 * tabset().
110 *
111 * Given and returned:
112 * tab struct tabprm*
113 * Tabular transformation parameters. Note that, in
114 * order to initialize memory management tabprm::flag
115 * should be set to -1 when tab is initialized for the
116 * first time (memory leaks may result if it had already
117 * been initialized).
118 *
119 * Function return value:
120 * int Status return value:
121 * 0: Success.
122 * 1: Null tabprm pointer passed.
123 * 2: Memory allocation failed.
124 * 3: Invalid tabular parameters.
125 *
126 * For returns > 1, a detailed error message is set in
127 * tabprm::err if enabled, see wcserr_enable().
128 *
129 *
130 * tabmem() - Acquire tabular memory
131 * ---------------------------------
132 * tabmem() takes control of memory allocated by the user for arrays in the
133 * tabprm struct.
134 *
135 * Given and returned:
136 * tab struct tabprm*
137 * Tabular transformation parameters.
138 *
139 * Function return value:
140 * int Status return value:
141 * 0: Success.
142 * 1: Null tabprm pointer passed.
143 * 2: Memory allocation failed.
144 *
145 * For returns > 1, a detailed error message is set in
146 * tabprm::err if enabled, see wcserr_enable().
147 *
148 *
149 * tabcpy() - Copy routine for the tabprm struct
150 * ---------------------------------------------
151 * tabcpy() does a deep copy of one tabprm struct to another, using tabini() to
152 * allocate memory for its arrays if required. Only the "information to be
153 * provided" part of the struct is copied; a call to tabset() is required to
154 * set up the remainder.
155 *
156 * Given:
157 * alloc int If true, allocate memory unconditionally for arrays in
158 * the tabprm struct.
159 *
160 * If false, it is assumed that pointers to these arrays
161 * have been set by the user except if they are null
162 * pointers in which case memory will be allocated for
163 * them regardless. (In other words, setting alloc true
164 * saves having to initalize these pointers to zero.)
165 *
166 * tabsrc const struct tabprm*
167 * Struct to copy from.
168 *
169 * Given and returned:
170 * tabdst struct tabprm*
171 * Struct to copy to. tabprm::flag should be set to -1
172 * if tabdst was not previously initialized (memory leaks
173 * may result if it was previously initialized).
174 *
175 * Function return value:
176 * int Status return value:
177 * 0: Success.
178 * 1: Null tabprm pointer passed.
179 * 2: Memory allocation failed.
180 *
181 * For returns > 1, a detailed error message is set in
182 * tabprm::err (associated with tabdst) if enabled, see
183 * wcserr_enable().
184 *
185 *
186 * tabfree() - Destructor for the tabprm struct
187 * --------------------------------------------
188 * tabfree() frees memory allocated for the tabprm arrays by tabini().
189 * tabini() records the memory it allocates and tabfree() will only attempt to
190 * free this.
191 *
192 * PLEASE NOTE: tabfree() must not be invoked on a tabprm struct that was not
193 * initialized by tabini().
194 *
195 * Returned:
196 * tab struct tabprm*
197 * Coordinate transformation parameters.
198 *
199 * Function return value:
200 * int Status return value:
201 * 0: Success.
202 * 1: Null tabprm pointer passed.
203 *
204 *
205 * tabprt() - Print routine for the tabprm struct
206 * ----------------------------------------------
207 * tabprt() prints the contents of a tabprm struct using wcsprintf(). Mainly
208 * intended for diagnostic purposes.
209 *
210 * Given:
211 * tab const struct tabprm*
212 * Tabular transformation parameters.
213 *
214 * Function return value:
215 * int Status return value:
216 * 0: Success.
217 * 1: Null tabprm pointer passed.
218 *
219 *
220 * tabset() - Setup routine for the tabprm struct
221 * -----------------------------------------------
222 * tabset() allocates memory for work arrays in the tabprm struct and sets up
223 * the struct according to information supplied within it.
224 *
225 * Note that this routine need not be called directly; it will be invoked by
226 * tabx2s() and tabs2x() if tabprm::flag is anything other than a predefined
227 * magic value.
228 *
229 * Given and returned:
230 * tab struct tabprm*
231 * Tabular transformation parameters.
232 *
233 * Function return value:
234 * int Status return value:
235 * 0: Success.
236 * 1: Null tabprm pointer passed.
237 * 3: Invalid tabular parameters.
238 *
239 * For returns > 1, a detailed error message is set in
240 * tabprm::err if enabled, see wcserr_enable().
241 *
242 *
243 * tabx2s() - Pixel-to-world transformation
244 * ----------------------------------------
245 * tabx2s() transforms intermediate world coordinates to world coordinates
246 * using coordinate lookup.
247 *
248 * Given and returned:
249 * tab struct tabprm*
250 * Tabular transformation parameters.
251 *
252 * Given:
253 * ncoord,
254 * nelem int The number of coordinates, each of vector length
255 * nelem.
256 *
257 * x const double[ncoord][nelem]
258 * Array of intermediate world coordinates, SI units.
259 *
260 * Returned:
261 * world double[ncoord][nelem]
262 * Array of world coordinates, in SI units.
263 *
264 * stat int[ncoord]
265 * Status return value status for each coordinate:
266 * 0: Success.
267 * 1: Invalid intermediate world coordinate.
268 *
269 * Function return value:
270 * int Status return value:
271 * 0: Success.
272 * 1: Null tabprm pointer passed.
273 * 3: Invalid tabular parameters.
274 * 4: One or more of the x coordinates were invalid,
275 * as indicated by the stat vector.
276 *
277 * For returns > 1, a detailed error message is set in
278 * tabprm::err if enabled, see wcserr_enable().
279 *
280 *
281 * tabs2x() - World-to-pixel transformation
282 * ----------------------------------------
283 * tabs2x() transforms world coordinates to intermediate world coordinates.
284 *
285 * Given and returned:
286 * tab struct tabprm*
287 * Tabular transformation parameters.
288 *
289 * Given:
290 * ncoord,
291 * nelem int The number of coordinates, each of vector length
292 * nelem.
293 * world const double[ncoord][nelem]
294 * Array of world coordinates, in SI units.
295 *
296 * Returned:
297 * x double[ncoord][nelem]
298 * Array of intermediate world coordinates, SI units.
299 * stat int[ncoord]
300 * Status return value status for each vector element:
301 * 0: Success.
302 * 1: Invalid world coordinate.
303 *
304 * Function return value:
305 * int Status return value:
306 * 0: Success.
307 * 1: Null tabprm pointer passed.
308 * 3: Invalid tabular parameters.
309 * 5: One or more of the world coordinates were
310 * invalid, as indicated by the stat vector.
311 *
312 * For returns > 1, a detailed error message is set in
313 * tabprm::err if enabled, see wcserr_enable().
314 *
315 *
316 * tabprm struct - Tabular transformation parameters
317 * -------------------------------------------------
318 * The tabprm struct contains information required to transform tabular
319 * coordinates. It consists of certain members that must be set by the user
320 * ("given") and others that are set by the WCSLIB routines ("returned"). Some
321 * of the latter are supplied for informational purposes while others are for
322 * internal use only.
323 *
324 * int flag
325 * (Given and returned) This flag must be set to zero whenever any of the
326 * following tabprm structure members are set or changed:
327 *
328 * - tabprm::M (q.v., not normally set by the user),
329 * - tabprm::K (q.v., not normally set by the user),
330 * - tabprm::map,
331 * - tabprm::crval,
332 * - tabprm::index,
333 * - tabprm::coord.
334 *
335 * This signals the initialization routine, tabset(), to recompute the
336 * returned members of the tabprm struct. tabset() will reset flag to
337 * indicate that this has been done.
338 *
339 * PLEASE NOTE: flag should be set to -1 when tabini() is called for the
340 * first time for a particular tabprm struct in order to initialize memory
341 * management. It must ONLY be used on the first initialization otherwise
342 * memory leaks may result.
343 *
344 * int M
345 * (Given or returned) Number of tabular coordinate axes.
346 *
347 * If tabini() is used to initialize the linprm struct (as would normally
348 * be the case) then it will set M from the value passed to it as a
349 * function argument. The user should not subsequently modify it.
350 *
351 * int *K
352 * (Given or returned) Pointer to the first element of a vector of length
353 * tabprm::M whose elements (K_1, K_2,... K_M) record the lengths of the
354 * axes of the coordinate array and of each indexing vector.
355 *
356 * If tabini() is used to initialize the linprm struct (as would normally
357 * be the case) then it will set K from the array passed to it as a
358 * function argument. The user should not subsequently modify it.
359 *
360 * int *map
361 * (Given) Pointer to the first element of a vector of length tabprm::M
362 * that defines the association between axis m in the M-dimensional
363 * coordinate array (1 <= m <= M) and the indices of the intermediate world
364 * coordinate and world coordinate arrays, x[] and world[], in the argument
365 * lists for tabx2s() and tabs2x().
366 *
367 * When x[] and world[] contain the full complement of coordinate elements
368 * in image-order, as will usually be the case, then map[m-1] == i-1 for
369 * axis i in the N-dimensional image (1 <= i <= N). In terms of the FITS
370 * keywords
371 *
372 * map[PVi_3a - 1] == i - 1.
373 *
374 * However, a different association may result if x[], for example, only
375 * contains a (relevant) subset of intermediate world coordinate elements.
376 * For example, if M == 1 for an image with N > 1, it is possible to fill
377 * x[] with the relevant coordinate element with nelem set to 1. In this
378 * case map[0] = 0 regardless of the value of i.
379 *
380 * double *crval
381 * (Given) Pointer to the first element of a vector of length tabprm::M
382 * whose elements contain the index value for the reference pixel for each
383 * of the tabular coordinate axes.
384 *
385 * double **index
386 * (Given) Pointer to the first element of a vector of length tabprm::M of
387 * pointers to vectors of lengths (K_1, K_2,... K_M) of 0-relative indexes
388 * (see tabprm::K).
389 *
390 * The address of any or all of these index vectors may be set to zero,
391 * i.e.
392 *
393 = index[m] == 0;
394 *
395 * this is interpreted as default indexing, i.e.
396 *
397 = index[m][k] = k;
398 *
399 * double *coord
400 * (Given) Pointer to the first element of the tabular coordinate array,
401 * treated as though it were defined as
402 *
403 = double coord[K_M]...[K_2][K_1][M];
404 *
405 * (see tabprm::K) i.e. with the M dimension varying fastest so that the
406 * M elements of a coordinate vector are stored contiguously in memory.
407 *
408 * int nc
409 * (Returned) Total number of coordinate vectors in the coordinate array
410 * being the product K_1 * K_2 * ... * K_M (see tabprm::K).
411 *
412 * int padding
413 * (An unused variable inserted for alignment purposes only.)
414 *
415 * int *sense
416 * (Returned) Pointer to the first element of a vector of length tabprm::M
417 * whose elements indicate whether the corresponding indexing vector is
418 * monotonic increasing (+1), or decreasing (-1).
419 *
420 * int *p0
421 * (Returned) Pointer to the first element of a vector of length tabprm::M
422 * of interpolated indices into the coordinate array such that Upsilon_m,
423 * as defined in Paper III, is equal to (p0[m] + 1) + tabprm::delta[m].
424 *
425 * double *delta
426 * (Returned) Pointer to the first element of a vector of length tabprm::M
427 * of interpolated indices into the coordinate array such that Upsilon_m,
428 * as defined in Paper III, is equal to (tabprm::p0[m] + 1) + delta[m].
429 *
430 * double *extrema
431 * (Returned) Pointer to the first element of an array that records the
432 * minimum and maximum value of each element of the coordinate vector in
433 * each row of the coordinate array, treated as though it were defined as
434 *
435 = double extrema[K_M]...[K_2][2][M]
436 *
437 * (see tabprm::K). The minimum is recorded in the first element of the
438 * compressed K_1 dimension, then the maximum. This array is used by the
439 * inverse table lookup function, tabs2x(), to speed up table searches.
440 *
441 * struct wcserr *err
442 * (Returned) If enabled, when an error status is returned this struct
443 * contains detailed information about the error, see wcserr_enable().
444 *
445 * int m_flag
446 * (For internal use only.)
447 * int m_M
448 * (For internal use only.)
449 * int m_N
450 * (For internal use only.)
451 * int set_M
452 * (For internal use only.)
453 * int m_K
454 * (For internal use only.)
455 * int m_map
456 * (For internal use only.)
457 * int m_crval
458 * (For internal use only.)
459 * int m_index
460 * (For internal use only.)
461 * int m_indxs
462 * (For internal use only.)
463 * int m_coord
464 * (For internal use only.)
465 *
466 *
467 * Global variable: const char *tab_errmsg[] - Status return messages
468 * ------------------------------------------------------------------
469 * Error messages to match the status value returned from each function.
470 *
471 *===========================================================================*/
472 
473 #ifndef WCSLIB_TAB
474 #define WCSLIB_TAB
475 
476 #include "wcserr.h"
477 
478 #ifdef __cplusplus
479 extern "C" {
480 #endif
481 
482 
483 extern const char *tab_errmsg[];
484 
486  TABERR_SUCCESS = 0, /* Success. */
487  TABERR_NULL_POINTER = 1, /* Null tabprm pointer passed. */
488  TABERR_MEMORY = 2, /* Memory allocation failed. */
489  TABERR_BAD_PARAMS = 3, /* Invalid tabular parameters. */
490  TABERR_BAD_X = 4, /* One or more of the x coordinates were
491  invalid. */
492  TABERR_BAD_WORLD = 5 /* One or more of the world coordinates were
493  invalid. */
494 };
495 
496 struct tabprm {
497  /* Initialization flag (see the prologue above). */
498  /*------------------------------------------------------------------------*/
499  int flag; /* Set to zero to force initialization. */
500 
501  /* Parameters to be provided (see the prologue above). */
502  /*------------------------------------------------------------------------*/
503  int M; /* Number of tabular coordinate axes. */
504  int *K; /* Vector of length M whose elements */
505  /* (K_1, K_2,... K_M) record the lengths of */
506  /* the axes of the coordinate array and of */
507  /* each indexing vector. */
508  int *map; /* Vector of length M usually such that */
509  /* map[m-1] == i-1 for coordinate array */
510  /* axis m and image axis i (see above). */
511  double *crval; /* Vector of length M containing the index */
512  /* value for the reference pixel for each */
513  /* of the tabular coordinate axes. */
514  double **index; /* Vector of pointers to M indexing vectors */
515  /* of lengths (K_1, K_2,... K_M). */
516  double *coord; /* (1+M)-dimensional tabular coordinate */
517  /* array (see above). */
518 
519  /* Information derived from the parameters supplied. */
520  /*------------------------------------------------------------------------*/
521  int nc; /* Number of coordinate vectors (of length */
522  /* M) in the coordinate array. */
523  int padding; /* (Dummy inserted for alignment purposes.) */
524  int *sense; /* Vector of M flags that indicate whether */
525  /* the Mth indexing vector is monotonic */
526  /* increasing, or else decreasing. */
527  int *p0; /* Vector of M indices. */
528  double *delta; /* Vector of M increments. */
529  double *extrema; /* (1+M)-dimensional array of coordinate */
530  /* extrema. */
531 
532  /* Error handling */
533  /*------------------------------------------------------------------------*/
534  struct wcserr *err;
535 
536  /* Private - the remainder are for memory management. */
537  /*------------------------------------------------------------------------*/
538  int m_flag, m_M, m_N;
539  int set_M;
540  int *m_K, *m_map;
541  double *m_crval, **m_index, **m_indxs, *m_coord;
542 };
543 
544 /* Size of the tabprm struct in int units, used by the Fortran wrappers. */
545 #define TABLEN (sizeof(struct tabprm)/sizeof(int))
546 
547 
548 int tabini(int alloc, int M, const int K[], struct tabprm *tab);
549 
550 int tabmem(struct tabprm *tab);
551 
552 int tabcpy(int alloc, const struct tabprm *tabsrc, struct tabprm *tabdst);
553 
554 int tabfree(struct tabprm *tab);
555 
556 int tabprt(const struct tabprm *tab);
557 
558 int tabset(struct tabprm *tab);
559 
560 int tabx2s(struct tabprm *tab, int ncoord, int nelem, const double x[],
561  double world[], int stat[]);
562 
563 int tabs2x(struct tabprm *tab, int ncoord, int nelem, const double world[],
564  double x[], int stat[]);
565 
566 
567 /* Deprecated. */
568 #define tabini_errmsg tab_errmsg
569 #define tabcpy_errmsg tab_errmsg
570 #define tabfree_errmsg tab_errmsg
571 #define tabprt_errmsg tab_errmsg
572 #define tabset_errmsg tab_errmsg
573 #define tabx2s_errmsg tab_errmsg
574 #define tabs2x_errmsg tab_errmsg
575 
576 #ifdef __cplusplus
577 }
578 #endif
579 
580 #endif /* WCSLIB_TAB */