fitshdr.h

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

Generated on Mon Sep 14 17:03:55 2009 for WCSLIB 4.4 by  doxygen 1.5.1