WCSLIB  7.3
wcsunits.h
Go to the documentation of this file.
1 /*============================================================================
2 
3  WCSLIB 7.3 - an implementation of the FITS WCS standard.
4  Copyright (C) 1995-2020, Mark Calabretta
5 
6  This file is part of WCSLIB.
7 
8  WCSLIB is free software: you can redistribute it and/or modify it under the
9  terms of the GNU Lesser General Public License as published by the Free
10  Software Foundation, either version 3 of the License, or (at your option)
11  any later version.
12 
13  WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16  more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with WCSLIB. If not, see http://www.gnu.org/licenses.
20 
21  Direct correspondence concerning WCSLIB to mark@calabretta.id.au
22 
23  Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
24  http://www.atnf.csiro.au/people/Mark.Calabretta
25  $Id: wcsunits.h,v 7.3 2020/06/03 03:37:02 mcalabre Exp $
26 *=============================================================================
27 *
28 * WCSLIB 7.3 - C routines that implement the FITS World Coordinate System
29 * (WCS) standard. Refer to the README file provided with WCSLIB for an
30 * overview of the library.
31 *
32 *
33 * Summary of the wcsunits routines
34 * --------------------------------
35 * Routines in this suite deal with units specifications and conversions, as
36 * described in
37 *
38 = "Representations of world coordinates in FITS",
39 = Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (WCS Paper I)
40 *
41 * The Flexible Image Transport System (FITS), a data format widely used in
42 * astronomy for data interchange and archive, is described in
43 *
44 = "Definition of the Flexible Image Transport System (FITS), version 3.0",
45 = Pence, W.D., Chiappetti, L., Page, C.G., Shaw, R.A., & Stobie, E. 2010,
46 = A&A, 524, A42 - http://dx.doi.org/10.1051/0004-6361/201015362
47 *
48 * See also http://fits.gsfc.nasa.gov
49 *
50 * These routines perform basic units-related operations:
51 *
52 * - wcsunitse(): given two unit specifications, derive the conversion from
53 * one to the other.
54 *
55 * - wcsutrne(): translates certain commonly used but non-standard unit
56 * strings. It is intended to be called before wcsulexe() which only
57 * handles standard FITS units specifications.
58 *
59 * - wcsulexe(): parses a standard FITS units specification of arbitrary
60 * complexity, deriving the conversion to canonical units.
61 *
62 *
63 * wcsunitse() - FITS units specification conversion
64 * -------------------------------------------------
65 * wcsunitse() derives the conversion from one system of units to another.
66 *
67 * A deprecated form of this function, wcsunits(), lacks the wcserr**
68 * parameter.
69 *
70 * Given:
71 * have const char []
72 * FITS units specification to convert from (null-
73 * terminated), with or without surrounding square
74 * brackets (for inline specifications); text following
75 * the closing bracket is ignored.
76 *
77 * want const char []
78 * FITS units specification to convert to (null-
79 * terminated), with or without surrounding square
80 * brackets (for inline specifications); text following
81 * the closing bracket is ignored.
82 *
83 * Returned:
84 * scale,
85 * offset,
86 * power double* Convert units using
87 *
88 = pow(scale*value + offset, power);
89 *
90 * Normally offset is zero except for log() or ln()
91 * conversions, e.g. "log(MHz)" to "ln(Hz)". Likewise,
92 * power is normally unity except for exp() conversions,
93 * e.g. "exp(ms)" to "exp(/Hz)". Thus conversions
94 * ordinarily consist of
95 *
96 = value *= scale;
97 *
98 * err struct wcserr **
99 * If enabled, for function return values > 1, this
100 * struct will contain a detailed error message, see
101 * wcserr_enable(). May be NULL if an error message is
102 * not desired. Otherwise, the user is responsible for
103 * deleting the memory allocated for the wcserr struct.
104 *
105 * Function return value:
106 * int Status return value:
107 * 0: Success.
108 * 1-9: Status return from wcsulexe().
109 * 10: Non-conformant unit specifications.
110 * 11: Non-conformant functions.
111 *
112 * scale is zeroed on return if an error occurs.
113 *
114 *
115 * wcsutrne() - Translation of non-standard unit specifications
116 * ------------------------------------------------------------
117 * wcsutrne() translates certain commonly used but non-standard unit strings,
118 * e.g. "DEG", "MHZ", "KELVIN", that are not recognized by wcsulexe(), refer to
119 * the notes below for a full list. Compounds are also recognized, e.g.
120 * "JY/BEAM" and "KM/SEC/SEC". Extraneous embedded blanks are removed.
121 *
122 * A deprecated form of this function, wcsutrn(), lacks the wcserr** parameter.
123 *
124 * Given:
125 * ctrl int Although "S" is commonly used to represent seconds,
126 * its translation to "s" is potentially unsafe since the
127 * standard recognizes "S" formally as Siemens, however
128 * rarely that may be used. The same applies to "H" for
129 * hours (Henry), and "D" for days (Debye). This
130 * bit-flag controls what to do in such cases:
131 * 1: Translate "S" to "s".
132 * 2: Translate "H" to "h".
133 * 4: Translate "D" to "d".
134 * Thus ctrl == 0 doesn't do any unsafe translations,
135 * whereas ctrl == 7 does all of them.
136 *
137 * Given and returned:
138 * unitstr char [] Null-terminated character array containing the units
139 * specification to be translated.
140 *
141 * Inline units specifications in a FITS header
142 * keycomment are also handled. If the first non-blank
143 * character in unitstr is '[' then the unit string is
144 * delimited by its matching ']'. Blanks preceding '['
145 * will be stripped off, but text following the closing
146 * bracket will be preserved without modification.
147 *
148 * err struct wcserr **
149 * If enabled, for function return values > 1, this
150 * struct will contain a detailed error message, see
151 * wcserr_enable(). May be NULL if an error message is
152 * not desired. Otherwise, the user is responsible for
153 * deleting the memory allocated for the wcserr struct.
154 *
155 * Function return value:
156 * int Status return value:
157 * -1: No change was made, other than stripping blanks
158 * (not an error).
159 * 0: Success.
160 * 9: Internal parser error.
161 * 12: Potentially unsafe translation, whether applied
162 * or not (see notes).
163 *
164 * Notes:
165 * Translation of non-standard unit specifications: apart from leading and
166 * trailing blanks, a case-sensitive match is required for the aliases listed
167 * below, in particular the only recognized aliases with metric prefixes are
168 * "KM", "KHZ", "MHZ", and "GHZ". Potentially unsafe translations of "D",
169 * "H", and "S", shown in parentheses, are optional.
170 *
171 = Unit Recognized aliases
172 = ---- -------------------------------------------------------------
173 = Angstrom angstrom
174 = arcmin arcmins, ARCMIN, ARCMINS
175 = arcsec arcsecs, ARCSEC, ARCSECS
176 = beam BEAM
177 = byte Byte
178 = d day, days, (D), DAY, DAYS
179 = deg degree, degrees, Deg, Degree, Degrees, DEG, DEGREE, DEGREES
180 = GHz GHZ
181 = h hr, (H), HR
182 = Hz hz, HZ
183 = kHz KHZ
184 = Jy JY
185 = K kelvin, kelvins, Kelvin, Kelvins, KELVIN, KELVINS
186 = km KM
187 = m metre, meter, metres, meters, M, METRE, METER, METRES, METERS
188 = min MIN
189 = MHz MHZ
190 = Ohm ohm
191 = Pa pascal, pascals, Pascal, Pascals, PASCAL, PASCALS
192 = pixel pixels, PIXEL, PIXELS
193 = rad radian, radians, RAD, RADIAN, RADIANS
194 = s sec, second, seconds, (S), SEC, SECOND, SECONDS
195 = V volt, volts, Volt, Volts, VOLT, VOLTS
196 = yr year, years, YR, YEAR, YEARS
197 *
198 * The aliases "angstrom", "ohm", and "Byte" for (Angstrom, Ohm, and byte)
199 * are recognized by wcsulexe() itself as an unofficial extension of the
200 * standard, but they are converted to the standard form here.
201 *
202 *
203 * wcsulexe() - FITS units specification parser
204 * --------------------------------------------
205 * wcsulexe() parses a standard FITS units specification of arbitrary
206 * complexity, deriving the scale factor required to convert to canonical
207 * units - basically SI with degrees and "dimensionless" additions such as
208 * byte, pixel and count.
209 *
210 * A deprecated form of this function, wcsulex(), lacks the wcserr** parameter.
211 *
212 * Given:
213 * unitstr const char []
214 * Null-terminated character array containing the units
215 * specification, with or without surrounding square
216 * brackets (for inline specifications); text following
217 * the closing bracket is ignored.
218 *
219 * Returned:
220 * func int* Special function type, see note 4:
221 * 0: None
222 * 1: log() ...base 10
223 * 2: ln() ...base e
224 * 3: exp()
225 *
226 * scale double* Scale factor for the unit specification; multiply a
227 * value expressed in the given units by this factor to
228 * convert it to canonical units.
229 *
230 * units double[WCSUNITS_NTYPE]
231 * A units specification is decomposed into powers of 16
232 * fundamental unit types: angle, mass, length, time,
233 * count, pixel, etc. Preprocessor macro WCSUNITS_NTYPE
234 * is defined to dimension this vector, and others such
235 * WCSUNITS_PLANE_ANGLE, WCSUNITS_LENGTH, etc. to access
236 * its elements.
237 *
238 * Corresponding character strings, wcsunits_types[] and
239 * wcsunits_units[], are predefined to describe each
240 * quantity and its canonical units.
241 *
242 * err struct wcserr **
243 * If enabled, for function return values > 1, this
244 * struct will contain a detailed error message, see
245 * wcserr_enable(). May be NULL if an error message is
246 * not desired. Otherwise, the user is responsible for
247 * deleting the memory allocated for the wcserr struct.
248 *
249 * Function return value:
250 * int Status return value:
251 * 0: Success.
252 * 1: Invalid numeric multiplier.
253 * 2: Dangling binary operator.
254 * 3: Invalid symbol in INITIAL context.
255 * 4: Function in invalid context.
256 * 5: Invalid symbol in EXPON context.
257 * 6: Unbalanced bracket.
258 * 7: Unbalanced parenthesis.
259 * 8: Consecutive binary operators.
260 * 9: Internal parser error.
261 *
262 * scale and units[] are zeroed on return if an error
263 * occurs.
264 *
265 * Notes:
266 * 1: wcsulexe() is permissive in accepting whitespace in all contexts in a
267 * units specification where it does not create ambiguity (e.g. not
268 * between a metric prefix and a basic unit string), including in strings
269 * like "log (m ** 2)" which is formally disallowed.
270 *
271 * 2: Supported extensions:
272 * - "angstrom" (OGIP usage) is allowed in addition to "Angstrom".
273 * - "ohm" (OGIP usage) is allowed in addition to "Ohm".
274 * - "Byte" (common usage) is allowed in addition to "byte".
275 *
276 * 3: Table 6 of WCS Paper I lists eleven units for which metric prefixes are
277 * allowed. However, in this implementation only prefixes greater than
278 * unity are allowed for "a" (annum), "yr" (year), "pc" (parsec), "bit",
279 * and "byte", and only prefixes less than unity are allowed for "mag"
280 * (stellar magnitude).
281 *
282 * Metric prefix "P" (peta) is specifically forbidden for "a" (annum) to
283 * avoid confusion with "Pa" (Pascal, not peta-annum). Note that metric
284 * prefixes are specifically disallowed for "h" (hour) and "d" (day) so
285 * that "ph" (photons) cannot be interpreted as pico-hours, nor "cd"
286 * (candela) as centi-days.
287 *
288 * 4: Function types log(), ln() and exp() may only occur at the start of the
289 * units specification. The scale and units[] returned for these refers
290 * to the string inside the function "argument", e.g. to "MHz" in log(MHz)
291 * for which a scale of 1e6 will be returned.
292 *
293 *
294 * Global variable: const char *wcsunits_errmsg[] - Status return messages
295 * -----------------------------------------------------------------------
296 * Error messages to match the status value returned from each function.
297 *
298 *
299 * Global variable: const char *wcsunits_types[] - Names of physical quantities
300 * ----------------------------------------------------------------------------
301 * Names for physical quantities to match the units vector returned by
302 * wcsulexe():
303 * - 0: plane angle
304 * - 1: solid angle
305 * - 2: charge
306 * - 3: mole
307 * - 4: temperature
308 * - 5: luminous intensity
309 * - 6: mass
310 * - 7: length
311 * - 8: time
312 * - 9: beam
313 * - 10: bin
314 * - 11: bit
315 * - 12: count
316 * - 13: stellar magnitude
317 * - 14: pixel
318 * - 15: solar ratio
319 * - 16: voxel
320 *
321 *
322 * Global variable: const char *wcsunits_units[] - Names of units
323 * --------------------------------------------------------------
324 * Names for the units (SI) to match the units vector returned by wcsulexe():
325 * - 0: degree
326 * - 1: steradian
327 * - 2: Coulomb
328 * - 3: mole
329 * - 4: Kelvin
330 * - 5: candela
331 * - 6: kilogram
332 * - 7: metre
333 * - 8: second
334 *
335 * The remainder are dimensionless.
336 *===========================================================================*/
337 
338 #ifndef WCSLIB_WCSUNITS
339 #define WCSLIB_WCSUNITS
340 
341 #include "wcserr.h"
342 
343 #ifdef __cplusplus
344 extern "C" {
345 #endif
346 
347 
348 extern const char *wcsunits_errmsg[];
349 
351  UNITSERR_SUCCESS = 0, /* Success. */
352  UNITSERR_BAD_NUM_MULTIPLIER = 1, /* Invalid numeric multiplier. */
353  UNITSERR_DANGLING_BINOP = 2, /* Dangling binary operator. */
354  UNITSERR_BAD_INITIAL_SYMBOL = 3, /* Invalid symbol in INITIAL
355  context. */
356  UNITSERR_FUNCTION_CONTEXT = 4, /* Function in invalid context. */
357  UNITSERR_BAD_EXPON_SYMBOL = 5, /* Invalid symbol in EXPON context. */
358  UNITSERR_UNBAL_BRACKET = 6, /* Unbalanced bracket. */
359  UNITSERR_UNBAL_PAREN = 7, /* Unbalanced parenthesis. */
360  UNITSERR_CONSEC_BINOPS = 8, /* Consecutive binary operators. */
361  UNITSERR_PARSER_ERROR = 9, /* Internal parser error. */
362  UNITSERR_BAD_UNIT_SPEC = 10, /* Non-conformant unit
363  specifications. */
364  UNITSERR_BAD_FUNCS = 11, /* Non-conformant functions. */
365  UNITSERR_UNSAFE_TRANS = 12 /* Potentially unsafe translation. */
366 };
367 
368 extern const char *wcsunits_types[];
369 extern const char *wcsunits_units[];
370 
371 #define WCSUNITS_PLANE_ANGLE 0
372 #define WCSUNITS_SOLID_ANGLE 1
373 #define WCSUNITS_CHARGE 2
374 #define WCSUNITS_MOLE 3
375 #define WCSUNITS_TEMPERATURE 4
376 #define WCSUNITS_LUMINTEN 5
377 #define WCSUNITS_MASS 6
378 #define WCSUNITS_LENGTH 7
379 #define WCSUNITS_TIME 8
380 #define WCSUNITS_BEAM 9
381 #define WCSUNITS_BIN 10
382 #define WCSUNITS_BIT 11
383 #define WCSUNITS_COUNT 12
384 #define WCSUNITS_MAGNITUDE 13
385 #define WCSUNITS_PIXEL 14
386 #define WCSUNITS_SOLRATIO 15
387 #define WCSUNITS_VOXEL 16
388 
389 #define WCSUNITS_NTYPE 17
390 
391 
392 int wcsunitse(const char have[], const char want[], double *scale,
393  double *offset, double *power, struct wcserr **err);
394 
395 int wcsutrne(int ctrl, char unitstr[], struct wcserr **err);
396 
397 int wcsulexe(const char unitstr[], int *func, double *scale,
398  double units[WCSUNITS_NTYPE], struct wcserr **err);
399 
400 /* Deprecated. */
401 int wcsunits(const char have[], const char want[], double *scale,
402  double *offset, double *power);
403 int wcsutrn(int ctrl, char unitstr[]);
404 int wcsulex(const char unitstr[], int *func, double *scale,
405  double units[WCSUNITS_NTYPE]);
406 
407 #ifdef __cplusplus
408 }
409 #endif
410 
411 #endif /* WCSLIB_WCSUNITS */
wcsutrn
int wcsutrn(int ctrl, char unitstr[])
wcsunits_errmsg
const char * wcsunits_errmsg[]
Status return messages.
UNITSERR_UNBAL_PAREN
@ UNITSERR_UNBAL_PAREN
Definition: wcsunits.h:359
wcsulex
int wcsulex(const char unitstr[], int *func, double *scale, double units[WCSUNITS_NTYPE])
UNITSERR_PARSER_ERROR
@ UNITSERR_PARSER_ERROR
Definition: wcsunits.h:361
UNITSERR_UNBAL_BRACKET
@ UNITSERR_UNBAL_BRACKET
Definition: wcsunits.h:358
UNITSERR_UNSAFE_TRANS
@ UNITSERR_UNSAFE_TRANS
Definition: wcsunits.h:365
wcsunits_types
const char * wcsunits_types[]
Names of physical quantities.
WCSUNITS_NTYPE
#define WCSUNITS_NTYPE
Number of entries in the units array.
Definition: wcsunits.h:389
UNITSERR_BAD_UNIT_SPEC
@ UNITSERR_BAD_UNIT_SPEC
Definition: wcsunits.h:362
wcsunitse
int wcsunitse(const char have[], const char want[], double *scale, double *offset, double *power, struct wcserr **err)
FITS units specification conversion.
UNITSERR_FUNCTION_CONTEXT
@ UNITSERR_FUNCTION_CONTEXT
Definition: wcsunits.h:356
UNITSERR_DANGLING_BINOP
@ UNITSERR_DANGLING_BINOP
Definition: wcsunits.h:353
UNITSERR_CONSEC_BINOPS
@ UNITSERR_CONSEC_BINOPS
Definition: wcsunits.h:360
wcsutrne
int wcsutrne(int ctrl, char unitstr[], struct wcserr **err)
Translation of non-standard unit specifications.
UNITSERR_BAD_EXPON_SYMBOL
@ UNITSERR_BAD_EXPON_SYMBOL
Definition: wcsunits.h:357
wcsunits_units
const char * wcsunits_units[]
Names of units.
wcsulexe
int wcsulexe(const char unitstr[], int *func, double *scale, double units[WCSUNITS_NTYPE], struct wcserr **err)
FITS units specification parser.
UNITSERR_BAD_NUM_MULTIPLIER
@ UNITSERR_BAD_NUM_MULTIPLIER
Definition: wcsunits.h:352
wcsunits
int wcsunits(const char have[], const char want[], double *scale, double *offset, double *power)
wcserr
Error message handling.
Definition: wcserr.h:223
UNITSERR_SUCCESS
@ UNITSERR_SUCCESS
Definition: wcsunits.h:351
wcserr.h
UNITSERR_BAD_FUNCS
@ UNITSERR_BAD_FUNCS
Definition: wcsunits.h:364
wcsunits_errmsg_enum
wcsunits_errmsg_enum
Definition: wcsunits.h:350
UNITSERR_BAD_INITIAL_SYMBOL
@ UNITSERR_BAD_INITIAL_SYMBOL
Definition: wcsunits.h:354