- Main Page
- Related Pages
- Data Structures
- Files

# fitshdr.h

Go to the documentation of this file.

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