- Main Page
- Related Pages
- Data Structures
- Files

# lin.h

Go to the documentation of this file.

    00001 /*============================================================================
    00002
    00003   WCSLIB 4.10 - an implementation of the FITS WCS standard.
    00004   Copyright (C) 1995-2012, Mark Calabretta
    00005
    00006   This file is part of WCSLIB.
    00007
    00008   WCSLIB is free software: you can redistribute it and/or modify it under the
    00009   terms of the GNU Lesser General Public License as published by the Free
    00010   Software Foundation, either version 3 of the License, or (at your option)
    00011   any later version.
    00012
    00013   WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
    00014   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00015   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
    00016   more details.
    00017
    00018   You should have received a copy of the GNU Lesser General Public License
    00019   along with WCSLIB.  If not, see <http://www.gnu.org/licenses/>.
    00020
    00021   Correspondence concerning WCSLIB may be directed to:
    00022     Internet email: mcalabre@atnf.csiro.au
    00023     Postal address: Dr. Mark Calabretta
    00024                     Australia Telescope National Facility, CSIRO
    00025                     PO Box 76
    00026                     Epping NSW 1710
    00027                     AUSTRALIA
    00028
    00029   Author: Mark Calabretta, Australia Telescope National Facility
    00030   http://www.atnf.csiro.au/~mcalabre/index.html
    00031   $Id: lin.h,v 4.10 2012/02/05 23:41:44 cal103 Exp $
    00032 *=============================================================================
    00033 *
    00034 * WCSLIB 4.10 - C routines that implement the FITS World Coordinate System
    00035 * (WCS) standard.  Refer to
    00036 *
    00037 *   "Representations of world coordinates in FITS",
    00038 *   Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (Paper I)
    00039 *
    00040 * Refer to the README file provided with WCSLIB for an overview of the
    00041 * library.
    00042 *
    00043 *
    00044 * Summary of the lin routines
    00045 * ---------------------------
    00046 * These routines apply the linear transformation defined by the FITS WCS
    00047 * standard.  They are based on the linprm struct which contains all
    00048 * information needed for the computations.  The struct contains some members
    00049 * that must be set by the user, and others that are maintained by these
    00050 * routines, somewhat like a C++ class but with no encapsulation.
    00051 *
    00052 * Three routines, linini(), lincpy(), and linfree() are provided to manage the
    00053 * linprm struct, and another, linprt(), prints its contents.
    00054 *
    00055 * A setup routine, linset(), computes intermediate values in the linprm struct
    00056 * from parameters in it that were supplied by the user.  The struct always
    00057 * needs to be set up by linset() but need not be called explicitly - refer to
    00058 * the explanation of linprm::flag.
    00059 *
    00060 * linp2x() and linx2p() implement the WCS linear transformations.
    00061 *
    00062 * An auxiliary matrix inversion routine, matinv(), is included.  It uses
    00063 * LU-triangular factorization with scaled partial pivoting.
    00064 *
    00065 *
    00066 * linini() - Default constructor for the linprm struct
    00067 * ----------------------------------------------------
    00068 * linini() allocates memory for arrays in a linprm struct and sets all members
    00069 * of the struct to default values.
    00070 *
    00071 * PLEASE NOTE: every linprm struct should be initialized by linini(), possibly
    00072 * repeatedly.  On the first invokation, and only the first invokation,
    00073 * linprm::flag must be set to -1 to initialize memory management, regardless
    00074 * of whether linini() will actually be used to allocate memory.
    00075 *
    00076 * Given:
    00077 *   alloc     int       If true, allocate memory unconditionally for arrays in
    00078 *                       the linprm struct.
    00079 *
    00080 *                       If false, it is assumed that pointers to these arrays
    00081 *                       have been set by the user except if they are null
    00082 *                       pointers in which case memory will be allocated for
    00083 *                       them regardless.  (In other words, setting alloc true
    00084 *                       saves having to initalize these pointers to zero.)
    00085 *
    00086 *   naxis     int       The number of world coordinate axes, used to determine
    00087 *                       array sizes.
    00088 *
    00089 * Given and returned:
    00090 *   lin       struct linprm*
    00091 *                       Linear transformation parameters.  Note that, in order
    00092 *                       to initialize memory management linprm::flag should be
    00093 *                       set to -1 when lin is initialized for the first time
    00094 *                       (memory leaks may result if it had already been
    00095 *                       initialized).
    00096 *
    00097 * Function return value:
    00098 *             int       Status return value:
    00099 *                         0: Success.
    00100 *                         1: Null linprm pointer passed.
    00101 *                         2: Memory allocation failed.
    00102 *
    00103 *                       For returns > 1, a detailed error message is set in
    00104 *                       linprm::err if enabled, see wcserr_enable().
    00105 *
    00106 *
    00107 * lincpy() - Copy routine for the linprm struct
    00108 * ---------------------------------------------
    00109 * lincpy() does a deep copy of one linprm struct to another, using linini() to
    00110 * allocate memory for its arrays if required.  Only the "information to be
    00111 * provided" part of the struct is copied; a call to linset() is required to
    00112 * initialize the remainder.
    00113 *
    00114 * Given:
    00115 *   alloc     int       If true, allocate memory for the crpix, pc, and cdelt
    00116 *                       arrays in the destination.  Otherwise, it is assumed
    00117 *                       that pointers to these arrays have been set by the
    00118 *                       user except if they are null pointers in which case
    00119 *                       memory will be allocated for them regardless.
    00120 *
    00121 *   linsrc    const struct linprm*
    00122 *                       Struct to copy from.
    00123 *
    00124 * Given and returned:
    00125 *   lindst    struct linprm*
    00126 *                       Struct to copy to.  linprm::flag should be set to -1
    00127 *                       if lindst was not previously initialized (memory leaks
    00128 *                       may result if it was previously initialized).
    00129 *
    00130 * Function return value:
    00131 *             int       Status return value:
    00132 *                         0: Success.
    00133 *                         1: Null linprm pointer passed.
    00134 *                         2: Memory allocation failed.
    00135 *
    00136 *                       For returns > 1, a detailed error message is set in
    00137 *                       linprm::err if enabled, see wcserr_enable().
    00138 *
    00139 *
    00140 * linfree() - Destructor for the linprm struct
    00141 * --------------------------------------------
    00142 * linfree() frees memory allocated for the linprm arrays by linini() and/or
    00143 * linset().  linini() keeps a record of the memory it allocates and linfree()
    00144 * will only attempt to free this.
    00145 *
    00146 * PLEASE NOTE: linfree() must not be invoked on a linprm struct that was not
    00147 * initialized by linini().
    00148 *
    00149 * Given:
    00150 *   lin       struct linprm*
    00151 *                       Linear transformation parameters.
    00152 *
    00153 * Function return value:
    00154 *             int       Status return value:
    00155 *                         0: Success.
    00156 *                         1: Null linprm pointer passed.
    00157 *
    00158 *
    00159 * linprt() - Print routine for the linprm struct
    00160 * ----------------------------------------------
    00161 * linprt() prints the contents of a linprm struct using wcsprintf().  Mainly
    00162 * intended for diagnostic purposes.
    00163 *
    00164 * Given:
    00165 *   lin       const struct linprm*
    00166 *                       Linear transformation parameters.
    00167 *
    00168 * Function return value:
    00169 *             int       Status return value:
    00170 *                         0: Success.
    00171 *                         1: Null linprm pointer passed.
    00172 *
    00173 *
    00174 * linset() - Setup routine for the linprm struct
    00175 * ----------------------------------------------
    00176 * linset(), if necessary, allocates memory for the linprm::piximg and
    00177 * linprm::imgpix arrays and sets up the linprm struct according to information
    00178 * supplied within it - refer to the explanation of linprm::flag.
    00179 *
    00180 * Note that this routine need not be called directly; it will be invoked by
    00181 * linp2x() and linx2p() if the linprm::flag is anything other than a
    00182 * predefined magic value.
    00183 *
    00184 * Given and returned:
    00185 *   lin       struct linprm*
    00186 *                       Linear transformation parameters.
    00187 *
    00188 * Function return value:
    00189 *             int       Status return value:
    00190 *                         0: Success.
    00191 *                         1: Null linprm pointer passed.
    00192 *                         2: Memory allocation failed.
    00193 *                         3: PCi_ja matrix is singular.
    00194 *
    00195 *                       For returns > 1, a detailed error message is set in
    00196 *                       linprm::err if enabled, see wcserr_enable().
    00197 *
    00198 *
    00199 * linp2x() - Pixel-to-world linear transformation
    00200 * -----------------------------------------------
    00201 * linp2x() transforms pixel coordinates to intermediate world coordinates.
    00202 *
    00203 * Given and returned:
    00204 *   lin       struct linprm*
    00205 *                       Linear transformation parameters.
    00206 *
    00207 * Given:
    00208 *   ncoord,
    00209 *   nelem     int       The number of coordinates, each of vector length nelem
    00210 *                       but containing lin.naxis coordinate elements.
    00211 *
    00212 *   pixcrd    const double[ncoord][nelem]
    00213 *                       Array of pixel coordinates.
    00214 *
    00215 * Returned:
    00216 *   imgcrd    double[ncoord][nelem]
    00217 *                       Array of intermediate world coordinates.
    00218 *
    00219 * Function return value:
    00220 *             int       Status return value:
    00221 *                         0: Success.
    00222 *                         1: Null linprm pointer passed.
    00223 *                         2: Memory allocation failed.
    00224 *                         3: PCi_ja matrix is singular.
    00225 *
    00226 *                       For returns > 1, a detailed error message is set in
    00227 *                       linprm::err if enabled, see wcserr_enable().
    00228 *
    00229 *
    00230 * linx2p() - World-to-pixel linear transformation
    00231 * -----------------------------------------------
    00232 * linx2p() transforms intermediate world coordinates to pixel coordinates.
    00233 *
    00234 * Given and returned:
    00235 *   lin       struct linprm*
    00236 *                       Linear transformation parameters.
    00237 *
    00238 * Given:
    00239 *   ncoord,
    00240 *   nelem     int       The number of coordinates, each of vector length nelem
    00241 *                       but containing lin.naxis coordinate elements.
    00242 *
    00243 *   imgcrd   const double[ncoord][nelem]
    00244 *                       Array of intermediate world coordinates.
    00245 *
    00246 * Returned:
    00247 *   pixcrd    double[ncoord][nelem]
    00248 *                       Array of pixel coordinates.
    00249 *
    00250 *             int       Status return value:
    00251 *                         0: Success.
    00252 *                         1: Null linprm pointer passed.
    00253 *                         2: Memory allocation failed.
    00254 *                         3: PCi_ja matrix is singular.
    00255 *
    00256 *                       For returns > 1, a detailed error message is set in
    00257 *                       linprm::err if enabled, see wcserr_enable().
    00258 *
    00259 *
    00260 * linprm struct - Linear transformation parameters
    00261 * ------------------------------------------------
    00262 * The linprm struct contains all of the information required to perform a
    00263 * linear transformation.  It consists of certain members that must be set by
    00264 * the user ("given") and others that are set by the WCSLIB routines
    00265 * ("returned").
    00266 *
    00267 *   int flag
    00268 *     (Given and returned) This flag must be set to zero whenever any of the
    00269 *     following members of the linprm struct are set or modified:
    00270 *
    00271 *       - linprm::naxis (q.v., not normally set by the user),
    00272 *       - linprm::pc,
    00273 *       - linprm::cdelt.
    00274 *
    00275 *     This signals the initialization routine, linset(), to recompute the
    00276 *     returned members of the linprm struct.  linset() will reset flag to
    00277 *     indicate that this has been done.
    00278 *
    00279 *     PLEASE NOTE: flag should be set to -1 when linini() is called for the
    00280 *     first time for a particular linprm struct in order to initialize memory
    00281 *     management.  It must ONLY be used on the first initialization otherwise
    00282 *     memory leaks may result.
    00283 *
    00284 *   int naxis
    00285 *     (Given or returned) Number of pixel and world coordinate elements.
    00286 *
    00287 *     If linini() is used to initialize the linprm struct (as would normally
    00288 *     be the case) then it will set naxis from the value passed to it as a
    00289 *     function argument.  The user should not subsequently modify it.
    00290 *
    00291 *   double *crpix
    00292 *     (Given) Pointer to the first element of an array of double containing
    00293 *     the coordinate reference pixel, CRPIXja.
    00294 *
    00295 *   double *pc
    00296 *     (Given) Pointer to the first element of the PCi_ja (pixel coordinate)
    00297 *     transformation matrix.  The expected order is
    00298 *
    00299 =       struct linprm lin;
    00300 =       lin.pc = {PC1_1, PC1_2, PC2_1, PC2_2};
    00301 *
    00302 *     This may be constructed conveniently from a 2-D array via
    00303 *
    00304 =       double m[2][2] = {{PC1_1, PC1_2},
    00305 =                         {PC2_1, PC2_2}};
    00306 *
    00307 *     which is equivalent to
    00308 *
    00309 =       double m[2][2];
    00310 =       m[0][0] = PC1_1;
    00311 =       m[0][1] = PC1_2;
    00312 =       m[1][0] = PC2_1;
    00313 =       m[1][1] = PC2_2;
    00314 *
    00315 *     The storage order for this 2-D array is the same as for the 1-D array,
    00316 *     whence
    00317 *
    00318 =       lin.pc = *m;
    00319 *
    00320 *     would be legitimate.
    00321 *
    00322 *   double *cdelt
    00323 *     (Given) Pointer to the first element of an array of double containing
    00324 *     the coordinate increments, CDELTia.
    00325 *
    00326 *   int unity
    00327 *     (Returned) True if the linear transformation matrix is unity.
    00328 *
    00329 *   int padding
    00330 *     (An unused variable inserted for alignment purposes only.)
    00331 *
    00332 *   double *piximg
    00333 *     (Returned) Pointer to the first element of the matrix containing the
    00334 *     product of the CDELTia diagonal matrix and the PCi_ja matrix.
    00335 *
    00336 *   double *imgpix
    00337 *     (Returned) Pointer to the first element of the inverse of the
    00338 *     linprm::piximg matrix.
    00339 *
    00340 *   struct wcserr *err
    00341 *     (Returned) If enabled, when an error status is returned this struct
    00342 *     contains detailed information about the error, see wcserr_enable().
    00343 *
    00344 *   int i_naxis
    00345 *     (For internal use only.)
    00346 *   int m_flag
    00347 *     (For internal use only.)
    00348 *   int m_naxis
    00349 *     (For internal use only.)
    00350 *   int m_padding
    00351 *     (For internal use only.)
    00352 *   double *m_crpix
    00353 *     (For internal use only.)
    00354 *   double *m_pc
    00355 *     (For internal use only.)
    00356 *   double *m_cdelt
    00357 *     (For internal use only.)
    00358 *   void *padding2
    00359 *     (For internal use only.)
    00360 *
    00361 *
    00362 * Global variable: const char *lin_errmsg[] - Status return messages
    00363 * ------------------------------------------------------------------
    00364 * Error messages to match the status value returned from each function.
    00365 *
    00366 *===========================================================================*/
    00367
    00368 #ifndef WCSLIB_LIN
    00369 #define WCSLIB_LIN
    00370
    00371 #include "wcserr.h"
    00372
    00373 #ifdef __cplusplus
    00374 extern "C" {
    00375 #endif
    00376
    00377
    00378 extern const char *lin_errmsg[];
    00379
    00380 enum lin_errmsg_enum {
    00381   LINERR_SUCCESS      = 0,      /* Success. */
    00382   LINERR_NULL_POINTER = 1,      /* Null linprm pointer passed. */
    00383   LINERR_MEMORY       = 2,      /* Memory allocation failed. */
    00384   LINERR_SINGULAR_MTX = 3       /* PCi_ja matrix is singular. */
    00385 };
    00386
    00387 struct linprm {
    00388   /* Initialization flag (see the prologue above).                          */
    00389   /*------------------------------------------------------------------------*/
    00390   int flag;                     /* Set to zero to force initialization.     */
    00391
    00392   /* Parameters to be provided (see the prologue above).                    */
    00393   /*------------------------------------------------------------------------*/
    00394   int naxis;                    /* The number of axes, given by NAXIS.      */
    00395   double *crpix;                /* CRPIXja keywords for each pixel axis.    */
    00396   double *pc;                   /* PCi_ja  linear transformation matrix.    */
    00397   double *cdelt;                /* CDELTia keywords for each coord axis.    */
    00398
    00399   /* Information derived from the parameters supplied.                      */
    00400   /*------------------------------------------------------------------------*/
    00401   double *piximg;               /* Product of CDELTia and PCi_ja matrices.  */
    00402   double *imgpix;               /* Inverse of the piximg matrix.            */
    00403   int    unity;                 /* True if the PCi_ja matrix is unity.      */
    00404
    00405   /* Error handling                                                         */
    00406   /*------------------------------------------------------------------------*/
    00407   int    padding;               /* (Dummy inserted for alignment purposes.) */
    00408   struct wcserr *err;
    00409
    00410   /* Private - the remainder are for memory management.                     */
    00411   /*------------------------------------------------------------------------*/
    00412   int    i_naxis;
    00413   int    m_flag, m_naxis, m_padding;
    00414   double *m_crpix, *m_pc, *m_cdelt;
    00415   void   *padding2;
    00416 };
    00417
    00418 /* Size of the linprm struct in int units, used by the Fortran wrappers. */
    00419 #define LINLEN (sizeof(struct linprm)/sizeof(int))
    00420
    00421
    00422 int linini(int alloc, int naxis, struct linprm *lin);
    00423
    00424 int lincpy(int alloc, const struct linprm *linsrc, struct linprm *lindst);
    00425
    00426 int linfree(struct linprm *lin);
    00427
    00428 int linprt(const struct linprm *lin);
    00429
    00430 int linset(struct linprm *lin);
    00431
    00432 int linp2x(struct linprm *lin, int ncoord, int nelem, const double pixcrd[],
    00433            double imgcrd[]);
    00434
    00435 int linx2p(struct linprm *lin, int ncoord, int nelem, const double imgcrd[],
    00436            double pixcrd[]);
    00437
    00438 int matinv(int n, const double mat[], double inv[]);
    00439
    00440
    00441 /* Deprecated. */
    00442 #define linini_errmsg lin_errmsg
    00443 #define lincpy_errmsg lin_errmsg
    00444 #define linfree_errmsg lin_errmsg
    00445 #define linprt_errmsg lin_errmsg
    00446 #define linset_errmsg lin_errmsg
    00447 #define linp2x_errmsg lin_errmsg
    00448 #define linx2p_errmsg lin_errmsg
    00449
    00450 #ifdef __cplusplus
    00451 }
    00452 #endif
    00453
    00454 #endif /* WCSLIB_LIN */