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