00001 /*============================================================================ 00002 00003 WCSLIB 4.4 - an implementation of the FITS WCS standard. 00004 Copyright (C) 1995-2009, 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_8h-source.html,v 1.1 2009/09/14 20:25:23 irby Exp $ 00032 *============================================================================= 00033 * 00034 * WCSLIB 4.4 - 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 * 00104 * lincpy() - Copy routine for the linprm struct 00105 * --------------------------------------------- 00106 * lincpy() does a deep copy of one linprm struct to another, using linini() to 00107 * allocate memory for its arrays if required. Only the "information to be 00108 * provided" part of the struct is copied; a call to linset() is required to 00109 * initialize the remainder. 00110 * 00111 * Given: 00112 * alloc int If true, allocate memory for the crpix, pc, and cdelt 00113 * arrays in the destination. Otherwise, it is assumed 00114 * that pointers to these arrays have been set by the 00115 * user except if they are null pointers in which case 00116 * memory will be allocated for them regardless. 00117 * linsrc const struct linprm* 00118 * Struct to copy from. 00119 * 00120 * Given and returned: 00121 * lindst struct linprm* 00122 * Struct to copy to. linprm::flag should be set to -1 00123 * if lindst was not previously initialized (memory leaks 00124 * may result if it was previously initialized). 00125 * 00126 * Function return value: 00127 * int Status return value: 00128 * 0: Success. 00129 * 1: Null linprm pointer passed. 00130 * 2: Memory allocation failed. 00131 * 00132 * 00133 * linfree() - Destructor for the linprm struct 00134 * -------------------------------------------- 00135 * linfree() frees memory allocated for the linprm arrays by linini() and/or 00136 * linset(). linini() keeps a record of the memory it allocates and linfree() 00137 * will only attempt to free this. 00138 * 00139 * PLEASE NOTE: linfree() must not be invoked on a linprm struct that was not 00140 * initialized by linini(). 00141 * 00142 * Given: 00143 * lin struct linprm* 00144 * Linear transformation parameters. 00145 * 00146 * Function return value: 00147 * int Status return value: 00148 * 0: Success. 00149 * 1: Null linprm pointer passed. 00150 * 00151 * 00152 * linprt() - Print routine for the linprm struct 00153 * ---------------------------------------------- 00154 * linprt() prints the contents of a linprm struct. 00155 * 00156 * Given: 00157 * lin const struct linprm* 00158 * Linear transformation parameters. 00159 * 00160 * Function return value: 00161 * int Status return value: 00162 * 0: Success. 00163 * 1: Null linprm pointer passed. 00164 * 00165 * 00166 * linset() - Setup routine for the linprm struct 00167 * ---------------------------------------------- 00168 * linset(), if necessary, allocates memory for the linprm::piximg and 00169 * linprm::imgpix arrays and sets up the linprm struct according to information 00170 * supplied within it - refer to the explanation of linprm::flag. 00171 * 00172 * Note that this routine need not be called directly; it will be invoked by 00173 * linp2x() and linx2p() if the linprm::flag is anything other than a 00174 * predefined magic value. 00175 * 00176 * Given and returned: 00177 * lin struct linprm* 00178 * Linear transformation parameters. 00179 * 00180 * Function return value: 00181 * int Status return value: 00182 * 0: Success. 00183 * 1: Null linprm pointer passed. 00184 * 2: Memory allocation failed. 00185 * 3: PCi_ja matrix is singular. 00186 * 00187 * 00188 * linp2x() - Pixel-to-world linear transformation 00189 * ----------------------------------------------- 00190 * linp2x() transforms pixel coordinates to intermediate world coordinates. 00191 * 00192 * Given and returned: 00193 * lin struct linprm* 00194 * Linear transformation parameters. 00195 * 00196 * Given: 00197 * ncoord, 00198 * nelem int The number of coordinates, each of vector length nelem 00199 * but containing lin.naxis coordinate elements. 00200 * pixcrd const double[ncoord][nelem] 00201 * Array of pixel coordinates. 00202 * 00203 * Returned: 00204 * imgcrd double[ncoord][nelem] 00205 * Array of intermediate world coordinates. 00206 * 00207 * Function return value: 00208 * int Status return value: 00209 * 0: Success. 00210 * 1: Null linprm pointer passed. 00211 * 2: Memory allocation failed. 00212 * 3: PCi_ja matrix is singular. 00213 * 00214 * 00215 * linx2p() - World-to-pixel linear transformation 00216 * ----------------------------------------------- 00217 * linx2p() transforms intermediate world coordinates to pixel coordinates. 00218 * 00219 * Given and returned: 00220 * lin struct linprm* 00221 * Linear transformation parameters. 00222 * 00223 * Given: 00224 * ncoord, 00225 * nelem int The number of coordinates, each of vector length nelem 00226 * but containing lin.naxis coordinate elements. 00227 * imgcrd const double[ncoord][nelem] 00228 * Array of intermediate world coordinates. 00229 * 00230 * Returned: 00231 * pixcrd double[ncoord][nelem] 00232 * Array of pixel coordinates. 00233 * 00234 * int Status return value: 00235 * 0: Success. 00236 * 1: Null linprm pointer passed. 00237 * 2: Memory allocation failed. 00238 * 3: PCi_ja matrix is singular. 00239 * 00240 * 00241 * linprm struct - Linear transformation parameters 00242 * ------------------------------------------------ 00243 * The linprm struct contains all of the information required to perform a 00244 * linear transformation. It consists of certain members that must be set by 00245 * the user ("given") and others that are set by the WCSLIB routines 00246 * ("returned"). 00247 * 00248 * int flag 00249 * (Given and returned) This flag must be set to zero whenever any of the 00250 * following members of the linprm struct are set or modified: 00251 * 00252 * - linprm::naxis (q.v., not normally set by the user), 00253 * - linprm::pc, 00254 * - linprm::cdelt. 00255 * 00256 * This signals the initialization routine, linset(), to recompute the 00257 * returned members of the linprm struct. linset() will reset flag to 00258 * indicate that this has been done. 00259 * 00260 * PLEASE NOTE: flag should be set to -1 when linini() is called for the 00261 * first time for a particular linprm struct in order to initialize memory 00262 * management. It must ONLY be used on the first initialization otherwise 00263 * memory leaks may result. 00264 * 00265 * int naxis 00266 * (Given or returned) Number of pixel and world coordinate elements. 00267 * 00268 * If linini() is used to initialize the linprm struct (as would normally 00269 * be the case) then it will set naxis from the value passed to it as a 00270 * function argument. The user should not subsequently modify it. 00271 * 00272 * double *crpix 00273 * (Given) Pointer to the first element of an array of double containing 00274 * the coordinate reference pixel, CRPIXja. 00275 * 00276 * double *pc 00277 * (Given) Pointer to the first element of the PCi_ja (pixel coordinate) 00278 * transformation matrix. The expected order is 00279 * 00280 = struct linprm lin; 00281 = lin.pc = {PC1_1, PC1_2, PC2_1, PC2_2}; 00282 * 00283 * This may be constructed conveniently from a 2-D array via 00284 * 00285 = double m[2][2] = {{PC1_1, PC1_2}, 00286 = {PC2_1, PC2_2}}; 00287 * 00288 * which is equivalent to 00289 * 00290 = double m[2][2]; 00291 = m[0][0] = PC1_1; 00292 = m[0][1] = PC1_2; 00293 = m[1][0] = PC2_1; 00294 = m[1][1] = PC2_2; 00295 * 00296 * The storage order for this 2-D array is the same as for the 1-D array, 00297 * whence 00298 * 00299 = lin.pc = *m; 00300 * 00301 * would be legitimate. 00302 * 00303 * double *cdelt 00304 * (Given) Pointer to the first element of an array of double containing 00305 * the coordinate increments, CDELTia. 00306 * 00307 * int unity 00308 * (Returned) True if the linear transformation matrix is unity. 00309 * 00310 * double *piximg 00311 * (Returned) Pointer to the first element of the matrix containing the 00312 * product of the CDELTia diagonal matrix and the PCi_ja matrix. 00313 * 00314 * double *imgpix 00315 * (Returned) Pointer to the first element of the inverse of the 00316 * linprm::piximg matrix. 00317 * 00318 * int i_naxis 00319 * (For internal use only.) 00320 * int m_flag 00321 * (For internal use only.) 00322 * int m_naxis 00323 * (For internal use only.) 00324 * double *m_crpix 00325 * (For internal use only.) 00326 * double *m_pc 00327 * (For internal use only.) 00328 * double *m_cdelt 00329 * (For internal use only.) 00330 * 00331 * 00332 * Global variable: const char *lin_errmsg[] - Status return messages 00333 * ------------------------------------------------------------------ 00334 * Error messages to match the status value returned from each function. 00335 * 00336 *===========================================================================*/ 00337 00338 #ifndef WCSLIB_LIN 00339 #define WCSLIB_LIN 00340 00341 #ifdef __cplusplus 00342 extern "C" { 00343 #endif 00344 00345 00346 extern const char *lin_errmsg[]; 00347 00348 00349 struct linprm { 00350 /* Initialization flag (see the prologue above). */ 00351 /*------------------------------------------------------------------------*/ 00352 int flag; /* Set to zero to force initialization. */ 00353 00354 /* Parameters to be provided (see the prologue above). */ 00355 /*------------------------------------------------------------------------*/ 00356 int naxis; /* The number of axes, given by NAXIS. */ 00357 double *crpix; /* CRPIXja keywords for each pixel axis. */ 00358 double *pc; /* PCi_ja linear transformation matrix. */ 00359 double *cdelt; /* CDELTia keywords for each coord axis. */ 00360 00361 /* Information derived from the parameters supplied. */ 00362 /*------------------------------------------------------------------------*/ 00363 double *piximg; /* Product of CDELTia and PCi_ja matrices. */ 00364 double *imgpix; /* Inverse of the piximg matrix. */ 00365 int unity; /* True if the PCi_ja matrix is unity. */ 00366 00367 int i_naxis; /* The remainder are for memory management. */ 00368 int m_flag, m_naxis; 00369 double *m_crpix, *m_pc, *m_cdelt; 00370 }; 00371 00372 /* Size of the linprm struct in int units, used by the Fortran wrappers. */ 00373 #define LINLEN (sizeof(struct linprm)/sizeof(int)) 00374 00375 00376 int linini(int alloc, int naxis, struct linprm *lin); 00377 00378 int lincpy(int alloc, const struct linprm *linsrc, struct linprm *lindst); 00379 00380 int linfree(struct linprm *lin); 00381 00382 int linprt(const struct linprm *lin); 00383 00384 int linset(struct linprm *lin); 00385 00386 int linp2x(struct linprm *lin, int ncoord, int nelem, const double pixcrd[], 00387 double imgcrd[]); 00388 00389 int linx2p(struct linprm *lin, int ncoord, int nelem, const double imgcrd[], 00390 double pixcrd[]); 00391 00392 int matinv(int n, const double mat[], double inv[]); 00393 00394 00395 /* Deprecated. */ 00396 #define linini_errmsg lin_errmsg 00397 #define lincpy_errmsg lin_errmsg 00398 #define linfree_errmsg lin_errmsg 00399 #define linprt_errmsg lin_errmsg 00400 #define linset_errmsg lin_errmsg 00401 #define linp2x_errmsg lin_errmsg 00402 #define linx2p_errmsg lin_errmsg 00403 00404 #ifdef __cplusplus 00405 } 00406 #endif 00407 00408 #endif /* WCSLIB_LIN */