00001 /*============================================================================ 00002 00003 WCSLIB 4.15 - 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 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: cel.h,v 4.15 2012/09/26 14:26:05 cal103 Exp $ 00026 *============================================================================= 00027 * 00028 * WCSLIB 4.15 - 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 * "Representations of celestial coordinates in FITS", 00035 * Calabretta, M.R., & Greisen, E.W. 2002, A&A, 395, 1077 (Paper II) 00036 * 00037 * Refer to the README file provided with WCSLIB for an overview of the 00038 * library. 00039 * 00040 * 00041 * Summary of the cel routines 00042 * --------------------------- 00043 * These routines implement the part of the FITS World Coordinate System (WCS) 00044 * standard that deals with celestial coordinates. They define methods to be 00045 * used for computing celestial world coordinates from intermediate world 00046 * coordinates (a linear transformation of image pixel coordinates), and vice 00047 * versa. They are based on the celprm struct which contains all information 00048 * needed for the computations. This struct contains some elements that must 00049 * be set by the user, and others that are maintained by these routines, 00050 * somewhat like a C++ class but with no encapsulation. 00051 * 00052 * Routine celini() is provided to initialize the celprm struct with default 00053 * values, celfree() reclaims any memory that may have been allocated to store 00054 * an error message, and celprt() prints its contents. 00055 * 00056 * A setup routine, celset(), computes intermediate values in the celprm struct 00057 * from parameters in it that were supplied by the user. The struct always 00058 * needs to be set up by celset() but it need not be called explicitly - refer 00059 * to the explanation of celprm::flag. 00060 * 00061 * celx2s() and cels2x() implement the WCS celestial coordinate 00062 * transformations. In fact, they are high level driver routines for the lower 00063 * level spherical coordinate rotation and projection routines described in 00064 * sph.h and prj.h. 00065 * 00066 * 00067 * celini() - Default constructor for the celprm struct 00068 * ---------------------------------------------------- 00069 * celini() sets all members of a celprm struct to default values. It should 00070 * be used to initialize every celprm struct. 00071 * 00072 * Returned: 00073 * cel struct celprm* 00074 * Celestial transformation parameters. 00075 * 00076 * Function return value: 00077 * int Status return value: 00078 * 0: Success. 00079 * 1: Null celprm pointer passed. 00080 * 00081 * 00082 * celfree() - Destructor for the celprm struct 00083 * -------------------------------------------- 00084 * celfree() frees any memory that may have been allocated to store an error 00085 * message in the celprm struct. 00086 * 00087 * Given: 00088 * cel struct celprm* 00089 * Celestial transformation parameters. 00090 * 00091 * Function return value: 00092 * int Status return value: 00093 * 0: Success. 00094 * 1: Null celprm pointer passed. 00095 * 00096 * 00097 * celprt() - Print routine for the celprm struct 00098 * ---------------------------------------------- 00099 * celprt() prints the contents of a celprm struct using wcsprintf(). Mainly 00100 * intended for diagnostic purposes. 00101 * 00102 * Given: 00103 * cel const struct celprm* 00104 * Celestial transformation parameters. 00105 * 00106 * Function return value: 00107 * int Status return value: 00108 * 0: Success. 00109 * 1: Null celprm pointer passed. 00110 * 00111 * 00112 * celset() - Setup routine for the celprm struct 00113 * ---------------------------------------------- 00114 * celset() sets up a celprm struct according to information supplied within 00115 * it. 00116 * 00117 * Note that this routine need not be called directly; it will be invoked by 00118 * celx2s() and cels2x() if celprm::flag is anything other than a predefined 00119 * magic value. 00120 * 00121 * Given and returned: 00122 * cel struct celprm* 00123 * Celestial transformation parameters. 00124 * 00125 * Function return value: 00126 * int Status return value: 00127 * 0: Success. 00128 * 1: Null celprm pointer passed. 00129 * 2: Invalid projection parameters. 00130 * 3: Invalid coordinate transformation parameters. 00131 * 4: Ill-conditioned coordinate transformation 00132 * parameters. 00133 * 00134 * For returns > 1, a detailed error message is set in 00135 * celprm::err if enabled, see wcserr_enable(). 00136 * 00137 * 00138 * celx2s() - Pixel-to-world celestial transformation 00139 * -------------------------------------------------- 00140 * celx2s() transforms (x,y) coordinates in the plane of projection to 00141 * celestial coordinates (lng,lat). 00142 * 00143 * Given and returned: 00144 * cel struct celprm* 00145 * Celestial transformation parameters. 00146 * 00147 * Given: 00148 * nx,ny int Vector lengths. 00149 * 00150 * sxy,sll int Vector strides. 00151 * 00152 * x,y const double[] 00153 * Projected coordinates in pseudo "degrees". 00154 * 00155 * Returned: 00156 * phi,theta double[] Longitude and latitude (phi,theta) in the native 00157 * coordinate system of the projection [deg]. 00158 * 00159 * lng,lat double[] Celestial longitude and latitude (lng,lat) of the 00160 * projected point [deg]. 00161 * 00162 * stat int[] Status return value for each vector element: 00163 * 0: Success. 00164 * 1: Invalid value of (x,y). 00165 * 00166 * Function return value: 00167 * int Status return value: 00168 * 0: Success. 00169 * 1: Null celprm pointer passed. 00170 * 2: Invalid projection parameters. 00171 * 3: Invalid coordinate transformation parameters. 00172 * 4: Ill-conditioned coordinate transformation 00173 * parameters. 00174 * 5: One or more of the (x,y) coordinates were 00175 * invalid, as indicated by the stat vector. 00176 * 00177 * For returns > 1, a detailed error message is set in 00178 * celprm::err if enabled, see wcserr_enable(). 00179 * 00180 * 00181 * cels2x() - World-to-pixel celestial transformation 00182 * -------------------------------------------------- 00183 * cels2x() transforms celestial coordinates (lng,lat) to (x,y) coordinates in 00184 * the plane of projection. 00185 * 00186 * Given and returned: 00187 * cel struct celprm* 00188 * Celestial transformation parameters. 00189 * 00190 * Given: 00191 * nlng,nlat int Vector lengths. 00192 * 00193 * sll,sxy int Vector strides. 00194 * 00195 * lng,lat const double[] 00196 * Celestial longitude and latitude (lng,lat) of the 00197 * projected point [deg]. 00198 * 00199 * Returned: 00200 * phi,theta double[] Longitude and latitude (phi,theta) in the native 00201 * coordinate system of the projection [deg]. 00202 * 00203 * x,y double[] Projected coordinates in pseudo "degrees". 00204 * 00205 * stat int[] Status return value for each vector element: 00206 * 0: Success. 00207 * 1: Invalid value of (lng,lat). 00208 * 00209 * Function return value: 00210 * int Status return value: 00211 * 0: Success. 00212 * 1: Null celprm pointer passed. 00213 * 2: Invalid projection parameters. 00214 * 3: Invalid coordinate transformation parameters. 00215 * 4: Ill-conditioned coordinate transformation 00216 * parameters. 00217 * 6: One or more of the (lng,lat) coordinates were 00218 * invalid, as indicated by the stat vector. 00219 * 00220 * For returns > 1, a detailed error message is set in 00221 * celprm::err if enabled, see wcserr_enable(). 00222 * 00223 * 00224 * celprm struct - Celestial transformation parameters 00225 * --------------------------------------------------- 00226 * The celprm struct contains information required to transform celestial 00227 * coordinates. It consists of certain members that must be set by the user 00228 * ("given") and others that are set by the WCSLIB routines ("returned"). Some 00229 * of the latter are supplied for informational purposes and others are for 00230 * internal use only. 00231 * 00232 * Returned celprm struct members must not be modified by the user. 00233 * 00234 * int flag 00235 * (Given and returned) This flag must be set to zero whenever any of the 00236 * following celprm struct members are set or changed: 00237 * 00238 * - celprm::offset, 00239 * - celprm::phi0, 00240 * - celprm::theta0, 00241 * - celprm::ref[4], 00242 * - celprm::prj: 00243 * - prjprm::code, 00244 * - prjprm::r0, 00245 * - prjprm::pv[], 00246 * - prjprm::phi0, 00247 * - prjprm::theta0. 00248 * 00249 * This signals the initialization routine, celset(), to recompute the 00250 * returned members of the celprm struct. celset() will reset flag to 00251 * indicate that this has been done. 00252 * 00253 * int offset 00254 * (Given) If true (non-zero), an offset will be applied to (x,y) to 00255 * force (x,y) = (0,0) at the fiducial point, (phi_0,theta_0). 00256 * Default is 0 (false). 00257 * 00258 * double phi0 00259 * (Given) The native longitude, phi_0 [deg], and ... 00260 * 00261 * double theta0 00262 * (Given) ... the native latitude, theta_0 [deg], of the fiducial point, 00263 * i.e. the point whose celestial coordinates are given in 00264 * celprm::ref[1:2]. If undefined (set to a magic value by prjini()) the 00265 * initialization routine, celset(), will set this to a projection-specific 00266 * default. 00267 * 00268 * double ref[4] 00269 * (Given) The first pair of values should be set to the celestial 00270 * longitude and latitude of the fiducial point [deg] - typically right 00271 * ascension and declination. These are given by the CRVALia keywords in 00272 * FITS. 00273 * 00274 * (Given and returned) The second pair of values are the native longitude, 00275 * phi_p [deg], and latitude, theta_p [deg], of the celestial pole (the 00276 * latter is the same as the celestial latitude of the native pole, 00277 * delta_p) and these are given by the FITS keywords LONPOLEa and LATPOLEa 00278 * (or by PVi_2a and PVi_3a attached to the longitude axis which take 00279 * precedence if defined). 00280 * 00281 * LONPOLEa defaults to phi_0 (see above) if the celestial latitude of the 00282 * fiducial point of the projection is greater than or equal to the native 00283 * latitude, otherwise phi_0 + 180 [deg]. (This is the condition for the 00284 * celestial latitude to increase in the same direction as the native 00285 * latitude at the fiducial point.) ref[2] may be set to UNDEFINED (from 00286 * wcsmath.h) or 999.0 to indicate that the correct default should be 00287 * substituted. 00288 * 00289 * theta_p, the native latitude of the celestial pole (or equally the 00290 * celestial latitude of the native pole, delta_p) is often determined 00291 * uniquely by CRVALia and LONPOLEa in which case LATPOLEa is ignored. 00292 * However, in some circumstances there are two valid solutions for theta_p 00293 * and LATPOLEa is used to choose between them. LATPOLEa is set in ref[3] 00294 * and the solution closest to this value is used to reset ref[3]. It is 00295 * therefore legitimate, for example, to set ref[3] to +90.0 to choose the 00296 * more northerly solution - the default if the LATPOLEa keyword is omitted 00297 * from the FITS header. For the special case where the fiducial point of 00298 * the projection is at native latitude zero, its celestial latitude is 00299 * zero, and LONPOLEa = +/- 90.0 then the celestial latitude of the native 00300 * pole is not determined by the first three reference values and LATPOLEa 00301 * specifies it completely. 00302 * 00303 * The returned value, celprm::latpreq, specifies how LATPOLEa was actually 00304 * used. 00305 * 00306 * struct prjprm prj 00307 * (Given and returned) Projection parameters described in the prologue to 00308 * prj.h. 00309 * 00310 * double euler[5] 00311 * (Returned) Euler angles and associated intermediaries derived from the 00312 * coordinate reference values. The first three values are the Z-, X-, and 00313 * Z'-Euler angles [deg], and the remaining two are the cosine and sine of 00314 * the X-Euler angle. 00315 * 00316 * int latpreq 00317 * (Returned) For informational purposes, this indicates how the LATPOLEa 00318 * keyword was used 00319 * - 0: Not required, theta_p (== delta_p) was determined uniquely by the 00320 * CRVALia and LONPOLEa keywords. 00321 * - 1: Required to select between two valid solutions of theta_p. 00322 * - 2: theta_p was specified solely by LATPOLEa. 00323 * 00324 * int isolat 00325 * (Returned) True if the spherical rotation preserves the magnitude of the 00326 * latitude, which occurs iff the axes of the native and celestial 00327 * coordinates are coincident. It signals an opportunity to cache 00328 * intermediate calculations common to all elements in a vector 00329 * computation. 00330 * 00331 * struct wcserr *err 00332 * (Returned) If enabled, when an error status is returned this struct 00333 * contains detailed information about the error, see wcserr_enable(). 00334 * 00335 * void *padding 00336 * (An unused variable inserted for alignment purposes only.) 00337 * 00338 * Global variable: const char *cel_errmsg[] - Status return messages 00339 * ------------------------------------------------------------------ 00340 * Status messages to match the status value returned from each function. 00341 * 00342 *===========================================================================*/ 00343 00344 #ifndef WCSLIB_CEL 00345 #define WCSLIB_CEL 00346 00347 #include "prj.h" 00348 #include "wcserr.h" 00349 00350 #ifdef __cplusplus 00351 extern "C" { 00352 #endif 00353 00354 00355 extern const char *cel_errmsg[]; 00356 00357 enum cel_errmsg_enum { 00358 CELERR_SUCCESS = 0, /* Success. */ 00359 CELERR_NULL_POINTER = 1, /* Null celprm pointer passed. */ 00360 CELERR_BAD_PARAM = 2, /* Invalid projection parameters. */ 00361 CELERR_BAD_COORD_TRANS = 3, /* Invalid coordinate transformation 00362 parameters. */ 00363 CELERR_ILL_COORD_TRANS = 4, /* Ill-conditioned coordinated transformation 00364 parameters. */ 00365 CELERR_BAD_PIX = 5, /* One or more of the (x,y) coordinates were 00366 invalid. */ 00367 CELERR_BAD_WORLD = 6 /* One or more of the (lng,lat) coordinates 00368 were invalid. */ 00369 }; 00370 00371 struct celprm { 00372 /* Initialization flag (see the prologue above). */ 00373 /*------------------------------------------------------------------------*/ 00374 int flag; /* Set to zero to force initialization. */ 00375 00376 /* Parameters to be provided (see the prologue above). */ 00377 /*------------------------------------------------------------------------*/ 00378 int offset; /* Force (x,y) = (0,0) at (phi_0,theta_0). */ 00379 double phi0, theta0; /* Native coordinates of fiducial point. */ 00380 double ref[4]; /* Celestial coordinates of fiducial */ 00381 /* point and native coordinates of */ 00382 /* celestial pole. */ 00383 00384 struct prjprm prj; /* Projection parameters (see prj.h). */ 00385 00386 /* Information derived from the parameters supplied. */ 00387 /*------------------------------------------------------------------------*/ 00388 double euler[5]; /* Euler angles and functions thereof. */ 00389 int latpreq; /* LATPOLEa requirement. */ 00390 int isolat; /* True if |latitude| is preserved. */ 00391 00392 /* Error handling */ 00393 /*------------------------------------------------------------------------*/ 00394 struct wcserr *err; 00395 00396 /* Private */ 00397 /*------------------------------------------------------------------------*/ 00398 void *padding; /* (Dummy inserted for alignment purposes.) */ 00399 }; 00400 00401 /* Size of the celprm struct in int units, used by the Fortran wrappers. */ 00402 #define CELLEN (sizeof(struct celprm)/sizeof(int)) 00403 00404 00405 int celini(struct celprm *cel); 00406 00407 int celfree(struct celprm *cel); 00408 00409 int celprt(const struct celprm *cel); 00410 00411 int celset(struct celprm *cel); 00412 00413 int celx2s(struct celprm *cel, int nx, int ny, int sxy, int sll, 00414 const double x[], const double y[], 00415 double phi[], double theta[], double lng[], double lat[], 00416 int stat[]); 00417 00418 int cels2x(struct celprm *cel, int nlng, int nlat, int sll, int sxy, 00419 const double lng[], const double lat[], 00420 double phi[], double theta[], double x[], double y[], 00421 int stat[]); 00422 00423 00424 /* Deprecated. */ 00425 #define celini_errmsg cel_errmsg 00426 #define celprt_errmsg cel_errmsg 00427 #define celset_errmsg cel_errmsg 00428 #define celx2s_errmsg cel_errmsg 00429 #define cels2x_errmsg cel_errmsg 00430 00431 #ifdef __cplusplus 00432 } 00433 #endif 00434 00435 #endif /* WCSLIB_CEL */