WCSLIB
8.4
Loading...
Searching...
No Matches
C
fitshdr.h
Go to the documentation of this file.
1
/*============================================================================
2
WCSLIB 8.4 - an implementation of the FITS WCS standard.
3
Copyright (C) 1995-2024, 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: fitshdr.h,v 8.4 2024/10/28 13:56:16 mcalabre Exp $
23
*=============================================================================
24
*
25
* WCSLIB 8.4 - 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 fitshdr routines
31
* -------------------------------
32
* The Flexible Image Transport System (FITS), is a data format widely used in
33
* astronomy for data interchange and archive. It is described in
34
*
35
= "Definition of the Flexible Image Transport System (FITS), version 3.0",
36
= Pence, W.D., Chiappetti, L., Page, C.G., Shaw, R.A., & Stobie, E. 2010,
37
= A&A, 524, A42 - http://dx.doi.org/10.1051/0004-6361/201015362
38
*
39
* See also http://fits.gsfc.nasa.gov
40
*
41
* fitshdr() is a generic FITS header parser provided to handle keyrecords that
42
* are ignored by the WCS header parsers, wcspih() and wcsbth(). Typically the
43
* latter may be set to remove WCS keyrecords from a header leaving fitshdr()
44
* to handle the remainder.
45
*
46
*
47
* fitshdr() - FITS header parser routine
48
* --------------------------------------
49
* fitshdr() parses a character array containing a FITS header, extracting
50
* all keywords and their values into an array of fitskey structs.
51
*
52
* Given:
53
* header const char []
54
* Character array containing the (entire) FITS header,
55
* for example, as might be obtained conveniently via the
56
* CFITSIO routine fits_hdr2str().
57
*
58
* Each header "keyrecord" (formerly "card image")
59
* consists of exactly 80 7-bit ASCII printing characters
60
* in the range 0x20 to 0x7e (which excludes NUL, BS,
61
* TAB, LF, FF and CR) especially noting that the
62
* keyrecords are NOT null-terminated.
63
*
64
* nkeyrec int Number of keyrecords in header[].
65
*
66
* nkeyids int Number of entries in keyids[].
67
*
68
* Given and returned:
69
* keyids struct fitskeyid []
70
* While all keywords are extracted from the header,
71
* keyids[] provides a convienient way of indexing them.
72
* The fitskeyid struct contains three members;
73
* fitskeyid::name must be set by the user while
74
* fitskeyid::count and fitskeyid::idx are returned by
75
* fitshdr(). All matched keywords will have their
76
* fitskey::keyno member negated.
77
*
78
* Returned:
79
* nreject int* Number of header keyrecords rejected for syntax
80
* errors.
81
*
82
* keys struct fitskey**
83
* Pointer to an array of nkeyrec fitskey structs
84
* containing all keywords and keyvalues extracted from
85
* the header.
86
*
87
* Memory for the array is allocated by fitshdr() and
88
* this must be freed by the user. See wcsdealloc().
89
*
90
* Function return value:
91
* int Status return value:
92
* 0: Success.
93
* 1: Null fitskey pointer passed.
94
* 2: Memory allocation failed.
95
* 3: Fatal error returned by Flex parser.
96
* 4: Unrecognised data type.
97
*
98
* Notes:
99
* 1: Keyword parsing is done in accordance with the syntax defined by
100
* NOST 100-2.0, noting the following points in particular:
101
*
102
* a: Sect. 5.1.2.1 specifies that keywords be left-justified in columns
103
* 1-8, blank-filled with no embedded spaces, composed only of the
104
* ASCII characters ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789-_
105
*
106
* fitshdr() accepts any characters in columns 1-8 but flags keywords
107
* that do not conform to standard syntax.
108
*
109
* b: Sect. 5.1.2.2 defines the "value indicator" as the characters "= "
110
* occurring in columns 9 and 10. If these are absent then the
111
* keyword has no value and columns 9-80 may contain any ASCII text
112
* (but see note 2 for CONTINUE keyrecords). This is copied to the
113
* comment member of the fitskey struct.
114
*
115
* c: Sect. 5.1.2.3 states that a keyword may have a null (undefined)
116
* value if the value/comment field, columns 11-80, consists entirely
117
* of spaces, possibly followed by a comment.
118
*
119
* d: Sect. 5.1.1 states that trailing blanks in a string keyvalue are
120
* not significant and the parser always removes them. A string
121
* containing nothing but blanks will be replaced with a single
122
* blank.
123
*
124
* Sect. 5.2.1 also states that a quote character (') in a string
125
* value is to be represented by two successive quote characters and
126
* the parser removes the repeated quote.
127
*
128
* e: The parser recognizes free-format character (NOST 100-2.0,
129
* Sect. 5.2.1), integer (Sect. 5.2.3), and floating-point values
130
* (Sect. 5.2.4) for all keywords.
131
*
132
* f: Sect. 5.2.3 offers no comment on the size of an integer keyvalue
133
* except indirectly in limiting it to 70 digits. The parser will
134
* translate an integer keyvalue to a 32-bit signed integer if it
135
* lies in the range -2147483648 to +2147483647, otherwise it
136
* interprets it as a 64-bit signed integer if possible, or else a
137
* "very long" integer (see fitskey::type).
138
*
139
* g: END not followed by 77 blanks is not considered to be a legitimate
140
* end keyrecord.
141
*
142
* 2: The parser supports a generalization of the OGIP Long String Keyvalue
143
* Convention (v1.0) whereby strings may be continued onto successive
144
* header keyrecords. A keyrecord contains a segment of a continued
145
* string if and only if
146
*
147
* a: it contains the pseudo-keyword CONTINUE,
148
*
149
* b: columns 9 and 10 are both blank,
150
*
151
* c: columns 11 to 80 contain what would be considered a valid string
152
* keyvalue, including optional keycomment, if column 9 had contained
153
* '=',
154
*
155
* d: the previous keyrecord contained either a valid string keyvalue or
156
* a valid CONTINUE keyrecord.
157
*
158
* If any of these conditions is violated, the keyrecord is considered in
159
* isolation.
160
*
161
* Syntax errors in keycomments in a continued string are treated more
162
* permissively than usual; the '/' delimiter may be omitted provided that
163
* parsing of the string keyvalue is not compromised. However, the
164
* FITSHDR_COMMENT status bit will be set for the keyrecord (see
165
* fitskey::status).
166
*
167
* As for normal strings, trailing blanks in a continued string are not
168
* significant.
169
*
170
* In the OGIP convention "the '&' character is used as the last non-blank
171
* character of the string to indicate that the string is (probably)
172
* continued on the following keyword". This additional syntax is not
173
* required by fitshdr(), but if '&' does occur as the last non-blank
174
* character of a continued string keyvalue then it will be removed, along
175
* with any trailing blanks. However, blanks that occur before the '&'
176
* will be preserved.
177
*
178
*
179
* fitskeyid struct - Keyword indexing
180
* -----------------------------------
181
* fitshdr() uses the fitskeyid struct to return indexing information for
182
* specified keywords. The struct contains three members, the first of which,
183
* fitskeyid::name, must be set by the user with the remainder returned by
184
* fitshdr().
185
*
186
* char name[12]:
187
* (Given) Name of the required keyword. This is to be set by the user;
188
* the '.' character may be used for wildcarding. Trailing blanks will be
189
* replaced with nulls.
190
*
191
* int count:
192
* (Returned) The number of matches found for the keyword.
193
*
194
* int idx[2]:
195
* (Returned) Indices into keys[], the array of fitskey structs returned by
196
* fitshdr(). Note that these are 0-relative array indices, not keyrecord
197
* numbers.
198
*
199
* If the keyword is found in the header the first index will be set to the
200
* array index of its first occurrence, otherwise it will be set to -1.
201
*
202
* If multiples of the keyword are found, the second index will be set to
203
* the array index of its last occurrence, otherwise it will be set to -1.
204
*
205
*
206
* fitskey struct - Keyword/value information
207
* ------------------------------------------
208
* fitshdr() returns an array of fitskey structs, each of which contains the
209
* result of parsing one FITS header keyrecord. All members of the fitskey
210
* struct are returned by fitshdr(), none are given by the user.
211
*
212
* int keyno
213
* (Returned) Keyrecord number (1-relative) in the array passed as input to
214
* fitshdr(). This will be negated if the keyword matched any specified in
215
* the keyids[] index.
216
*
217
* int keyid
218
* (Returned) Index into the first entry in keyids[] with which the
219
* keyrecord matches, else -1.
220
*
221
* int status
222
* (Returned) Status flag bit-vector for the header keyrecord employing the
223
* following bit masks defined as preprocessor macros:
224
*
225
* - FITSHDR_KEYWORD: Illegal keyword syntax.
226
* - FITSHDR_KEYVALUE: Illegal keyvalue syntax.
227
* - FITSHDR_COMMENT: Illegal keycomment syntax.
228
* - FITSHDR_KEYREC: Illegal keyrecord, e.g. an END keyrecord with
229
* trailing text.
230
* - FITSHDR_TRAILER: Keyrecord following a valid END keyrecord.
231
*
232
* The header keyrecord is syntactically correct if no bits are set.
233
*
234
* char keyword[12]
235
* (Returned) Keyword name, null-filled for keywords of less than eight
236
* characters (trailing blanks replaced by nulls).
237
*
238
* Use
239
*
240
= sprintf(dst, "%.8s", keyword)
241
*
242
* to copy it to a character array with null-termination, or
243
*
244
= sprintf(dst, "%8.8s", keyword)
245
*
246
* to blank-fill to eight characters followed by null-termination.
247
*
248
* int type
249
* (Returned) Keyvalue data type:
250
* - 0: No keyvalue (both the value and type are undefined).
251
* - 1: Logical, represented as int.
252
* - 2: 32-bit signed integer.
253
* - 3: 64-bit signed integer (see below).
254
* - 4: Very long integer (see below).
255
* - 5: Floating point (stored as double).
256
* - 6: Integer complex (stored as double[2]).
257
* - 7: Floating point complex (stored as double[2]).
258
* - 8: String.
259
* - 8+10*n: Continued string (described below and in fitshdr() note 2).
260
*
261
* A negative type indicates that a syntax error was encountered when
262
* attempting to parse a keyvalue of the particular type.
263
*
264
* Comments on particular data types:
265
* - 64-bit signed integers lie in the range
266
*
267
= (-9223372036854775808 <= int64 < -2147483648) ||
268
= (+2147483647 < int64 <= +9223372036854775807)
269
*
270
* A native 64-bit data type may be defined via preprocessor macro
271
* WCSLIB_INT64 defined in wcsconfig.h, e.g. as 'long long int'; this
272
* will be typedef'd to 'int64' here. If WCSLIB_INT64 is not set, then
273
* int64 is typedef'd to int[3] instead and fitskey::keyvalue is to be
274
* computed as
275
*
276
= ((keyvalue.k[2]) * 1000000000 +
277
= keyvalue.k[1]) * 1000000000 +
278
= keyvalue.k[0]
279
*
280
* and may reported via
281
*
282
= if (keyvalue.k[2]) {
283
= printf("%d%09d%09d", keyvalue.k[2], abs(keyvalue.k[1]),
284
= abs(keyvalue.k[0]));
285
= } else {
286
= printf("%d%09d", keyvalue.k[1], abs(keyvalue.k[0]));
287
= }
288
*
289
* where keyvalue.k[0] and keyvalue.k[1] range from -999999999 to
290
* +999999999.
291
*
292
* - Very long integers, up to 70 decimal digits in length, are encoded
293
* in keyvalue.l as an array of int[8], each of which stores 9 decimal
294
* digits. fitskey::keyvalue is to be computed as
295
*
296
= (((((((keyvalue.l[7]) * 1000000000 +
297
= keyvalue.l[6]) * 1000000000 +
298
= keyvalue.l[5]) * 1000000000 +
299
= keyvalue.l[4]) * 1000000000 +
300
= keyvalue.l[3]) * 1000000000 +
301
= keyvalue.l[2]) * 1000000000 +
302
= keyvalue.l[1]) * 1000000000 +
303
= keyvalue.l[0]
304
*
305
* - Continued strings are not reconstructed, they remain split over
306
* successive fitskey structs in the keys[] array returned by
307
* fitshdr(). fitskey::keyvalue data type, 8 + 10n, indicates the
308
* segment number, n, in the continuation.
309
*
310
* int padding
311
* (An unused variable inserted for alignment purposes only.)
312
*
313
* union keyvalue
314
* (Returned) A union comprised of
315
*
316
* - fitskey::i,
317
* - fitskey::k,
318
* - fitskey::l,
319
* - fitskey::f,
320
* - fitskey::c,
321
* - fitskey::s,
322
*
323
* used by the fitskey struct to contain the value associated with a
324
* keyword.
325
*
326
* int i
327
* (Returned) Logical (fitskey::type == 1) and 32-bit signed integer
328
* (fitskey::type == 2) data types in the fitskey::keyvalue union.
329
*
330
* int64 k
331
* (Returned) 64-bit signed integer (fitskey::type == 3) data type in the
332
* fitskey::keyvalue union.
333
*
334
* int l[8]
335
* (Returned) Very long integer (fitskey::type == 4) data type in the
336
* fitskey::keyvalue union.
337
*
338
* double f
339
* (Returned) Floating point (fitskey::type == 5) data type in the
340
* fitskey::keyvalue union.
341
*
342
* double c[2]
343
* (Returned) Integer and floating point complex (fitskey::type == 6 || 7)
344
* data types in the fitskey::keyvalue union.
345
*
346
* char s[72]
347
* (Returned) Null-terminated string (fitskey::type == 8) data type in the
348
* fitskey::keyvalue union.
349
*
350
* int ulen
351
* (Returned) Where a keycomment contains a units string in the standard
352
* form, e.g. [m/s], the ulen member indicates its length, inclusive of
353
* square brackets. Otherwise ulen is zero.
354
*
355
* char comment[84]
356
* (Returned) Keycomment, i.e. comment associated with the keyword or, for
357
* keyrecords rejected because of syntax errors, the compete keyrecord
358
* itself with null-termination.
359
*
360
* Comments are null-terminated with trailing spaces removed. Leading
361
* spaces are also removed from keycomments (i.e. those immediately
362
* following the '/' character), but not from COMMENT or HISTORY keyrecords
363
* or keyrecords without a value indicator ("= " in columns 9-80).
364
*
365
*
366
* Global variable: const char *fitshdr_errmsg[] - Status return messages
367
* ----------------------------------------------------------------------
368
* Error messages to match the status value returned from each function.
369
*
370
*===========================================================================*/
371
372
#ifndef WCSLIB_FITSHDR
373
#define WCSLIB_FITSHDR
374
375
#include "wcsconfig.h"
376
377
#ifdef __cplusplus
378
extern
"C"
{
379
#endif
380
381
#define FITSHDR_KEYWORD 0x01
382
#define FITSHDR_KEYVALUE 0x02
383
#define FITSHDR_COMMENT 0x04
384
#define FITSHDR_KEYREC 0x08
385
#define FITSHDR_CARD 0x08
// Alias for backwards compatibility.
386
#define FITSHDR_TRAILER 0x10
387
388
389
extern
const
char
*
fitshdr_errmsg
[];
390
391
enum
fitshdr_errmsg_enum
{
392
FITSHDRERR_SUCCESS
= 0,
// Success.
393
FITSHDRERR_NULL_POINTER
= 1,
// Null fitskey pointer passed.
394
FITSHDRERR_MEMORY
= 2,
// Memory allocation failed.
395
FITSHDRERR_FLEX_PARSER
= 3,
// Fatal error returned by Flex parser.
396
FITSHDRERR_DATA_TYPE
= 4
// Unrecognised data type.
397
};
398
399
#ifdef WCSLIB_INT64
400
typedef
WCSLIB_INT64
int64
;
401
#else
402
typedef
int
int64
[3];
403
#endif
404
405
406
// Struct used for indexing the keywords.
407
struct
fitskeyid
{
408
char
name
[12];
// Keyword name, null-terminated.
409
int
count
;
// Number of occurrences of keyword.
410
int
idx
[2];
// Indices into fitskey array.
411
};
412
413
// Size of the fitskeyid struct in int units, used by the Fortran wrappers.
414
#define KEYIDLEN (sizeof(struct fitskeyid)/sizeof(int))
415
416
417
// Struct used for storing FITS keywords.
418
struct
fitskey
{
419
int
keyno
;
// Header keyrecord sequence number (1-rel).
420
int
keyid
;
// Index into fitskeyid[].
421
int
status
;
// Header keyrecord status bit flags.
422
char
keyword
[12];
// Keyword name, null-filled.
423
int
type
;
// Keyvalue type (see above).
424
int
padding
;
// (Dummy inserted for alignment purposes.)
425
union
{
426
int
i
;
// 32-bit integer and logical values.
427
int64
k
;
// 64-bit integer values.
428
int
l
[8];
// Very long signed integer values.
429
double
f
;
// Floating point values.
430
double
c
[2];
// Complex values.
431
char
s
[72];
// String values, null-terminated.
432
}
keyvalue
;
// Keyvalue.
433
int
ulen
;
// Length of units string.
434
char
comment
[84];
// Comment (or keyrecord), null-terminated.
435
};
436
437
// Size of the fitskey struct in int units, used by the Fortran wrappers.
438
#define KEYLEN (sizeof(struct fitskey)/sizeof(int))
439
440
441
int
fitshdr
(
const
char
header[],
int
nkeyrec,
int
nkeyids,
442
struct
fitskeyid
keyids[],
int
*nreject,
struct
fitskey
**keys);
443
444
445
#ifdef __cplusplus
446
}
447
#endif
448
449
#endif
// WCSLIB_FITSHDR
fitshdr_errmsg
const char * fitshdr_errmsg[]
Status return messages.
fitshdr_errmsg_enum
fitshdr_errmsg_enum
Definition
fitshdr.h:391
FITSHDRERR_FLEX_PARSER
@ FITSHDRERR_FLEX_PARSER
Definition
fitshdr.h:395
FITSHDRERR_NULL_POINTER
@ FITSHDRERR_NULL_POINTER
Definition
fitshdr.h:393
FITSHDRERR_SUCCESS
@ FITSHDRERR_SUCCESS
Definition
fitshdr.h:392
FITSHDRERR_DATA_TYPE
@ FITSHDRERR_DATA_TYPE
Definition
fitshdr.h:396
FITSHDRERR_MEMORY
@ FITSHDRERR_MEMORY
Definition
fitshdr.h:394
int64
int int64[3]
64-bit signed integer data type.
Definition
fitshdr.h:402
fitshdr
int fitshdr(const char header[], int nkeyrec, int nkeyids, struct fitskeyid keyids[], int *nreject, struct fitskey **keys)
FITS header parser routine.
fitskey
Keyword/value information.
Definition
fitshdr.h:418
fitskey::comment
char comment[84]
Definition
fitshdr.h:434
fitskey::padding
int padding
Definition
fitshdr.h:424
fitskey::keyno
int keyno
Definition
fitshdr.h:419
fitskey::keyword
char keyword[12]
Definition
fitshdr.h:422
fitskey::keyvalue
union fitskey::@1 keyvalue
fitskey::c
double c[2]
Definition
fitshdr.h:430
fitskey::i
int i
Definition
fitshdr.h:426
fitskey::status
int status
Definition
fitshdr.h:421
fitskey::l
int l[8]
Definition
fitshdr.h:428
fitskey::ulen
int ulen
Definition
fitshdr.h:433
fitskey::type
int type
Definition
fitshdr.h:423
fitskey::f
double f
Definition
fitshdr.h:429
fitskey::k
int64 k
Definition
fitshdr.h:427
fitskey::keyid
int keyid
Definition
fitshdr.h:420
fitskey::s
char s[72]
Definition
fitshdr.h:431
fitskeyid
Keyword indexing.
Definition
fitshdr.h:407
fitskeyid::name
char name[12]
Definition
fitshdr.h:408
fitskeyid::count
int count
Definition
fitshdr.h:409
fitskeyid::idx
int idx[2]
Definition
fitshdr.h:410
Generated on Tue Oct 29 2024 00:57:38 for WCSLIB by
1.12.0