WCSLIB 8.5

Loading...
Searching...
No Matches
wcsunits.h
Go to the documentation of this file.
1/*============================================================================
2 WCSLIB 8.5 - an implementation of the FITS WCS standard.
3 Copyright (C) 1995-2025, 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 8.5 2025/12/06 13:47:41 mcalabre Exp $
23*=============================================================================
24*
25* WCSLIB 8.5 - 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
349 enum wcsunits_errmsg_enum {
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
wcserr
Error message handling.
Definition wcserr.h:243
wcserr.h
wcsunits_errmsg
const char * wcsunits_errmsg[]
Status return messages.
wcsutrne
int wcsutrne(int ctrl, char unitstr[], struct wcserr **err)
Translation of non-standard unit specifications.
wcsunitse
int wcsunitse(const char have[], const char want[], double *scale, double *offset, double *power, struct wcserr **err)
FITS units specification conversion.
wcsutrn
int wcsutrn(int ctrl, char unitstr[])
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.
WCSUNITS_NTYPE
#define WCSUNITS_NTYPE
Number of entries in the units array.
Definition wcsunits.h:386
wcsunits_errmsg_enum
wcsunits_errmsg_enum
Definition wcsunits.h:349
UNITSERR_BAD_EXPON_SYMBOL
@ UNITSERR_BAD_EXPON_SYMBOL
Definition wcsunits.h:355
UNITSERR_PARSER_ERROR
@ UNITSERR_PARSER_ERROR
Definition wcsunits.h:359
UNITSERR_UNBAL_BRACKET
@ UNITSERR_UNBAL_BRACKET
Definition wcsunits.h:356
UNITSERR_UNBAL_PAREN
@ UNITSERR_UNBAL_PAREN
Definition wcsunits.h:357
UNITSERR_BAD_NUM_MULTIPLIER
@ UNITSERR_BAD_NUM_MULTIPLIER
Definition wcsunits.h:351
UNITSERR_BAD_FUNCS
@ UNITSERR_BAD_FUNCS
Definition wcsunits.h:361
UNITSERR_CONSEC_BINOPS
@ UNITSERR_CONSEC_BINOPS
Definition wcsunits.h:358
UNITSERR_DANGLING_BINOP
@ UNITSERR_DANGLING_BINOP
Definition wcsunits.h:352
UNITSERR_FUNCTION_CONTEXT
@ UNITSERR_FUNCTION_CONTEXT
Definition wcsunits.h:354
UNITSERR_SUCCESS
@ UNITSERR_SUCCESS
Definition wcsunits.h:350
UNITSERR_BAD_UNIT_SPEC
@ UNITSERR_BAD_UNIT_SPEC
Definition wcsunits.h:360
UNITSERR_UNSAFE_TRANS
@ UNITSERR_UNSAFE_TRANS
Definition wcsunits.h:362
UNITSERR_BAD_INITIAL_SYMBOL
@ UNITSERR_BAD_INITIAL_SYMBOL
Definition wcsunits.h:353
wcsulex
int wcsulex(const char unitstr[], int *func, double *scale, double units[WCSUNITS_NTYPE])
wcsunits_types
const char * wcsunits_types[]
Names of physical quantities.
wcsunits
int wcsunits(const char have[], const char want[], double *scale, double *offset, double *power)