## 4 CFITSIO Routines

This chapter describes the main CFITSIO routines that can be used to perform the most common types of operations on FITS files.

### 4.1 Error Reporting

    void fits_report_error(FILE *stream, int status)
    void fits_get_errstatus(int status, char *err_text)
    float fits_get_version(float *version)

The first routine prints out information about any error that has occurred. Whenever any CFITSIO routine encounters an error it usually writes a message describing the nature of the error to an internal error message stack and then returns with a positive integer status value. Passing the error status value to this routine will cause a generic description of the error and all the messages from the internal CFITSIO error stack to be printed to the specified stream. The stream parameter is usually set equal to "stdout" or "stderr".

The second routine simply returns a 30-character descriptive error message corresponding to the input status value.

The last routine returns the current CFITSIO library version number.

### 4.2 File Open/Close Routines

    int fits_open_file( fitsfile **fptr, char *filename, int mode, int *status)
    int fits_open_data( fitsfile **fptr, char *filename, int mode, int *status)
    int fits_open_table(fitsfile **fptr, char *filename, int mode, int *status)
    int fits_open_image(fitsfile **fptr, char *filename, int mode, int *status)

    int fits_create_file(fitsfile **fptr, char *filename, int *status)
    int fits_close_file(fitsfile *fptr, int *status)

These routines open or close a file. The first fitsfile parameter in these and nearly every other CFITSIO routine is a pointer to a structure that CFITSIO uses to store relevant parameters about each opened file. You should never directly read or write any information in this structure. Memory for this structure is allocated automatically when the file is opened or created, and is freed when the file is closed.

The mode parameter in the fits_open_xxxx set of routines can be set to either READONLY or READWRITE to select the type of file access that will be allowed. These symbolic constants are defined in fitsio.h.

The fits_open_file routine opens the file and positions the internal file pointer to the beginning of the file, or to the specified extension if an extension name or number is appended to the file name (see the later section on “CFITSIO File Names and Filters” for a description of the syntax). fits_open_data behaves similarly except that it will move to the first HDU containing significant data if a HDU name or number to open is not explicitly specified as part of the filename. It will move to the first IMAGE HDU with NAXIS greater than 0, or the first table that does not contain the strings ‘GTI’ (a Good Time Interval extension) or ‘OBSTABLE’ in the EXTNAME keyword value. The fits_open_table and fits_open_image routines are similar except that they will move to the first significant table HDU or image HDU, respectively if a HDU name of number is not specified as part of the input file name.

When opening an existing file, the filename can include optional arguments, enclosed in square brackets that specify filtering operations that should be applied to the input file. For example,

       myfile.fit[EVENTS][counts > 0]

opens the table in the EVENTS extension and creates a virtual table by selecting only those rows where the COUNTS column value is greater than 0. See section 5 for more examples of these powerful filtering capabilities.

In fits_create_file, the filename is simply the root name of the file to be created. You can overwrite an existing file by prefixing the name with a ‘!’ character (on the Unix command line this must be prefixed with a backslash, as in ``\!file.fit'`). If the file name ends with .gz the file will be compressed using the gzip algorithm. If the filename is stdout or "-" (a single dash character) then the output file will be piped to the stdout stream. You can chain several tasks together by writing the output from the first task to stdout and then reading the input file in the 2nd task from stdin or "-".

### 4.3 HDU-level Routines

The routines listed in this section operate on Header-Data Units (HDUs) in a file.

    _______________________________________________________________
    int fits_get_num_hdus(fitsfile *fptr, int *hdunum, int *status)
    int fits_get_hdu_num(fitsfile *fptr,  int *hdunum)

The first routines returns the total number of HDUs in the FITS file, and the second routine returns the position of the currently opened HDU in the FITS file (starting with 1, not 0).

    __________________________________________________________________________
    int fits_movabs_hdu(fitsfile *fptr, int hdunum, int *hdutype, int *status)
    int fits_movrel_hdu(fitsfile *fptr, int nmove,  int *hdutype, int *status)
    int fits_movnam_hdu(fitsfile *fptr, int hdutype, char *extname,
                        int extver, int *status)

These routines enable you to move to a different HDU in the file. Most of the CFITSIO functions which read or write keywords or data operate only on the currently opened HDU in the file. The first routine moves to the specified absolute HDU number in the FITS file (the first HDU = 1), whereas the second routine moves a relative number of HDUs forward or backward from the currently open HDU. The hdutype parameter returns the type of the newly opened HDU, and will be equal to one of these symbolic constant values: IMAGE_HDU, ASCII_TBL, or BINARY_TBL. hdutype may be set to NULL if it is not needed. The third routine moves to the (first) HDU that matches the input extension type, name, and version number, as given by the XTENSION, EXTNAME (or HDUNAME) and EXTVER keywords. If the input value of extver = 0, then the version number will be ignored when looking for a matching HDU.

    _________________________________________________________________
    int fits_get_hdu_type(fitsfile *fptr,  int *hdutype, int *status)

Get the type of the current HDU in the FITS file: IMAGE_HDU, ASCII_TBL, or BINARY_TBL.

    ____________________________________________________________________
    int fits_copy_hdu(fitsfile *infptr, fitsfile *outfptr, int morekeys,
                      int *status)
    int fits_copy_file(fitsfile *infptr, fitsfile *outfptr, int previous,
                      int current, int following, > int *status)

The first routine copies the current HDU from the FITS file associated with infptr and appends it to the end of the FITS file associated with outfptr. Space may be reserved for morekeys additional keywords in the output header. The second routine copies any HDUs previous to the current HDU, and/or the current HDU, and/or any HDUs following the current HDU, depending on the value (True or False) of previous, current, and following, respectively. For example,

      fits_copy_file(infptr, outfptr, 0, 1, 1, &status);

will copy the current HDU and any HDUs that follow it from the input to the output file, but it will not copy any HDUs preceding the current HDU.

### 4.4 Image I/O Routines

This section lists the more important CFITSIO routines which operate on FITS images.

    _______________________________________________________________
    int fits_get_img_type(fitsfile *fptr, int *bitpix, int *status)
    int fits_get_img_dim( fitsfile *fptr, int *naxis,  int *status)
    int fits_get_img_size(fitsfile *fptr, int maxdim,  long *naxes,
                          int *status)
    int fits_get_img_param(fitsfile *fptr, int maxdim,  int *bitpix,
                           int *naxis, long *naxes, int *status)

Get information about the currently opened image HDU. The first routine returns the datatype of the image as (defined by the BITPIX keyword), which can have the following symbolic constant values:

        BYTE_IMG      =   8   ( 8-bit byte pixels, 0 - 255)
        SHORT_IMG     =  16   (16 bit integer pixels)
        LONG_IMG      =  32   (32-bit integer pixels)
        LONGLONG_IMG  =  64   (64-bit integer pixels)
        FLOAT_IMG     = -32   (32-bit floating point pixels)
        DOUBLE_IMG    = -64   (64-bit floating point pixels)

The second and third routines return the number of dimensions in the image (from the NAXIS keyword), and the sizes of each dimension (from the NAXIS1, NAXIS2, etc. keywords). The last routine simply combines the function of the first 3 routines. The input maxdim parameter in this routine gives the maximum number dimensions that may be returned (i.e., the dimension of the naxes array)

    __________________________________________________________
    int fits_create_img(fitsfile *fptr, int bitpix, int naxis,
                        long *naxes, int *status)

Create an image HDU by writing the required keywords which define the structure of the image. The 2nd through 4th parameters specified the datatype, the number of dimensions, and the sizes of the dimensions. The allowed values of the bitpix parameter are listed above in the description of the fits_get_img_type routine. If the FITS file pointed to by fptr is empty (previously created with fits_create_file) then this routine creates a primary array in the file, otherwise a new IMAGE extension is appended to end of the file following the other HDUs in the file.

    ______________________________________________________________
    int fits_write_pix(fitsfile *fptr, int datatype, long *fpixel,
                   long nelements, void *array, int *status);

    int fits_write_pixnull(fitsfile *fptr, int datatype, long *fpixel,
                   long nelements, void *array, void *nulval, int *status);

    int fits_read_pix(fitsfile *fptr, int  datatype, long *fpixel,
                      long nelements, void *nulval, void *array,
                      int *anynul, int *status)

Read or write all or part of the FITS image. There are 2 different ’write’ pixel routines: The first simply writes the input array of pixels to the FITS file. The second is similar, except that it substitutes the appropriate null pixel value in the FITS file for any pixels which have a value equal to *nulval (note that this parameter gives the address of the null pixel value, not the value itself). Similarly, when reading an image, CFITSIO will substitute the value given by nulval for any undefined pixels in the image, unless nulval = NULL, in which case no checks will be made for undefined pixels when reading the FITS image.

The fpixel parameter in these routines is an array which gives the coordinate in each dimension of the first pixel to be read or written, and nelements is the total number of pixels to read or write. array is the address of an array which either contains the pixel values to be written, or will hold the values of the pixels that are read. When reading, array must have been allocated large enough to hold all the returned pixel values. These routines starts at the fpixel location and then read or write the nelements pixels, continuing on successive rows of the image if necessary. For example, to write an entire 2D image, set fpixel[0] = fpixel[1] = 1, and nelements = NAXIS1 * NAXIS2. Or to read just the 10th row of the image, set fpixel[0] = 1, fpixel[1] = 10, and nelements = NAXIS1. The datatype parameter specifies the datatype of the C array in the program, which need not be the same as the datatype of the FITS image itself. If the datatypes differ then CFITSIO will convert the data as it is read or written. The following symbolic constants are allowed for the value of datatype:

      TBYTE     unsigned char
      TSBYTE    signed char
      TSHORT    signed short
      TUSHORT   unsigned short
      TINT      signed int
      TUINT     unsigned int
      TLONG     signed long
      TLONGLONG signed 8-byte integer
      TULONG    unsigned long
      TFLOAT    float
      TDOUBLE   double

    _________________________________________________________________
    int fits_write_subset(fitsfile *fptr, int datatype, long *fpixel,
                 long *lpixel, DTYPE *array, > int *status)

    int fits_read_subset(fitsfile *fptr, int  datatype, long *fpixel,
                 long *lpixel, long *inc, void *nulval,  void *array,
                 int *anynul, int *status)

Read or write a rectangular section of the FITS image. These are very similar to fits_write_pix and fits_read_pix except that you specify the last pixel coordinate (the upper right corner of the section) instead of the number of pixels to be read. The read routine also has an inc parameter which can be used to read only every inc-th pixel along each dimension of the image. Normally inc[0] = inc[1] = 1 to read every pixel in a 2D image. To read every other pixel in the entire 2D image, set

        fpixel[0] = fpixel[1] = 1
        lpixel[0] = {NAXIS1}
        lpixel[1] = {NAXIS2}
        inc[0] = inc[1] = 2

Or, to read the 8th row of a 2D image, set

        fpixel[0] = 1
        fpixel[1] = 8
        lpixel[0] = {NAXIS1}
        lpixel[1] = 8
        inc[0] = inc[1] = 1

### 4.5 Table I/O Routines

This section lists the most important CFITSIO routines which operate on FITS tables.

    __________________________________________________________________________
    int fits_create_tbl(fitsfile *fptr, int tbltype, long nrows, int tfields,
        char *ttype[],char *tform[], char *tunit[], char *extname, int *status)

Create a new table extension by writing the required keywords that define the table structure. The required null primary array will be created first if the file is initially completely empty. tbltype defines the type of table and can have values of ASCII_TBL or BINARY_TBL. Binary tables are generally preferred because they are more efficient and support a greater range of column datatypes than ASCII tables.

The nrows parameter gives the initial number of empty rows to be allocated for the table; this should normally be set to 0. The tfields parameter gives the number of columns in the table (maximum = 999). The ttype, tform, and tunit parameters give the name, datatype, and physical units of each column, and extname gives the name for the table (the value of the EXTNAME keyword). The FITS Standard recommends that only letters, digits, and the underscore character be used in column names with no embedded spaces. It is recommended that all the column names in a given table be unique within the first 8 characters.

The following table shows the TFORM column format values that are allowed in ASCII tables and in binary tables:

            ASCII Table Column Format Codes
            -------------------------------
            (w = column width, d = no. of decimal places to display)
                Aw   - character string
                Iw   - integer
                Fw.d - fixed floating point
                Ew.d - exponential floating point
                Dw.d - exponential floating point

            Binary Table Column Format Codes
            --------------------------------
            (r = vector length, default = 1)
                rA  - character string
                rAw - array of strings, each of length w
                rL  - logical
                rX  - bit
                rB  - unsigned byte
                rS  - signed byte **
                rI  - signed 16-bit integer
                rU  - unsigned 16-bit integer **
                rJ  - signed 32-bit integer
                rV  - unsigned 32-bit integer **
                rK  - signed 64-bit integer
                rE  - 32-bit floating point
                rD  - 64-bit floating point
                rC  - 32-bit complex pair
                rM  - 64-bit complex pair

         ** The S, U and V format codes are not actual legal TFORMn values.
            CFITSIO substitutes the somewhat more complicated set of
            keywords that are used to represent unsigned integers or
            signed bytes.

The tunit and extname parameters are optional and may be set to NULL if they are not needed.

Note that it may be easier to create a new table by copying the header from another existing table with fits_copy_header rather than calling this routine.

    _______________________________________________________________
    int fits_get_num_rows(fitsfile *fptr, long *nrows, int *status)
    int fits_get_num_cols(fitsfile *fptr, int  *ncols, int *status)

Get the number of rows or columns in the current FITS table. The number of rows is given by the NAXIS2 keyword and the number of columns is given by the TFIELDS keyword in the header of the table.

    _______________________________________________________________
    int fits_get_colnum(fitsfile *fptr, int casesen, char *template,
                        int *colnum, int *status)
    int fits_get_colname(fitsfile *fptr, int casesen, char *template,
                        char *colname, int *colnum, int *status)

Get the column number (starting with 1, not 0) of the column whose name matches the specified template name. The only difference in these 2 routines is that the 2nd one also returns the name of the column that matched the template string.

Normally, casesen should be set to CASEINSEN, but it may be set to CASESEN to force the name matching to be case-sensitive.

The input template string gives the name of the desired column and may include wildcard characters: a ‘*’ matches any sequence of characters (including zero characters), ‘?’ matches any single character, and ‘#’ matches any consecutive string of decimal digits (0-9). If more than one column name in the table matches the template string, then the first match is returned and the status value will be set to COL_NOT_UNIQUE as a warning that a unique match was not found. To find the next column that matches the template, call this routine again leaving the input status value equal to COL_NOT_UNIQUE. Repeat this process until status = COL_NOT_FOUND is returned.

    _______________________________________________________________
    int fits_get_coltype(fitsfile *fptr, int colnum, int *typecode,
                         long *repeat, long *width, int *status)

    int fits_get_eqcoltype(fitsfile *fptr, int colnum, int *typecode,
                         long *repeat, long *width, int *status)

Return the datatype, vector repeat count, and the width in bytes of a single column element for column number colnum. Allowed values for the returned datatype in ASCII tables are: TSTRING, TSHORT, TLONG, TFLOAT, and TDOUBLE. Binary tables support these additional types: TLOGICAL, TBIT, TBYTE, TINT32BIT, TCOMPLEX and TDBLCOMPLEX. The negative of the datatype code value is returned if it is a variable length array column.

These 2 routines are similar, except that in the case of scaled integer columns the 2nd routine, fit_get_eqcoltype, returns the ’equivalent’ datatype that is needed to store the scaled values, which is not necessarily the same as the physical datatype of the unscaled values as stored in the FITS table. For example if a ’1I’ column in a binary table has TSCALn = 1 and TZEROn = 32768, then this column effectively contains unsigned short integer values, and thus the returned value of typecode will be TUSHORT, not TSHORT. Or, if TSCALn or TZEROn are not integers, then the equivalent datatype will be returned as TFLOAT or TDOUBLE, depending on the size of the integer.

The repeat count is always 1 in ASCII tables. The ’repeat’ parameter returns the vector repeat count on the binary table TFORMn keyword value. (ASCII table columns always have repeat = 1). The ’width’ parameter returns the width in bytes of a single column element (e.g., a ’10D’ binary table column will have width = 8, an ASCII table ’F12.2’ column will have width = 12, and a binary table’60A’ character string column will have width = 60); Note that this routine supports the local convention for specifying arrays of fixed length strings within a binary table character column using the syntax TFORM = ’rAw’ where ’r’ is the total number of characters (= the width of the column) and ’w’ is the width of a unit string within the column. Thus if the column has TFORM = ’60A12’ then this means that each row of the table contains 5 12-character substrings within the 60-character field, and thus in this case this routine will return typecode = TSTRING, repeat = 60, and width = 12. The number of substings in any binary table character string field can be calculated by (repeat/width). A null pointer may be given for any of the output parameters that are not needed.

    ____________________________________________________________________________
    int fits_insert_rows(fitsfile *fptr, long firstrow, long nrows, int *status)
    int fits_delete_rows(fitsfile *fptr, long firstrow, long nrows, int *status)
    int fits_delete_rowrange(fitsfile *fptr, char *rangelist, int *status)
    int fits_delete_rowlist(fitsfile *fptr, long *rowlist, long nrows, int *stat)

Insert or delete rows in a table. The blank rows are inserted immediately following row frow. Set frow = 0 to insert rows at the beginning of the table. The first ’delete’ routine deletes nrows rows beginning with row firstrow. The 2nd delete routine takes an input string listing the rows or row ranges to be deleted (e.g., ’2,4-7, 9-12’). The last delete routine takes an input long integer array that specifies each individual row to be deleted. The row lists must be sorted in ascending order. All these routines update the value of the NAXIS2 keyword to reflect the new number of rows in the table.

    _________________________________________________________________________
    int fits_insert_col(fitsfile *fptr, int colnum, char *ttype, char *tform,
                        int *status)
    int fits_insert_cols(fitsfile *fptr, int colnum, int ncols, char **ttype,
                         char **tform, int *status)

    int fits_delete_col(fitsfile *fptr, int colnum, int *status)

Insert or delete columns in a table. colnum gives the position of the column to be inserted or deleted (where the first column of the table is at position 1). ttype and tform give the column name and column format, where the allowed format codes are listed above in the description of the fits_create_table routine. The 2nd ’insert’ routine inserts multiple columns, where ncols is the number of columns to insert, and ttype and tform are arrays of string pointers in this case.

    ____________________________________________________________________
    int fits_copy_col(fitsfile *infptr, fitsfile *outfptr, int incolnum,
            int outcolnum, int create_col, int *status);

Copy a column from one table HDU to another. If create_col = TRUE (i.e., not equal to zero), then a new column will be inserted in the output table at position outcolumn, otherwise the values in the existing output column will be overwritten.

    __________________________________________________________________________
    int fits_write_col(fitsfile *fptr, int datatype, int colnum, long firstrow,
                      long firstelem, long nelements, void *array, int *status)
    int fits_write_colnull(fitsfile *fptr, int datatype, int colnum,
                      long firstrow, long firstelem, long nelements,
                      void *array, void *nulval, int *status)
    int fits_write_col_null(fitsfile *fptr, int colnum, long firstrow,
                      long firstelem, long nelements, int *status)

    int fits_read_col(fitsfile *fptr, int datatype, int colnum, long firstrow,
           long firstelem, long nelements, void *nulval, void *array,
           int *anynul, int *status)

Write or read elements in column number colnum, starting with row firstsrow and element firstelem (if it is a vector column). firstelem is ignored if it is a scalar column. The nelements number of elements are read or written continuing on successive rows of the table if necessary. array is the address of an array which either contains the values to be written, or will hold the returned values that are read. When reading, array must have been allocated large enough to hold all the returned values.

There are 3 different ’write’ column routines: The first simply writes the input array into the column. The second is similar, except that it substitutes the appropriate null pixel value in the column for any input array values which are equal to *nulval (note that this parameter gives the address of the null pixel value, not the value itself). The third write routine sets the specified table elements to a null value. New rows will be automatical added to the table if the write operation extends beyond the current size of the table.

When reading a column, CFITSIO will substitute the value given by nulval for any undefined elements in the FITS column, unless nulval or *nulval = NULL, in which case no checks will be made for undefined values when reading the column.

datatype specifies the datatype of the C array in the program, which need not be the same as the intrinsic datatype of the column in the FITS table. The following symbolic constants are allowed for the value of datatype:

      TSTRING   array of character string pointers
      TBYTE     unsigned char
      TSHORT    signed short
      TUSHORT   unsigned short
      TINT      signed int
      TUINT     unsigned int
      TLONG     signed long
      TLONGLONG signed 8-byte integer
      TULONG    unsigned long
      TFLOAT    float
      TDOUBLE   double

Note that TSTRING corresponds to the C char** datatype, i.e., a pointer to an array of pointers to an array of characters.

Any column, regardless of it’s intrinsic datatype, may be read as a TSTRING character string. The display format of the returned strings will be determined by the TDISPn keyword, if it exists, otherwise a default format will be used depending on the datatype of the column. The tablist example utility program (available from the CFITSIO web site) uses this feature to display all the values in a FITS table.

    _____________________________________________________________________
    int fits_select_rows(fitsfile *infptr, fitsfile *outfptr, char *expr,
                         int *status)
    int fits_calculator(fitsfile *infptr, char *expr, fitsfile *outfptr,
                        char *colname, char *tform, int *status)

These are 2 of the most powerful routines in the CFITSIO library. (See the full CFITSIO Reference Guide for a description of several related routines). These routines can perform complicated transformations on tables based on an input arithmetic expression which is evaluated for each row of the table. The first routine will select or copy rows of the table for which the expression evaluates to TRUE (i.e., not equal to zero). The second routine writes the value of the expression to a column in the output table. Rather than supplying the expression directly to these routines, the expression may also be written to a text file (continued over multiple lines if necessary) and the name of the file, prepended with a ’@’ character, may be supplied as the value of the ’expr’ parameter (e.g. ’@filename.txt’).

The arithmetic expression may be a function of any column or keyword in the input table as shown in these examples:

    Row Selection Expressions:
       counts > 0                          uses COUNTS column value
       sqrt( X**2 + Y**2) < 10.            uses X and Y column values
       (X > 10) || (X < -10) && (Y == 0)   used 'or' and 'and' operators
       gtifilter()                         filter on Good Time Intervals
       regfilter("myregion.reg")           filter using a region file
       @select.txt                         reads expression from a text file
    Calculator Expressions:
       #row % 10                        modulus of the row number
       counts/#exposure                 Fn of COUNTS column and EXPOSURE keyword
       dec < 85 ? cos(dec * #deg) : 0   Conditional expression: evaluates to
                                          cos(dec) if dec < 85, else 0
       (count{-1}+count+count{+1})/3.   running mean of the count values in the
                                          previous, current, and next rows
       max(0, min(X, 1000))             returns a value between 0 - 1000
       @calc.txt                        reads expression from a text file

Most standard mathematical operators and functions are supported. If the expression includes the name of a column, than the value in the current row of the table will be used when evaluating the expression on each row. An offset to an adjacent row can be specified by including the offset value in curly brackets after the column name as shown in one of the examples. Keyword values can be included in the expression by preceding the keyword name with a ‘#’ sign. See Section 5 of this document for more discussion of the expression syntax.

gtifilter is a special function which tests whether the TIME column value in the input table falls within one or more Good Time Intervals. By default, this function looks for a ’GTI’ extension in the same file as the input table. The ’GTI’ table contains START and STOP columns which define the range of each good time interval. See section 5.4.3 for more details.

regfilter is another special function which selects rows based on whether the spatial position associated with each row is located within in a specified region of the sky. By default, the X and Y columns in the input table are assumed to give the position of each row. The spatial region is defined in an ASCII text file whose name is given as the argument to the regfilter function. See section 5.4.4 for more details.

The infptr and outfptr parameters in these routines may point to the same table or to different tables. In fits_select_rows, if the input and output tables are the same then the rows that do not satisfy the selection expression will be deleted from the table. Otherwise, if the output table is different from the input table then the selected rows will be copied from the input table to the output table.

The output column in fits_calculator may or may not already exist. If it exists then the calculated values will be written to that column, overwriting the existing values. If the column doesn’t exist then the new column will be appended to the output table. The tform parameter can be used to specify the datatype of the new column (e.g., the TFORM keyword value as in ’1E’, or ’1J’). If tform = NULL then a default datatype will be used, depending on the expression.

    _____________________________________________________________________
    int fits_read_tblbytes(fitsfile *fptr, long firstrow, long firstchar,
                         long nchars, unsigned char *array, int *status)
    int fits_write_tblbytes (fitsfile *fptr, long firstrow, long firstchar,
                         long nchars, unsigned char *array, int *status)

These 2 routines provide low-level access to tables and are mainly useful as an efficient way to copy rows of a table from one file to another. These routines simply read or write the specified number of consecutive characters (bytes) in a table, without regard for column boundaries. For example, to read or write the first row of a table, set firstrow = 1, firstchar = 1, and nchars = NAXIS1 where the length of a row is given by the value of the NAXIS1 header keyword. When reading a table, array must have been declared at least nchars bytes long to hold the returned string of bytes.

### 4.6 Header Keyword I/O Routines

The following routines read and write header keywords in the current HDU.

    ____________________________________________________________________
    int fits_get_hdrspace(fitsfile *fptr, int *keysexist, int *morekeys,
                          int *status)

Return the number of existing keywords (not counting the mandatory END keyword) and the amount of empty space currently available for more keywords. The morekeys parameter may be set to NULL if it’s value is not needed.

    ___________________________________________________________________________
    int fits_read_record(fitsfile *fptr, int keynum, char *record, int *status)
    int fits_read_card(fitsfile *fptr, char *keyname, char *record, int *status)
    int fits_read_key(fitsfile *fptr, int datatype, char *keyname,
                      void *value, char *comment, int *status)

    int fits_find_nextkey(fitsfile *fptr, char **inclist, int ninc,
                          char **exclist, int nexc, char *card, int *status)

    int fits_read_key_unit(fitsfile *fptr, char *keyname, char *unit,
                           int *status)

These routines all read a header record in the current HDU. The first routine reads keyword number keynum (where the first keyword is at position 1). This routine is most commonly used when sequentially reading every record in the header from beginning to end. The 2nd and 3rd routines read the named keyword and return either the whole record, or the keyword value and comment string. In each case any non-significant trailing blank characters in the strings are truncated.

Wild card characters (*, ?, and #) may be used when specifying the name of the keyword to be read, in which case the first matching keyword is returned.

The datatype parameter specifies the C datatype of the returned keyword value and can have one of the following symbolic constant values: TSTRING, TLOGICAL (== int), TBYTE, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TFLOAT, TDOUBLE, TCOMPLEX, and TDBLCOMPLEX. Data type conversion will be performed for numeric values if the intrinsic FITS keyword value does not have the same datatype. The comment parameter may be set equal to NULL if the comment string is not needed.

The 4th routine provides an easy way to find all the keywords in the header that match one of the name templates in inclist and do not match any of the name templates in exclist. ninc and nexc are the number of template strings in inclist and exclist, respectively. Wild cards (*, ?, and #) may be used in the templates to match multiple keywords. Each time this routine is called it returns the next matching 80-byte keyword record. It returns status = KEY_NO_EXIST if there are no more matches.

The 5th routine returns the keyword value units string, if any. The units are recorded at the beginning of the keyword comment field enclosed in square brackets.

    _______________________________________________________________
    int fits_write_key(fitsfile *fptr, int datatype, char *keyname,
            void *value, char *comment, int *status)
    int fits_update_key(fitsfile *fptr, int datatype, char *keyname,
            void *value, char *comment, int *status)
    int fits_write_record(fitsfile *fptr, char *card, int *status)

    int fits_modify_comment(fitsfile *fptr, char *keyname, char *comment,
            int *status)
    int fits_write_key_unit(fitsfile *fptr, char *keyname, char *unit,
            int *status)

Write or modify a keyword in the header of the current HDU. The first routine appends the new keyword to the end of the header, whereas the second routine will update the value and comment fields of the keyword if it already exists, otherwise it behaves like the first routine and appends the new keyword. Note that value gives the address to the value and not the value itself. The datatype parameter specifies the C datatype of the keyword value and may have any of the values listed in the description of the keyword reading routines, above. A NULL may be entered for the comment parameter, in which case the keyword comment field will be unmodified or left blank.

The third routine is more primitive and simply writes the 80-character card record to the header. It is the programmer’s responsibility in this case to ensure that the record conforms to all the FITS format requirements for a header record.

The fourth routine modifies the comment string in an existing keyword, and the last routine writes or updates the keyword units string for an existing keyword. (The units are recorded at the beginning of the keyword comment field enclosed in square brackets).

    ___________________________________________________________________
    int fits_write_comment(fitsfile *fptr, char *comment,  int *status)
    int fits_write_history(fitsfile *fptr, char *history,  int *status)
    int fits_write_date(fitsfile *fptr,  int *status)

Write a COMMENT, HISTORY, or DATE keyword to the current header. The COMMENT keyword is typically used to write a comment about the file or the data. The HISTORY keyword is typically used to provide information about the history of the processing procedures that have been applied to the data. The comment or history string will be continued over multiple keywords if it is more than 70 characters long.

The DATE keyword is used to record the date and time that the FITS file was created. Note that this file creation date is usually different from the date of the observation which obtained the data in the FITS file. The DATE keyword value is a character string in ’yyyy-mm-ddThh:mm:ss’ format. If a DATE keyword already exists in the header, then this routine will update the value with the current system date.

    ___________________________________________________________________
    int fits_delete_record(fitsfile *fptr, int keynum,  int *status)
    int fits_delete_key(fitsfile *fptr, char *keyname,  int *status)

Delete a keyword record. The first routine deletes a keyword at a specified position (the first keyword is at position 1, not 0), whereas the second routine deletes the named keyword.

    _______________________________________________________________________
    int fits_copy_header(fitsfile *infptr, fitsfile *outfptr,  int *status)

Copy all the header keywords from the current HDU associated with infptr to the current HDU associated with outfptr. If the current output HDU is not empty, then a new HDU will be appended to the output file. The output HDU will then have the identical structure as the input HDU, but will contain no data.

### 4.7 Utility Routines

This section lists the most important CFITSIO general utility routines.

    ___________________________________________________________________
    int fits_write_chksum( fitsfile *fptr, int *status)
    int fits_verify_chksum(fitsfile *fptr, int *dataok, int *hduok, int *status)

These routines compute or validate the checksums for the currenrt HDU. The DATASUM keyword is used to store the numerical value of the 32-bit, 1’s complement checksum for the data unit alone. The CHECKSUM keyword is used to store the ASCII encoded COMPLEMENT of the checksum for the entire HDU. Storing the complement, rather than the actual checksum, forces the checksum for the whole HDU to equal zero. If the file has been modified since the checksums were computed, then the HDU checksum will usually not equal zero.

The returned dataok and hduok parameters will have a value = 1 if the data or HDU is verified correctly, a value = 0 if the DATASUM or CHECKSUM keyword is not present, or value = -1 if the computed checksum is not correct.

    ___________________________________________________________________
    int fits_parse_value(char *card, char *value, char *comment, int *status)
    int fits_get_keytype(char *value, char *dtype, int *status)
    int fits_get_keyclass(char *card)
    int fits_parse_template(char *template, char *card, int *keytype, int *status)

fits_parse_value parses the input 80-chararacter header keyword record, returning the value (as a literal character string) and comment strings. If the keyword has no value (columns 9-10 not equal to ’= ’), then a null value string is returned and the comment string is set equal to column 9 - 80 of the input string.

fits_get_keytype parses the keyword value string to determine its datatype. dtype returns with a value of ’C’, ’L’, ’I’, ’F’ or ’X’, for character string, logical, integer, floating point, or complex, respectively.

fits_get_keyclass returns a classification code that indicates the classification type of the input keyword record (e.g., a required structural keyword, a TDIM keyword, a WCS keyword, a comment keyword, etc. See the CFITSIO Reference Guide for a list of the different classification codes.

fits_parse_template takes an input free format keyword template string and returns a formatted 80*char record that satisfies all the FITS requirements for a header keyword record. The template should generally contain 3 tokens: the keyword name, the keyword value, and the keyword comment string. The returned keytype parameter indicates whether the keyword is a COMMENT keyword or not. See the CFITSIO Reference Guide for more details.