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