00001 /*============================================================================ 00002 00003 WCSLIB 4.13 - 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.13.1.1 2012/03/14 07:40:37 cal103 Exp cal103 $ 00032 *============================================================================= 00033 * 00034 * WCSLIB 4.13 - 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 */