- Main Page
- Related Pages
- Data Structures
- Files

# fitshdr.h

Go to the documentation of this file.

    00001 /*============================================================================
    00002
    00003   WCSLIB 4.17 - an implementation of the FITS WCS standard.
    00004   Copyright (C) 1995-2013, 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   Direct correspondence concerning WCSLIB to mark@calabretta.id.au
    00022
    00023   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
    00024   http://www.atnf.csiro.au/people/Mark.Calabretta
    00025   $Id: fitshdr.h,v 4.17 2013/01/29 05:29:20 cal103 Exp $
    00026 *=============================================================================
    00027 *
    00028 * The Flexible Image Transport System (FITS), a data format widely used in
    00029 * astronomy for data interchange and archive, is described in
    00030 *
    00031 *   "Definition of The Flexible Image Transport System (FITS)",
    00032 *   Hanisch, R.J., Farris, A., Greisen, E.W., et al. 2001, A&A, 376, 359
    00033 *
    00034 * which formalizes NOST 100-2.0, a document produced by the NASA/Science
    00035 * Office of Standards and Technology, see http://fits.gsfc.nasa.gov.
    00036 *
    00037 * Refer to the README file provided with WCSLIB for an overview of the
    00038 * library.
    00039 *
    00040 *
    00041 * Summary of the fitshdr routines
    00042 * -------------------------------
    00043 * fitshdr() is a generic FITS header parser provided to handle keyrecords that
    00044 * are ignored by the WCS header parsers, wcspih() and wcsbth().  Typically the
    00045 * latter may be set to remove WCS keyrecords from a header leaving fitshdr()
    00046 * to handle the remainder.
    00047 *
    00048 *
    00049 * fitshdr() - FITS header parser routine
    00050 * --------------------------------------
    00051 * fitshdr() parses a character array containing a FITS header, extracting
    00052 * all keywords and their values into an array of fitskey structs.
    00053 *
    00054 * Given:
    00055 *   header    const char []
    00056 *                       Character array containing the (entire) FITS header,
    00057 *                       for example, as might be obtained conveniently via the
    00058 *                       CFITSIO routine fits_hdr2str().
    00059 *
    00060 *                       Each header "keyrecord" (formerly "card image")
    00061 *                       consists of exactly 80 7-bit ASCII printing characters
    00062 *                       in the range 0x20 to 0x7e (which excludes NUL, BS,
    00063 *                       TAB, LF, FF and CR) especially noting that the
    00064 *                       keyrecords are NOT null-terminated.
    00065 *
    00066 *   nkeyrec   int       Number of keyrecords in header[].
    00067 *
    00068 *   nkeyids   int       Number of entries in keyids[].
    00069 *
    00070 * Given and returned:
    00071 *   keyids    struct fitskeyid []
    00072 *                       While all keywords are extracted from the header,
    00073 *                       keyids[] provides a convienient way of indexing them.
    00074 *                       The fitskeyid struct contains three members;
    00075 *                       fitskeyid::name must be set by the user while
    00076 *                       fitskeyid::count and fitskeyid::name are returned by
    00077 *                       fitshdr().  All matched keywords will have their
    00078 *                       fitskey::keyno member negated.
    00079 *
    00080 * Returned:
    00081 *   nreject   int*      Number of header keyrecords rejected for syntax
    00082 *                       errors.
    00083 *
    00084 *   keys      struct fitskey**
    00085 *                       Pointer to an array of nkeyrec fitskey structs
    00086 *                       containing all keywords and keyvalues extracted from
    00087 *                       the header.
    00088 *
    00089 *                       Memory for the array is allocated by fitshdr() and
    00090 *                       this must be freed by the user by invoking free() on
    00091 *                       the array.
    00092 *
    00093 * Function return value:
    00094 *             int       Status return value:
    00095 *                         0: Success.
    00096 *                         1: Null fitskey pointer passed.
    00097 *                         2: Memory allocation failed.
    00098 *                         3: Fatal error returned by Flex parser.
    00099 *
    00100 * Notes:
    00101 *   1: Keyword parsing is done in accordance with the syntax defined by
    00102 *      NOST 100-2.0, noting the following points in particular:
    00103 *
    00104 *      a: Sect. 5.1.2.1 specifies that keywords be left-justified in columns
    00105 *         1-8, blank-filled with no embedded spaces, composed only of the
    00106 *         ASCII characters ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789-_
    00107 *
    00108 *         fitshdr() accepts any characters in columns 1-8 but flags keywords
    00109 *         that do not conform to standard syntax.
    00110 *
    00111 *      b: Sect. 5.1.2.2 defines the "value indicator" as the characters "= "
    00112 *         occurring in columns 9 and 10.  If these are absent then the
    00113 *         keyword has no value and columns 9-80 may contain any ASCII text
    00114 *         (but see note 2 for CONTINUE keyrecords).  This is copied to the
    00115 *         comment member of the fitskey struct.
    00116 *
    00117 *      c: Sect. 5.1.2.3 states that a keyword may have a null (undefined)
    00118 *         value if the value/comment field, columns 11-80, consists entirely
    00119 *         of spaces, possibly followed by a comment.
    00120 *
    00121 *      d: Sect. 5.1.1 states that trailing blanks in a string keyvalue are
    00122 *         not significant and the parser always removes them.  A string
    00123 *         containing nothing but blanks will be replaced with a single
    00124 *         blank.
    00125 *
    00126 *         Sect. 5.2.1 also states that a quote character (') in a string
    00127 *         value is to be represented by two successive quote characters and
    00128 *         the parser removes the repeated quote.
    00129 *
    00130 *      e: The parser recognizes free-format character (NOST 100-2.0,
    00131 *         Sect. 5.2.1), integer (Sect. 5.2.3), and floating-point values
    00132 *         (Sect. 5.2.4) for all keywords.
    00133 *
    00134 *      f: Sect. 5.2.3 offers no comment on the size of an integer keyvalue
    00135 *         except indirectly in limiting it to 70 digits.  The parser will
    00136 *         translates an integer keyvalue to a 32-bit signed integer if it
    00137 *         lies in the range -2147483648 to +2147483647, otherwise it
    00138 *         interprets it as a 64-bit signed integer if possible, or else a
    00139 *         "very long" integer (see fitskey::type).
    00140 *
    00141 *      g: END not followed by 77 blanks is not considered to be a legitimate
    00142 *         end keyrecord.
    00143 *
    00144 *   2: The parser supports a generalization of the OGIP Long String Keyvalue
    00145 *      Convention (v1.0) whereby strings may be continued onto successive
    00146 *      header keyrecords.  A keyrecord contains a segment of a continued
    00147 *      string if and only if
    00148 *
    00149 *      a: it contains the pseudo-keyword CONTINUE,
    00150 *
    00151 *      b: columns 9 and 10 are both blank,
    00152 *
    00153 *      c: columns 11 to 80 contain what would be considered a valid string
    00154 *         keyvalue, including optional keycomment, if column 9 had contained
    00155 *         '=',
    00156 *
    00157 *      d: the previous keyrecord contained either a valid string keyvalue or
    00158 *         a valid CONTINUE keyrecord.
    00159 *
    00160 *      If any of these conditions is violated, the keyrecord is considered in
    00161 *      isolation.
    00162 *
    00163 *      Syntax errors in keycomments in a continued string are treated more
    00164 *      permissively than usual; the '/' delimiter may be omitted provided that
    00165 *      parsing of the string keyvalue is not compromised.  However, the
    00166 *      FITSHDR_COMMENT status bit will be set for the keyrecord (see
    00167 *      fitskey::status).
    00168 *
    00169 *      As for normal strings, trailing blanks in a continued string are not
    00170 *      significant.
    00171 *
    00172 *      In the OGIP convention "the '&' character is used as the last non-blank
    00173 *      character of the string to indicate that the string is (probably)
    00174 *      continued on the following keyword".  This additional syntax is not
    00175 *      required by fitshdr(), but if '&' does occur as the last non-blank
    00176 *      character of a continued string keyvalue then it will be removed, along
    00177 *      with any trailing blanks.  However, blanks that occur before the '&'
    00178 *      will be preserved.
    00179 *
    00180 *
    00181 * fitskeyid struct - Keyword indexing
    00182 * -----------------------------------
    00183 * fitshdr() uses the fitskeyid struct to return indexing information for
    00184 * specified keywords.  The struct contains three members, the first of which,
    00185 * fitskeyid::name, must be set by the user with the remainder returned by
    00186 * fitshdr().
    00187 *
    00188 *   char name[12]:
    00189 *     (Given) Name of the required keyword.  This is to be set by the user;
    00190 *     the '.' character may be used for wildcarding.  Trailing blanks will be
    00191 *     replaced with nulls.
    00192 *
    00193 *   int count:
    00194 *     (Returned) The number of matches found for the keyword.
    00195 *
    00196 *   int idx[2]:
    00197 *     (Returned) Indices into keys[], the array of fitskey structs returned by
    00198 *     fitshdr().  Note that these are 0-relative array indices, not keyrecord
    00199 *     numbers.
    00200 *
    00201 *     If the keyword is found in the header the first index will be set to the
    00202 *     array index of its first occurrence, otherwise it will be set to -1.
    00203 *
    00204 *     If multiples of the keyword are found, the second index will be set to
    00205 *     the array index of its last occurrence, otherwise it will be set to -1.
    00206 *
    00207 *
    00208 * fitskey struct - Keyword/value information
    00209 * ------------------------------------------
    00210 * fitshdr() returns an array of fitskey structs, each of which contains the
    00211 * result of parsing one FITS header keyrecord.  All members of the fitskey
    00212 * struct are returned by fitshdr(), none are given by the user.
    00213 *
    00214 *   int keyno
    00215 *     (Returned) Keyrecord number (1-relative) in the array passed as input to
    00216 *     fitshdr().  This will be negated if the keyword matched any specified in
    00217 *     the keyids[] index.
    00218 *
    00219 *   int keyid
    00220 *     (Returned) Index into the first entry in keyids[] with which the
    00221 *     keyrecord matches, else -1.
    00222 *
    00223 *   int status
    00224 *     (Returned) Status flag bit-vector for the header keyrecord employing the
    00225 *     following bit masks defined as preprocessor macros:
    00226 *
    00227 *       - FITSHDR_KEYWORD:    Illegal keyword syntax.
    00228 *       - FITSHDR_KEYVALUE:   Illegal keyvalue syntax.
    00229 *       - FITSHDR_COMMENT:    Illegal keycomment syntax.
    00230 *       - FITSHDR_KEYREC:     Illegal keyrecord, e.g. an END keyrecord with
    00231 *                             trailing text.
    00232 *       - FITSHDR_TRAILER:    Keyrecord following a valid END keyrecord.
    00233 *
    00234 *     The header keyrecord is syntactically correct if no bits are set.
    00235 *
    00236 *   char keyword[12]
    00237 *     (Returned) Keyword name, null-filled for keywords of less than eight
    00238 *     characters (trailing blanks replaced by nulls).
    00239 *
    00240 *     Use
    00241 *
    00242 =       sprintf(dst, "%.8s", keyword)
    00243 *
    00244 *     to copy it to a character array with null-termination, or
    00245 *
    00246 =       sprintf(dst, "%8.8s", keyword)
    00247 *
    00248 *     to blank-fill to eight characters followed by null-termination.
    00249 *
    00250 *   int type
    00251 *     (Returned) Keyvalue data type:
    00252 *       - 0: No keyvalue.
    00253 *       - 1: Logical, represented as int.
    00254 *       - 2: 32-bit signed integer.
    00255 *       - 3: 64-bit signed integer (see below).
    00256 *       - 4: Very long integer (see below).
    00257 *       - 5: Floating point (stored as double).
    00258 *       - 6: Integer complex (stored as double[2]).
    00259 *       - 7: Floating point complex (stored as double[2]).
    00260 *       - 8: String.
    00261 *       - 8+10*n: Continued string (described below and in fitshdr() note 2).
    00262 *
    00263 *     A negative type indicates that a syntax error was encountered when
    00264 *     attempting to parse a keyvalue of the particular type.
    00265 *
    00266 *     Comments on particular data types:
    00267 *       - 64-bit signed integers lie in the range
    00268 *
    00269 =           (-9223372036854775808 <= int64 <  -2147483648) ||
    00270 =                    (+2147483647 <  int64 <= +9223372036854775807)
    00271 *
    00272 *         A native 64-bit data type may be defined via preprocessor macro
    00273 *         WCSLIB_INT64 defined in wcsconfig.h, e.g. as 'long long int'; this
    00274 *         will be typedef'd to 'int64' here.  If WCSLIB_INT64 is not set, then
    00275 *         int64 is typedef'd to int[3] instead and fitskey::keyvalue is to be
    00276 *         computed as
    00277 *
    00278 =           ((keyvalue.k[2]) * 1000000000 +
    00279 =             keyvalue.k[1]) * 1000000000 +
    00280 =             keyvalue.k[0]
    00281 *
    00282 *         and may reported via
    00283 *
    00284 =            if (keyvalue.k[2]) {
    00285 =              printf("%d%09d%09d", keyvalue.k[2], abs(keyvalue.k[1]),
    00286 =                                   abs(keyvalue.k[0]));
    00287 =            } else {
    00288 =              printf("%d%09d", keyvalue.k[1], abs(keyvalue.k[0]));
    00289 =            }
    00290 *
    00291 *         where keyvalue.k[0] and keyvalue.k[1] range from -999999999 to
    00292 *         +999999999.
    00293 *
    00294 *       - Very long integers, up to 70 decimal digits in length, are encoded
    00295 *         in keyvalue.l as an array of int[8], each of which stores 9 decimal
    00296 *         digits.  fitskey::keyvalue is to be computed as
    00297 *
    00298 =           (((((((keyvalue.l[7]) * 1000000000 +
    00299 =                  keyvalue.l[6]) * 1000000000 +
    00300 =                  keyvalue.l[5]) * 1000000000 +
    00301 =                  keyvalue.l[4]) * 1000000000 +
    00302 =                  keyvalue.l[3]) * 1000000000 +
    00303 =                  keyvalue.l[2]) * 1000000000 +
    00304 =                  keyvalue.l[1]) * 1000000000 +
    00305 =                  keyvalue.l[0]
    00306 *
    00307 *       - Continued strings are not reconstructed, they remain split over
    00308 *         successive fitskey structs in the keys[] array returned by
    00309 *         fitshdr().  fitskey::keyvalue data type, 8 + 10n, indicates the
    00310 *         segment number, n, in the continuation.
    00311 *
    00312 *   int padding
    00313 *     (An unused variable inserted for alignment purposes only.)
    00314 *
    00315 *   union keyvalue
    00316 *     (Returned) A union comprised of
    00317 *
    00318 *       - fitskey::i,
    00319 *       - fitskey::k,
    00320 *       - fitskey::l,
    00321 *       - fitskey::f,
    00322 *       - fitskey::c,
    00323 *       - fitskey::s,
    00324 *
    00325 *     used by the fitskey struct to contain the value associated with a
    00326 *     keyword.
    00327 *
    00328 *   int i
    00329 *     (Returned) Logical (fitskey::type == 1) and 32-bit signed integer
    00330 *     (fitskey::type == 2) data types in the fitskey::keyvalue union.
    00331 *
    00332 *   int64 k
    00333 *     (Returned) 64-bit signed integer (fitskey::type == 3) data type in the
    00334 *     fitskey::keyvalue union.
    00335 *
    00336 *   int l[8]
    00337 *     (Returned) Very long integer (fitskey::type == 4) data type in the
    00338 *     fitskey::keyvalue union.
    00339 *
    00340 *   double f
    00341 *     (Returned) Floating point (fitskey::type == 5) data type in the
    00342 *     fitskey::keyvalue union.
    00343 *
    00344 *   double c[2]
    00345 *     (Returned) Integer and floating point complex (fitskey::type == 6 || 7)
    00346 *     data types in the fitskey::keyvalue union.
    00347 *
    00348 *   char s[72]
    00349 *     (Returned) Null-terminated string (fitskey::type == 8) data type in the
    00350 *     fitskey::keyvalue union.
    00351 *
    00352 *   int ulen
    00353 *     (Returned) Where a keycomment contains a units string in the standard
    00354 *     form, e.g. [m/s], the ulen member indicates its length, inclusive of
    00355 *     square brackets.  Otherwise ulen is zero.
    00356 *
    00357 *   char comment[84]
    00358 *     (Returned) Keycomment, i.e. comment associated with the keyword or, for
    00359 *     keyrecords rejected because of syntax errors, the compete keyrecord
    00360 *     itself with null-termination.
    00361 *
    00362 *     Comments are null-terminated with trailing spaces removed.  Leading
    00363 *     spaces are also removed from keycomments (i.e. those immediately
    00364 *     following the '/' character), but not from COMMENT or HISTORY keyrecords
    00365 *     or keyrecords without a value indicator ("= " in columns 9-80).
    00366 *
    00367 *
    00368 * Global variable: const char *fitshdr_errmsg[] - Status return messages
    00369 * ----------------------------------------------------------------------
    00370 * Error messages to match the status value returned from each function.
    00371 *
    00372 *===========================================================================*/
    00373
    00374 #ifndef WCSLIB_FITSHDR
    00375 #define WCSLIB_FITSHDR
    00376
    00377 #include "wcsconfig.h"
    00378
    00379 #ifdef __cplusplus
    00380 extern "C" {
    00381 #endif
    00382
    00383 #define FITSHDR_KEYWORD  0x01
    00384 #define FITSHDR_KEYVALUE 0x02
    00385 #define FITSHDR_COMMENT  0x04
    00386 #define FITSHDR_KEYREC   0x08
    00387 #define FITSHDR_CARD     0x08   /* Alias for backwards compatibility. */
    00388 #define FITSHDR_TRAILER  0x10
    00389
    00390
    00391 extern const char *fitshdr_errmsg[];
    00392
    00393 #ifdef WCSLIB_INT64
    00394   typedef WCSLIB_INT64 int64;
    00395 #else
    00396   typedef int int64[3];
    00397 #endif
    00398
    00399
    00400 /* Struct used for indexing the keywords. */
    00401 struct fitskeyid {
    00402   char name[12];                /* Keyword name, null-terminated.           */
    00403   int  count;                   /* Number of occurrences of keyword.        */
    00404   int  idx[2];                  /* Indices into fitskey array.              */
    00405 };
    00406
    00407 /* Size of the fitskeyid struct in int units, used by the Fortran wrappers. */
    00408 #define KEYIDLEN (sizeof(struct fitskeyid)/sizeof(int))
    00409
    00410
    00411 /* Struct used for storing FITS keywords. */
    00412 struct fitskey {
    00413   int  keyno;                   /* Header keyrecord sequence number (1-rel).*/
    00414   int  keyid;                   /* Index into fitskeyid[].                  */
    00415   int  status;                  /* Header keyrecord status bit flags.       */
    00416   char keyword[12];             /* Keyword name, null-filled.               */
    00417   int  type;                    /* Keyvalue type (see above).               */
    00418   int  padding;                 /* (Dummy inserted for alignment purposes.) */
    00419   union {
    00420     int    i;                   /* 32-bit integer and logical values.       */
    00421     int64  k;                   /* 64-bit integer values.                   */
    00422     int    l[8];                /* Very long signed integer values.         */
    00423     double f;                   /* Floating point values.                   */
    00424     double c[2];                /* Complex values.                          */
    00425     char   s[72];               /* String values, null-terminated.          */
    00426   } keyvalue;                   /* Keyvalue.                                */
    00427   int  ulen;                    /* Length of units string.                  */
    00428   char comment[84];             /* Comment (or keyrecord), null-terminated. */
    00429 };
    00430
    00431 /* Size of the fitskey struct in int units, used by the Fortran wrappers. */
    00432 #define KEYLEN (sizeof(struct fitskey)/sizeof(int))
    00433
    00434
    00435 int fitshdr(const char header[], int nkeyrec, int nkeyids,
    00436             struct fitskeyid keyids[], int *nreject, struct fitskey **keys);
    00437
    00438
    00439 #ifdef __cplusplus
    00440 }
    00441 #endif
    00442
    00443 #endif /* WCSLIB_FITSHDR */