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