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: wcsunits.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 * The Flexible Image Transport System (FITS), a data format widely used in 00041 * astronomy for data interchange and archive, is described in 00042 * 00043 * "Definition of The Flexible Image Transport System (FITS)", 00044 * Hanisch, R.J., Farris, A., Greisen, E.W., et al. 2001, A&A, 376, 359 00045 * 00046 * which formalizes NOST 100-2.0, a document produced by the NASA/Science 00047 * Office of Standards and Technology, see http://fits.gsfc.nasa.gov. 00048 * 00049 * Refer to the README file provided with WCSLIB for an overview of the 00050 * library. 00051 * 00052 * 00053 * Summary of the wcsunits routines 00054 * -------------------------------- 00055 * Routines in this suite deal with units specifications and conversions: 00056 * 00057 * - wcsunitse(): given two unit specifications, derive the conversion from 00058 * one to the other. 00059 * 00060 * - wcsutrne(): translates certain commonly used but non-standard unit 00061 * strings. It is intended to be called before wcsulexe() which only 00062 * handles standard FITS units specifications. 00063 * 00064 * - wcsulexe(): parses a standard FITS units specification of arbitrary 00065 * complexity, deriving the conversion to canonical units. 00066 * 00067 * 00068 * wcsunitse() - FITS units specification conversion 00069 * ------------------------------------------------- 00070 * wcsunitse() derives the conversion from one system of units to another. 00071 * 00072 * A deprecated form of this function, wcsunits(), lacks the wcserr** 00073 * parameter. 00074 * 00075 * Given: 00076 * have const char [] 00077 * FITS units specification to convert from (null- 00078 * terminated), with or without surrounding square 00079 * brackets (for inline specifications); text following 00080 * the closing bracket is ignored. 00081 * 00082 * want const char [] 00083 * FITS units specification to convert to (null- 00084 * terminated), with or without surrounding square 00085 * brackets (for inline specifications); text following 00086 * the closing bracket is ignored. 00087 * 00088 * Returned: 00089 * scale, 00090 * offset, 00091 * power double* Convert units using 00092 * 00093 = pow(scale*value + offset, power); 00094 * 00095 * Normally offset is zero except for log() or ln() 00096 * conversions, e.g. "log(MHz)" to "ln(Hz)". Likewise, 00097 * power is normally unity except for exp() conversions, 00098 * e.g. "exp(ms)" to "exp(/Hz)". Thus conversions 00099 * ordinarily consist of 00100 * 00101 = value *= scale; 00102 * 00103 * err struct wcserr ** 00104 * If enabled, for function return values > 1, this 00105 * struct will contain a detailed error message, see 00106 * wcserr_enable(). May be NULL if an error message is 00107 * not desired. 00108 * 00109 * Function return value: 00110 * int Status return value: 00111 * 0: Success. 00112 * 1-9: Status return from wcsulexe(). 00113 * 10: Non-conformant unit specifications. 00114 * 11: Non-conformant functions. 00115 * 00116 * scale is zeroed on return if an error occurs. 00117 * 00118 * 00119 * wcsutrne() - Translation of non-standard unit specifications 00120 * ------------------------------------------------------------ 00121 * wcsutrne() translates certain commonly used but non-standard unit strings, 00122 * e.g. "DEG", "MHZ", "KELVIN", that are not recognized by wcsulexe(), refer to 00123 * the notes below for a full list. Compounds are also recognized, e.g. 00124 * "JY/BEAM" and "KM/SEC/SEC". Extraneous embedded blanks are removed. 00125 * 00126 * A deprecated form of this function, wcsutrn(), lacks the wcserr** parameter. 00127 * 00128 * Given: 00129 * ctrl int Although "S" is commonly used to represent seconds, 00130 * its translation to "s" is potentially unsafe since the 00131 * standard recognizes "S" formally as Siemens, however 00132 * rarely that may be used. The same applies to "H" for 00133 * hours (Henry), and "D" for days (Debye). This 00134 * bit-flag controls what to do in such cases: 00135 * 1: Translate "S" to "s". 00136 * 2: Translate "H" to "h". 00137 * 4: Translate "D" to "d". 00138 * Thus ctrl == 0 doesn't do any unsafe translations, 00139 * whereas ctrl == 7 does all of them. 00140 * 00141 * Given and returned: 00142 * unitstr char [] Null-terminated character array containing the units 00143 * specification to be translated. 00144 * 00145 * Inline units specifications in the a FITS header 00146 * keycomment are also handled. If the first non-blank 00147 * character in unitstr is '[' then the unit string is 00148 * delimited by its matching ']'. Blanks preceding '[' 00149 * will be stripped off, but text following the closing 00150 * bracket will be preserved without modification. 00151 * 00152 * err struct wcserr ** 00153 * If enabled, for function return values > 1, this 00154 * struct will contain a detailed error message, see 00155 * wcserr_enable(). May be NULL if an error message is 00156 * not desired. 00157 * 00158 * Function return value: 00159 * int Status return value: 00160 * -1: No change was made, other than stripping blanks 00161 * (not an error). 00162 * 0: Success. 00163 * 9: Internal parser error. 00164 * 12: Potentially unsafe translation, whether applied 00165 * or not (see notes). 00166 * 00167 * Notes: 00168 * Translation of non-standard unit specifications: apart from leading and 00169 * trailing blanks, a case-sensitive match is required for the aliases listed 00170 * below, in particular the only recognized aliases with metric prefixes are 00171 * "KM", "KHZ", "MHZ", and "GHZ". Potentially unsafe translations of "D", 00172 * "H", and "S", shown in parentheses, are optional. 00173 * 00174 = Unit Recognized aliases 00175 = ---- ------------------------------------------------------------- 00176 = Angstrom angstrom 00177 = arcmin arcmins, ARCMIN, ARCMINS 00178 = arcsec arcsecs, ARCSEC, ARCSECS 00179 = beam BEAM 00180 = byte Byte 00181 = d day, days, (D), DAY, DAYS 00182 = deg degree, degrees, DEG, DEGREE, DEGREES 00183 = GHz GHZ 00184 = h hr, (H), HR 00185 = Hz hz, HZ 00186 = kHz KHZ 00187 = Jy JY 00188 = K kelvin, kelvins, Kelvin, Kelvins, KELVIN, KELVINS 00189 = km KM 00190 = m metre, meter, metres, meters, M, METRE, METER, METRES, METERS 00191 = min MIN 00192 = MHz MHZ 00193 = Ohm ohm 00194 = Pa pascal, pascals, Pascal, Pascals, PASCAL, PASCALS 00195 = pixel pixels, PIXEL, PIXELS 00196 = rad radian, radians, RAD, RADIAN, RADIANS 00197 = s sec, second, seconds, (S), SEC, SECOND, SECONDS 00198 = V volt, volts, Volt, Volts, VOLT, VOLTS 00199 = yr year, years, YR, YEAR, YEARS 00200 * 00201 * The aliases "angstrom", "ohm", and "Byte" for (Angstrom, Ohm, and byte) 00202 * are recognized by wcsulexe() itself as an unofficial extension of the 00203 * standard, but they are converted to the standard form here. 00204 * 00205 * 00206 * wcsulexe() - FITS units specification parser 00207 * -------------------------------------------- 00208 * wcsulexe() parses a standard FITS units specification of arbitrary 00209 * complexity, deriving the scale factor required to convert to canonical 00210 * units - basically SI with degrees and "dimensionless" additions such as 00211 * byte, pixel and count. 00212 * 00213 * A deprecated form of this function, wcsulex(), lacks the wcserr** parameter. 00214 * 00215 * Given: 00216 * unitstr const char [] 00217 * Null-terminated character array containing the units 00218 * specification, with or without surrounding square 00219 * brackets (for inline specifications); text following 00220 * the closing bracket is ignored. 00221 * 00222 * Returned: 00223 * func int* Special function type, see note 4: 00224 * 0: None 00225 * 1: log() ...base 10 00226 * 2: ln() ...base e 00227 * 3: exp() 00228 * 00229 * scale double* Scale factor for the unit specification; multiply a 00230 * value expressed in the given units by this factor to 00231 * convert it to canonical units. 00232 * 00233 * units double[WCSUNITS_NTYPE] 00234 * A units specification is decomposed into powers of 16 00235 * fundamental unit types: angle, mass, length, time, 00236 * count, pixel, etc. Preprocessor macro WCSUNITS_NTYPE 00237 * is defined to dimension this vector, and others such 00238 * WCSUNITS_PLANE_ANGLE, WCSUNITS_LENGTH, etc. to access 00239 * its elements. 00240 * 00241 * Corresponding character strings, wcsunits_types[] and 00242 * wcsunits_units[], are predefined to describe each 00243 * quantity and its canonical units. 00244 * 00245 * err struct wcserr ** 00246 * If enabled, for function return values > 1, this 00247 * struct will contain a detailed error message, see 00248 * wcserr_enable(). May be NULL if an error message is 00249 * not desired. 00250 * 00251 * Function return value: 00252 * int Status return value: 00253 * 0: Success. 00254 * 1: Invalid numeric multiplier. 00255 * 2: Dangling binary operator. 00256 * 3: Invalid symbol in INITIAL context. 00257 * 4: Function in invalid context. 00258 * 5: Invalid symbol in EXPON context. 00259 * 6: Unbalanced bracket. 00260 * 7: Unbalanced parenthesis. 00261 * 8: Consecutive binary operators. 00262 * 9: Internal parser error. 00263 * 00264 * scale and units[] are zeroed on return if an error 00265 * occurs. 00266 * 00267 * Notes: 00268 * 1: wcsulexe() is permissive in accepting whitespace in all contexts in a 00269 * units specification where it does not create ambiguity (e.g. not 00270 * between a metric prefix and a basic unit string), including in strings 00271 * like "log (m ** 2)" which is formally disallowed. 00272 * 00273 * 2: Supported extensions: 00274 * - "angstrom" (OGIP usage) is allowed in addition to "Angstrom". 00275 * - "ohm" (OGIP usage) is allowed in addition to "Ohm". 00276 * - "Byte" (common usage) is allowed in addition to "byte". 00277 * 00278 * 3: Table 6 of WCS Paper I lists eleven units for which metric prefixes are 00279 * allowed. However, in this implementation only prefixes greater than 00280 * unity are allowed for "a" (annum), "yr" (year), "pc" (parsec), "bit", 00281 * and "byte", and only prefixes less than unity are allowed for "mag" 00282 * (stellar magnitude). 00283 * 00284 * Metric prefix "P" (peta) is specifically forbidden for "a" (annum) to 00285 * avoid confusion with "Pa" (Pascal, not peta-annum). Note that metric 00286 * prefixes are specifically disallowed for "h" (hour) and "d" (day) so 00287 * that "ph" (photons) cannot be interpreted as pico-hours, nor "cd" 00288 * (candela) as centi-days. 00289 * 00290 * 4: Function types log(), ln() and exp() may only occur at the start of the 00291 * units specification. The scale and units[] returned for these refers 00292 * to the string inside the function "argument", e.g. to "MHz" in log(MHz) 00293 * for which a scale of 1e6 will be returned. 00294 * 00295 * 00296 * Global variable: const char *wcsunits_errmsg[] - Status return messages 00297 * ----------------------------------------------------------------------- 00298 * Error messages to match the status value returned from each function. 00299 * 00300 * 00301 * Global variable: const char *wcsunits_types[] - Names of physical quantities 00302 * ---------------------------------------------------------------------------- 00303 * Names for physical quantities to match the units vector returned by 00304 * wcsulexe(): 00305 * - 0: plane angle 00306 * - 1: solid angle 00307 * - 2: charge 00308 * - 3: mole 00309 * - 4: temperature 00310 * - 5: luminous intensity 00311 * - 6: mass 00312 * - 7: length 00313 * - 8: time 00314 * - 9: beam 00315 * - 10: bin 00316 * - 11: bit 00317 * - 12: count 00318 * - 13: stellar magnitude 00319 * - 14: pixel 00320 * - 15: solar ratio 00321 * - 16: voxel 00322 * 00323 * 00324 * Global variable: const char *wcsunits_units[] - Names of units 00325 * -------------------------------------------------------------- 00326 * Names for the units (SI) to match the units vector returned by wcsulexe(): 00327 * - 0: degree 00328 * - 1: steradian 00329 * - 2: Coulomb 00330 * - 3: mole 00331 * - 4: Kelvin 00332 * - 5: candela 00333 * - 6: kilogram 00334 * - 7: metre 00335 * - 8: second 00336 * 00337 * The remainder are dimensionless. 00338 *===========================================================================*/ 00339 00340 #ifndef WCSLIB_WCSUNITS 00341 #define WCSLIB_WCSUNITS 00342 00343 #include "wcserr.h" 00344 00345 #ifdef __cplusplus 00346 extern "C" { 00347 #endif 00348 00349 00350 extern const char *wcsunits_errmsg[]; 00351 00352 enum wcsunits_errmsg_enum { 00353 UNITSERR_SUCCESS = 0, /* Success. */ 00354 UNITSERR_BAD_NUM_MULTIPLIER = 1, /* Invalid numeric multiplier. */ 00355 UNITSERR_DANGLING_BINOP = 2, /* Dangling binary operator. */ 00356 UNITSERR_BAD_INITIAL_SYMBOL = 3, /* Invalid symbol in INITIAL 00357 context. */ 00358 UNITSERR_FUNCTION_CONTEXT = 4, /* Function in invalid context. */ 00359 UNITSERR_BAD_EXPON_SYMBOL = 5, /* Invalid symbol in EXPON context. */ 00360 UNITSERR_UNBAL_BRACKET = 6, /* Unbalanced bracket. */ 00361 UNITSERR_UNBAL_PAREN = 7, /* Unbalanced parenthesis. */ 00362 UNITSERR_CONSEC_BINOPS = 8, /* Consecutive binary operators. */ 00363 UNITSERR_PARSER_ERROR = 9, /* Internal parser error. */ 00364 UNITSERR_BAD_UNIT_SPEC = 10, /* Non-conformant unit 00365 specifications. */ 00366 UNITSERR_BAD_FUNCS = 11, /* Non-conformant functions. */ 00367 UNITSERR_UNSAFE_TRANS = 12 /* Potentially unsafe translation. */ 00368 }; 00369 00370 extern const char *wcsunits_types[]; 00371 extern const char *wcsunits_units[]; 00372 00373 #define WCSUNITS_PLANE_ANGLE 0 00374 #define WCSUNITS_SOLID_ANGLE 1 00375 #define WCSUNITS_CHARGE 2 00376 #define WCSUNITS_MOLE 3 00377 #define WCSUNITS_TEMPERATURE 4 00378 #define WCSUNITS_LUMINTEN 5 00379 #define WCSUNITS_MASS 6 00380 #define WCSUNITS_LENGTH 7 00381 #define WCSUNITS_TIME 8 00382 #define WCSUNITS_BEAM 9 00383 #define WCSUNITS_BIN 10 00384 #define WCSUNITS_BIT 11 00385 #define WCSUNITS_COUNT 12 00386 #define WCSUNITS_MAGNITUDE 13 00387 #define WCSUNITS_PIXEL 14 00388 #define WCSUNITS_SOLRATIO 15 00389 #define WCSUNITS_VOXEL 16 00390 00391 #define WCSUNITS_NTYPE 17 00392 00393 00394 int wcsunitse(const char have[], const char want[], double *scale, 00395 double *offset, double *power, struct wcserr **err); 00396 00397 int wcsutrne(int ctrl, char unitstr[], struct wcserr **err); 00398 00399 int wcsulexe(const char unitstr[], int *func, double *scale, double units[], 00400 struct wcserr **err); 00401 00402 /* Deprecated. */ 00403 int wcsunits(const char have[], const char want[], double *scale, 00404 double *offset, double *power); 00405 int wcsutrn(int ctrl, char unitstr[]); 00406 int wcsulex(const char unitstr[], int *func, double *scale, double units[]); 00407 00408 #ifdef __cplusplus 00409 } 00410 #endif 00411 00412 #endif /* WCSLIB_WCSUNITS */